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

库函数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;
}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值