C++ 指向数组的指针和指向数组第一个元素的指针之间的差异
C++ 指向数组的指针和指向数组第一个元素的指针之间的差异,c++,arrays,pointers,C++,Arrays,Pointers,int(*arr)[5]表示arr是指向5个整数数组的指针。这个指针到底是什么 如果我声明int-arr[5]其中arr是指向第一个元素的指针,这是否相同 两个示例中的arr是否相同?如果不是,那么指向数组的指针到底是什么?指向数组的指针是指向特定类型数组的指针。类型包括元素的类型以及大小。不能为其分配不同类型的数组: int (*arr)[5]; int a[5]; arr = &a; // OK int b[42]; arr = &b; // ERROR: b is not
int(*arr)[5]
表示arr
是指向5个整数数组的指针。这个指针到底是什么
如果我声明int-arr[5]
其中arr
是指向第一个元素的指针,这是否相同
两个示例中的
arr
是否相同?如果不是,那么指向数组的指针到底是什么?指向数组的指针是指向特定类型数组的指针。类型包括元素的类型以及大小。不能为其分配不同类型的数组:
int (*arr)[5];
int a[5];
arr = &a; // OK
int b[42];
arr = &b; // ERROR: b is not of type int[5].
指向数组第一个元素的指针可以指向任何具有正确元素类型的数组的开头(实际上,它可以指向数组中的任何元素):
<>注意,在C和C++中,数组在某些上下文中会退化为指向元素的类型。这就是为什么可以这样做:
int* arr;
int a[5];
arr = a; // OK, a decays to int*, points to &a[0]
在这里,
arr
(int*
)的类型与a
(int[5]
)的类型不同,但是a
衰减为指向其第一个元素的int*
,使赋值合法。如果写入int-arr[5]
,则在堆栈上创建一个五个int
数组。这占用的大小等于五个整数的大小
如果您写入int(*arr)[5]
,您将创建一个指向堆栈上五个int
数组的指针。这占用的大小等于指针的大小
如果从上面看不清楚,则指针具有与数组分离的存储,可以指向任何对象,但不能将数组名称指定给指向其他对象
<> P> >我的答案更多。 < P>整个数组的地址和第一个元素的地址定义为相同,因为C++和(C)中的数组除了组成对象之外没有固有填充。 但是,这些指针的类型是不同的。在您执行某种类型的类型转换之前,将
int*
与int(*)[5]
进行比较是非常困难的
如果声明arr[5]
,则arr
不是指向第一个元素的指针。它是数组对象。您可以观察到这一点,因为sizeof(arr)
将等于5*sizeof(int)
。数组对象隐式转换为指向其第一个元素的指针
指向数组的指针不会隐式转换为任何内容,这可能是造成混淆的另一个原因。指向数组的指针和指向数组第一个元素的指针都是不同的。在
int(*arr)[5]
的情况下,arr
是指向5
int
的内存块的指针。取消引用arr
将给出整行。在int-arr[5]
的情况下,arr
衰减到指向第一个元素的指针。取消对arr的引用将给出第一个元素。在这两种情况下,起始地址相同,但两个指针的类型不同 如果我声明
int-arr[5]
其中arr
是指向第一个元素的指针,这是否相同?两个示例中的arr
是否相同?如果不是,那么指向数组的指针到底是什么
否。要了解这一点,请参见功能图1:
所有三个指针当然都允许您在矩阵[0][0]
中定位0
,如果您将这些指针转换为“字节地址”,并在printf()
中使用%p
指令打印出来,这三个指针很可能产生相同的输出(在典型的现代计算机上)。但是int*
指针p1
,只指向一个int
,如黑色圆圈所示。红色指针p2
,其类型为int(*)[2]
,指向两个int
s,蓝色指针——指向整个矩阵的指针——确实指向整个矩阵。
这些差异影响指针算术和一元*
(间接)运算符的结果。由于p1
指向一个int
,p1+1
向前移动一个int
。黑色圆圈只有一个int
,并且*(p1+1)
只是下一个int,其值为1。同样,sizeof*p1
只是sizeof(int)
(可能是4)
由于p2
指向一个完整的“int数组2”,因此p2+1
将向前移动一个这样的数组。结果将是指向围绕{2,3}
对的红色圆圈的指针。由于间接运算符的结果是一个对象,*(p2+1)
是可能属于该规则的整个数组对象。如果它确实属于该规则,则该对象将成为指向其第一个元素的指针,即当前持有2
的int
。如果它不属于该规则,例如,insizeof*(p2+1)
,它将对象放在对象上下文中——它将保持整个数组对象。这意味着sizeof*(p2+1)
(当然还有sizeof*p2
)是sizeof(int[2])
(可能是8)
1以上内容取自。理论 首先是一些理论(你可以跳到“答案”部分,但我建议你也读一下): 这是一个数组,“arr”不是指向数组第一个元素的指针。在特定情况下(即将它们作为左值传递给函数),它们会衰减为指针。:您将失去对它们调用
sizeof
的能力
在正常情况下,数组是数组,指针是指针,它们是两个完全不同的东西
<
int* arr;
int a[5];
arr = a; // OK, a decays to int*, points to &a[0]
void f(void) {
int matrix[4][2] = { {0,1}, {2,3}, {4,5}, {6,7} };
char s[] = "abc";
int i = 123;
int *p1 = &matrix[0][0];
int (*p2)[2] = &matrix[0];
int (*p3)[4][2] = &matrix;
/* code goes here */
}
int arr[5]
int array1[2][2] = {{0, 1}, {2, 3}};
void function1(int **a);
void function1(int a[][2]);
void function1(int a[2][2]);
int (*arr)[5]
int arr[5]
int* ptrToArr = arr;
int (*arr)[5]
int* ptrToArr = arr; // NOT ALLOWED
Error cannot convert ‘int (*)[5]’ to ‘int*’ in initialization
int theArray[5];
int (*ptrToArray)[5];
ptrToArray = &theArray; // OK
int anotherArray[10];
int (*ptrToArray)[5];
ptrToArray = &anotherArray; // ERROR!
int theArray[5];
int* ptrToElement = &theArray[0]; // OK - Pointer-to element 0
int anotherArray[10];
int* ptrToElement = &anotherArray[0]; // Also OK!