C++指针与数组表示法
C++ pointer vs array notation
当我声明一个这样的新数组时:
int foo[5]
foo
真的是指向数组第一个元素的指针吗?我能做到这一点吗:
*(foo+2)
访问数组的第三个元素?假设我正在制作一个 2D 数组:
int foo[3][4]
foo
现在是int**
吗?
不,"foo"在这两种情况下都是数组类型,但是当表达式中需要带有"foo"的指针时,它会隐式转换为一个(指向数组第一个元素(。所有数组都具有此行为。在这种情况下,由于可以通过指针类型完成加法,但不能通过数组完成,因此"foo"被转换为"int *"。
*(foo+2) // 'foo' is implicitly converted into 'int *', pointing to 'foo' first element
foo + 1 //same as above
但是现在你可能会问,'array'类型的属性是什么,为什么我们应该使用它,而不是指向第一个元素转换的隐式指针。问题是它们不多。你可以用数组类型判断对象的大小,如下所示:
sizeof(foo) //returns the size which array 'foo' occupies
并使用"&"运算符获取其地址:
&foo // '&foo' has type of 'int (*)[5]'
您还可以使用"array"引用(或指针(类型的参数创建函数,以便仅接受具有指定大小的函数(如果它们只是指针并期望传递的数组衰减到这样的指针中,则这是不可能的(。例:
void func(int (&)[5]);
void func1(int (*arg)[5]); // should be accessed by '*arg', allow the use of null-pointers
void func2(int *); //same as the misleading 'void func2(int [5])' or 'void func2(int [6])' etc.
int foo[5];
int foo1[6];
func(foo); // 'foo' type is ('int [5]') - ok
func1(&foo); // '&foo' type is ('int (*)[5]') - ok
func(foo1); // 'foo1' type is ('int [6]') - not allowed, param type is 'int (&)[5]' !
func1(&foo1); // '&foo1' type is ('int (*)[6]') - not allowed, param type is 'int (*)[5]' !
func2(foo); // 'foo' is implicitly converted to 'int *' - ok
func2(foo1); // 'foo1' is implicitly converted to 'int *' - ok
在第二种情况下,当数组为 2D 时 - 将应用相同的属性。它的声明的意思是:"一个 3 个元素的数组,类型为 4 个元素的数组,类型 int"所以它实际上只是一个数组数组,仅此而已。它是指向第一个元素转换的隐式指针不是类型为"int **",而是"int (*([4]",因为它的每个元素都是另一个数组。
声明也可以这样写:
int (foo[3])[4];
另请注意,"数组"不能赋值,因此它们不能按值传递或由函数返回。我的意思是:
int funcReturningArray()[2]; //not allowed
int funcAcceptingArray(int [2]); //just converted into pointer
int funcAcceptingArray(int *); //same as above
尽管数组参数由于遗留原因(或因为其他原因?(在语法上被接受,但它们的真正含义永远不会被容忍,它们只是被"调整"为指针。
注意:数组类型到其第一个元素的指针的隐式转换有时称为"数组到指针衰减"。
没有数组不是指针,但在表达式中,它们被转换为指向其第一个元素的右值指针。所以在这个表达中
*(foo+2)
首先将Foo转换为右值指针,然后使用指针算法。
对于此数组声明
int foo[3][4];
表达式中使用的名称 foo 将转换为类型 int ( * )[4]
的右值指针
右值这个词意味着例如你不能写++foo
也就是说,表达式中使用的数组名称的编译器创建一个临时对象,该对象是数组第一个元素的 poimnter。
请注意,如果您使用带有数组名称的示例运算符sizeof
,则最后一个不会转换为指针。所以对于您的最后一个数组定义
sizeof( foo )
将相当于
3 * 4 * sizeof( int )
而
sizeof( int ( * )[4] )
将返回指针本身的大小。
最后,如果您将运算符&
应用于数组名称,那么您将获得指向数组本身的指针。例如
int foo[3][4];
int ( *ptr_to_foo )[3][4] = &foo;
- 寻找一种更好的方法来表示无符号字符数组
- 数组指针表示法C++(移动数组时)
- 在 C++ 中将整数数组转换为位集表示形式的最佳方法?
- 表示带有输入的数组中的元素数?
- N 维数组的大 O 表示法
- 为什么使用 size_t 来索引/表示数组的大小?
- 如何更好地表示 6 个整数键而不是作为 6 维数组的索引?
- 十六进制 QString 表示为无符号字符数组
- 如何以指针格式表示多维数组?
- 如何将升压数组表示为类型的指针?
- C++字符串表示中将无符号字符数组转换为长(或长长)
- 表示为 1D 的多维数组(模板化为 n 维)
- 对于Boost.Propertytree,有没有办法使用JSON点表示法来引用数组元素?
- ptrdiff_t可以表示指向同一数组对象元素的指针的所有减法吗?
- 如何就地反转由数组表示的排列
- 访问表示 2D 矩阵的 1D 存储数组
- C 中的动态数组(用指针表示) - 输入元素
- 整数数组元素,前导 0 表示垃圾输出
- 从文本文件读取到表示一个月的二维数组中
- 如何在c++中表示数组位置的范围