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);
还有很多函数是这样的参数形式,函数参数内部都要指定 "数组" 的长度,
.
- 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);
- 还有很多函数是这样的参数形式,函数参数内部都要指定 "数组" 的长度,
- .
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;
}
很容易就证明了 数组第一个元素 并不是指针
- 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;
- }
- 很容易就证明了 数组第一个元素 并不是指针
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;
}
很容易就证明了 数组第一个元素 并不是指针