C 语言小技巧

·6min·st1020

C 语言有许多可以提高编程效率,简化代码,提高代码可读性的小技巧。这里列出几个小技巧及其应用,抛砖引玉,供大家参考。

逗号运算符

C 语言提供了一种特殊的运算符——逗号运算符,又称顺序求值运算符,可以用它将两个表达式连接起来。

逗号表达式的一般形式如下:

Exp1, Exp2

其计算过程为:

先计算 Exp1,再计算 Exp2,然后将 Exp2 的返回值作为整个逗号表达式的值。

1+1, 2+2,这个表达式的值是 4。

需要注意,逗号运算符的优先级是所有运算符中最低的,比如:

a = 1 + 2, 3 * 4;

表示将变量 a 赋值为 1+2,然后计算 3*4 作为整个表达式的值,但这个值并没有被使用。

所以,这个表达式有什么用呢?

可以看以下几个例子:

#include <stdio.h>

int main() {
    int n;
    while (scanf("%d", &n), n) {
        printf("%d\n", n);
    }
    return 0;
}

如果不用逗号表达式,上述代码就需要写成:

#include <stdio.h>

int main() {
    int n = 1;
    while (n) {
        scanf("%d", &n);
        printf("%d\n", n);
    }
    return 0;
}

还有:

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0, j = n; i < j; ++i, --j) {
        printf("%d %d %d\n", n, i, j);
    }
    return 0;
}

如果不用逗号表达式,上述代码就需要写成:

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0, j = n; i < j; ++i) {
        printf("%d %d %d\n", n, i, j);
        --j;
    }
    return 0;
}

多了一行……好吧,实际上都没有多多少代码,但能少一行是一行嘛,并且,这样写代码的可读性提高了不少。

数组的部分初始化

当我们声明一个数组并对其进行初始化时,我们可以仅对其部分进行初始化,如:

int arr[] = {[1]=5, [5]=10, [2]=20};
int arr2[] = {[0 ... 9] = 10, [10 ... 19] = 20, [20 ... 29] = 30};

上面的例子很简单,应该没有什么可说的,这也算是 C 语言的一个很少有人知道的一个小特性吧。

C 语言的预处理器

C 语言的预处理器不是编译器的组成部分,而是编译过程中一个单独的步骤。实际上,我们可以把它理解为一个在开始编译源码之前的一个文本替换工具。最常用的预处理指令就是 #include,用于包含另一个源码文件,当我们在程序开头加上下面这行时,

#include <stdio.h>

预处理器就会在程序开始的地方引入 stdio.h 的全部内容,这样我们就可以使用这个头文件中包含的函数了。

另一个常用的预处理指令就是 #define,定义宏,如

#define PI 3.1415927

实际上就是将下面所有出现 PI 的地方替换为 3.1415927

完整的预处理指令如下:

指令描述
#define定义宏
#include包含一个源代码文件
#undef取消已定义的宏
#ifdef如果宏已经定义,则返回真
#ifndef如果宏没有定义,则返回真
#if如果给定条件为真,则编译下面代码
#else#if 的替代方案
#elif如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif结束一个 #if……#else 条件编译块
#error当遇到标准错误时,输出错误消息
#pragma使用标准化方法,向编译器发布特殊的命令到编译器中

ANSI C 标准还定义了许多宏。在编程中我们可以使用这些宏,但是不能直接修改这些预定义的宏。

描述
__DATE__当前日期,一个以“MMM DD YYYY”格式表示的字符常量。
__TIME__当前时间,一个以“HH:MM:SS”格式表示的字符常量。
__FILE__这会包含当前文件名,一个字符串常量。
__LINE__这会包含当前行号,一个十进制常量。
__STDC__当编译器以 ANSI 标准编译时,则定义为 1。

例:

#include <stdio.h>

int main() {
    printf("File :%s\n", __FILE__);
    printf("Date :%s\n", __DATE__);
    printf("Time :%s\n", __TIME__);
    printf("Line :%d\n", __LINE__);
    printf("ANSI :%d\n", __STDC__);
}

通过巧用预处理指令,我们可以有效的简化代码,比如,我们可以用预处理指令来定义求较大值、求较小值、转大写和求数组元素数的函数。

#define MAX(x, y) (((x)>(y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define UPCASE(c) (((c)>='a' && (c) <= 'z') ? ((c) - 0x20) : (c))
#define ARR_SIZE(a)  (sizeof((a))/sizeof((a[0])))