先思考这个问题,假设我有一组数,我需要在每两个数字中间加入一个空格然后再输出出来,末尾和头部都没有空格,应该如何实现。

实现方法很简单,加个if就可以实现了,比如我想输出1 2 3 4 5 6,就可以这样:

#include<stdio.h>
int main()
{
    int arr[6] = { 1, 2, 3, 4, 5, 6 };
    for (int i = 0; i < 6; i++)
    {
        if (i == 5) //输出到最后一个数字了
            printf("%d", arr[i]);
        else
            printf("%d ", arr[i]);
    }
    return 0;
}

我们利用一个if语句来判断是否输出到最后一个数字,来选择是否输出占位的空格。事实上,也可以对第一个数字特殊对待,然后剩余数据输出时附带一个空格。

但是如果我们这么做呢:

#include<stdio.h>
int main()
{
    int arr[6] = { 1, 2, 3, 4, 5, 6 };
    for (int i = 0; i < 6; i++)
        printf(" %d" + !i, arr[i]);
    return 0;
}

极其简单的几句话完成了我们之前要的操作,一气呵成。

我详细叙述下它的过程:

玄机在于printf语句的那个加法上。C语言的字符串常量作参数,实际上是一个指向常量池中该字符串的指针,也就是可以进行运算。然后就是一个!i,这是把C语言中的整型数据当布尔值来看待,对他取非。当循环第一趟时,i=0,0在C语言中是false,非i得到true,默认为1,当那个指针+1,指针就从原来的指向空格,变成指向“%d”,那么就不会输出空格。而当之后几轮时,i均为非0数,C语言中为true,那么取非则得到false,即0,那么原指针+0,就是它本身,也就会正常输出空格,最后达到我们的要求。

这种写法说实话有很大局限性,可读性也极差,但是却很好的体现了C语言的灵活之处。C语言对数据和内存的操作极为灵活,这就要求使用者有很高的水平。这种写法不推荐在正式的程序设计中使用,但是对于开拓思维、优化程序是很有帮助的。