指向数组Vs正常指针的指针

时间:2013-10-25 06:09:03

标签: c arrays pointers

我对指向数组的指针和正常指针以及如何访问感到困惑。 我试过这个......

int *ptr1, i;
int (*ptr2)[3];
int myArray[3] = {1, 1, 1};
int myArray1[5] = {1, 1, 1, 1, 1};
ptr1 = myArray;
ptr2 = myArray1;// compiles fine even though myArray1 contains 5 elements 
                 // and ptr2 is pointing to array of 3 elements.

printf("%d",ptr2[3]); // prints some garbage.

为什么这句话是打印垃圾?什么是正确的陈述? 谁能解释一下?

3 个答案:

答案 0 :(得分:4)

我们也可以将指向数组的指针声明为

int (*ptr)[]; // ptr is a pointer to array.

当你这样做时

ptr2 = myArray1;

编译器会向您发出警告消息。 Look boss types are not compatible. 在某些情况下,数组会衰减为指针。警告消息是因为,当数组衰减成指针时,衰减类型是指针。在这种情况下,当你做

ptr1 = myArray; 

myArray衰变为int *

但是当你这样做时,

ptr2 = myArray1;

myArray1衰减为int *的指针,但ptr2的类型为int (*)[]

为了避免警告,你应该说

ptr2 = &myArray1; //&myArray1 returns address of array and type is int(*)[].

为什么这句话会打印垃圾?什么是正确的陈述?任何人都可以解释一下吗?

printf("%d",ptr2[3]);// prints some garbage. 

是的,但为什么呢?让我们先看看正确的陈述......(注意索引应该小于3)

printf("myArray1[%d] = %d\n", i, (*ptr2)[2]); 

我们必须使用(*ptr2)[i]来打印数组元素。这是因为,仅提及ptr2,我们将获得数组的地址(而不是某些int的地址)。通过取消引用它(*ptr2),我们将得到数组0th element的地址。

答案 1 :(得分:1)

指针ptr2是指向大小为3的int数组的指针

ptr2 = myArray1;  // you may getting warning for this 

应该是:

ptr2 = &myArray1; // use & operator 

并且

printf("%d", ptr2[3]);

应该是:

printf("%d", (*ptr2)[2]); // index can't be 3 for three size array 
 //          ^^^^^^^  

需要*ptr2周围的括号,因为[]运算符的优先级高于*解除引用运算符(如果使用指向int的指针,则不需要括号,如上面的代码)。

阅读Inconsistency in using pointer to an array and address of an array directly我已经解释了两个数组来访问数组元素。 (1)使用指向int(2)指向数组

的指针

虽然找到ptr1 = myArray;,但您只需使用ptr1[i]访问数组元素(不是i值应为0到4)

答案 2 :(得分:1)

int (*ptr2)[3];

这表示(*ptr2)是包含整数数组开头的内存位置的标识符。或者,改写一下,ptr2是一个地址。该地址包含一个值。该值本身就是一个int数组开头的地址。

所以当你写ptr2 = myArray1时,你基本上是在说“我的地址持有人的地址是myArray1”开头的地址。

因此,当您使用ptr2[3]打印值时,您实际上正在打印myArray1内存地址的值,递增3*sizeof(ptr2)个单位。这就是为什么它看起来像垃圾,它是一些内存地址。

print语句中应该包含(*ptr2)[3],这意味着“获取ptr2的地址并获取存储在该地址的值。接下来,使用该第二个地址,将其递增{{1}并获取存储在该递增地址的值。“

C中的数组只不过是分配内存的连续区域。这就是为什么说:

3*sizeof(int)

与:

相同
int *x = malloc(3*sizeof(int));

由于int x[3]; []都取消引用指针,如果我们想要访问任一数组的第二个元素,我们可以写:

*

int value = x[1];

两个主要区别是int value = *x+sizeof(int); // Since *x would be index 0 表示法更容易阅读,但长度必须在编译时确定。然而,使用[] / *x表示法,我们可以动态创建数组或任意长度。

相关问题