C 语言小技巧
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])))