编写一些程序(大小无关紧要),然后放置看起来无用的行,但实际上并不是这样-如果将其删除,程序将崩溃或做错事。随意标记注释中未使用的行,或在代码说明中提及它,如下面的示例(当然,在此示例中,实际上不需要该行,仅是示例)。
int main(void) {
/* The line below is actually needed. */
2 + 2;
return 0;
}
由于这是人气竞赛,因此票数最高的解决方案将获胜。
编写一些程序(大小无关紧要),然后放置看起来无用的行,但实际上并不是这样-如果将其删除,程序将崩溃或做错事。随意标记注释中未使用的行,或在代码说明中提及它,如下面的示例(当然,在此示例中,实际上不需要该行,仅是示例)。
int main(void) {
/* The line below is actually needed. */
2 + 2;
return 0;
}
由于这是人气竞赛,因此票数最高的解决方案将获胜。
Answers:
int main(int argc, char **argv) {
switch(argc) {
case 2:
;
int allowed = 0;
case 3:
argc--;
break;
default:
argc = 3;
}
return 0;
}
如果删除单个,则不会编译;
。
编辑:
解决方案如下:
发生这种情况是因为一条
case
语句只是一个标签,因此,必须在其后跟随一条语句(该标准称为“要执行的操作的指定者”,该语句排除了声明)。为避免这种情况,我们在声明的前面加上;
了null语句。对于产品规格case
标签可以发现这里的(在文档131)142页
只是一些以介绍/教程风格编写的代码...
教程nr。2:读取数字,对其进行数学运算,然后打印结果。
//////////////////////////////////////////////////
///////////////////////////////////////////////////
///// //
///// T U T O R I A L //
///// //
///////////////////////////////////////////////////
#include "stdio.h"
int main()
{
///////////////////////////////////////////////
// Local variables (int means integer!!) /
int a, b, result;
///////////////////////////////////////////////
// Reading them in /
scanf("%d", &a);
scanf("%d", &b);
///////////////////////////////////////////////
// Performing an operation, e.g. addition!!! /
result = a+b;
///////////////////////////////////////////////
// Why is the next line absolutely mandatory??/
result = 42;
printf("The result is: %d", result);
}
删除result = 42;
乍看之下似乎多余的行,并且考虑到所说明的目标,实际上是错误的,实际上将导致程序不执行描述中所述的操作。
为什么?
三部曲再次罢工!?? /将被预处理器替换为\,然后将下一行连接到注释中。的结果= 42; 成为注释的一部分,因此“保存”了打印行。与结果= 42; 行被删除,printf行将被注释吞噬。一些编译器可能会发出警告,或可能在默认情况下关闭trigraph,并且必须打开才能使本示例正常工作。语法高亮也可能会背叛它,但是周围有编译器和IDE会让您更明智。
>!
而不是just 开头的方式将blockquote更改为剧透文本>
。
>!
并不是每行都使用。我虽然它们在我写它们时不为我显示。有趣的是,SE解析器不会破坏它:)
"stdio.h"
而不是实际的图书馆包含内容时就偷偷摸摸地走了,<stdio.h>
不幸的是,我无法在此处显示程序,因为StackExchange会剥离所有尾随的空格。pastebin.com和pastie.org也是如此,因此我也无法链接到它。
当然,整个程序看起来“没用”,但是如果删除任何行,它会做一些不同的事情。
for (var a = 0, b = 4; ++a < b; a++)b+-
2 + 2; // This line is needed, or it will alert twice!
alert(a);
它工作的原因是因为主体
for
是b+-
,不是b++
或b--
; 因此,如果删除所需的行,它将添加到b
的值-alert(a)
。
b
价值alert(a)
”:所以,不应该b+-
是b+=
?
b++
还是b--
。
b + -2 + 2
。这就是为什么如果删除带有的行2 + 2;
,其结果为b + -alert(a);
。
#include <stdio.h>
#include <string.h>
int main() {
int i,sum;
char s[4];
/* Add all the integers < 1000 that contain no '0' or '9' */
sum=0;
for (i=0; i<1000; i++) {
sprintf(s,"%d",i);
if (strchr(s,'0')) goto skip;
if (strchr(s,'9')) goto skip;
sum += i;
skip:
i = i; /* Don't delete this line! */
}
printf("The answer is %d\n",sum); /* <<< Should be 258948 */
return 0;
}
如果您删除该行,i = i;
则该代码将无效。这是因为...
...实际上,它甚至不会编译。根据C标准,以上示例中的标签(例如skip)必须与语句关联。即使是单个分号也已足够,但是如果删除整行,则标签将没有关联的语句,并且编译将失败。该答案将更详细地说明。
这是一个APL函数:
i_←{
⍺←⎕IO ⋄ ⎕IO←⍺
⍵⍴⍳×/⍵
}
它的作用与J的monadic相同i.
:
i_ 5 5
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
它可以使用可选的left参数,该参数给出偏移量:
0 i_ 5 5
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
该行⍺←⎕IO ⋄ ⎕IO←⍺
看起来毫无用处(“分配⎕IO
给⍺
,然后分配⍺
给⎕IO
”),但是第一部分仅在未给出left参数的情况下运行,因此实际上它可以执行以下操作:
⍺
给出,则设置⍺
为(global)⎕IO
。⎕IO
为⍺
Func<int, int> fibo;
fibo = null; //Note that this can be set to *any* Func<int, int> reference. It doesn't matter.
fibo = x => x < 1 ? 1 : fibo(x-1) + fibo(x-2);
fibo
即使您正在为lambda分配变量,也必须先分配该变量,然后才能在lambda中使用它fibo
。如果删除(似乎无用)分配,则会发生编译器错误(“使用未分配的局部变量'fibo'”)。
Windows批处理:
echo hello
pause
echo world
设置程序运行并将文件修改为:
rem test01
pause
echo hello world
如果删除注释或调整注释大小,则会在程序的第一个实例暂停并随后从第19个字节开始继续解释时造成严重破坏。
package stackexchange;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class Curl
{
public void getUrl(String address)
{
try {
URL url = new URL(address);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader input = new BufferedReader(new InputStreamReader(conn.getInputStream()));
/* don't remove this line! */
http://codegolf.stackexchange.com
while( true ){
String line = input.readLine();
if( line==null ) break http;
System.out.println(line);
}
input.close();
} catch(IOException ex){
// ignore.
}
}
public static void main(String[] args) {
Curl curl = new Curl();
curl.getUrl("http://codegolf.stackexchange.com");
}
}
它是一个工作程序,可从URL检索网页。您可能会对行感到惊讶
http://codegolf.stackexchange.com
甚至没有警告就编译。实际上,没有该程序就无法编译。
它实际上是一个标签,
http:
后跟一个注释//codegolf...
。标签适用于while并在break http;
语句中使用。
require 'prime'
# Given a regular expression, return the smallest prime containing it
# and the substring of the prime that matches it
def smallest_prime_matching_regexp(regexp)
match = 'this assignment is necessary even though the value is never used'
prime = Prime.find { |n| match = n.to_s[regexp] }
return prime, match
end
[ /4/, /1+2/, /[02468]{2,}/ ].each do |regexp|
prime, match = smallest_prime_matching_regexp(regexp)
puts "#{regexp.inspect}:\t#{prime} (#{match})"
end
最近在工作中发生了类似的事情-一位同事实际上在代码审查期间标记了我看似不必要的初始化,并且我真的很想将解释放在扰流块中。所以我在这里做。
该行是必需的,因为在块内初始化的变量是该块的局部变量。如果我们在块外对其进行初始化,则该值可以转义到方法范围。
输出为:
/4/: 41 (4)
/1+2/: 127 (12)
/[02468]{2,}/: 223 (22)
删除方法第一行的输出:
main:Object(NameError)的未定义局部变量或方法“ match”
match = Prime.find { |n| n.to_s[regexp] }
Prime.find
返回n
(例如223),并且match
需要返回n.to_s[regexp]
(例如“ 22”)。显然,我设计该问题是必要的。
find
的Prime
,而不是一个数组。无论如何,仍然很容易注意到为什么需要该行...
COBOL(IBM大型机)
ID DIVISION.
PROGRAM-ID. USELESS.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 W-WHEN-COMPILED PIC X(8)BX(8) VALUE SPACE.
PROCEDURE DIVISION.
IF W-WHEN-COMPILED EQUAL TO SPACE
NEXT SENTENCE
END-IF
MOVE SPACE TO W-WHEN-COMPILED.
MOVE WHEN-COMPILED TO W-WHEN-COMPILED
DISPLAY W-WHEN-COMPILED " HELLO WORLD!"
GOBACK
.
如果运行上述程序(COBOL II之后的任何IBM Mainframe COBOL(1985年标准的第一个IBM编译器,也可能是其他IBM COBOL),则输出为:
2014年2月22日13.11.02您好,世界!
但是,如果您删除了三行没用的行“将空间移至W-WHEN-COMPILED”。(该字段的初始值为空格,并且在下一条指令中放入了其他内容,并且仍然分支了该字段),该程序不产生任何输出,并且实际上出现Abends(U4038)(这意味着它崩溃),并显示以下消息:
IGZ0037S The flow of control in program USELESS proceeded beyond the
last line of the program. From compile unit USELESS at entry
point USELESS at compile unit offset +000003AC at entry offset
+000003AC at address 119003AC.
(消息代码和文本在编译器之间会有所不同,偏移量取决于实际使用的编译器和编译选项,地址取决于在执行时加载程序的位置)。
原因是NEXT SENTENCE
。这是一个Secret GO TO
。编译器在源代码中搜寻下一个句号/句点,并生成一条跳转到以下指令的分支。从COBOL II开始,轻松使用句号/句号。程序必须以句号/句号结尾。在这种情况下,分支不在程序末尾。
这两个程序均编译为100%干净(无诊断消息,返回码为零)。
此行为是对COBOL的愚蠢的“ IBM扩展”。1985年标准不允许NEXT SENTENCE
在IF
/ END-IF
(CONTINUE
内使用,而是禁止操作)内。IBM允许这样做-有时会造成可怕的混乱。
#include <stdio.h>
#include <stdlib.h>
void strcmp_or_die(char *s, char *t) {
if(!strcmp(s, t)) {
printf("Success!\n");
} else {
int *ptr = NULL;
*ptr = 0;
}
}
int main(void) {
char blah = '\0'; //segfaults without this line
char v[2] = "ok";
strcmp_or_die(v, "ok");
}
简单的字符串溢出问题。
blah
?在这里,使用OpenBSD 5.5 / amd64和系统gcc,无论是否blah
存在,它都不会发生段错误。编译后的程序分配16个字节的堆栈空间,并将16位值“ ok”复制到前2个字节中。幸运的是,未初始化的第3个字节的值为'\ 0'。如果blah
存在,则在第16个字节中,并且仍不终止字符串。
这可能是最愚蠢,最明显的一个。
'=|hello\|:
'=~!|Useless?\|:
@'[|y|]|n|:
如果没有第二行,它会抛出一个错误,并打印出来y
。
反斜杠不是转义字符,呵呵。
~-~!
这是一个批处理文件,在每个文件之后打印数字1至10,并用空行显示:
@echo off
setlocal EnableDelayedExpansion
set NL=^
rem Previous two lines deliberately left blank for NL to work.
for /l %%a in (1,1,10) do (
echo %%a!NL!
)
endlocal
pause
这有效地利用了肮脏的hack来在变量中存储换行符(使用延迟扩展摆脱了链接的答案中看上去更恐怖的NL行)。如果您删除或以其他方式更改了注释上方的两个看起来完全无用的空白行,那么它将无法正常工作。
Troff是最出色的文本处理系统。我将其用于文档。它需要一个宏系统才能使用,最著名的是ms
宏程序包。让我们用classic -ms
选项编译以下代码。
.\" -ms macro package
.\" the following line seems to be useless
\& \" print an invisible character
.ad c
.sp |300p \" absolute vertical positionning
.ps 36p
.ft B
My title.
.PP
This is a paragraph.
第三行似乎无用,并且如果没有宏包,实际上将无用。由于它在下面两行之后是绝对垂直位置,因此之前什么也不打印似乎毫无意义。但是如果没有这个看不见的字符,垂直定位将不会起作用,尽管我不确定我可以解释为什么(如果您想看一下讨论,请参阅此主题)。这使新用户发疯,但是对于更多尝试过的用户,此技巧应该变得熟悉。
刚刚用我最喜欢的troff版本(传家宝troff)进行了检查,但是我很确定它仍然可以与GNU troff一起使用。