C的温故而知新:指针和数组(C Primer Plus第十章)

第十章:数组和指针

讲道理,我是不太像总结这一章的,因为啥呢,反正也没几个人看这玩意儿,主要是作为自己个的学习流水账。因为啥不想写呢,是因为这一章的东西太多了,还比较难以理解,所以我不想写。但是为什么又存在这一篇文章呢,因为像之前所说的,学习流水账嘛,还是要记录的,只是知识点很可能没有那么全,理解的内容可能也不是很到位。但是话说回来,这玩意儿除了我,有谁会仔细看呢,就好比上一篇发的文章,明明是第九章编程练习,我一开始发布的那一版写的是第八章,而且等到第二天才发现,才修改了一下,而这一段时间里,有着或多或少的僵尸号刷阅读数,收藏数,试问这有什么意义。是为了让人们接着进行创作,还是让那些退了好几年的号重新得以利用?我不得而知,我也不想知道,我感觉这与博客的初衷背道而驰。是,或许这是其谋取生存之道或者说存于世的根本,牟利吗,不寒碜。就像王者荣耀,这么大的游戏IP,利润那么高,都有人机的存在。一个博客要想在当下生存,这些数据或许真的很重要。

好,扯远了,秉着总结一遍博客就好比再过一遍书的原则,再加上最近人比较闲,就努力一下,总结一些东西吧。

对于数组的定义呢,咱就不说了,就看一个简单的模版

const int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

上面的代码定义了一个只读数组,数组元素类型为int,个数为12个,并且初始化了12个值。在这里书上还提到了存储类别的概念,在后面应该还会详细说,在这就先不唠了。初始化列表中的项数应该与数组的大小一致,如果少于数组元素个数的话,会将剩余的元素初始化为0,如果多的话,会报错。如果省略[]中的内容,会根据初始化列表中的数据个数来确定数组的大小。可以用sizeof运算符来计算数组的大小,sizeof(days)是整个数组的大小,sizeof(days[0])是一个元素的大小,两数相除便得到了数组元素的个数。

指定初始化器:可以在初始化列表中使用带方括号的下标指明待初始化的元素,例如

int arr[7] = {[5] = 212,213};//把arr[5]初始化为212

如果后面还有其他的值,那这个值将会用于初始化后面的元素,也就是arr[6] = 213,如果在此初始化已经初始化的元素,后面的将会取代先前的初始化。数组生命中的[]中的内容只能是整形常量表达式。

多维数组:也就是数组的数组,可以说数组的元素是数组,维度越多,越复杂。初始化的时候,如果某一列的数值个数超过了数组每行的元素个数,会出错,但并不会影响其他行的初始化。内部的{}可以省略,不过有可能因为数值不够,引发数据错位的问题,详情看书上的图解。

指针和数组:这两者的关系十分密切,可以说是息息相关,我感觉我也说不太明白,只能说如果能读懂的话,尽量还是自己去理解这部分内容。间接运算符*的优先级高于+。数组名就是数组首元素的地址。数组作为函数形参的时候需要注意格式。以下两种格式都是指向int的指针。都可以作为数组的首元素去做函数的形参。

int * ar;
int ar[];

接着,书上用了很大的篇幅去讲解指针操作数组元素的操作,这一段还是自行理解吧。需要注意的是,千万不要解引用未初始化的指针

在之前,函数一般是处理从主调函数拷贝过来的值,对原值不会产生影响。除非将指针作为参数,直接去操作主调函数的变量地址。在数组这儿也是类似的,因为去操作数组的数据,我们默认传递的是地址,所以可能就会对数据造成不必要的修改,对此,我们可以在形参前面添加const去修饰它的值不可更改。

此外,const还有一些其他的注意事项。指向const的指针不能用于改变值;把const数据或非const数据的地址初始化为指向const的指针或为其赋值是合法的,然而,只能把非const数据的地址赋给普通指针;使用非const标识符修改const数据,导致的结果是未定义的;const可以声明并初始化一个不能指向别处的指针 ;使用两次const,还可以声明一个既不能更改指向的值,也不能修改指向地址上的值;

const double * pd = rates;//指向const的指针,不能用于改变值
double * const pc = rates;//声明一个不能指向别处的指针
const double * const ptr = rates;//声明一个既不能更改指向的地址,也不能更改地址上的值的指针

指针和多维数组:简单来说就好比一个较大的地址,嵌套一些较小的地址。这一块书上都有很多例子去解释,这些我就不一一的叙述了,自己去看书比较快。

指向多维数组的指针:[]的优先级高于*

int (* pz) [2];//声明一个指针指向,一个内含两个int类型值的数组

指针表示法或者数组表示法去表示一个数组都是可行的,看个人习惯,效率也是差不多的,因为数组表示借用了指针的内容,但是指针表示法更像机器语言,可能编译起来更快。

把const指针赋给非const指针是不安全的,允许这样做,但是行为是未定义的。C++不允许这么做

函数与多维数组:在函数中使用多维数组,如果作为形参,有两种传参风格,具体的声明格式自行看书吧。

void function(int (* pt)[4]);
void function(int pt[][4]);

变长数组:因为规定数组的维数是常量,不能使用变量,不太方便。所以有了变长数组,可以使用变量来表示数组的维度。变长数组必须是自动存储类别。其作为函数形参时也有一些特殊的格式要求,首先是维度变量要定义在变长数组之前,如果在函数原型中要省略形参名的话,可以用*来代替省略的维度。允许在声明变长数组的时候使用const常量。

复合字面量:字面量是除符号常量外的常量,说实话,我不太清楚它的意义是啥?复合字面量是匿名的,所以不能先创建然后再使用,必须在创建的同时拥有它。使用指针记录地址就是一种用法。具体有啥用,等用到的时候再议吧。

好,以上就是第十章的内容,我认为比较重要的点哈,都总结的话太多了,一些例子还是书上比较全面。指针毕竟是C语言比较难理解的内容,只能通过日后的使用进行反复地深刻理解。好,接下来,我们就看一下第十章后面的编程练习来看一下指针和数组的关系。

  • 19
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值