C语言中数组指针的理解

留个标记,以防自己忘掉

在《C陷阱与缺陷》这本书中说道:

C语言中的数组值得注意的地方有以下两点:

1. C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来。然而,C语言中数组的元素可以是任何类型的对象,当然也可以是另外一个数组。

    这样,要“仿真”出来一个多维数组就不是一件难事。

2. 对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。其他有关数组的操作,哪怕它们乍看上去是以数组下标进行

    运算的,实际上都是通过指针进行的。换句话说,任何一个数组下标运算都等同于一个对应的指针运算,因此我们完全可以依据指针行为定义数组下标的行为。


数组指针的定义形式:


然后可以使用新类型定义一个变量并赋值:

以上是三种赋值形式,下面先看一下这数组的中的各个形式的地址:

从上面地址可看出,a与*a地址是同一个,a + 1与*a + 3是同一个;我们知道a,*a现在表示的还都是指针,那么它们加1后表示什么呢?虽然a与*a表示的地址相同,但是它们

表示的涵义却是不同的。现在我们定义: int *p = b[3];我们知道如果p + 1实际上是加的不是一个字节(只有void *p这种形式,p加1才会加一个字节;当然除了1个字节的变量

类型:char等),而是加了int类型的字节数sizeof(int),那我们来看一下a与*a加了几个字节(*a没什么好说的,它就相当于一维数组的首地址,移动一次就移动一个数组元素):

从上面的地址中可看出,a + 1实际上是加了12字节,*a + 1加了4字节;也就是说*a所加的实际上是数组中的一个元素的字节数,数组元素是int类型,所以加的是sizeof(int) = 4;

而a + 1实际上是加了整个数组的所有元素的字节数3X4 = 12;因为a是数组指针变量,也就说它的一个偏移实际上是移动了数组的整个长度。

a还可以理解为是a是二维数组的指针,这是为什么呢?首先看一下二维数组的定义:

首先声明一个一维数组类型


用一维数组类型去声明一个二维数组b,也就是说b是一个拥有3个整型元素的数组,b中的每一个元素类型为:拥有3个整型元素的数组。这也验证了C语言中的那个只有一维数组的原则,实际上二维数组也是一维的,只不过它的元素类型是一维数组。这样我们就可以用这个一维数组类型来定义一个它的指针,也就是数组指针,它指向的是个二维数组。

这样一来上面的变量a,就能更好理解了。而对于*a来说,实际上就是把二维数组的行指针变成了列指针,因此它每移动一次就移动了一个元素。

下面扩展一下,看下下面的代码:

输出的结果是什么呢?我们来分析一下,b是一维数组,对b取地址也就是说&b实际上是b的数组的地址的地址,也就是说&b表示数组指针。这样一来&b + 1相当于移动了一行,

也就是&b + 1移动了12字节,指向了b数组的尾地址的下一个地址。而后将它转换为指向整型的指针类型,这样一来它每移动1,不能加12字节了,只能加一个整型的4字节,所以

p - 3相当于移动到了数组b的第一个元素的地址,对其取内容的结果就是b[0] = 1。






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值