标签:
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;
}
答案 40 4
解释 虽然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]的内存空间;
.
标签:
原文地址:http://my.oschina.net/kkkkkkkkkkkkk/blog/469116