这个函数 f1() 将如何执行?
How this function f1() will execute?
#include <stdio.h>
void f1(char* str, int index)
{
*(str + index) &= ~32;
}
int main()
{
char arr[] = "gatecsit";
f1(arr, 0);
printf("%s", arr);
return 0;
}
函数 f1() 是如何工作的?
具体 *(str + index) &= ~32; 这个....
谢谢
我认为 f1() 通过利用 ASCII 的 属性 将字符串的第一个字母大写,这意味着相应的小写字母和大写字母相差 32。例如 [=12= 的代码] 是 65,而 'a' 是 97。代码的 '&= ~32' 位将转为字符 str[index] 的 ASCII 表示的第 5 位,它应该转为 'g' 变成 'G'。这对于只包含普通字母的字符串应该没问题,但对数字和标点字符会有奇怪的影响。
表达式
*(str + index)
等同于
str[index]
所以位置index
的字符被改变成下面的方式
*(str + index) &= ~32;
在 ASCII table 中,小写字母与大写字母的区别在于多了一位。例如,小写字母 'a'
的十六进制代码为 61
,而大写字母 'A"
的十六进制代码为 41
。因此,差值等于十六进制值 20
,十进制值等于 32
。
所以原表达式将字符中的相应位重置为0,将小写字母转换为大写字母。
代码从字符中删除 1 位
从字节或 0x20 中有效地减去 32。
#include <stdio.h>
#include <string.h>
void f1(char* str, int index)
{
// The code removes 1 bit from the character at the position `str[index]`
// effectively subtracting 32 from that character
// Capital letters in ASCII are apart by 32 (0x20) from small letters
// Since 'a' = 0x61 and 'A' = 0x41 'a' - 32 = 'A'
// Since 'b' = 0x62 and 'B' = 0x42 'b' - 32 = 'B'
// `~` is a binary negation operator 0 -> 1; 1 -> 0
// `&` is a binary AND
// x &= y; is equivalent to x = x & y;
// ~0x20 = 0b11011111
*(str + index) &= ~0x20; // 0x20 = 32;
}
int main()
{
int i;
char arr[] = "gatecsit";
size_t len = strlen(arr);
for(i = 0; i< len; i++)
printf(" %c " , arr[i]);
printf("\n");
for(i = 0; i< len; i++)
printf(" %X" , arr[i]);
printf("\n");
// convert all letters:
for(i = 0; i< len; i++)
f1(arr, i);
printf("\n");
for(i = 0; i< len; i++)
printf(" %c " , arr[i]);
printf("\n");
for(i = 0; i< len; i++)
printf(" %X" , arr[i]);
return 0;
}
输出:
小写字母和大写字母是相隔 0x20(或小数点后 32)的字母。
从这个打印输出中可以清楚地看出这一点:
g a t e c s i t
67 61 74 65 63 73 69 74
G A T E C S I T
47 41 54 45 43 53 49 54
#include <stdio.h>
void f1(char* str, int index)
{
*(str + index) &= ~32;
}
int main()
{
char arr[] = "gatecsit";
f1(arr, 0);
printf("%s", arr);
return 0;
}
函数 f1() 是如何工作的?
具体 *(str + index) &= ~32; 这个....
谢谢
我认为 f1() 通过利用 ASCII 的 属性 将字符串的第一个字母大写,这意味着相应的小写字母和大写字母相差 32。例如 [=12= 的代码] 是 65,而 'a' 是 97。代码的 '&= ~32' 位将转为字符 str[index] 的 ASCII 表示的第 5 位,它应该转为 'g' 变成 'G'。这对于只包含普通字母的字符串应该没问题,但对数字和标点字符会有奇怪的影响。
表达式
*(str + index)
等同于
str[index]
所以位置index
的字符被改变成下面的方式
*(str + index) &= ~32;
在 ASCII table 中,小写字母与大写字母的区别在于多了一位。例如,小写字母 'a'
的十六进制代码为 61
,而大写字母 'A"
的十六进制代码为 41
。因此,差值等于十六进制值 20
,十进制值等于 32
。
所以原表达式将字符中的相应位重置为0,将小写字母转换为大写字母。
代码从字符中删除 1 位 从字节或 0x20 中有效地减去 32。
#include <stdio.h>
#include <string.h>
void f1(char* str, int index)
{
// The code removes 1 bit from the character at the position `str[index]`
// effectively subtracting 32 from that character
// Capital letters in ASCII are apart by 32 (0x20) from small letters
// Since 'a' = 0x61 and 'A' = 0x41 'a' - 32 = 'A'
// Since 'b' = 0x62 and 'B' = 0x42 'b' - 32 = 'B'
// `~` is a binary negation operator 0 -> 1; 1 -> 0
// `&` is a binary AND
// x &= y; is equivalent to x = x & y;
// ~0x20 = 0b11011111
*(str + index) &= ~0x20; // 0x20 = 32;
}
int main()
{
int i;
char arr[] = "gatecsit";
size_t len = strlen(arr);
for(i = 0; i< len; i++)
printf(" %c " , arr[i]);
printf("\n");
for(i = 0; i< len; i++)
printf(" %X" , arr[i]);
printf("\n");
// convert all letters:
for(i = 0; i< len; i++)
f1(arr, i);
printf("\n");
for(i = 0; i< len; i++)
printf(" %c " , arr[i]);
printf("\n");
for(i = 0; i< len; i++)
printf(" %X" , arr[i]);
return 0;
}
输出: 小写字母和大写字母是相隔 0x20(或小数点后 32)的字母。 从这个打印输出中可以清楚地看出这一点:
g a t e c s i t
67 61 74 65 63 73 69 74
G A T E C S I T
47 41 54 45 43 53 49 54