大小写转换
#define toupper(c) ((c) + 'A' - 'a')
#define tolower(c) ((c) + 'a' - 'A')
这两个宏都依赖于特定实现中字符集的性质,即需要所有大写的小写字母与相应的小写字母之间的差值是一个常量。因为这些宏不能移植,且这些宏被封装在一个文件中,所以这个假设也并不那么危险。
这些宏的不足之处:如果输入的字母大小写不对,那么它们返回的就都是无用的垃圾信息。
这段代码无法工作:
int c;
while ((c = getchar()) != EOF) {
putchar(tolower(c));
}
应该写成这样才对:
int c;
while ((c = getchar()) != EOF) {
putchar(isupper(c) ? tolower(c) : c);
}
#define toupper(c) ((c) >= 'a' && (c) <= 'z' ? (c) + 'A' - 'a' : (c));
#define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c));
可能每次宏调用,致使c被求值1到3次。例如遇到toupper(*p++)这样的表达式。
int toupper(int c) {
if (c >= 'a' && c <= 'z') {
return c + 'A' - 'a';
}
return c;
}
健壮性得到增强,代价是引入了函数调用的开销。
因此引入了新的宏名:
#define _toupper(c) ((c) + 'A' - 'a');
#define _tolower(c) ((c) + 'a' - 'A');