函数f1()执行流程解析及*(str + index) &= ~32语句工作原理问询
解析C语言函数f1()的执行过程
先把完整代码贴出来方便对照:
#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; }
整体执行流程先捋一遍
- 主函数里定义了字符数组
arr,存的是字符串"gatecsit",每个字符依次是'g'、'a'、't'、'e'、'c'、's'、'i'、't'。 - 调用
f1(arr, 0)的时候,把数组arr的首地址传给了指针str,index设为0,意思就是要处理数组的第0个元素(也就是第一个字符'g')。 - 最后
printf输出修改后的数组,结果会是Gatecsit。
核心代码拆解:*(str + index) &= ~32
咱们一步一步把这行代码唠明白:
*(str + index)指向啥?str是指向数组首地址的指针,index是0,所以str + 0还是指向数组第一个元素'g'的内存地址。*(str + index)就是取这个地址里存的字符值——也就是'g'的ASCII码103,二进制是01100111。~32到底是个啥?
32的二进制是00100000(因为32是2的5次方,对应从0开始数的第5位是1)。~是C语言里的按位取反运算符,这里我们只看和字符相关的低8位就行:取反之后,~32的低8位就是11011111(除了第5位是0,其他位全是1)。&=按位与赋值的作用
这一步是把*(str + index)的当前值(也就是'g'的ASCII码103)和~32的低8位做按位与操作,然后把结果存回原来的内存地址里。
咱们手动算一遍:
01100111 // 'g'的ASCII码值 & 11011111 // ~32的低8位值 -------- 01000111 // 结果是71,对应ASCII字符'G'
- 为啥这行代码能把小写转大写?
看ASCII表就懂了:所有小写字母的ASCII码值都比对应的大写字母大32。二进制层面,小写字母的第5位(从0开始计数)是1,而大写字母的这一位是0。~32的作用就是把这一位固定为0,其他位保持不变,所以按位与之后,就把小写字母的这一位从1改成0,直接得到对应的大写字母的ASCII码。
举个额外的例子:'a'的ASCII是97(二进制01100001),和~32按位与后得到01000001,也就是65,对应字符'A',完美转成大写。
⚠️ 小提醒:这行代码只对小写字母有效,如果传入的是大写字母、数字或者符号,操作后可能会改变它们的原有值——比如大写字母的第5位本来就是0,按位与后还是原样;但如果是数字'1'(ASCII码49,二进制00110001),按位与后会变成00010001(也就是17,对应不可见字符),这就不符合预期了。
内容的提问来源于stack exchange,提问作者Pawan Kumar
相关产品推荐
相关产品推荐

