(编程基础)从大小写转换看define的用法

来源:互联网 发布:小米主题制作软件 编辑:程序博客网 时间:2024/04/29 01:20

库函数toupper和tolower有一段不为人知的历史,具体的实现有如下几个阶段:

阶段一:

#include <stdio.h>#define toupper(c) ((c) + 'A' - 'a')#define tolower(c) ((c) + 'a' - 'A')int main(){    printf("A = %d, a toupper result is: %d\n", 'A', toupper('a'));    printf("a = %d, A tolower result is: %d\n", 'a', tolower('A'));    printf("a to lower: %d\n", tolower('a'));    return 0;}

运行结果:

cheny.le@cheny-ThinkPad-T420:~$ ./a.out
A = 65, a toupper result is: 65
a = 97, A tolower result is: 97
a to lower: 129

可以看到大写字母转小写字母是ok的,小写字母转大写也是ok的,但是如果误用了小写字母转小写,会出现问题,这个阶段没有考虑到用户的误操作。


阶段二:

#include <stdio.h>#define toupper(c) ((c) >= 'a' && (c) <= 'z' ? (c) + 'A' - 'a' : (c))#define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c))int main(){    printf("A = %d, a toupper result is: %d\n", 'A', toupper('a'));    printf("a = %d, A tolower result is: %d\n", 'a', tolower('A'));    printf("a to lower: %d\n", tolower('a'));    return 0;}

这个可以看到小写字母转小写字母的问题避免了,但是每次宏调用会使c被求值1-3次,如果遇到tolower(*p++)类似的表达式,会产生不良的后果。


阶段三:

#include <stdio.h>int toupper(int c){    if (c >= 'a' && c <= 'z') {        return c + 'A' - 'a';    }    return c;}int tolower(int c){    if (c >= 'A' && c <= 'Z') {        return c + 'a' - 'A';    }    return c;}int main(){    printf("A = %d, a toupper result is: %d\n", 'A', toupper('a'));    printf("a = %d, A tolower result is: %d\n", 'a', tolower('A'));    printf("a to lower: %d\n", tolower('a'));    return 0;}
这样改动之后程序的健壮性显著增强,看起来没有什么缺点了,但是每次使用这些函数的时候又引入了函数调用的开销。


阶段四:

#include <stdio.h>#define _toupper(c) ((c) + 'A' - 'a')#define _tolower(c) ((c) + 'a' - 'A')int toupper(int c){    if (c >= 'a' && c <= 'z') {        return c + 'A' - 'a';    }    return c;}int tolower(int c){    if (c >= 'A' && c <= 'Z') {        return c + 'a' - 'A';    }    return c;}int main(){    printf("A = %d, a toupper result is: %d\n", 'A', toupper('a'));    printf("A = %d, a toupper result is: %d\n", 'A', _toupper('a'));    printf("a = %d, A tolower result is: %d\n", 'a', tolower('A'));    printf("a = %d, A tolower result is: %d\n", 'a', _tolower('A'));    printf("a to lower: %d\n", tolower('a'));    printf("a to lower: %d\n", _tolower('a'));    return 0;}

这样子改动给了用户更多的选择,如果不需要考虑速度,就可以使用函数调用,如果考虑效率就必须自己注意使用方式,这样子速度和效率有了一个平衡,这个也就是最终版本了

原创粉丝点击