注解目录

第二章《c语言的一些“操作”及其深层理解》

一、字符串的实质就是指针

(如何将 35 转为对应的十六进制字符串”0X23”?)

二 、转义符\

(打入字符串内部的“奸细”。)

三、字符串常量的连接

(字符串常量是双面胶,你知道吗?)

四、长字符串的拆分技巧

(GPS 数据帧 NMEA、Shell 命令行和 AT 指令的解析,是长串拆分的典型应用。)

五、巧取数值的各位数码

(玩多位数码管的必有操作。)

六、printf 的实质与使用技巧

(自认为很了解 printf?那你试过向 3 个 UART 打印吗?或者打印到液晶屏上?)

七、关于浮点数的传输

(浮点只是一种假象,看清它的本质。)

八、关于数据的直接操作

(如何快速计算浮点的相反数,乘以-1.0?再想想。)

九、 浮点的四舍五入与比较

(老师说浮点不能直接判等,为什么?)

十、的 出神入化的 for 循环

(for 循环很熟悉了吧?OK,振南出了几道题,来试试。)

十一、 隐藏的死循环

(我们在明处,有时死循环在暗处。)

十二、 看似多余的空循环

(没用的东西?)

十三、 独立执行体

(这个概念 C 语言里没学过?那就对了,我经常用。)

十四、 多用() 无坏处

(万物皆可加括号。)

十五、== 的反向测试

(把==错写成=,能让你调程序调到吐血。)

十六、 赋值操作的实质

(让数学教授困惑半生的 C 语言赋值操作。)

十七、 关于补码

(摊牌了,CPU 其实不会作减法。)

十八、 关于-1

(-1 就是全 F,全 F 就是-1。)

二十、字节快速位逆序

(时间与空间的相互转化--计算机中的相对论)

二十一、关于 volatile

(有些东西不可优化。)

二十二、关于变量互换

(位操作的奇妙。)

二十三、关于 sizeof

(告诉你关于 sizeof 那些少人关注的问题。)

二十四、memcpy 的效率

(小小的函数也有大大的背景)

二十五、[ ] 的本质

(你以为[]只是数组下标?)

二十六、# 与##( 串化与连接)

(一个不曾出现在 C 语言教材中的知识点)

memcpy 的效率

memcpy 函数的功能是用来作内存搬运,就是将数据从一个数组赋值到另一个数组。它的实现很简单:

振南技术干货集:C语言的一些“骚操作”及其深层理解(10)-LMLPHP
但是这种实现方式,其实是比较肤浅而低效的。作为嵌入式或硬件工程师,如果对上面的代码看不出什么问题的话,那可能要好好找找自身的原因。上面的代码,对 CPU 数据总线带宽的利用率不高,我们把它改成这样:

振南技术干货集:C语言的一些“骚操作”及其深层理解(10)-LMLPHP
改进后的代码最大限度的利用了CPU数据总线带宽,每次传输(如32位平台为4字节)。这一实例告诉我们:C语言,尤其是嵌入式 C语言很多时候需要考虑硬件层面的因素,如 CPU 总线、内存结构等。

[]的本质

当我们想取出一个数组中的某个元素时,我们会用到[ ],采用下标的方式。如下例:

振南技术干货集:C语言的一些“骚操作”及其深层理解(10)-LMLPHP
其实我们可以用其他方式取出这个元素,即 * (a+1)。可以看到]与 *,在功能上有相似之处。其实门]并不限于与数组搭配访问数组元素,它的实质是:访问以指针所指向的地址为开始地址,以其下标为偏移量的存储单元中的数据,如图 2.12 所示。

振南技术干货集:C语言的一些“骚操作”及其深层理解(10)-LMLPHP
上图可能颠覆了一些人对[]的认识,下标还能是负数?[]可以在一个开始地址后面去取数据,为什么不能在它前面取数据呢?我们可以理解[]是对指针加减和取值操作的综合。认清了[]的实质,再加上对 C 语言的精髓一一指针深刻的理解,我们编程将会非常灵活肆意挥洒。

#与##(串化与连接)

我在C语言编程的过程中,经常乐于使用一种“局部独立化”的方式,我称之为“独立执行体”,如下例:

振南技术干货集:C语言的一些“骚操作”及其深层理解(10)-LMLPHP
这就是串化,在宏定义中#可以将宏参数转换为字符串,即在宏参数的开头和末尾添加引号。似乎有些鸡肋,但是如果看到别人的代码有用到串化的时候,我们需要能够看懂。

再来看一下连接符 # #,它用来将参数和其他的内容连接起来,如下例:

振南技术干货集:C语言的一些“骚操作”及其深层理解(10)-LMLPHP
我在很多 ARM 官方评估板的配套代码中看到过大量串化与连接的应用,当时我并不知道C 语言还有串化连接这些东西(虽然我已经用 C 语言有十几年了),所以有些看不明白。通过百度学习了一下#与##,这才懂了。所以,C语言学得多精都不为过,很多知识我们可能一辈子都不会用到,但是不代表我们可以不知道,因为别人在用。

关于 C语言方面的一些常见问题、非常规操作以及认知误区振南就讲这么多。C 语言其实是博大精深,还是那句话:“学得多精都不为过!”我一直把嵌人式工程师比喻成“能与硬件对话的灵媒”,我们所使用的语言就是 C语言。我们自认为对 C 语言已经足够了解了,足够精通了,但是我们又会发现在实际开发过程中,会遇到很多新的问题,很多问题是与 C 语言本身相关的。

所以记住:“学海无涯!”有 C语言方面的问题,欢迎与振南来沟通交流,我自己也在不断学习的过程中。振南技术干货集:C语言的一些“骚操作”及其深层理解(10)-LMLPHP

11-10 10:50