这个自定义toupper()函数如何工作?

时间:2015-06-28 13:30:42

标签: c toupper

我见过以下使用自定义toupper()功能的程序。

#include <stdio.h> 
void my_toUpper(char* str, int index)
{
    *(str + index) &= ~32;
}
int main()
{
    char arr[] = "geeksquiz";
    my_toUpper(arr, 0);
    my_toUpper(arr, 5);
    printf("%s", arr);
    return 0;
}

这个功能究竟如何运作?我无法理解它背后的逻辑。如果有人轻易解释它会很好。

2 个答案:

答案 0 :(得分:3)

ASCII table之后,要将字母从小写转换为大写,您需要从小写字母的ASCII值中减去32

对于表示小写字母的ASCII值,减去32,等于ANDing ~32。这就是在

中完成的事情
 *(str + index) &= ~32;

index获取str成员的值,减去32(按位与~32,清除特定位值)并将其存储回相同的索引

FWIW,这是&#34;重置&#34;的一个特例。一个特定的位来得到实际减去32的结果。这个&#34;减法&#34;这里基于小写字母ASCII值的特定位表示。正如评论中所提到的,这不是一种通用的减法方法,因为这将重置&#34;逻辑不会对减法的任何值起作用。

关于使用的operators

  • &=是按位AND
  • 分配的
  • ~是按位NOT。

注意:此自定义函数缺少str中存在的(有效)值的错误检查。你需要照顾它。

答案 1 :(得分:1)

要理解这一点,我们必须查看字母的ASCII表示。在2号基地最容易做到这一点。

A  01000001        a  01100001
B  01000010        b  01100010
C  01000011        c  01100011
D  01000100        d  01100100
   ...                ...
X  01011000        x  01111000
Y  01011001        y  01111001
Z  01011010        z  01111010

请注意,大写字母均以010开头,小写字母均以011开头。请注意,对于相同字母的大写和小写版本,低位位都是相同的。

所以:我们需要做的就是将小写字母转换为相应的大写字母,将011更改为010,换句话说,关闭{{ 1}}位。

现在,关闭一点的标准方法是对要关闭的位的位置为0的掩码进行按位AND,其他地方为1。所以我们想要的面具是00100000。我们可以将其写为11011111,但本例中的程序员选择通过编写0xdf来强调它是00100000的补充掩码。二进制32是~32

这种技术很好,除了它会用非字母做奇怪的事情。例如,它会将00100000变为'{'(因为它们分别具有ASCII代码'['01111011)。它会将星号001011011转换为换行符'*''\n'转换为00101010)。

在ASCII中将大小写转换为小写的另一种方法是减去32.这也会将00001010转换为'a'(97到65,十进制),但是如果还要转换例如,'A''A'。在这种情况下,按位AND技术实际上是有利的,因为它将'!'转换为'A'(这是转换为大写例程应该执行的操作)。

最重要的是,无论你是和~32还是减去32,在正确安全的功能中,你还必须检查被转换的字符是否是正确的字母开头。

此外,值得注意的是,此技术绝对采用7位ASCII字符集,并且不适用于其他字符集的重音或非罗马字母,例如ISO-8859或Unicode。 (EBCDIC将是另一回事。)