我是指针和学习指针基础知识的新手。我想知道它们之间的区别 * ptr和*(& ptr + 1)来自以下代码。
#include<stdio.h>
int main()
{
int a[3] = {1, 2, 3};
int *ptr = a;
printf("*ptr = %d\n",*ptr);
printf("&ptr = %p\n",&ptr);
printf("(&ptr + 1) = %p\n",(&ptr + 1));
printf("*(&ptr + 1) = %d\n",*(&ptr + 1));
return 0;
}
根据我的分析,gcc产生了以下输出,
*ptr = 1 // as ptr = a, Ultimately *ptr will print the first value of array i.e. 1
&ptr = 0x7fffa7e97788 // Starting Address of array or address of first element
(&ptr + 1) = 0x7fffa7e97790 //address of next element in the array
*(&ptr + 1) = 1 // I want to know how this is getting dereffered
先谢谢。
答案 0 :(得分:8)
&ptr
是指针变量ptr
的地址。该地址与数组的地址无关。
*(&ptr + 1)
是未定义的行为,因为&ptr + 1
比ptr
的地址快一步。取消引用这样的指针会产生未定义的行为。
你的意思是*(ptr + 1)
。
答案 1 :(得分:7)
似乎编译器按照以下方式在堆栈上放置了定义的对象
--------------------------------
| ptr | a[0] | a[1] | a[2] |
--------------------------------
因此&ptr
是分配ptr的地址。 &ptr + 1
是ptr之后的下一个地址,同时它是[0]的地址。
考虑到编译器必须将局部变量放在堆栈上的顺序是未指定的。
似乎在编译程序的环境sizeof( int * )
中,to sizeof( *( &ptr + 1 ) )
对应sizeof( int )
等于sizeof( int * )
,而等于4。
sizeof( int )
等于8,但%d
等于4.正如您在printf中使用格式说明符*( &ptr + 1 )
表达式printf("(&ptr + 1) = %p\n", &ptr + 1 );
printf("(&a[0]) = %p\n", &a[0] );
那样,输出的确是[0]。< / p>
顺便说一句,您可以通过打印来检查此方案是否与变量的实际位置相对应
&ptr + 1
如果地址不相等,则表示地址*ptr
处有一些与[0]不对应的任意值。
关于帖子标题中的问题
* ptr和*(&amp; ptr + 1)之间的差异
然后a[0]
对应*(&ptr + 1)
,而使用表达式{{1}}会导致未定义的行为,因为您尝试在ptr之后取消引用地址。
答案 2 :(得分:1)
ptr
是一个指针,指向您案例中的某个有效内存位置。
&ptr
是指针的地址,可以将其分配给双指针
int **ptr1 = &ptr;
否则,您的第一个元素的地址仅由ptr
给出。
如果要解析数组,请
for(i=0;i<4;i++)
{
printf("Value %d is stored in %p\n",ptr[i],(void *)(ptr+i));
}
被取消引用的 (&ptr+1)
会导致未定义的行为,因为这不是您分配的内存。 &ptr
由您控制,而不是&ptr+1
答案 3 :(得分:0)
嗯,这看起来很有意思。首先,正如您所知*ptr
给出a[0]
的值,ptr
包含a[0]
的地址,&ptr
是ptr
的地址即整数指针变量。
考虑到这一点,当您打印*ptr
时,a[0]
即1
的值将被打印,(&ptr+1)
将在地址{ {1}}和ptr
会在地址*(&ptr+1)
处打印该值。在上面的代码中,(&ptr+1)
的地址紧跟在a[0]
的地址之后(即ptr
)。因此,当您打印&ptr
时,它会打印*(&ptr+1)
,因为1
指向&ptr+1
。这取决于分配给变量的内存。
将上述变量声明为全局变量,a[0]
将打印值为零(如果'*(&amp; ptr + 1)'未指向任何位置,因为全局变量初始化为零)。此外,当声明为全局变量和本地变量时,请观察分配给变量的地址的差异。希望这会有所帮助。