C++ 11代码:C&C++:数组的指针和地址有什么区别?
int a[3];
auto b = a; // b is of type int*
auto c = &a; // c is of type int(*)[1]
的C代码:
int a[3];
int *b = a;
int (*c)[3] = &a;
b
的和c
的值是相同的。
b
和c
有什么区别?他们为什么不是同一类型?
更新:我改变了数组大小为1〜3
C++ 11代码:C&C++:数组的指针和地址有什么区别?
int a[3];
auto b = a; // b is of type int*
auto c = &a; // c is of type int(*)[1]
的C代码:
int a[3];
int *b = a;
int (*c)[3] = &a;
b
的和c
的值是相同的。
b
和c
有什么区别?他们为什么不是同一类型?
更新:我改变了数组大小为1〜3
的sizeof
经营者应不同的表现,为一体,特别是如果你改变a
申报到不同数量的整数,如int a[7]
:
int main()
{
int a[7];
auto b = a;
auto c = &a;
std::cout << sizeof(*b) << std::endl; // outputs sizeof(int)
std::cout << sizeof(*c) << std::endl; // outputs sizeof(int[7])
return 0;
}
对于我来说,这个打印:
4
28
这是因为两个指针是非常不同的类型。一个是指向整数的指针,另一个是指向7个整数数组的指针。
第二个确实有指针数组类型。如果你取消引用它,当然,在大多数情况下它将会是decay to a pointer,但它实际上并不是指向int的指针。第一个是指向int的指针,因为衰减发生在赋值处。
其它地方它会显示是,如果你真的有指针到数组类型的两个变量,并试图分配一个到另一个:
int main()
{
int a[7];
int b[9];
auto aa = &a;
auto bb = &b;
aa = bb;
return 0;
}
这赢得了我的错误消息:
xx.cpp: In function ‘int main()’:
xx.cpp:14:8: error: cannot convert ‘int (*)[9]’ to ‘int (*)[7]’ in assignment
aa = bb;
该实施例,然而,工,因为访问bb
允许其衰减到指针到INT:
int main()
{
int a;
int b[9];
auto aa = &a;
auto bb = &b;
aa = *bb;
return 0;
}
请注意,衰减不会发生在任务的左侧。这不起作用:
int main()
{
int a[7];
int b[9];
auto aa = &a;
auto bb = &b;
*aa = *bb;
return 0;
}
它赚你:
xx2.cpp: In function ‘int main()’:
xx2.cpp:14:9: error: incompatible types in assignment of ‘int [9]’ to ‘int [7]’
*aa = *bb;
'sizeof'也会丢弃'const'部分为你的第二''cout'''变量。这就是为什么他们会产生相同的输出。 – user2485710
@ user2485710:什么导致相同的输出?我的两条'cout'线输出两个不同的数字。 'const'根本不会出现在图片中。我无法将您的评论与我的帖子中的任何内容对齐。 –
很棒的回答。突出一大堆我以前没有想过的概念!我可能应该更频繁地使用数组类型来支持指针类型! – Domi
在C++中的任何对象的身份由其类型及其地址的对确定。
在你的例子中,有两个不同的对象具有相同的地址:数组本身和数组的第一个元素。第一种是int[1]
,第二种是int
。如果一个对象是另一个对象的子对象,那么两个不同的对象可以具有相同的地址,就像数组元素,类成员和类基类子对象一样。
如果你写你的例子会比较清楚:
int a[5];
int (*ptr_to_array)[5] = &a;
int * ptr_to_array_element = &a[0];
但你已经采取的,对于阵列的ID表达a
衰变到一个指向数组的第一个元素的事实优势,所以a
有在您的上下文中与&a[0]
的值相同。
谢谢!我在你的代码中添加了一个稍微修改过的版本。 – Domi
考虑这个例子:
#include<stdio.h>
int main()
{
int myArray[10][10][10][10]; //A 4 Dimentional array;
//THESE WILL ALL PRINT THE SAME VALUE
printf("%d, %d, %d, %d, %d\n",
myArray,
myArray[0],
myArray[0][0],
myArray[0][0][0],
&myArray[0][0][0][0]
);
//NOW SEE WHAT VALUES YOU GET AFTER ADDING 1 TO EACH OF THESE POINTERS
printf("%d, %d, %d, %d, %d\n",
myArray+1,
myArray[0]+1,
myArray[0][0]+1,
myArray[0][0][0]+1,
&myArray[0][0][0][0]+1
);
}
你会发现,在第一种情况下打印所有5个值都相等。因为他们指向相同的初始位置。
但是当你将它们加1时,你会发现不同的指针现在跳到(指向)不同的位置。这是因为myArray[0][0][0] + 1
将跳过40个字节的10个整数值,而myArray[0][0] + 1
将跳过100个整数值,即400个字节。同样myArray[0] + 1
跳转1000个整数值或4000个字节。
所以这个值取决于你指的的的水平。
但现在,如果我用指针来指代所有的人:
#include<stdio.h>
int main()
{
int myArray[10][10][10][10]; //A 4 Dimentional array;
int * ptr1 = myArray[10][10][10];
int ** ptr2 = myArray[10][10];
int *** ptr3 = myArray[10];
int **** ptr4 = myArray;
//THESE WILL ALL PRINT THE SAME VALUE
printf("%u, %u, %u, %u\n", ptr1, ptr2, ptr3, ptr4);
//THESE ALSO PRINT SAME VALUES!!
printf("%d, %d, %d, %d\n",ptr1+1,ptr2+1,ptr3+1,ptr4+1);
}
所以你看,不同层次的指针变量的不规矩数组变量的方式做。
'auto'不能很好的使用指针,这种类型通常是不可信的。 – user2485710
@ user2485710你能详细说明一下吗?任何参考/引用? – Domi
'auto'在指针下工作得很好,不知道你有什么想法。 –