int main()
{
int a,b;
while(~scanf("%d%d", &a, &b))printf("%d\n",a+b);
return 0;
}
这个代码段是一个简单的C语言程序,用于不断读取两个整数,并输出它们的和,直到输入结束
这个特殊点就是“不断读取”
这块代码使用 scanf
函数读取用户输入的两个整数,并将它们存储在变量 a
和 b
中。~
运算符用于对 scanf
返回值进行按位取反
scanf
函数的返回值(这也是函数的知识,你并没有系统的学习过)是成功读取的项数(重要!!!)。例如,在这种情况下,如果成功读取到两个整数,返回值为2
(布尔值为真),在这种情况下~2
的结果是-3
,所以循环继续- 如果读取失败(例如遇到文件结束符或输入不符合格式),
scanf
会返回EOF
,此时~EOF
的结果是一个非负数,循环会结束
这里再分析~2的结果为什么是-3
- 确定2的二进制表示:
- 在8位二进制中,2的表示为:
0000 0010
(了解太深反而弄不清了,所以记住二进制补码成8位就行了)
- 在8位二进制中,2的表示为:
- 进行按位取反:
- 将每一位取反:
- 0变为1,1变为0。
- 所以,
0000 0010
取反后为:1111 1101
- 将每一位取反:
1111 1101
是一个负数,因为最高位(符号位)为1
最高位(符号位)有两个用处,第一个是它也有用,第二个是它能帮助我们判断正数还是负数
要计算这个补码的值
//我在这里解释,你对~2确实进行了取反,也得到了取反后的二进制,但是C语言中默认的的十进制数
所以,你还得计算这个去反后二进制的值
可以按以下步骤进行:
- 按位取反:
0000 0010
(妈的,又回来了,所以你懂省略就好) - 加1:
0000 0010 + 0000 0001 = 0000 0011
(逢2进1) - 这个结果是3,因此
1111 1101
表示 (-3)
在其他位数的补码表示中(就算不是8位补码),结果仍然是 (-3),只是具体的二进制表示(补多少个0)可能会有所不同(前面加0没多大用啊,前面写过)
所以你又知道了,在补码表示法中,负数的处理是通过取反和加1的方式来实现
你是因为最高位是1知道它是负数才进行取反加1的
正是由于~scanf的返回值是-3,是负数,因此会持续循环
顺便补充下上周对%d这些格式占位符的知识点
老师讲的是,%d%d这种写法是正确的,程序会给出三种不同的格式从第一个占位转到第二个占位
第一个是空格(如果你自己在两个%d的中间加了空格,那就只有空格这一种)
第二个是tab键,第三个就是换行enter
但是最美观的还是空格
while(~scanf("%d%d", &a, &b))printf("%d\n",a+b);
详细看看这个代码,while(~scanf("%d%d", &a, &b)) 外面的括号是while循环的条件
因此,当 scanf
成功读取两个整数时,while(~scanf(...))
的条件会为假(非零值被视为 "真",零值被视为 "假"),循环将结束(因为你只输入两个%d,所以scanf返回布尔值是2,去反后是-3 !=0)
要将"China"译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母.
例如,字母"A"后面第4个字母是"E"."E"代替"A"。因此,"China"应译为"Glmre"。
请编一程序(这是告诉你编写程序的要求),用赋初值的方法使cl、c2、c3、c4、c5五个变量的值分别为,’C’、’h’、’i’、’n’、’a’,经过运算,使c1、c2、c3、c4、c5分别变为’G’、’l’、’m’、’r’、’e’,并输出
int main() {
// 初始化字符变量
char c1 = 'C';
char c2 = 'h';
char c3 = 'i';
char c4 = 'n';
char c5 = 'a';
// 创建新的字符变量来存储转换后的字符
char c1_new, c2_new, c3_new, c4_new, c5_new;
// 进行转换:每个字符加 4
c1_new = c1 + 4;
c2_new = c2 + 4;
c3_new = c3 + 4;
c4_new = c4 + 4;
c5_new = c5 + 4;
// 输出转换后的结果
printf("%c%c%c%c%c", c1_new, c2_new, c3_new, c4_new, c5_new);
return 0;
}
这应该是最简单的方法了
因为ASCII值的字母就是按照26字母歌顺序排的,而且大写也是对应大写,小写也是对应小写
Comments NOTHING