我遇到了一个有趣的C代码,可以打印A + B个字符,但我很难理解它.

输入格式:

A B

其中,A,B是由单个空格分隔的010之间的整数.

代码:

main( n )
{
    gets( &n );
    printf("%d", n % 85 - 43);
}

这是为了简短的编码,请不要介意警告.

到目前为止,我的理解是:

gets( &n )将A、SPACE和B的ASCII值存储在n的低三个字节中.例如,A = 3B = 8将得到n = 0x00382033.给定的条件可以防止n溢出.但我不明白n % 85 - 43怎么会产生A + B.

你是怎么得出这些数字的?

推荐答案

使用小端整数(假设ASCII文本和8位字节,以及代码所需的所有其他假设),并忽略代码中所有在技术上错误的现代C内容,您的"我到目前为止所理解的"是正确的.

gets(&n)会将A、SPACE和B的ASCII值存储到n的前3个字节中.它还会在第4个字节中存储一个空终止符.将这些ASCII值存储到n的字节中会导致n取值B*256*256 + space*256 + A,其中BspaceA表示相应的ASCII值.

256 mod 85是1,所以根据模运算的性质,

(B*256*256 + space*256 + A) % 85 = (B + space + A) % 85

顺便说一句,使用4字节的大端整数,我们得到

(A*256*256*256 + space*256*256 + B*256) % 85 = (B + space + A) % 85

所以只要我们有4字节的整数,endianness就不重要了.(更大或更小的整数可能是个问题;例如,对于8字节整数,我们必须担心gets没有设置的n字节中有什么.)

空格是ASCII 32,数字字符的ASCII值是48+数字的值.将ab定义为输入数字的数值(而不是数字字符的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

其中最后两个类似功能依赖于ab取值从0到9的事实.

C++相关问答推荐

C:gcc返回多个错误定义,但msvc—不""'

C指针算法在函数参数中的应用

如何创建由符号组成的垂直结果图形?

从组播组地址了解收到的数据包长度

ESP32在vTaskDelay上崩溃

C lang:当我try 将3个或更多元素写入数组时,出现总线错误

使用错误的命令执行程序

关于scanf()和空格的问题

将变量或参数打包到 struct /联合中是否会带来意想不到的性能损失?

不使用任何预定义的C函数进行逐位运算

如何读取程序中嵌入的数据S自己的ELF?

Valgrind用net_pton()抱怨

在下面的C程序中,.Ap0是如何解释的?

C中2个数字的加法 - 简单的人类方法

Ubuntu编译:C中的文件格式无法识别错误

为什么程序在打印每个数字之前要等待所有输入?

如何向 execl 创建的后台程序提供输入?

创建 makefile 来编译位于不同目录中的多个源文件

C 中 struct 体自赋值是否安全?特别是如果一侧是指向 struct 的指针?

C23 中的 [[reproducible]] 和 [[unsequenced]] 属性是什么?什么时候应该使用它们?