区别
1. 初始化方式不同
int *pt=4;
int arr1[]={1,2,4};
int arr2[][]={{1,3,4},{2,3,4}};
2. 指针可变,数组名不可变
赋值
int *pt=4;
int arr[]={1,2,4};
int arr2[];
pt = arr;//数组名指向数组地址
arr2 = arr;
//错误
加减运算
int arr[]={1,2,4};
int *pt;
pt = arr; //只能单向赋值,arr=pt的用法是错误的!
//数组名不可直接赋值,类似a=2,不能2=a
pt = pt+1; //加法运算后,值为arr[1]的地址
*++pt; //pt先指向下一个存储单元即arr[1]的存储地址,再解引用,其值为2
*pt++; //pt先解引用,再+1,其值为2+1=3
//数组名无法进行此类运算
3. 大小
int arr[]={1,2,4};
int *pt;
printf("The size of arr[] is %d bytes",sizeof arr);
//一个int占4字节,存储3个int,3×4字节。
printf("The size of pt is %d bytes",sizeof pt);
//用于存储地址所用的字节数,64位系统是8字节。
联系
1.数组名是数组首元素的地址,而指针的值也是地址。
int function(int arr[]);
int function(int *arr);
//可以相互代替,只有定义函数原型才可以这样用,
//第一行代码中arr是指向int型数组元素的指针
//第二行代码中arr是指向int型整数的指针。
2.指针表示法和数组表示法
copy数组的每一个元素时,占用内存大(一个新的数组),因而运行速度慢,但是可以保护原始数据不会改变。
但是直接用指针指向,只需一个存储指针地址的内存,因而运行速度快,但是指针方式会直接修改原始数据,对原来的数据保护不利。
//一维数组与指针
int arr[]={1,2,4};
int *pt;
pt = arr; //arr==&arr[0]
printf("arr[0]=%d",*pt); //*pt=*(&arr[0])=arr[0]
printf("arr[1]=%d",*(pt+1)); //*(pt+1)=*(&arr[1])=arr[1]
//二维数组与指针
int arr[2][3]= {{1,2,3},
{4,5,6}};
int (*pt1)[3];//表示pt1是一个指向数组的指针,所指向的数组内含三个int型数据。
//int *pt1[3]; //该表示pt1为数组,该数组内含三个指向int型数据的指针。
int *pt2;
pt1 = arr; //arr=&arr[0]
pt2 = arr[0]; //arr[0]=&arr[0][0],pt2=*pt1
/*pt1指向一个pt2存储的地址,即*pt1=pt2,是一个地址。
pt1指向对象为包含三个int型整数的数组,pt2指向对象大小为一个int型整数,指针递增指的是对应存储单元递增,所以
pt1+1,表示指向下一个行存储单元arr[1],即pt1+1=&arr[1]
pt2+1,表示指向下一个列存储单元arr[0][1],pt2+1=&arr[0][1]
**(pt1+1)=arr[1][0],
*(*(pt1+1)+2)=arr[1][2]
*(*pt1+1)=*(pt2+1)=arr[0][1]
*/
//验证代码
printf("**pt1=%d",**pt1);
//**pt1=**(&arr[0])=**(&&arr[0][0])=arr[0][0]=1
printf("*pt2=%d",**pt2);
//*pt2=arr[0][0]=1
printf("**(pt1+1)=%d",**(pt1+1));
//**(pt1+1)=**(arr+1)=**(&arr[1])=**(&&arr[1][0])=arr[1][0]=4
printf("*(pt2+1)=%d",*(pt2+1));
//*(pt2+1)=*(arr[0]+1)=*(arr[0][1])=2