2

我有一个关于数组和指向数组的指针的相当简单的问题。考虑这个代码片段..

int (*ptr)[3];               //A pointer to an array of 3 ints
int arr1[3] = {2,4,6,};      
ptr = &arr1;                //ptr now points to arr1

//3 different ways to express  the same address
cout << &arr1 << "\t" << arr1 << "\t" << &arr1[0] << endl;

现在如果:

&arr1 == arr1 == &arr1[0]..

为什么这段代码不正确:

ptr = arr1;

或者

ptr = &arr1[0];

这一直让我发疯......所以请任何解释都将不胜感激。也请不要说这不是一个家庭作业问题,只是我试图掌握的问题。

4

4 回答 4

5

ptr = arr1;

arr1被转换为int*,因此您尝试从不兼容的指针类型进行分配。&arr1[0]直接是一个int*,没有转换,所以再次不兼容。

&arr1 == arr1 == &arr1[0]

是错误的,因为实体有不同的类型。它们只指向相同的地址,因此在打印输出时,它们会给出相同的结果。

于 2012-09-06T18:17:35.917 回答
3

在大多数情况下,具有数组类型的表达式被隐式转换为指向该数组第一个元素的指针,如 6.3.2.1p3 所述:

除非它是运算sizeof符、运算符_Alignof或一元&运算符的操作数,或者是用于初始化数组的字符串字面量,否则类型为数组的表达式将转换为类型为指向类型的指针的表达式数组对象的初始元素,不是左值。

因此,您的作业的右侧

ptr = arr1;

被隐式转换为不兼容的指针类型(int*vs. int (*)[3]),并且不能在没有强制转换的情况下存储到指针变量中。

这并不是任何规则的真正例外,因为您也需要将一元运算&符与其他类型一起使用:

T val, *ptr;
ptr = &val;
于 2012-09-06T18:26:00.723 回答
1

下面的程序将帮助您更好地理解 pointer_to_first_member_of_array、pointer_to_1D_array、pointer_to_2D_array 之间的区别。请仔细查看程序,执行它并查看输出。

#include<stdio.h>

int priv_element = 88;

int array[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int next_element = 99;

main (int argc, char *argv[])
{

  int *ptr_to_first_element = &array[0][0];

  int (*ptr_to_1d_arry)[5] = &array[0];

  int (*ptr_to_2d_arry)[2][5] = &array;

  printf ("Print first num of first array of 2-Dim array: %d\n",
      *ptr_to_first_element);

  ptr_to_first_element += 5;

  printf ("Print first num of second array of 2-Dim array: %d\n",
      *ptr_to_first_element);

  printf ("Print first num of first array of 2-Dim array: %d\n",
      (*ptr_to_1d_arry)[0]);

  ptr_to_1d_arry++;

  printf ("Print first num of second array of 2-Dim array: %d\n",
      (*ptr_to_1d_arry)[0]);

  printf ("Print first num of first array of 2-Dim array: %d\n",
      (*ptr_to_2d_arry)[0][0]);

  ptr_to_2d_arry++;

  printf
    ("Now you increased to point end of 2d-array space. So next to it is next_element on data-seg: %d\n",
     (*ptr_to_2d_arry)[0][0]);

}
于 2015-05-10T10:45:05.840 回答
0

当您打印各种表达式时,它表明它们的是相同的。但是,它们没有相同的类型

C 和 C++ 包含类型功能,以减少人为错误并使编写复杂代码变得更容易。假设您在某个指针 p 中有一个地址,并且 C/C++ 允许您执行以下任一操作:

float *f = p;

或者:

int *i = p;

这将是一个错误,因为通常情况下,内存中 p 处的任何位都不代表有用的 int 和有用的 float。通过强制执行有关类型的规则,该语言可以防止程序员在这里犯错;指针 p 只能分配给兼容类型的另一个指针,除非程序员使用强制转换显式覆盖规则。

同样, yourptr是一个指向三个数组的指针int。起初,您似乎arr1也是一个由三个 int 组成的数组,因此您应该能够分配ptr = arr1;. 这是错误的,因为ptr它只是一个指针,而是arr1一个完整的数组对象。您不能将整个数组放入指针中;您需要将指向数组的指针放入指针中。要获取指向数组的指针,请使用&运算符:ptr = &arr1;

这里令人困惑的另一件事是 C/C++ 包含一个自动快捷方式:它将数组转换为指向数组第一个元素的指针。在arr1大多数情况下出现时,它会自动更改为&arr1[0]. 这没有很大的哲学原因。它只是为了方便我们经常使用数组的方式。所以ptr = arr1;将等同于ptr = &arr1[0];,这也是不允许的。在这种形式中,你可以看到arr1已经变成了一个指向 int 的指针,所以你不能将它赋给一个指向 int 数组的指针。即使指针具有您想要的,它也是错误的类型

当数组作为&orsizeof或的操作数出现时_Alignof,不会发生这种自动转换。所以&arr1结果是数组的地址。

在初始化中使用的字符串文字,例如char a[] = "abc";经过特殊处理,不会如上所述自动转换。

于 2012-09-06T18:32:00.880 回答