Difference between int* and int[] in C++
Context: C++ Consider the example below
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 fails but B = 0 succeeds. What's the catch? What exactly is A? A constant pointer? How do I initialize it the开发者_如何学JAVAn?
The question "what is the difference between int* and int[]?" is a less trivial question than most people will think of: it depends on where it is used.
In a declaration, like extern int a[];
it means that somewhere there is an array called a
, for which the size is unknown here. In a definition with aggregate initialization, like int a[] = { 1, 2, 3 };
it means an array of a size I, as programmer, don't want to calculate and you, compiler, have to interpret from the initialization. In a definition without initialization, it is an error, as you cannot define an array of an unknown size. In a function declaration (and/or) definition, it is exactly equivalent to int*
, the language specifies that when processing the types of the arguments for functions, arrays are converted into pointers to the contained type.
In your particular case, as declaration of members of a class, int a[];
is an error, as you are declaring a member of an incomplete type. If you add a size there, as in int a[10]
then it becomes the declaration of an array of type int
and size 10, and that will reserve space for 10 int
inside each object of the class. While on the other hand, int *b
will only reserve space for a pointer to integers in the class.
The only difference between them is that int A[]
in a class would not compile, and should not compile!
Comeau C++ compiler gives this error:
"ComeauTest.c", line 4: error: incomplete type is not allowed int A[]; ^
Wikipedia says,
Comeau C/C++ has been regarded as the most standards-conformant C++ compiler.
I therefore would suggest : Don't write such code even if your compiler compiles it.
A
is an array, and in C++ you need to specify the array size when you define the variable itself i.e. you need to do something like int A[10]
. Then you can access individual elements using A[0], A[1]
etc. B
is a pointer, so doing B=0;
sets the pointer to NULL. If you don't want to specify the size at compile time, but still want array like syntax you can use std::vector<int>
.
int A[]
is an memory range inside the class instance, where int *B
is a pointer that you may or may not initialize later.
so
A=0
means that you want to change a pointer that cannot be changed,
where
B=0
means that you are changing a pointer to point to 0x00000000
A[] is an array with its size undefined. You need to declare it like this:
int A[SIZE];
then initialize it like this:
A[0] = 0, A[1] = 5,
etc
long answer short, A is of type array and B is of type pointer to int.
A[] initializes an array of zero size, which you cannot assign a value to.
Btw, you can ask C++ yourself with:
#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;
}
The code snapshot you have there should not compile since A[]
is effectively a zero sized array, thus an incomplete type, which is not allowed in class specifications.
For e.g. Visual Studio fails to compile this with these errors:
1>...\test.h(4) : warning C4200: nonstandard extension used : zero-sized array in struct/union 1>
Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array 1>...\test.h(5) : error C2229: class 'TestClass' has an illegal zero-sized array
To initialize and use A[]
you must declare it as static and initialize it with file scope like this:
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};
As for A = 0 this is wrong too and Visual Studio will complain with this error, which is self explanatory:
1>..\test.h(13) : error C2440: '=' : cannot convert from 'int' to 'int []' 1> There are no conversions to array types, although there are conversions to references or pointers to arrays.
LE: Also see David Rodríguez - dribeas answer for a complete interpretation of zero sized arrays.
精彩评论