C语言中同一内存地址为何存不同值?代码疑问求解
C语言指针地址与取值的疑问解答
问题描述
在以下C语言代码中,第7、8行输出的&q+1与&p的地址相同,但第9、10行输出的*(q+1)与*p的值却不同,地址对比也显示二者一致。而循环中数组元素的地址是连续分配的,这符合预期,但为何之前会出现地址相同的情况?地址为何变化?同一内存空间如何存储不同值?
代码示例
#include<stdio.h> void main(){ int x = 50, *p, *q; int arr[10] = {1,2,3,4,5,6,7,8,9,10}; p = &x; q = &arr[0]; printf("\nValue : %d", &q+1); printf("\nValue : %d", &p); printf("\nValue : %d", *(q+1)); printf("\nValue : %d", *p); if(&p == &q+1){ printf("\nSame"); } printf("\nfor loop"); for(int i=0; i<=10; i++){ printf("\nValue : %d", &q[i]); } }
运行输出
output: Value : 6422292 Value : 6422292 Value : 2 Value : 50 Same for loop Value : 6422248 Value : 6422252 Value : 6422256 Value : 6422260 Value : 6422264 Value : 6422268 Value : 6422272 Value : 6422276 Value : 6422280 Value : 6422284 Value : 6422288
问题分析与解答
这里的核心是混淆了指针变量自身的地址偏移和指针指向内容的地址偏移,两者的计算规则完全不同:
&q+1与&p地址相同的原因q是int*类型的指针变量,&q获取的是q这个变量本身在栈上的内存地址,其类型为int**(指向指针的指针)。- 对指针做
+1运算时,偏移量由指针指向的类型大小决定:&q指向的是int*类型,所以&q+1的偏移量是sizeof(int*)(32位平台为4字节,64位为8字节)。 - 栈上局部变量的分配顺序由编译器决定,
p作为和q同类型的指针变量,刚好被分配在q之后一个指针大小的位置,因此&q+1的地址值恰好等于&p,这是栈内存分配的巧合。
*(q+1)与*p值不同的原因q是指向数组首元素arr[0]的int*指针,q+1的偏移量由int类型的大小决定(通常为4字节),指向的是数组的第二个元素arr[1],因此*(q+1)取到的是arr[1]的值2。p被赋值为&x,指向变量x,*p取到的是x的值50。- 两者指向完全不同的内存空间:
arr[1]的地址是6422252(看循环输出),而x的地址和arr数组的地址区域完全不重叠,自然取值不同。
不存在“同一内存空间存储不同值”的情况
你混淆了两个完全无关的地址:&q+1是指针变量p的地址,而q+1是数组元素arr[1]的地址,这两个地址本身数值就不一样(对比输出里的6422292和6422252),只是错误地将&q+1和q+1当成了同一个地址,才产生了“同一空间存不同值”的误解。
内容的提问来源于stack exchange,提问作者Bitanu Biswas
相关产品推荐
相关产品推荐

