c语言提高篇(二)——指针和数组



在我对c语言的认知里,指针和数组有着密不可分的关系,大家从平时的事例中可以看出,譬如说指针存储的是其他变量的地址,而数组名表示着该数组的地址;在函数传参时,指针和数组经常能互相替换等等这些例子;因为我写的是c语言的提高篇,所以我就讲讲指针和数组更加深层次的应用,或者说是一些大家会忽略的细节,如果注意到这些细节,相信一定会更深入理解他们两者的关系


首先来一下扫盲:int *p[2];//这是一个指针数组,实质是一个数组,里面的元素是指针类型
                           int (*p)[2];//这是一个数组指针,实质是一个指针,这个指针指向一个数组

一、二维数组

int a[2];
int *p = NULL;
p = a;
  上面的初始化函数是肯定没错的,那么就可以看出a实际上是一个地址,知道这一点,我们再来看看下面的例子
 
int a[2][3];
int *p = NULL;
p = a;
  大家觉得上面的初始化正确吗?如果大家去编译一下的话,编译器会毫不留情得给你一个大大的错误提示信息,相信这里就有很多人感到疑惑吧!所以,现在就来讲讲上面错误的原因吧!

  大家得知道,在一维数组里面,数组名代表的是数组首元素的地址。在二维数组中,数组名代表的是第一维数组a[0]的地址。如果你们用%p去打印一下这两个地址的话,会发现这两个地址是相同的,那么问题就来了,地址相同的话,那两者不就是一样的?答案是,不一样的。
  造成这一误区是因为对数据类型的不理解。上一节我讲过,定义变量时需要两因素,一是数据类型,一是变量名字。数据类型代表该变量所占的内存大小,而变量名字代表着变量的内存地址。所以说,在c语言的世界里,变量的地址和大小是十分重要的。
  而上面所说的首元素的地址代表着那一个元素的地址,那一个元素的大小是一个int类型的大小,所以当这个地址赋给指针后,指针加1时,那么地址偏移一个int类型的大小。
  而第一维数组的地址,那一维元素的大小是3个int类型的大小,当这个地址赋给指针后,指针加1时,那么地址偏移3个int类型的大小
  说到这里,大家可能有一点明白了,那么我们到底应该用什么类型的指针去指向二维数组呢?二维数组名字的本质是一个数组的地址,所以我们需要用的是数组指针
 int a[2][3];
 int (*p)[2] = NULL;
 p = a;
上面程序编译能完美通过

注意:int a[2][3];
 int b[3];
其实a与&b[3]是同一类型的


二、指针和数组作为函数参数

(1)
int fun(int *p);
int main()
{
    int a[10];
    fun(a);
}
  上面的函数调用肯定是没错的,很多人也经常这样用,但是函数参数明明是一个指针类型,我传一个数组类型的,为什么这样可以呢?
  这就要搞清楚指针作为参数时,此时是址传递,也就是说实质上传递的是一个地址,传递后,在函数里面直接用指针指向这个内存地址,然后直接操作里面的内容
  而一维数组的名字代表着什么?恰恰是首元素的地址,类型匹配,所以,这样传递是没有问题的

(2)
int main(int argc, char *argv[]);
int main(int argc, char **argv);
    上面的两个定义大家是不是觉得有点眼熟,没错,是在main函数的参数中出现的,两者都可以,那么两者是不是等价的呢?答案:当作为参数是可以等价的
  上者一定义的是一个指针数组,代表着这是一个数组,数组里面的元素是指针类型,但是作为参数时,数组名等价于一维数组,再加一个*,指的就是二维数组
  所以上面第二个参数的实质是要一个指向char型的指针的地址

总结:当指针作为函数参数的时候,这个参数的实质意义是传递的要是一个地址,数组作为参数时,也是需要一个地址,因此在传递参数时,指针和数组可以互换.
而从上面的例子可以看出,想要真正掌握好指针,就要深刻的知道指针也是一个变量,只不过这个变量的类型是地址类型,正是因为是地址类型,而数组名也是地址类型,且只要知道这个地址,后面的元素就能用地址相加的原理来得出,所以指针和数组的关系十分密切。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值