int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%p,%p\n", arr, &arr);
printf("%p,%p\n", arr+1, &arr+1);
return 0;
对于此代码,GCC编译器返回
0xbfe41348,0xbfe41348
0xbfe4134c,0xbfe41370
第一行很清楚,没问题。但第二行让我感到困惑。第一个地址移动到下一个int
,因此在arr
之后是4个字节,清除。但是,对于 &arr+1
,我认为它会指向整个数组arr[10]
的结尾,所以它应该将 4 * 10 添加到地址。我误解了什么吗?
答案 0 :(得分:6)
&arr
的类型是指向10 int
'数组的指针。因此,当您向其中添加一个(&arr+1
)时,它将移动到下一个10 int
数组的开头,该数组超出&arr
开头的40个字节。
答案 1 :(得分:6)
你认为是对的,它只是这样做的。
自&arr
=> 0xbfe41348
和
0xbfe41348
+ 0x28
(十进制4*10
)= 0xbfe41370
我认为你因为将十进制数加到十六进制数而感到困惑。
答案 2 :(得分:2)
&arr+1
会将40
添加到数组arr
的基地址,但它不是明显的,因为地址是十六进制或基数16,不是小数。
现在,为了它的价值,我会为每个陈述添加一些解释,以便明确。
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
上述语句将arr
定义为int[10]
类型,即10
整数数组。然后它使用数组初始化列表初始化arr
。
printf("%p,%p\n", arr, &arr);
在上面的语句中arr
衰减(计算或隐式转换)指向其第一个元素的指针。因此其类型为int *
。 &arr
计算指向arr
的指针。 arr
的类型为int[10]
。因此,&arr
的类型是int (*)[10]
,即指向10个整数数组的指针。使用括号是因为数组下标运算符[]
的优先级高于*
运算符。所以没有括号int *[10]
表示一个包含10个整数指针的数组。这是数组不会衰减为指向其第一个元素的指针的情况之一。
请注意arr
和&arr
评估为相同的值,即上述printf
语句中数组的基址,但它们的类型不同,它们有所不同指针算术。这显示在以下声明中 -
printf("%p,%p\n", arr+1, &arr+1);
arr+1
指向下一个元素。这里的元素类型是int
。因此arr+1
评估为
arr + (1 * sizeof(int))
&arr + 1
也指向下一个元素,但此处的元素类型为int[10]
- 一个10 integers
的数组。因此&arr + 1
评估为
arr + (1 * sizeof(int[10]))
答案 3 :(得分:1)
arr+1
这里arr是指向整数数组的基指针,因此结果增加sizeof(int)
&arr+1
这里&arr
导致数组的地址,因此结果会按数组大小递增。