上下文:C ++ 考虑下面的例子
class TestClass
{
private:
int A[];
int *B;
public:
TestClass();
};
TestClass::TestClass()
{
A = 0; // Fails due to error: incompatible types in assignment of `int' to `int[0u]'
B = 0; // Passes
}
A = 0失败,但B = 0成功。有什么收获? A究竟是什么?常量指针?我如何初始化呢?
答案 0 :(得分:10)
问题“int *和int []有什么区别?”这是一个不像大多数人想象的那么简单的问题:它取决于它的使用位置。
在声明中,如extern int a[];
,这意味着某处有一个名为a
的数组,此处的大小未知。在使用聚合初始化的定义中,如int a[] = { 1, 2, 3 };
,它意味着一个大小为I的数组,作为程序员,不想计算,编译器必须从初始化中解释。在没有初始化的定义中,这是一个错误,因为您无法定义未知大小的数组。在函数声明(和/或)定义中,它完全等同于int*
,该语言指定在处理函数的参数类型时,数组将转换为指向包含类型的指针。
在您的特定情况下,作为类成员的声明,int a[];
是一个错误,因为您声明了一个不完整类型的成员。如果你在那里添加一个大小,就像在int a[10]
中一样,那么它就变成了类型int
和大小为10的数组的声明,并且会在每个对象内保留10 int
的空间。类。另一方面,int *b
仅为类中的整数指针保留空间。
答案 1 :(得分:4)
它们之间的唯一区别是类中的int A[]
无法编译,也不应该编译!
"ComeauTest.c", line 4: error: incomplete type is not allowed int A[]; ^
Comeau C / C ++被认为是 大多数符合标准的C ++ 编译器。强>
因此我建议:即使您的编译器编译它,也不要写这样的代码。
答案 2 :(得分:2)
A []是一个未定义大小的数组。你需要这样声明:
int A [SIZE];
然后像这样初始化它:
A [0] = 0, A [1] = 5,
等
答案 3 :(得分:1)
A
是一个数组,在C ++中,您需要在定义变量本身时指定数组大小,即需要执行int A[10]
之类的操作。然后,您可以使用A[0], A[1]
等访问单个元素。B
是一个指针,因此执行B=0;
会将指针设置为NULL。如果您不想在编译时指定大小,但仍希望使用类似数组的语法,则可以使用std::vector<int>
。
答案 4 :(得分:1)
int A[]
是类实例中的内存范围,其中int *B
是一个指针,您可能会在以后初始化,也可能不会。
所以
A=0
表示您想要更改无法更改的指针
,其中
B=0
表示您正在将指针更改为指向0x00000000
答案 5 :(得分:1)
你在那里的代码快照不应该编译,因为A[]
实际上是一个零大小的数组,因此是一个不完整的类型,这在类规范中是不允许的。
对于例如Visual Studio无法使用以下错误编译它:
1&gt; ... \ test.h(4):警告C4200: 使用非标准扩展: struct / union 1中的零大小数组&gt;
无法生成copy-ctor或 UDT时的复制赋值运算符 包含一个零大小的数组 1&gt; ... \ test.h(5):错误C2229:class 'TestClass'有一个非法的零大小 阵列
要初始化并使用A[]
,您必须将其声明为静态,并使用如下文件范围对其进行初始化:
class TestClass
{
private:
static int A[];
int *B;
public:
TestClass();
};
TestClass::TestClass()
{
//A = 0; Yes this is wrong, see below.
B = 0; // Passes
}
int TestClass::A[] = {1,2,3};
至于A = 0,这也是错误的,Visual Studio会抱怨这个错误,这是不言自明的:
1&gt; .. \ test.h(13):错误C2440:'=':无法从'int'转换为'int []' 1 GT;虽然存在对引用或指向数组的指针的转换,但是没有对数组类型的转换。
LE:另请参阅David Rodríguez - dribeas答案以获得零大小数组的完整解释。
答案 6 :(得分:1)
长答案简短,A是类型数组 和B是int的类型指针。
A []初始化零大小的数组,您无法为其赋值。
不过,您可以自己问C ++:#include <iostream>
#include <typeinfo>
using namespace std;
class TestClass{
private:
int A[];
int* B;
public:
TestClass();
};
TestClass::TestClass(){
cout<<"Type A: "<<typeid(A).name()<<endl;
cout<<"Type B: "<<typeid(B).name()<<endl;
}
int main(int argc, char** argv){
TestClass A;
return 0;
}