我想确保我理解指向array
个n
元素的指针的概念,例如:int (*myarr)[10]; //myarr is a pointer to an array that can hold 10 integer
我尝试过以下代码:
void main(){
int arr[][3] = { { 10, 20, 50 }, { 30, 60, 90 }, { 22, 92, 63 } };
int(*arrptr)[3]; /* a pointer to an array of 3 ints*/
int *ip = arr[0];
arrptr = arr;
int index;
for (index = 0; index < 9; index++)
{
printf("[ %d ][ %p ]\n\n", *ip, ip);ip++;
}
for (index = 0; index < 3; index++)
{
printf("%x <-> %p,%d\n", *arrptr, arrptr,**arrptr);
arrptr++;
}
}
我得到了
*[ 10 ][ 001BFA40 ]* [ 20 ][ 001BFA44 ] [ 50 ][ 001BFA48 ] *[ 30 ][ 001BFA4C ]* [ 60 ][ 001BFA50 ] [ 90 ][ 001BFA54 ] *[ 22 ][ 001BFA58 ]* [ 92 ][ 001BFA5C ] [ 63 ][ 001BFA60 ] *1bfa40* <-> *001BFA40*,10 1bfa4c <-> 001BFA4C,30 1bfa58 <-> 001BFA58,22
据我所知,arrptr
包含数组所指向的整个地址。这意味着指针可以在这些地址范围内自由移动。
但是,为什么保持arrptr
的地址值等于保存arr[0]
值的地址?
换句话说:我知道*arrptr
保存arr[0]
的地址是正常的,但arrptr
的地址包含arrptr
指向的地方与arr[0]
?!
答案 0 :(得分:4)
数组是一个连续的存储区域。所以使用你的代码片段这些表达式
&arr
,arr
,arr[0]
,&arr[0]
和&arr[0][0]
提供与阵列占用的存储内存相同的地址。它们都指向存储区的第一个字节。
让我们考虑一下这个陈述
printf("%x <-> %p,%d\n", *arrptr, arrptr,**arrptr);
arrptr
是一个类型为int ( * )[3];
的指针。取消引用此指针*arrptr
,您将获得类型为int[3]
的数组,而这些数组又被隐式转换为指向其第一个元素的指针,该表达式将具有类型int *
和两个{{1 }和arrptr
产生相同的值。那就是价值本身没有改变。它是被更改的表达式的类型。:)
因此,*arrptr
具有类型*arrptr
并且它是一个指针(在相应的一维数组的隐式converiosn之后; C没有像C ++那样引用对象)然后表达式{{1产生int *
类型的对象。根据代码片段逻辑,它是二维数组的每一行的第一个元素。
答案 1 :(得分:2)
*arrptr
与arrptr[0]
相同(相同类型,相同值)。由于您已分配arrptr = arr
,这也意味着*arrptr
等于*arr
。
顺便说一句,使用%x
技术上打印指针会给出未定义的行为(因为%x
是unsigned
整数值)。请改用%p
。同样,使用%p
时,建议将打印的指针转换为(void *)
。
答案 2 :(得分:1)
为什么持有
值的地址arrptr
的地址值等于保存arr[0]
数组的地址始终等于其第一个元素的地址。
对于任何
T a[n]; /* n > 0 */
表达式
&a == &a[0]
是真的。
另请注意,在C a&#34; 2D&#34; array只是一个数组数组。
答案 3 :(得分:0)
参考asm(" PUSH {R0}\n");
及其打印内容:
以下代码
%p
打印如下内容:
void * p = 1;
printf("%p, %p\n", p, &p);
第一个数字是0000000000000001, 7fffffff0234585a
的值,第二个数字是第一个数字的存储位置,这是p
的地址。 (由于p
是指针,值都是地址)。