我遇到了一个打印A + B
的有趣C代码,但是我很难理解它。
A B
其中A
,B
是0
和10
之间的整数,用一个空格隔开。
main( n )
{
gets( &n );
printf("%d", n % 85 - 43);
}
这是为简短编码而设计的,请不要在意警告。
gets( &n )
将A,空格和B的ASCII值存储在n
的低三位字节中。例如,A = 3
和B = 8
将产生n = 0x00382033
。给定条件可以防止n
溢出。但是我不明白n % 85 - 43
如何产生A + B
。
您如何得出这些数字?
答案 0 :(得分:87)
使用little-endian整数(并假设使用ASCII文本和8位字节,以及代码要求的所有其他假设),并忽略代码中所有技术上错误的现代C内容,到目前为止,我的理解是正确的。
gets(&n)
会将A,空格和B的ASCII值存储到n
的前3个字节中。还将在第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
偶然地,我们使用4字节的big-endian int,我们得到了
(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85
因此字节序无关紧要,只要我们有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
最后两个等价项取决于a
和b
取值为0到9的事实。