这个函数 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