📝tolower/toupper函数
🌉tolower
tolower
函数是C标准库中用于将字母从大写转换为小写的函数。
函数原型:
int tolower(int c); c: 需要转换的字符,必须是unsigned char类型或可隐式转换为unsigned char类型的值。
回值:
返回转换后的小写字符。如果c不是一个字母,则返回原值c。
返回值类型为int,这是为了能够返回任何可能的字符值。
注意:
c必须是unsigned char类型或能隐式转换为unsigned char,如char、int等。
返回值类型为int,是为了能够返回任何可能的字符值,包括非字母字符本身。
如果c不是一个字母,函数直接返回c而不进行转换。
代码:
# define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <ctype.h> int main() { char uppercase = 'A'; char lowercase = tolower(uppercase); printf("%c 转为小写是:%c\n", uppercase, lowercase); return 0; }
🌠 toupper
toupper函数是C标准库中用于将字母从小写转换为大写的函数。
int toupper(int c);
和tolower函数一样:
- 参数c类型为int,需要转换的字符可以隐式转换为unsigned char
- 返回值类型为int,返回转换后的大写字符或原字符c如果c不是字母t
oupper函数和tolower函数的参数和返回值类型是完全相同的:
int tolower(int c);
int toupper(int c);
两者都以int类型作为参数和返回值,目的是为了能处理任何可能的字符值。
#include <stdio.h> #include <ctype.h> int main() { char lowercase = 'a'; char uppercase = toupper(lowercase); printf("%c 转为大写是: %c\n", lowercase, uppercase); return 0; }
🌠 ASCII码关系
通过ASCII码表来进行大小写字母的转换。ASCII码表中小写字母的范围是97到122,大写字母的范围是65到90,它们之间相差32。因此,可以通过加上或者减去32来进行大小写字母的转换。
#include <stdio.h> char to_uppercase(char c) { if (c >= 'a' && c <= 'z') { // 如果是小写字母,则将ASCII码值减去32转换为大写字母 return c - 32; } else { return c; } } char to_lowercase(char c) { if (c >= 'A' && c <= 'Z') { // 如果是大写字母,则将ASCII码值加上32转换为小写字母 return c + 32; } else { return c; } } int main() { for (char lowercase = 'a'; lowercase <= 'z'; lowercase++) { char uppercase = to_uppercase(lowercase); printf("%c 小转大: %c\n", lowercase, uppercase); } for (char uppercase2 = 'A'; uppercase2 <= 'Z'; uppercase2++) { char lowercase2 = to_lowercase(uppercase2); printf("%c 大写转小写: %c\n", uppercase2, lowercase2); } return 0; } >
🌉位操作
二进制是由0和1组成的数字系统。在位运算中,&
(按位与)、|
(按位或)和~
(按位取反)是常用的操作符。
这些运算符在二进制中的作用:
按位与(&):对两个二进制数的对应位进行逻辑与操作,只有当两个位都是1时,结果才为1,否则为0。
按位或(|):对两个二进制数的对应位进行逻辑或操作,只要有一个位是1,结果就为1。
按位取反(~):对一个二进制数的每一位进行取反操作,即0变为1,1变为0。
现在我们用二进制来解释一下如何使用这些操作符进行大小写字母的转换。
假设我们有一个字符 'A',对应的ASCII码为65,其二进制表示为 01000001。
小写字符‘a’为
- 小写字母转换为大写字母:我们想要将其转换为小写字母
'a'
。
我们知道大写字母和小写字母的ASCII码值之间差32。因此,我们可以通过将65的第6位(从右往左数,从0开始)设置为0来将其转换为小写字母。我们可以使用按位或操作符|
来实现这一点。
原始 ASCII: 01000001 32的二进制: 00100000 <-- 这是32的二进制表示,它的第6位是1,其他位都是0 按位或: 01100001 ('a'的ASCII码)
- 这样,我们就成功地将大写字母
'A'
转换为小写字母'a'
。
char toUpper(char c) { if (c >= 'a' && c <= 'z') return c & ~32; // Clear the 6th bit to convert to uppercase else return c; }
大写字母转换为小写字母:我们想要将其转换为大写字母 'A'。
我们知道大写字母和小写字母的ASCII码值之间差32。因此,我们可以通过将小写字母的第6位设置为0来将其转换为大写字母。我们可以使用按位与操作符 & 和按位取反操作符 ~ 来实现这一点。
原始 ASCII: 01000001 按位取反: 10111110 <-- 这是65的按位取反结果 32的二进制: 00100000 <-- 这是32的二进制表示,它的第6位是1,其他位都是0 按位与: 01000000 ('A'的ASCII码)
- 这样,我们就成功地将小写字母
'a'
转换为大写字母'A'
。
#inclu#include <stdio.h> char toLower(char c) { if (c >= 'A' && c <= 'Z') return c | 32; else return c; }
🌠小巧第五位
上面了解位运算,并且用的是32的二进制进行第6位操作,还要取反(~)是不是觉得有点繁琐,能不能一步到位呢,这里有个小巧比较,以下用的是第五位进行操作:
- 小转大
#include <stdio.h> char to_uppercase(char c) { // 如果字符是小写字母,将第5位(32)置为0,即转换为大写字母 return (c & 0xdf); }
首先,我们知道大写字母的ASCII码值范围是65到90,而小写字母的ASCII码值范围是97到122。它们之间的差值恰好是32。
在ASCII码中,将小写字母转换为大写字母,实际上就是将对应字符的第5位(从右往左数,从0开始)置为0。
为了实现这一点,我们使用了按位与运算符 &,并将字符 c 与十六进制数 0xdf 进行按位与操作。0xdf 的二进制表示是 11011111,将其与字符 c 进行按位与操作,可以确保字符的第5位被置
为0。
- 小写字母 `'a'` 的ASCII码值是97,其二进制表示为 `01100001`。 - 我们将其与 `0xdf` 进行按位与操作, - 得到的结果是 `01100001 & 11011111 = 01000001`, 这就是大写字母 `'A'` 的ASCII码值。
- 大转小
char to_lowercase(char c) { // 如果字符是大写字母,将第5位(32)置为1,即转换为小写字母 return (c | 0x20); }
- 类似地,将大写字母转换为小写字母实际上就是将对应字符的第5位置为1。
- 为了实现这一点,我们使用了按位或运算符
|
,并将字符c
与十六进制数0x20
进行按位或操作。0x20
的二进制表示是00100000
,将其与字符c
进行按位或操作,可以确保字符的第5位被置为1。
-- 大写字母 `'A'` 的ASCII码值是65,其二进制表示为 `01000001`。 - 我们将其与 `0x20` 进行按位或操作, - 得到的结果是 `01000001 | 00100000 = 01100001`, - 这就是小写字母 `'a'` 的ASCII码值。
int main() { char lowercase = 'l'; char uppercase = to_uppercase(lowercase); printf("%c converted to uppercase is: %c\n", lowercase, uppercase); char uppercase2 = 'G'; char lowercase2 = to_lowercase(uppercase2); printf("%c converted to lowercase is: %c\n", uppercase2, lowercase2); return 0; }
通过这种方法,我们可以在不使用 <ctype.h>
中的函数的情况下,实现大小写字母之间的转换。