我正在学习C,并且已经开始探索指针和指针算术的世界。例如,在以下代码段中:
int nums[] = {1, 2, 3};
nums
是一个Array变量,其作用类似于指向数组第一个内存位置的指针。我写了下面的示例代码,并试图理解为什么我得到了我得到的结果:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int nums[] = {1, 2, 3};
if(nums == &nums)
puts("nums == &nums");
else
puts("nums != &nums");
if((nums + 1) == (&nums + 1))
puts("(nums + 1) == (&nums + 1)");
else
puts("(nums + 1) != (&nums + 1)");
printf("nums: %i\n", nums);
printf("&nums: %i\n", &nums);
printf("nums + 1: %i\n", nums + 1);
printf("&nums + 1: %i\n", &nums + 1);
return 0;
}
我得到nums == &nums
符合预期的那样;但是,当我应用指针算法并将1
添加到nums
时,此结果不等于&nums + 1
。换句话说,(nums + 1) != (&nums + 1)
即使是nums == &nums
。
这是我得到的程序的输出:
nums == &nums
(nums + 1) != (&nums + 1)
nums: 2345600
&nums: 2345600
nums + 1: 2345604
&nums + 1: 2345612
似乎nums
和nums + 1
被4个字节偏移;但是,&nums
和&nums + 1
偏移12.为什么这个偏移量是12个字节而不是4个?
答案 0 :(得分:7)
混淆与C中的数据有关,数组在某些上下文中隐含地衰减为指针。
更容易解释,nums + 1
实际上意味着&nums[0] + 1
。 nums[0]
是类型int
,每个元素4个字节。因此&nums[0] + 1
在&nums
之后是4个字节。
至于&nums + 1
,&nums
的类型为int(*)[3]
,每个元素为12个字节。因此&nums + 1
在&nums
之后是12个字节。
答案 1 :(得分:2)
两个表达式(int*) nums
和&nums
都有指针类型,但指向的类型不同。您只能在C中测试它们是否相等,而不是C ++。
nums
的类型为int[3]
,即“int
类型的3个对象的数组,(int*) nums
的类型为int*
,也就是说,'指向int
'的指针。向(int*) nums
添加1表示获取指向int
后面的nums[0]
类型对象的指针。就地址而言,意味着添加1 * sizeof (int)
。
&nums
的类型是int(*)[3]
,即“指向3个int
类型对象的数组的指针”。向&nums
添加1表示获取指向int[3]
后面的nums
类型对象的指针。就地址而言,意味着添加1 * sizeof (int[3])
,即3 * sizeof (int)
。