指针和数组的异同点
在某些时候,指针和数组可以混淆,有的时候却不行,那么我们应该怎么认识指针和数组呢?我们需要从定义去理解它们。
首先指针变量是用来存放某种类型的地址的变量,定义一个整型的指针:int* p,定义了一个指针后,编译器会为指针分配一个地址空间,空间大小是指针的大小,类型定义只是在告诉编译器,这个指针标量存放的是什么类型的地址,并不影响指针的空间分配,就是说char*p,和int*p1,p和p1的空间分配大小是一样的,不一样的是p存放的是整型变量的地址,p1存放的是字符型变量的地址,并且移动的时候,是按照类型的内存空间大小进行移动,例如:在x86的环境下,字符型的变量是1个字节,整型变量是4个字节,p移动的时候是一个字节一个字节的移动,p1移动的时候是4个字节,4个字节的移动。指针变量里,只能放地址,就是我们常说的左值,不能把一个非地址的常量赋值给指针,那样是错误赋值。例如:int*p=2;
数组的定义,数组就是存放一定数量变量的内存空间,定义的时候,编译器会根据你的定义为数组分配适当的内存空间。例如chararray[10],编译器会给array分配10个字节的内存空间,如果定义为int array[10],在x86环境下,就会分配40个字节的内存空间,在单片机里,就会分配20个字节的内存空间。数组里面存放的变量类型取决于定义的类型,可以是常量数组,也可以是指针数组。也就是说数组里的变量可以是常量,可以是变量,只要用户去定义数组的类型就可以了。
从定义上看,指针和数组是有很大的区别的。
那么在什么时候,数组等同于指针呢?在作为函数传递参数的时候,数组是等同于指针的,为什么呢?因为,数组在作为参数传递或者调用数组的时候,通常都是把数组首元素的地址作为参数来传递或者调用,这个时候数组名就相当于数组首元素的地址,也就是指针了。就是说void test (int array[]); void test (int * array),这两种函数声明其实都是一样的,形参这都是&array[0];只是表达的方式不一样。
在使用下标的时候,二者的用法相同。都是原地址加上下标的值,不过数组的原地址就是数组首元素的地址是固定的,指针的原地址就不是固定的,指针指向那个元素,该元素的地址就是要加上下标之前的原地址,因为这样,这样指针的灵活性很大。
还要搞清楚一个知识点,指向数组的指针:int(*p)[10];和指针数组int*p1[10],二者的区别。举个例子,一个二维数组int array[5][10],想要指针对数组的元素进行改写或运算,首先要对指针进行正确的赋值。那么这么赋值:int*p =array对不对呢?答案是否定的,你的意思是定义一个整数类型的指针,指向了一个二维数组array[0]?那么为什么错呢,因为array[0]是一行有十个元素的数组,并不是一个整型变量!正确的定义的方法就是:int(*p)[10]= array;或者int *p = array[0][0];如果直接操作数组名取得array[1][5]的元素,除了了用下标,用数组名作为指针的取元素方法是:*(*(array+1)+5),因为array+1其实还是一个指针,他是指向了第二行第一个元素的指针,想要取得元素,必须要要再解引用一次。但是如果混淆了指针和数组,很容易会定义出:int**p = array;这就变成了定义了一个指向指针的指针,然后把一个数组给了这个指针,显然是不对的。
int_Paul
2017年7月28日11:09:38