数组和指针问题
1………考虑一下 代码 输出什么 ?
void func(int arg[10]) { cout << sizeof (arg)<<endl; } int main() { int arg[10]; func(arg); cout << sizeof arg<<endl; system("pause"); return 0; } 答案 4 40 解释 虽然func函数申明了参数为整形数组,但是这时候arg已经退化为了int*的指针 也就是说 函数参数占用4字节内存空间 证明如下 func(arg); 00374D2E lea eax,[arg] 00374D31 push eax 00374D32 call func (03714E7h) 00374D37 add esp,4 由于C函数默认cdecl 调用,所以 add esp,4 中的4为函数func参数大小, 我明明申明了是int a[10] 为什么变成了 int* ?,这就是涉及到了数组名的退化, 我们知道数组名 是首地址,没错,他的值是该数组的首地址 但是 数组名的数据类型 却不是 指针,只不过值等于指针, 所以函数func 申明等价于以下代码 void func(int *arg); 就算申明为数组,也会退化为int*指针类型,所以 我们可以这样理解,数组 是一个基本数据类型,和指针有区别 ,所以,我们来看看一些库函数的申明 void *memcpy(void *dest, const void *src, size_t n); void *memset(void *s, int ch, size_t n); 还有很多函数是这样的参数形式,函数参数内部都要指定 "数组" 的长度, .
2….考虑一下代码输出多少?
int main() { int arg[10] = {5,5,5,5,6,8,7,41,2,5}; int *ptr_; ptr_ = arg; cout << sizeof ptr_; system("pause"); return 0; } 答案 4 arg是个数组类型,ptr 是个int* 答案当然是4 ,但是为什么sizeof arg就是 40 ? 操作 ptr_=arg 并不是一个简单的赋值操作,因为arg和ptr数据类型不一样,所以arg要被转换为ptr_ 一样的数据类型 ,以下证明 int *ptr_=arg; 01108C8E lea eax,[arg] 01108C91 mov dword ptr [ptr_],eax 所以才导致了 所谓的数组名退化为指针,对于程序来说 数组类型并不是 像float int这样的基本数据类型; 而不是 直接 mov eax,arg; 因为他们数据类型都不一样 当然不能直接赋值操作 以下代码 int main() { int arg[10] = {1,2,3,4,5,6,7,8,9,0}; int *ptr_=arg; int int_ptr = (int)arg; int_ptr += 4; cout << *((int*)int_ptr); system("pause"); return 0; } int_ptr+=4 的结果值 等效于 cout << *++ptr_; 也就是说 他们并不是一个数据类型 对于指针来说 +1操作是 该块内存单元的下一个单元 也就是 arg 的下一个地址单元 也就是arg[1]的内存空间; . 以下代码利用c++11 int main() { int arg[10] = {1,2,3,4,5,6,7,8,9,0}; decltype(arg) arg_test; cout << sizeof (arg_test); system("pause"); return 0; } 很容易就证明了 数组第一个元素 并不是指针