这真是一个快速的问题。
想象一下,你有一个名为“No”的结构和以下代码:
No *v_nos; // What does this mean?
我从哪里拿出这个,他们称“v_nos”是一个数组?它不仅仅是指向结构“No”的指针吗?
感谢。
答案 0 :(得分:7)
数组和指针 NOT 相同。在您的情况下,变量是指针,而不是数组。即使它们不一样,这种混淆也很常见,你会发现很多地方(包括C / C ++书籍)它们都是一样的。这意味着您应该熟悉调用指针 arrays 的人。
当开发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;
}
最后这意味着它们不是同一个东西,但是你总是可以在指针的位置使用一个数组,它将被编译器自动转换为指向数组第一个元素的指针。通常情况下,人们会将指向一块连续内存(无论是堆栈还是堆分配)的指针引用为 array 。
答案 1 :(得分:3)
你是对的,但它也可以用作数组:
v_nos = new Nos[10];
v_nos[5].whatever = something;
// etc
答案 2 :(得分:3)
在实现方面,数组和指针是相同的。也就是说,数组只是作为指向数组中第一个元素的指针实现的。
之间的区别No *v_nos;
和
No v_nos[3];
后者是否为该数组的3个元素留出了内存,而指针则需要使用malloc(或new)分配内存。
你仍然可以将第二个视为指针,例如*v_nos
会给你第一个元素,&v_nos
会给出指针的地址。
答案 3 :(得分:2)
是的,它声明(但不初始化)指向No
的指针。
答案 4 :(得分:2)
它是一个指向No struct的指针。
如果他们将其称为数组,那么该指针可能指向No structs数组的第一个成员
例如
No* nos= getNosArray();//pseudocode
*nos;//first element
*(nos+1)//2nd element;
答案 5 :(得分:0)
在C ++中,数组和指针或多或少可以互换。您可以取消引用指针的偏移量 - *(v_nos+2)
- 它实际上与索引数组v_nos[2]
相同。事实上,你可以使用任何一种符号,IIRC。两个示例都告诉编译器执行相同的操作:将指针递增2 *指向对象的大小,然后返回它在该位置找到的内容。
答案 6 :(得分:0)
typedef struct NO { int x; } _NO;
int main() { _NO * v_nos; _NO * v_nos_array;
v_nos = new _NO(); // allocate mem for 1 struct
v_nos_array = new _NO[100]; allocate mem for 100 structs
for(1=0; 1<100; i++) v_nos_array[i].x = i; //five some value to 'x' of each struct
for(1=0; 1<100; i++) cout << v_nos_array[i].x << "\n";
}
希望你能提炼出意义。请注意,具有单个元素的数组仍然是数组。