C语言指针与数组总结

指针与数组本是两个互不相干的概念。但是在C语言中,指针和数组却有着一些奇怪的关系,让我们这些初学者非常的头疼。

首先,指针是一种变量类型,它一般包含两个属性:

  1. 指向的变量的地址
  2. 该变量所占的空间大小。

在实际操作中,对指针进行解引用的过程,就是根据指针中保存的地址找到对应的内存,再根据该变量类型的大小对这块内存区进行读取。
(1) 一级指针就是指向一个变量的指针,对一级指针进行解引用操作可以得到所指向的变量的值。
(2) 二级指针本质上是一个一级指针,只不过这个指针指向了一个一级指针。这么说好像有点绕口,简单来讲,二级指针保存了一个地址,根据这个地址可以找到一个一级指针。
三级指针同理,不过一般我们不会见到三级指针(面试除外)。

接下来再说数组,数组就是同一类型的变量的集合,因此数组实际上就是为了方便程序员批量创建变量,提取需要使用的变量常采取 数组名+下标 的形式,例如:

int arr[5] = {1, 2, 3, 4, 5};
arr[3];

上例中,arr就是该数组的数组名,3就是下标。下标从0开始,arr[0]表示数组的第一个元素。
以上都是(废话)基础,下面才是重点

在C语言中,数组名保存的是数组的首元素地址,一定条件下,数组名会隐式转换成指针。
例如:
(1)

	int arr[] = { 1, 2, 3, 4, 5 };
	printf("%d\n", *arr);

在该例中,对arr数组名进行了解引用操作,其效果相当于arr[0], 打印的结果是1。这样的操作不禁让人深思:既然可以对数组名进行解引用操作,那么是不是也可以对指针进行取下标操作 " [] " 呢?答案是肯定的,对指针变量进行操作: 变量名[0], 效果与 *变量名无异。

(2) 将数组名作为参数进行传参的过程中也会将数组名隐式转换成指针。因为将实参传给函数后,函数会生成新的变量来保存实参,这个新的变量我们常称之为形参,形参其实就是实参的一份拷贝。数组传参时,由于C语言的设计,并不能知道数组的大小,因此只能将数组名隐式转换成指针,形参中保存的就是数组的首元素地址,而形参也成了一个指针变量。

(3) 指针有一个特性,对指针相加减整数则向前或向后跳过整数个元素。对数组进行加减也会如此,因此对数组进行加减运算的时候也会隐式转换成指针,例如:

	int arr[] = { 1, 2, 3, 4, 5 };
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(arr));

在这段代码中,虽然看起来好像没对arr做什么,但是我们运行一下会发现打印的结果大不相同。首先打印的是 4 ,然后打印了一个 20。也就是说,arr 在加 0 后已经不再是那个单纯的 arr 了,它变成了一个指针;而后面这个没有进行任何操作的纯天然无污染的 arr ,它还是一个宝宝数组名,打印出来的结果自然也就是整个数组的大小。

虽然数组名可以隐式转换成指针,但是数组名是不可修改的,换句话说,数组名中保存的地址是不可修改的。

有了上面这些理论基础,下面这段代码就不难理解了

	int arr[] = { 1, 2, 3, 4, 5 };
	printf("%d\n", sizeof(&*(arr + 1) ) );
	printf("%d\n", sizeof(*(&arr+1) ) );

第一个打印操作中,先将 arr 隐式转换成了指针再加一,然后再对其进行解引用再取地址,得到的就是这个指针的大小;而第二个打印操作是先对数组名进行取地址操作得到了一个数组指针,这个数组指针指向的变量在内存空间中所占的大小就是原数组的大小 20,再对其进行解引用得到了一个占用空间大小为 20 的数组,这个数组实际上是不存在的,但是由于sizeof的编译器求值的特性,程序并没有崩溃,打印出来的结果就是20。

上文中提到了数组指针,于是最后总结一下数组指针和指针数组。
数组指针本质上是一个指针,但是这个指针指向了一个数组(整个数组),因此它的两个属性中一个保存了数组的首元素地址,一个保存了该数组的大小。
指针数组本质上是一个数组,但是这个数组的每个元素都是一个指针,这个很好理解就不多说了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值