精华内容
下载资源
问答
  • 指针运算

    2018-06-04 11:46:33
    什么是指针运算 指针运算是指针对指针进行整数加减运算,以及指针之间进行减法运算的功能,那么指针的加减运算的加n或减n是不是在原来的基础上加n或减n呢。下面通过gdb调试方法去了解指针的加减运算。 调试程序 ...

    博客搬家:https://blog.csdn.net/zheyufuck/article/details/53187042

    什么是指针运算

    指针运算是指针对指针进行整数加减运算,以及指针之间进行减法运算的功能,那么指针的加减运算的加n或减n是不是在原来的基础上加n或减n呢。下面通过gdb调试方法去了解指针的加减运算。

    调试程序

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    struct stu{
    
            int age;
            char * name;
    
    };
    
    
    int main(){
    
            int num = 10;
            int *p_num = &num;
    
            printf("p_num value is %d\n",*p_num);
    
            struct stu * p_stu = (struct stu*)malloc(sizeof(*p_stu));
            p_stu->name = (char*)malloc(5*sizeof(char));
            strcpy(p_stu->name,"jack");
            p_stu->age = 20;
    
            printf("student name is: %s",p_stu->name);
            printf("\t age is: %d\n",p_stu->age);
    
    
            return 0;
    }           

    ①指针 p_num 的运算:
    先打印p_num,再打印进行加减运算的后的值:
    这里写图片描述
    为什么对指针加n或减n之后的结果是增加了’n×4’或减少了’n×4’呢,而不是直接加n或减n呢。这就是指针运算的特征了;在c语言中,对指针进行加1或减1的运算,地址的值会增加当前指针所指向数据类型的长度。而这里p_num的值实际是num变量的地址,num为int类型,占用4个字节,这也就是为什么是加n×4或减n×4的原因:
    这里写图片描述

    ②指针 p_stu 的运算:
    先打印p_stu,再打印进行加减运算的后的值:
    这里写图片描述

    先打印&p_stu->name,再打印进行加减运算的后的值:
    这里写图片描述

    总结

    对于指针的运算,对指针加减N,指针前进或后退“当前指针指向的数据类型的长度×N”

    展开全文
  • C++漫谈指针运算

    万次阅读 2019-04-09 14:24:55
    C++漫谈指针运算 首先我问大家一个问题:指针为什么要有自己的类型? 前不久我也问过自己同样的问题,你想,既然指针存储的是一个地址,即一串十六进制的数字,那他完全可以没有类型,因为地址又不会有什么和数据...

    C++漫谈指针运算

    首先我们先提出一个问题:指针为什么要有自己的类型?

    前不久我也问过自己同样的问题,既然指针存储的是一个地址,即一串十六进制的数字,那他完全没必要有自己的类型,因为地址并不会有什么和数据类型有关的差异。那为什么还要有int类型指针,char类型指针这些呢,后来联想到指针运算才想明白这个问题。那么,什么是指针运算呢?

    指针作为一个变量当然也可以进行运算,但是他的运算方式与普通运算不同,我们先来看一个例子:

    #include <iostream>
    
    int main(void)
    {
        int a = 6;
        int *pointer = &a;
        std::cout << "地址1:" << pointer << std::endl;
        std::cout << "地址2:" << (pointer + 1) << std::endl;
        return 0;
    }
    

    运行这段代码查看输出结果,你会发现两个地址的差值是4个字节,正好是一个int类型占的字节数。这两者有什么联系吗?为什么不是一个字节而四个字节呢?是因为在指针运算中,编译器是根据指针的类型来进行加减运算,也就是说,加减的字节数将与指针的类型进行绑定。比如,如果我们把一个指向char类型的指针进行加一操作,地址的变化将会是一个字节,这正好就是一个char类型所占的字节数。

    以int举例,指针的加减运算可以理解为:指针加1,就是下一个int类型变量的首地址;指针加2,就是下下一个int类型变量的首地址;指针减1,就是上一个int类型变量的首地址;指针减2,就是上上一个int类型变量的首地址;以此类推。是不是很好理解呢?

    如果理解的话我们再来看一个例子:

    #include <iostream>
    using namespace std;
    
    int main() {
    	int m[5] = { 1, 2, 3, 4, 5 };
    	int* p = m;
    	for (int i = 0; i < 5; i++) {
    		cout << *(p + i) << endl;
    	}
    }
    

    如此一来我们就可以用指针来遍历一个数组,有一点要注意的是,这里的数组名m实际上是数组第一个元素的地址,即数组的首指针,因此我们才可以将他的值赋值给指针p,完成下面的指针运算。

    我们再回到文章开头的那个问题,现在大家心里应该有了答案了吧。指针的类型使得所有数据类型的指针运算全部统一起来,无论是什么数据类型,指针+1都是指下一个元素的地址,这种特性使得我们在进行指针运算的时候没有必要再考虑这个数据类型占几个字节,大大简化了编写代码的过程,降低了错误率。

    2019年4月9日

    展开全文
  • 指针运算 到底什么是指针呢? 内存就是一系列有序列号的存储单元,变量就是编译器为内存地址分配的昵称,那么指针是什么呢? 指针就是一个指向另一个内存地址变量的值 指针指向变量的内存地址,指针就像该变量...

    目录

    到底什么是指针呢?

    指针

    指针地址和指针类型

    指针取值

    指针变量初始化

    指针运算符

    多重指针

    指针运算


    到底什么是指针呢?

    内存就是一系列有序列号的存储单元,变量就是编译器为内存地址分配的昵称,那么指针是什么呢?

    指针就是一个指向另一个内存地址变量的值

    指针指向变量的内存地址,指针就像该变量值的内存地址一样

    我们来看一个代码片段

    func main() {
        a := 200
        b := &a
        *b++
        fmt.Println(a)
    }
    

    在 main 函数的第一行,我们定义了一个新的变量 a ,并赋值为 200。接下来我们定义了一个变量 b ,并将变量 a 的地址赋值给 b 。我们并不知道 a 的准确存储地址,但是我们依然可以将 a 的地址存储在变量 b 中。

    因为 Go 强类型的特性,第三行代码也许是最具干扰性的了,b 包含 a 变量的地址,但是我们想增加存储在 a 变量中的值。

    这样我们必须取消引用 b ,而是跟随指针由 b 引用 a。
    然后我们将该值加 1 后,存储回 b 中存储的内存地址上。

    最后一行打印了 a 的值,可以看到 a 的值已经增加为了 201

    指针

    Go语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量

    区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针

    要搞明白Go语言中的指针需要先知道3个概念:指针地址、指针类型和指针取值

    指针地址和指针类型

    Go语言中的指针操作非常简单,只需要记住两个符号:&(取地址)和*(根据地址取值)

    每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用&字符放在变量前面对变量进行“取地址”操作。

    取变量指针的语法如下:

    ptr := &v    // v的类型为T

    其中:

    v:代表被取地址的变量,类型为T
    ptr:用于接收地址的变量,ptr的类型就为*T,称做T的指针类型。*代表指针。

    func main() {
        a := 10
        b := &a
        fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078
        fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
        fmt.Println(&b)                    // 0xc00000e018
    }

    指针取值

     取地址操作符&和取值操作符*是一对互补操作符,&取出地址,*根据地址取出地址指向的值。

    变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

    1.对变量进行取地址(&)操作,可以获得这个变量的指针变量。
    2.指针变量的值是指针地址。
    3.对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。

    • 当一个指针被定义后没有分配到任何变量时,它的值为 nil

    指针变量初始化

    func main() {
        var a *int
        *a = 100
        fmt.Println(*a)
    
        var b map[string]int
        b["测试"] = 100
        fmt.Println(b)
    }
    
    
    // panic: runtime error: invalid memory address or nil pointer dereference
    //[signal 0xc0000005 code=0x1 addr=0x0 pc=0x49a7ca]

    执行上面的代码会引发panic,为什么呢?

    •  在Go语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储。
    • 而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间

     Go语言中new和make是内建的两个函数,主要用来分配内存

    func new(Type) *Type
    func make(t Type, size ...IntegerType) Type

    1. 二者都是用来做内存分配的。
    2. make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身
    3. 而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。

    指针运算符

    1.指针运算符为左值时,我们可以更新目标对象的状态;而为右值时则是为了获取目标的状态。

    func main() {
        x := 10
        var p *int = &x  //获取地址,保存到指针变量
        *p += 20        //用指针间接引用,并更新对象
        println(p, *p)  //输出指针所存储的地址,以及目标对象
    }
    

    输出:

    0xc000040780 30
    

    2.指针类型支持相等运算符,但不能做加减运算和类型转换。如果两个指针指向同一地址,或都为nil,那么它们相等。

    func main() {
        x := 10
        p := &x
    
        p++   //编译报错 invalid operation: p++ (non-numeric type *int)
        var p2 *int = p+1  //invalid operation: p + 1 (mismatched types *int and int)
        p2 = &x
        println(p == p2)   //指向同一地址
    }
    

    可通过unsafe.Pointer将指针转换为uintptr后进行加减法运算,但可能会造成非法访问。


    多重指针

    指针可以指向任何类型的变量。所以也可以指向另一个指针。以下示例显示如何创建指向另一个指针的指针:

    package main
    
    import "fmt"
    
    func main() {
    
    	var a = 3.141596
    	var p = &a
    	var pp = &p
    
    	fmt.Println("a = ", a)
    	fmt.Println("p = ", p)
    	fmt.Println("pp = ", pp)
    
    	fmt.Println("&p = ", &p)
    	fmt.Println("&pp = ", &pp)
    
    	fmt.Println("*p = ", *p)
    	fmt.Println("*pp = ", *pp)
    	fmt.Println("**pp = ", **pp)
    
    	//a =  3.141596
    	//p =  0xc00008e060
    	//pp =  0xc000090018
    	//&p =  0xc000090018
    	//&pp =  0xc000090020
    	//*p =  3.141596
    	//*pp =  0xc00008e060
    	//**pp =  3.141596
    
    }
    

    指针运算

    在很多 golang 程序中,虽然用到了指针,但是并不会对指针进行加减运算,这和 C 程序是很不一样的。Golang 的官方入门学习工具(go tour) 甚至说 Go 不支持指针算术。虽然实际上并不是这样的,但我在一般的 go 程序中,好像确实没见过指针运算(嗯,我知道你想写不一般的程序)。

    • 但实际上,go 可以通过 unsafe.Pointer 来把指针转换为 uintptr 类型的数字,来实现指针运算。
    • 这里请注意,uintptr 是一种整数类型,而不是指针类型。

    比如:

    uintptr(unsafe.Pointer(&p)) + 1
    

    就得到了 &p 的下一个字节的位置。然而,根据 《Go Programming Language》 的提示,我们最好直接把这个计算得到的内存地址转换为指针类型:

    unsafe.Pointer(uintptr(unsafe.Pointer(&p) + 1))
    

    因为 go 中是有垃圾回收机制的,如果某种 GC 挪动了目标值的内存地址,以整型来存储的指针数值,就成了无效的值。

    同时也要注意,go 中对指针的 + 1,真的就只是指向了下一个字节,而 C 中 + 1 或者 ++ 考虑了数据类型的长度,会自动指向当前值结尾后的下一个字节(或者说,有可能就是下一个值的开始)。如果 go 中要想实现同样的效果,可以使用 unsafe.Sizeof 方法:

    unsafe.Pointer(uintptr(unsafe.Pointer(&p) + unsafe.Sizeof(p)))
    

    最后,另外一种常用的指针操作是转换指针类型。这也可以利用 unsafe 包来实现:

    var a int64 = 1
    (*int8)(unsafe.Pointer(&a))
    

    如果你没有遇到过需要转换指针类型的需求,可以看看这个项目(端口扫描工具),其中构建 IP 协议首部的代码,就用到了指针类型转换。

    展开全文
  • 数组与指针运算

    2015-04-21 17:17:59
    数组与指针运算 指针深度讲解教程
  • 以下是对指针的数据类型与指针运算进行了详细的总结介绍,需要的朋友可以过来参考下
  • 指针运算1.1 算术运算1.2 单位长度2. 指针类型 1. 指针运算 1.1 算术运算 加减+、- 指针与整数相加:表示指针指向下个变量。 指针与整数相减:表示指针指向上个变量。 指针与指针相减:两个指针的元素间隔...

    1. 指针运算

    1.1 算术运算

    • 加减+、-
      指针与整数相加:表示指针指向下个变量。
      指针与整数相减:表示指针指向上个变量。
      指针与指针相减:两个指针的元素间隔个数。
      在这里插入图片描述
    • 自增自减++、–
      指针能够算术运算,必然能够自增自减。
      在这里插入图片描述

    在这里插入图片描述

    • *p++/*p--

    操作说明

    1. 操作数是指针

    2. 自增自减++--优先级高于解引用*

    计算过程

    1. 运算++/--,返回的是p的值(地址),然后p自加/自减。
    2. 运算*,获取p指向的值。

    等价于

    *p;
    p=p+1;
    
    自增自减相当于
    *q++*(q++)
    *q--*(q--)

    • *++p/*--p

    操作说明

    1. 操作数是指针
    2. 前缀自增自减++--和解引用*的结合律是自右向左。
    3. 前缀自增自减++--在解引用*的右边,优先计算。

    计算过程

    1. 运算++/--p自加/自减,返回的是p自加/自减后的值(地址)。
    2. 运算*,获取p指向的值。
    自增自减相当于
    *++q*(++q)
    *--q*(--q)

    • ++*q/--*q
      操作说明
    1. *操作数是指针,前缀自增自减++--操作数是指针指向的值。
    2. 前缀自增自减++--和解引用*的结合律是自右向左。
    3. 解引用*在前缀自增自减++--的右边,优先计算。

    计算过程

    1. 运算*,获取p指向的值。
    2. 运算++/--p指向的值自加/自减。
    自增自减相当于
    ++*q++(*q)
    --*q--(*q)

    如果一个表达式里有多个运算符,则先进行优先级比较,先执行优先级高的运算符;如果优先级相同,那就看结合性,根据结合方向来做运算。

    在这里插入图片描述

    1.2 单位长度

    在这里插入图片描述
    从上面可以看到,指针的加1减1,地址并非加1减1。

    应用范围
    指针的算术运算表示在一片连续空间上的移动。
    指针的比较运算也是用于一片连续空间的地址比较。
    常用于数组等连续内存。

    2. 指针类型

    1. 无论指向什么类型,所有指针的大小都是一样的,都是地址的大小。
    char* str;
    short* ps;
    int* pn;
    long* pl;
    long long* pll;
    float* pf;
    double* pd;
    long double* pld;
    
    1. 指针类型转换

    指向不同类型的指针不能直接相互赋值(特例void*),需要强制类型转换。

    char* str = "abcd";
    int* p = str;
    

    指针类型转换没有改变指针内的地址,也没有改变指针指向的值,只是改变了移动的单位长度。
    在这里插入图片描述

    1. void类型的指针
      void*是一种很特别的指针,表示指向未知类型的指针,并不指定它是指向哪一种类型的数据,而是根据需要转换为所需数据类型。
    int n = 0;
    int* p = &n;
    void* q = p;
    int* k = (int*) q;
    

    指针作用小结

    1. 较大数据结构体传入时做参数。
    2. 传入数组后,对数组做操作。
    3. 函数需要多个返回值时,作为返回值参数。
    4. 动态申请内存。
    5. 避免使用未初始化指针、空指针和野指针。
    展开全文
  • 主要介绍了Go语言中的指针运算技巧,实例分析了Go语言指针运算的实现方法,具有一定参考借鉴价值,需要的朋友可以参考下
  • C语言中的指针运算.pdf
  • 用P0 口显示指针运算结果
  • 指针运算包括自增

    2019-05-29 09:14:54
    指针运算, 指针的赋值运算, 1,把一个变量的地址赋给具有相同数据类型的指针变量, int a,*p;p=&a; 2,具有相同数据类型的两个指针之间可以相互赋值, int a,*p,*q;p=&a;q=p; 3,其他常用的赋值...
  • 野指针野指针的成因如何避免野指针指针运算指针+-整数指针-指针指针的关系运算二级指针 指针是什么? 指针的定义 在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)...
  • 本文主要介绍了在ICCAVR中数据类型和指针运算
  • 娓娓道来c指针 (7)指针运算

    千次阅读 2014-07-27 00:11:16
    在前几篇文章中,我们已经见过指针运算的使用场景,并多次使用指针运算来进行验证。这里我们来特别地总结下,指针运算的本质含义。 在c语言中,假设p、pa、pb都是某种类型的指针,这样的运算被称为指针运算: ,...
  • 指针运算——算术运算、关系运算  是不是对指针的任何运算都是合法的呢?答案是它可以执行某些运算,但并非所有的运算都合法。除了加法运算之外,你还可以对指针执行一些其他运算,但并不是很多。  指针加上...
  • 指针运算指针与整数之间在C ++中,您可以将运算符+和 - 应用于指针。 结果与某些方面熟悉的算术运算相似,但在其他方面不同。 将这些运算符应用于指针值的过程称为指针运算(pointer arithmetic.)。 指针算术由一个...
  • 指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)
  • C指针总结--指针运算

    2014-11-04 21:18:05
    关于指针运算的总结:
  • 也谈指针运算

    2013-04-18 14:09:16
    指针在C语言中的位置这里就...指针运算一般针对的是同一连续内存块,不同内存块之间的指针运算无意义,甚至可能导致异常情况。 指针运算主要针对数组,常见的运算类型:+i, -i, ++, –以及 等。 我们以+i操作
  • 单片机C语言实例26:用P0 口显示指针运算结果.txt
  • 指针运算:  1.指针与整数的运算:  a.指针与整数的运算只能加减,不能乘除取余  b.指针与整数的运算得到的结果还是指针(地址)    公式: 指针 + n = 指针 + n * 指向的类型所占的字节数 ...
  • C语言指针三——指针运算本质 对于如下的声明: int arr[]={1,3,5,7,8}; int *p; p=arr; 尽管最后一个语句看起来是将一个指针赋值为数组名,但C语言中并不存在指向数组的指针,日常说某某个指针指向了数组只不过是...
  • 指针运算1.指针的基本运算包括取地址以及取值运算等运算。 单目运算符“&”是取操作对象的地址,“*”是取指针指向的对象的内容,两个互为互逆运算。 示例:int a = 10,*p; p = &a;//p指针指向了a所在的地址,&a...
  • 指针运算实际上是地址运算,但是指针运算又不同于地址运算 指针加1实际上所加的地址值不一定是1,而是该指针的类型所占内存的字节数 int型指针加1在32位机上,地址值被加4。 不同类型的指针加1时,地址值被加...
  • 标题对于指针运算的一些心得总结 最近在复习第三遍C语言,C语言当中指针是个重要的知识点,对于初学C的人来说,指针往往是个头大的板块,之前由于应用场景不多,对于指针的认识还是很浅,然而在数据结构和简化代码...
  • C:指针与数组·上【指针类型,指针运算,二级指针,指针与数组(名)】 指针是什么 指针是一个变量,里面存放的是地址,通过存在指针里的地址能找到所需的变量单元,也说地址指向该变量单元。 指针和指针类型 (1...
  • C++中的指针运算

    2018-11-09 03:01:19
    C++中的指针运算: 在C++中,有一种特殊的运算符与数据类型,也就是指针。指针具有灵活,能够传递与输出多个值的功能,常常与函数相结合,也可以轻松的处理数组中的元素,数组的声明其实就是声明其指针的位置。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 274,742
精华内容 109,896
关键字:

指针运算