C++ 指针与数组表示法

标签 c++ arrays pointers

当我像这样声明一个新数组时:

int foo[5]

foo 真的是指向数组第一个元素的指针吗?我能做到吗:

*(foo+2)

访问数组的第三个元素?假设我正在制作一个二维数组:

int foo[3][4]

foo 现在是 int** 了吗?

最佳答案

不,'foo' 在这两种情况下都是数组类型,但是当在表达式中使用 'foo' 时需要指针时,它会隐式转换为 one(指向数组的第一个元素)。所有数组都有这种行为。在这种情况下,由于可以通过指针类型而不是数组来完成加法,因此“foo”被转换为“int *”。

*(foo+2) // 'foo' is implicitly converted into 'int *', pointing to 'foo' first element

foo + 1 //same as above

但现在您可能会问,“数组”类型的属性是什么以及为什么我们应该使用它,而不是指向第一个元素转换的隐式指针。事情是他们并不多。您可以像这样判断具有类型数组的对象的大小:

sizeof(foo) //returns the size which array 'foo' occupies 

然后使用“&”运算符获取它的地址:

&foo // '&foo' has type of 'int (*)[5]'

您还可以使用“数组”引用(或指针)类型的参数创建函数,以便只接受具有指定大小的参数(如果它们只是指针并且期望传递的数组衰减成这样,这是不可能的)。示例:

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

在第二种情况下,数组是二维的——应用相同的属性。它的声明意味着:“一个包含 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

尽管数组参数由于遗留原因(或其他原因?)在句法上被接受,但它们的真正含义永远不会被容忍,它们只是“调整”为指针。

注意:将数组类型隐式转换为其第一个元素的指针有时称为“数组到指针衰减”。

关于C++ 指针与数组表示法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27316953/

相关文章:

c++ - c/c++ - 通过套接字发送 time_t 的最安全方式

C++ 多重继承和与 void* 的交叉委托(delegate)?

javascript - 如何使用 nbind 包装由 FlatBuffers 编译器生成的 C++ gRPC 接口(interface)作为 Javascript/Typescript 接口(interface)?

c# - 找出所有给定数组中公共(public)元素的最佳算法

php - 使用数组函数删除两个数组中不存在的键后比较 2 个数组

arrays - 在 Swift 3 中对 [Dictionary<String, Any>] 进行排序

c - 如何更改 C 中二维数组的内容?

c++如何获取指向另一个类中当前对象的指针?

c# - "Base b = new Derived()"是哪个 OO 概念的一个例子?

c++ - 如何将地址与空指针对齐?