“作弊” ;-) 但很短的解决方案是
#include <cstdio>
int main() {
puts("I\nIN\nIND\nINDI\nINDIA\nINDIA\nINDI\nIND\nIN\nI\n");
}
基于TonyK的绝妙想法的另一个解决方案(适用于 C 和 C++):
#include <stdio.h>
int main() {
for (int i = 1; i < 11; ++i)
printf("%.*s\n", i < 6 ? i : 11 - i, "INDIA") ;
}
更新:(在 TonyK 发表评论后):
如果你想要空格,然后printf用这个替换上面的
printf("%.*s\n", 2*(i < 6 ? i : 11 - i), "I N D I A ");
更新:没有循环的解决方案:
#include <stdio.h>
int main(int i, char**) {
return printf("%.*s\n", i < 6 ? i : 11 - i, "INDIA") - 1 && main(i + 1, 0);
}
以下为初学者的利益的详细解释。
最重要的一点是,这是一个“学术”练习。代码晦涩难懂,应该避免编写这样的严肃代码。
该标准没有为 function 修复特定的签名main。它只是说它必须返回一个int并且编译器必须接受两种特定的形式:
int main();
int main(int argc, char** argv);
我正在使用第二个。更流行的形式int main(int argc, char* argv[])等价于(2)。实际上,通常,用作函数参数的 T 数组被隐式转换为指向 T的指针。在这个例子中,是一个指向 charchar* argv[]的指针数组,它变成了指向 char的指针。上面的程序虽然没有使用第二个参数(它要么被忽略,要么被赋予 NULL,即 0 值)。
程序不是循环,而是main递归调用。实际上,这是非法的,但主要编译器对此视而不见(如果您要求它使用选项 -Wpedantic 迂腐,最多 GCC 会发出警告)。当从没有参数的命令行调用程序时,操作系统调用main传递1(即1+ 参数的数量)和指向 char 的指针的指针,如前所述,该程序将忽略该指针。因此,i = 1在第一次通话时。
随后,每次都main可能称自己为递增。i总而言之,main依次调用ibeing 1, 2, 3, 4, ...
很容易看出,对于 的这个值序列i,表达式的计算i < 6 ? i : 11 - i结果为1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, ...保存一行;-) 这些数字是每次应显示的“印度”字符数5.5 - abs(5.5 - i)。#include <cmath>
调用printf("%.s\n", j, "INDIA"),其中j = i < 6 ? i : 11 - i,显示j“印度”的第一个字符,后跟一个新行,并返回有效打印的字符数(包括新行),即j + 1。带走1收益j。
a && b我们现在回忆一下, 对于整数a和的语义的一个重要点b。如果a == 0,b 则不计算。否则,b被评估。对我们来说,a = printf("%.*s\n", j, "INDIA") - 1(即a = j)和b = main(i + 1, 0)。
现在,让我们把这些部分放在一起。
1.最初,i = 1和j = 1。调用printf输出 "I\n" 并返回2. 带走1,给a = 1 != 0。因此,b = main(2, 0)被评估(main(2, 0)即被调用)。
2.好吧,对于第二次调用main,我们有i = 2,j = 2,printf显示“IN\n”,a = 2 != 0并被b = main(3, 0)评估。
重复这个论点,每次调用main我们都有:
3. i = 3 , j = 3, "IND\n" 被打印,a = 3 != 0并被main(4, 0)调用。
4. i = 4 , j = 4, "INDI\n" 被打印,a = 4 != 0并被main(5, 0)调用。
5. i = 5 , j = 5, "INDIA\n" 被打印,a = 5 != 0并被main(6, 0)调用。
6. i = 6 , j = 5, "INDIA\n" 被打印,a = 5 != 0并被main(7, 0)调用。
7. i = 7 , j = 4, "INDI\n" 被打印,a = 4 != 0并被main(8, 0)调用。
...
10. i = 10 , j = 1, "I\n" 被打印,a = 1 != 0并被main(11, 0)调用。
11. i = 11 , j = 0, "\n" 被打印出来, a = 0. 现在main(12, 0)不执行,main返回
请注意,main在第 1 步中调用第 2 步,main在第 2main步中调用3,...main在第 11 步中调用。因此,main在第 11 步中返回到main第 10 步,main在第 9 步中返回,...,在第 9 步中main返回步骤1。最后,main在步骤1中返回操作系统。
如果您对更加模糊的代码感兴趣,请查看IOCCC的现在和过去的获奖者。享受!