关于 printf 的骚操作
是的,
今天我要来说一个特别“简单”的标准库函数——printf
。
为什么说他简单呢?
毕竟这个函数真的没有太多东西,
我们早在第一堂课输出 Hello World 时就已经接触了,
而且几乎无时无刻不会用到这个函数,
以至于我们对它实在太熟悉了!
那我们还有什么好说的呢?
其实不然,我今天要说的东西与其说是 printf
的骚操作,
还不如说是 C 语言本身的骚操作,
也就是 C 的灵魂——指针的骚操作。
printf
和指针在一起就能有骚操作?
是的,我想看完这篇文章后你应该会对 C 语言有个更加深刻的理解。
下面就不卖关子了,直接进入正题。
一、首先看个题目!
看似很简单,
但是实现起来总是蹑手蹑脚的,对吧?
二、怎么解?
如果你是怎么写?
像这样先单独输出第一个吗?
1 | int a[] = {1, 2, 3, 4, 5, 6}, i; |
好像实现了,但是 printf("%d", a[0])
总显得很难受!
好像不是最优解!
那或者用 if/switch
判断语句?类似于这样?
1 | int a[] = {1, 2, 3, 4, 5, 6}, i; |
嗯!好像结构很漂亮了,但是用 if/switch 判断语句处理这么个小问题总感觉有些杀鸡用牛刀了!
那怎么做?这里我直接给出代码:
1 | int a[] = {1, 2, 3, 4, 5, 6}, i; |
三、怎么做到的?
答案很简单,我认为这是一种指针偏移的合理运用。非常得简洁和优雅!
我初次看到这串代码,真的是佩服得五体投地。但细细琢磨一下,好像又没什么东西。
或许很多事都差不多吧,看着很绚丽,实际上说清楚了也就没什么了!
下面简单讲解一下:
首先,我们知道在 C 语言中,非零为真,零为假。
那么,对于 !i
这个式子来说,
当 i = 0
时,得到的是 1
;
当 i = 1,2,3...
时,得到的是 0
。
所以,对于 printf
的第一个参数 ",%d" + !i
来说,
当 i = 0
时,它就变成了 ",%d" + 1
。
这里首先做了从字符串到指针的转换,然后再做了指针的 +1 运算,
就相当于指针后移了一位,即指向 "%d"
。
类似的,
当 i = 1,2,3...
时,
它就变成了 **",%d" + 0
**,
即得到了 ",%d"
。
四、补充新解法
上面说的写法固然很妙,也很简洁。但是有一个可能的缺点,那就是可读性。
对于已经理解的人来说,一看就懂。但是并不是所有人都能一眼看懂那段代码的!
所以,这里提供一个最新的增加了可读性的写法:
1 | int a[] = {1, 2, 3, 4, 5, 6}, i; |