指针数组和数组指针

指针和数组的区别:
    数组:
    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位平台下都是四个字节,如果是计算数组的元素个数,需要将元素作为参数传给函数。

思考问题:如果是函数的参数为一级指针可以接收什么参数?
                可以接收变量地址、一维数组名、一级指针、字符串、一维字符型数组。
                如果是二级指针呢?
                可以接收二级指针、一级指针地址、指针数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值