C和指针 1.8课后习题3

该博客介绍了一个C语言程序,从标准输入读取字符并写入标准输出,同时计算校验和。校验和用signed char类型变量计算,初始为 -1,字符值依次累加,溢出忽略。最后以十进制整数形式打印校验和,还给出了“Hello world!”的校验和计算过程,结果为102。

编写一个程序,从标准输入读取一些字符,并把他们写到标准输出上,它同时应该计算checksum值,并写在字符的后面。
checksum(检验和)用一个sunged char 类型的变量进行计算,它初始为-1.当每个字符从标准输入读取时,它的值就被加到checksum中。如果checksum变量产出了溢出,那么这些溢出就会被忽略。当所有的字符均被写入后,程序以十进制整数的形式打印出checksum的值,它有可能是负值。注意在checksum后面要添加一个换行符。在使用ASSII码的计算机中,在包含“Hello world!”这几个词并以换行符结尾的文件上运行这个程序,应该产生以下列输出:
Hello world!
102

#include<stdio.h>
int main(){

signed char checksum = -1;
signed char c;
  
while( ( c = getchar() ) != '\n' )
{
    checksum += c;
    printf("checksum: %d c: %d\n", checksum, c);
  }

  checksum += c;
  printf("\n%d\n", checksum);
  return 0;

}

输入输出结果截图
解释:
计算机用的是补码运算的,而通过printf显示给我们看的是原码,通过补码运算得到。

第一位是符号位,

正数 = 原码 = 反码 = 补码
负数 = 原码 = [符号位][真值]
负数反码 = [符号位][真值取反]
负数补码 = [符号位][真值取反 + 1]

以下所有加减均用补码

DEC是十进制的意思

-1:1000 0001 反码:1111 1110 补码:1111 1111
H: 0100 1000
checksum = H + (-1)= 0100 1000 + 1111 1111 = 0100 0111

e: 0110 0101
checksum = e + checksum = 0110 0101 + 0100 0111 = 1010 1100
此时checksum为补码,获得真值就要补码-1,除符号位外其它位取反
1010 1100 - 1 = 1010 1011
1010 1011取反 = 1101 0100 = - 2^6 + 2^4 + 2^2 = -84

l: 0110 1100
checksum = l + checksum = 0110 1100 + 1010 1100 = 0001 1000
checksum = 0001 1000 = 2^4 + 2^3 = 24

l: 0110 1100
checksum = l + checksum = 0110 1100 + 0001 1000 = 1000 0100
1000 0100 - 1 = 1000 0011
1000 0011取反 = 1111 1100 = -2^6 + 2^5 + 2^4 + 2^3 + 2^2 = -124

o: 0110 1111
checksum = o + checksum = 0110 1111 + 1000 0100 = 1111 0011
1111 0011 - 1 = 1111 0010
1111 0010取反 = 1000 1101 = -2^3 + 2^2 + 2^0 = -13

空格:0010 0000
checksum = 空格 + checksum = 0010 0000 + 1111 0011 = 0001 0011
checksum = 0001 0011 = 2^4 + 2^1 + 2^0 = 19

w: 0111 0111
checksum = w + checksum = 0111 0111 + 0001 0011 = 1000 1010
1000 1010 - 1 = 1000 1001
1000 1001取反 = 1111 0110 = -2^6 + 2^5 + 2^4 + 2^2 + 2^1 = -118

o:0110 1111
checksum = o + checksum = 0110 1111 + 1000 1010 = 1111 1001
1111 1001 - 1 = 1111 1000
1111 1000取反 = 1000 0111 = -2^2 + 2^1 + 2^0 = -7

r:0111 0010
checksum = r + checksum = 0111 0010 + 1111 1001 = 0110 1011
0110 1011 = 2^6 + 2^5 + 2^3 + 2^1 + 2^0 = 107

l:0110 1100
checksum = l + checksum = 0110 1100 + 0110 1011 = 1101 0111
1101 0111 - 1 = 1101 0110
1101 0110取反:1010 1001 = -2^5 +2^3 + 2^0 = -41

d:0110 0100
checksum = d + checksum = 0110 0100 + 1101 0111 = 0011 1011
checksum = 0011 1011 = 2^5 + 2^4 + 2^3 + 2^1 + 2^0 = 59

!:0010 0001
checksum = ! + checksum = 0010 0001 + 0011 1011 = 0101 1100
checksum = 0101 1100 = 2^6 + 2^4 + 2^3 + 2^2 = 92

'\n’回车:0000 1010
checksum = ‘\n’ + checksum = 0000 1010 + 0101 1100 = 0110 0110
checksum = 0110 0110 = 2^6 + 2^5 + 2^2 + 2^1 = 102

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值