我遇到了一个有趣的C代码打印A + B,但我无法理解它.
A B
Run Code Online (Sandbox Code Playgroud)
其中A,B是一个整数之间0,10由一个空格分隔.
main( n )
{
gets( &n );
printf("%d", n % 85 - 43);
}
Run Code Online (Sandbox Code Playgroud)
这是用于短编码,请不要介意警告.
gets( &n )将A,空格和B的ASCII值存储在较低的三个字节中n.例如,A = 3并且B = 8会屈服n = 0x00382033.鉴于条件防止n溢出.但我不明白n % 85 - 43收益率如何A + B.
你怎么想出这些数字?
use*_*ica 87
使用little-endian int(并假设ASCII文本和8位字节,以及代码所需的所有其他假设),并忽略代码中所有技术上错误的现代C内容,"我理解的内容到目前为止"是正确的.
gets(&n)将A,空格和B的ASCII值存储到前3个字节中n.它还会在第4个字节中存储一个空终止符.存储这些ASCII值成那些字节n结果n取值B*256*256 + space*256 + A,其中B,space和A表示对应的ASCII值.
256 mod 85是1,所以通过模运算的属性,
(B*256*256 + space*256 + A) % 85 = (B + space + A) % 85
Run Code Online (Sandbox Code Playgroud)
顺便说一下,我们得到了4字节的大端整数
(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85
Run Code Online (Sandbox Code Playgroud)
因此,只要我们有4字节的整数,字节顺序无关紧要.(更大或更小整数可能是一个问题;例如,具有8个字节的整数,我们就不用担心什么在的字节数n是gets没有设置.)
空格为ASCII 32,数字字符的ASCII值为48 +数字的值.定义a和b输入数字的数值(而不是数字字符的ASCII值),我们有
(B + space + A) % 85 = (b + 48 + 32 + a + 48) % 85
= (a + b + 128) % 85
= (a + b + 43) % 85
(B + space + A) % 85 - 43 = (a + b + 43) % 85 - 43
= (a + b) % 85
= a + b
Run Code Online (Sandbox Code Playgroud)
其中最后两个等价依赖于这一事实,a并b取值从0到9.