以下问题是在一次大学编程竞赛中提出的。我们被要求猜测输出和/或解释其工作原理。不用说,我们都没有成功。
main(_){write(read(0,&_,1)&&main());}
一些简短的谷歌搜索引导我找到了这个问题,在codegolf中被问到。stackexchange。com:
https://codegolf.stackexchange.com/a/1336/4085
在那里,它解释了它的作用:反转标准输入法并放置在标准输出上,但没有解释如何。
我在这个问题上也找到了一些帮助:main的三个参数和其他模糊技巧,但它仍然没有解释如何
main(_)
,
我的问题是,这些语法是如何工作的?它们是我应该知道的吗,比如,它们仍然相关吗?
如果没有明确的答案,我将非常感谢您提供任何(指向资源链接等)的提示。
好的,\uu只是在早期K中声明的一个变量
程序将尝试从标准输入中读取一个字节。如果有输入,它将递归调用main继续读取一个字节。
在输入结束时,
read(2)
将返回0,表达式将返回0,将执行write(2)
系统调用,调用链可能会展开。
我在这里说“可能”,因为从这一点上看,结果高度依赖于实现。写入(2)
的其他参数缺失,但寄存器和堆栈中会有一些内容,因此会将一些内容传递到内核。相同的未定义行为适用于各种递归激活main的返回值。
在我的x86_64 Mac上,程序读取标准输入,直到EOF,然后退出,什么也不写。
这个程序做什么?
main(_){write(read(0,&_,1)&&main());}
在我们分析它之前,让我们先把它修饰一下:
main(_) {
write ( read(0, &_, 1) && main() );
}
首先,您应该知道_
是一个有效的变量名,尽管它很难看。让我们改变它:
main(argc) {
write( read(0, &argc, 1) && main() );
}
接下来,认识到函数的返回类型和参数的类型在C中是可选的(但在C中不是):
int main(int argc) {
write( read(0, &argc, 1) && main() );
}
接下来,了解返回值是如何工作的。对于某些CPU类型,返回值总是存储在相同的寄存器中(例如x86上的EAX)。因此,如果省略返回
语句,返回值很可能是最近返回的函数。
int main(int argc) {
int result = write( read(0, &argc, 1) && main() );
return result;
}
对读取的调用或多或少是明显的:它从标准in(文件描述符0)读取到位于
<代码>
在这种情况下,右侧调用不带参数的
main
。在使用1个参数声明后不带参数调用main
是未定义的行为。尽管如此,它通常有效,只要您不关心argc
参数的初始值。
<代码>
int main(int argc) {
int read_result = read(0, &argc, 1) && main();
int result = write(read_result);
return result;
}
嗯。快速查看手册页可以发现,write需要三个参数,而不是一个。另一种未定义的行为。就像用太少的参数调用main一样,我们无法预测write的第二个和第三个参数将收到什么。在典型的计算机上,他们会得到一些东西,但我们不能确定是什么。(在非典型计算机上,可能会发生奇怪的事情。)作者依赖于接收以前存储在内存堆栈上的内容。而且,他依赖于这是阅读的第二和第三个论点。
int main(int argc) {
int read_result = read(0, &argc, 1) && main();
int result = write(read_result, &argc, 1);
return result;
}
修复对
main
的无效调用,并添加标头,展开
#include <unistd.h>
int main(int argc, int argv) {
int result;
result = read(0, &argc, 1);
if(result) result = main(argc, argv);
result = write(result, &argc, 1);
return result;
}
这个程序在许多计算机上都无法正常工作。即使您使用与原作者相同的计算机,它也可能无法在不同的操作系统上工作。即使使用同一台计算机和同一个操作系统,它也无法在许多编译器上工作。即使使用相同的计算机编译器和操作系统,如果更改编译器的命令行标志,也可能无法工作。
正如我在评论中所说,这个问题没有有效的答案。如果你发现一个竞赛组织者或竞赛评委有不同的说法,不要邀请他们参加你的下一次竞赛。
里面很多都是像 laterain 学习到的,如果能考上 cuit 的话,自动献菊花了。
主要内容:1 概述,2 JUnit 4常用的注解,3 结论1 概述 在本文中,我们将讨论常用的注释,当您在类路径中包含junit4.jar时可用。 常用的注解是: 让我们用示例讨论每个注解。 2 JUnit 4常用的注解 2.1 @Before和@After 在Junit4中,没有setup() 或tearDown() 方法,相反,我们具有@Before和@After批注。通过使用@Before,可以将任何方法设置为setup(),通过使用@Afte
本文向大家介绍C++常见异常处理原理及代码示例解析,包括了C++常见异常处理原理及代码示例解析的使用技巧和注意事项,需要的朋友参考一下 编程中常见的错误 程序的编译错误——比较好解决,主要是一些语法错误 程序的运行错误——产生因素较为复杂,如空间不够,下标越界,访问非法空间等。 异常是指程序运行时出现的不正常,可分为一下几类: CPU异常;如在计算过程中,出现除数为0的情况。 内存异常,如: 使用
问1:INSERT/UPDATE/DELETE被解析为Query或DDL语句? 答1: 出现这类情况主要原因为收到的binlog就为Query事件,比如: binlog格式为非row模式,通过show variables like 'binlog_format'可以查看. 针对statement/mixed模式,DML语句都会是以SQL语句存在 mysql5.6+之后,在binlog为row模式下
本页面罗列了大家使用 YApi 时遇到的常见问题. 如果没有找到您要的答案,请联系管理员. Q1 怎样联系组长? 组长分为 分组组长 和 项目组长: 分组组长:选择首页左侧的分组,点击右侧面板的 成员列表,成员右侧显示着 组长/开发者 的权限信息。 项目组长: 点击项目页的 设置 - 成员列表,成员右侧显示着 组长/开发者 的权限信息。 Q2 怎么快速迁移旧项目? 第一步. 使用 Chrome 浏
译者:冯宝宝 我的模型报告“cuda runtime error(2): out of memory” 正如错误消息所示,您的GPU显存已耗尽。由于经常在PyTorch中处理大量数据,因此小错误会迅速导致程序耗尽所有GPU资源; 幸运的是,这些情况下的修复通常很简单。这里有一些常见点需要检查: 不要在训练循环中积累历史记录。 默认情况下,涉及需要梯度计算的变量将保留历史记录。这意味着您应该避免在计