理解指针运算符&和取值运算符*的原理

    科技2026-02-16  15

    理解指针运算符&和取值运算符*的原理

    通过下面一段代码的输出结果,可以很好的理解指针运算符&和取值运算符的原理: 文字分析已经写在了代码注释中,是在做实验时根据输出结果分析的

    #include <stdio.h> int main(void) { /* * int a[5] 与 int a 的本质: * 其实两个a并无本质区别,它们都是汇编中的标签 * 汇编中的标签代表的是地址 * 所以这两个a都是代表这片空间的起始地址 * 再具体一点说: * 数组名a代表了一个具有20字节的空间的起始地址 * 整型变量a代表了一个具有4个字节空间的起始地址 */ int a[5] = {1,2,3,4,5};/* a作为右值时代表数组首元素的地址 */ int *ptr = (int *)(&a + 1); /* 数组在栈上的布局 */ for (int i = 0; i < 5; i++) { printf("address a[%d] = %p\n", i, &a[i]); } printf("address a:%p\n", a); /* a代表的是数组首元素的地址 */ printf("address &a:%p\n", &a);/* &a代表的是数组的首地址 */ /* * sizeof(&a) = 8:说明&a是一个指针类型 * 一个类型为T的指针的移动,以sizeof(T)为移动单位 * 所以 * a+1: * a本身就是一个地址,它就是汇编中的一个标签 * a代表的时数组首元素的地址,地址就是一个指针,它是一个int类型的指针,意思就是指针指向4个字节大小的内存单元 * 移动单位为sizeof(int) * &a+1: * 先理解&a: * 取地址符&后面跟的是指针的类型,什么是指针的类型? * int类型的指针,就是这个指针指向4个字节大小的内存空间 * long类型的指针,就是这个指针指向8个字节大小的内存空间 * 这个就是指针的类型 * 所以,因为这里的a是一个数组,内存空间大小为20字节 * 所以 &a + 1 的第一步就是根据a的大小计算出移动单位,然后将&a(地址)加上移动单位,最后得到新的地址 * 理解概念,你是一个什么类型的指针 * * 总结: * &a表示的是一个指针,更具体一点说,代表一个a类型的指针 * 再进一步说,&a 表示的是指向a类型所占有的字节空间的地址 * * & 和 * 的原理: * 取地址符 & 的工作原理: * 1.先计算出占用内存空间的大小: * 举个例子:&a就是先计算出类型a的大小 * 2.将标签a替换成地址 * * * 取值运算符 * 的工作原理: * 举例: * int * p = &a; * *p; * 1.先读取p里的内容,找到内存空间的首地址 * 2.连续读取这个指针类型大小的字节单元 * */ printf("address a+1:%p\n", a+1); /* a+1代表数组第二个元素的地址 */ printf("address &a+1:%p\n", &a+1);/* &a+1代表第二个数组的地址 */ printf("size a:%d\n", sizeof(a)); /* sizeof(a) = 20 */ printf("size &a:%d\n", sizeof(&a));/* sizeof(&a) = 8 */ printf("address (int *)(&a + 1):%p\n", ptr); printf("address (int *)(&a + 1):%p\n", (int *)(&a +1)); printf("%d, %d\n", *(a + 1), *(ptr - 1)); return 0; }

    输出结果:

    address a[0] = 0x7ffc494a8200 address a[1] = 0x7ffc494a8204 address a[2] = 0x7ffc494a8208 address a[3] = 0x7ffc494a820c address a[4] = 0x7ffc494a8210 address a:0x7ffc494a8200 address &a:0x7ffc494a8200 address a+1:0x7ffc494a8204 address &a+1:0x7ffc494a8214 size a:20 size &a:8 address (int *)(&a + 1):0x7ffc494a8214 address (int *)(&a + 1):0x7ffc494a8214 2, 5

    图解: 上面的输出结果对应的图,更容易理解

    Processed: 0.012, SQL: 9