当前位置:  开发笔记 > 编程语言 > 正文

指向结构的指针怎么可能是一个数组呢?

如何解决《指向结构的指针怎么可能是一个数组呢?》经验,为你挑选了1个好方法。

这真是一个快速的问题.

想象一下,你有一个名为"No"的结构和下面的代码:

No *v_nos; // What does this mean?

我从哪里拿出这个,他们称"v_nos"是一个数组?它不只是指向结构"否"的指针吗?

谢谢.



1> David Rodríg..:

数组和指针一样.在您的情况下,变量是指针,而不是数组.即使它们不一样,这种混淆也很常见,你会发现它们在很多地方(包括C/C++书籍)都是一样的.这意味着你应该熟悉调用指针数组的人.

当开发C语言时,他们决定不是按值传递数组(可能需要大量的复制和堆栈内存),而是将数组静默转换为指向第一个元素的指针,然后将该指针传递给函数.

void f( int a[3] ); // valid and misleading
// what it means:
// void f( int *a);
void test() {
   int array[3];
   f( array );
   // what it means:
   // f( & array[0] )
}

为了向后兼容,C++保留了这个功能,你不能按值传递数组,也不能定义一个按值获取数组的函数(在这两种情况下,它都将被静默转换为指向第一个元素的指针).同时,您可以在指针上使用数组访问语法来简化指针运算,使其更加混乱:

int array[3];
int *pointer = array; // simplified: 
// int * pointer = & array[0]
pointer[2]; // equivalent to *(pointer+2) or array[2]

这意味着使用C和C++数组中的常规函数​​会无声地衰减成指针,大多数人都会认为它们是同一个东西:数组是指向第一个元素的指针.好吧,他们不是.

在C和C++中,它们都是不同的实体,即使某些使用模式因设计决策而相同.但它们实际上是不同的:

int array[3]; sizeof(array); // 3*sizeof(int)
int *p1=array;               // sizeof(int*), usually 4/8 bytes for 32/64 bit
int *p2=new int[3];          // sizeof(int*)

在通过函数/方法调用之后,它们都是指针:

void f( int array[3] ) { sizeof(array); } // sizeof(int*) it is really a pointer! size is ignored
void g( int *p ) { sizeof(array); }       // sizeof(int*)

在C++中,事情变得更加有趣,因为传值不是唯一可用的范例,您可以通过引用传递:

void f( int (&array)[3] ); // funny syntax to pass an array of 3 integers by reference
void testf() {
   int array1[3]; f(array1); // correct
   int array2[2]; // f(array2); compilation error, it is not an array of 3 ints!
   int *p = array1; // f(p); compilation error, it is not an array of 3 ints!
}

void g( int array[3] ); // means: void g( int *array );
void testg() {
   int array1[3]; g(array1); // correct, the array decays into & array[0]
   int array2[2]; g(array2); // correct, the array decays again
   int *p = array1; g( p );  // correct it is a pointer
}

请注意,当您定义一个按值获取数组的函数时,您实际上是在定义一个按值获取指针的函数,并且编译器不会检查函数调用的参数是否实际具有该大小.这是一个已知的错误来源,也是大多数采用数组的函数也采用大小参数的原因.

最后,你不能动态创建数组,你只能动态地获取内存到指针,所以当你需要一个堆分配数组时,你实际上需要一个指向堆分配的连续块o内存的指针:

void test() {
   int *p = new int[3];
   // int array[3] = new int[3]; // error!! an array is not a pointer
   delete p;
}

最后,这一切都意味着它们不是同一个东西,但是你总是可以在指针的位置使用数组,它将由编译器自动转换为指向数组第一个元素的指针.通常,人们会将指向一块连续内存(无论是堆栈还是堆分配)的指针称为数组.

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有