指针和数组的区别:
数组:
1.数组要么在静态存储区被创建(全局数组),要么在栈上被创建(局部数组);
2.数组名对应着(不是指向)一块内存(大小已知),其地址与容量在生命周期保持不变,只有数组内容可以改变。
指针:
1.指针可以随时指向任意类型的内存块(不同类型可以用强制类型来转换实现),他的特征是“可变的”。
2.常用指针来操作内存,指针远比数组灵活,但也更危险。
指针数组:数组的元素是指针。
例如:int *pai[3]; 由于‘*’是自右向左结合,因此从右向左看,首先看到[3]说明是一个数组,是一个包含4个元素的数组,然后看到‘*’,显然是指针类型,由此可以看出数组中存放的是指针而不是一般的类型。
*注意:不能将二维数组的数组名赋给指针数组的数组名,因为俩者类型不一致,二维数组名是指向int[][]型的指针,而指针数组的数组名是指向int * []类型的指针。
数组指针:指向数组的指针。
分析例子:
int (*p)[10]; p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫做数组指针。
*注意:[]的优先级高于*所以得加()来保证p先和*结合。
当问答指针数组有多大?第一时间反映出内存映像区
一般的从栈区到代码区,是从高地址到低地址,栈是向下增长,堆是向下增长。
举个例子:
char * (arr[4])
//首先arr[4]是一个主函数定义的数组,把它对应到内存中,arr实在栈区,有四个元素数组,而每个数组有是一个指针,所有说四个元素各占四个字节,所以变量arr的大小是16个字节。
数组的指针使用:
首先看一个测试:
int main()
{
char buf[] = "abcdefg";
int arr[10] = {0};
//p一般以十六进制整数方式输出指针的值,附加前缀0x。
printf("%p\n", arr);
printf("%p\n", arr + 1);
printf("%p\n",&arr);
printf("%p\n", &arr + 1);
system("pause");
return 0;
}
输出结果:
有输出结果可知:数组的地址和数组首元素的地址是相同的,但是意义不同。
数组的指针是如何存储的?
看一段代码:
//数组指针的存储
int arr[10] = {0};
int * p2 = &arr;
int(*p3)[10] = &arr;
printf("%p\n", p2);
printf("%p\n", p3);
输出结果:
p2是数组指正,所以存放数组的指针是合适的
数组的传参:
一维数组的传参:首先看代码分析:
void arr1test1(int arr1[10])
{}
void arr1test2(int arr1[])
{}
void arr1test3(int * arr1)
{}
void arr2test1(int **arr2)
{}
void arr2test2(int *arr[10])
{}
int main()
{
//数组和指针的传参
int arr1[10] = { 0 };
int * arr2[10] = { 0 };
arr1test1(arr1);
arr1test2(arr1);
arr1test3(arr1);
arr2test1(arr2);
arr2test2(arr2);
return 0;
}
很显然传数组时候的三种都是正确的。
二维数组传参:
先看代码分析:
void test1(int arr[3][5])//正确
{}
void test2(int arr[][5])//正确
{}
//void test2(int arr[][])错误只可以省略第一个[]的数字
void test3(int (*arr)[5])//该二维数组内部是一个内部元素类型为5个整型元素的一位数组
{}
//void test3(int * arr)//错误
//void test3(int *arr[5])//错误,int *arr[5]是指针数组,是数组,而不是指针,类型不相符
//void test3(int **arr)//错误,int**arr是二级指针,与类型不想符。
int main()
{
int arr[3][5];
test1(arr);
test2(arr);
test3(arr);
system("pause");
return 0;
}
总结:数组在传参的时候,降级为内部元素类型的指针。二维数组在传参的时候,只可以省略第一个[]号的数字,因为对于二维数组可以不知道它有多少行,但一定到知道它每行有多少元素。所以在多维数组传参的时候,可将其看为一位数组方便思考。
*注意:在数组传参的时候,都需要降级为内部元素类型的指针,无论什么类型,在32位平台下都是四个字节,如果是计算数组的元素个数,需要将元素作为参数传给函数。
思考问题:如果是函数的参数为一级指针可以接收什么参数?
可以接收变量地址、一维数组名、一级指针、字符串、一维字符型数组。
如果是二级指针呢?
可以接收二级指针、一级指针地址、指针数组。