1

我对指向数组的指针和普通指针以及如何访问有点困惑。我试过这个...

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.

为什么这个语句打印垃圾?正确的说法是什么?谁能解释一下?

4

3 回答 3

4

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

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

当你这样做

ptr2 = myArray1;

编译器会给你一个警告信息。Look boss types are not compatible. 在某些情况下,数组会衰减为指针。警告消息是因为,当数组衰减为指针时,衰减的类型是指针。在这种情况下,当你这样做

ptr1 = myArray; 

myArray 衰减为int *.

但是当你这样做时,

ptr2 = myArray1;

myArray1衰减为指针 that is int *,但类型ptr2is 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,我们就会得到数组的地址(而不是 some 的地址int)。通过取消引用它,(*ptr2)我们将获得0th element数组的地址。

于 2013-10-25T06:10:15.657 回答
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 的指针,则不需要像上面的代码中那样使用括号)。

Read Inconsistency in using pointer to a array and address directly我已经解释了这两个数组来访问数组元素。(1) 使用指向 int 的指针 (2) 指向数组的指针

ptr1 = myArray;只是查找,您可以简单地使用ptr1[i]i不值应该是 0 到 4)访问数组元素

于 2013-10-25T06:10:23.333 回答
1
int (*ptr2)[3];

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

因此,当您编写时,ptr2 = myArray1您基本上是在说“我的地址持有人的地址是开头的地址myArray1”。

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

print 语句中的(*ptr2)[3]内容应该是“获取地址ptr2并获取存储在该地址的值。接下来,使用第二个地址,将其递增3*sizeof(int)并获取存储在该递增地址的值。”

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

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/malloc()符号,我们可以动态地创建一个数组或任意长度。

于 2013-10-25T08:01:28.543 回答