数组和指针问题

梦想游戏人
目录:
C/C++

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;
}

很容易就证明了 数组第一个元素   并不是指针
Scroll Up