Viết một dòng trong chương trình có vẻ vô dụng [đã đóng]


26

Viết một số chương trình (kích thước không thành vấn đề) và đặt một dòng trông có vẻ vô dụng, nhưng thực tế không phải vậy - nếu nó bị xóa, chương trình sẽ bị sập hoặc làm sai điều gì đó. Vui lòng đánh dấu dòng có vẻ không được sử dụng bởi một nhận xét hoặc đề cập đến nó mô tả mã của bạn, như trong ví dụ dưới đây (tất nhiên, trong ví dụ này, dòng thực sự không cần thiết, đó chỉ là một ví dụ).

int main(void) {
    /* The line below is actually needed. */
    2 + 2;

    return 0;
}

Vì đây là cuộc thi phổ biến, giải pháp có số phiếu bầu cao nhất sẽ chiến thắng.


2
Tại sao dòng trong ví dụ cần thiết?
Gari BN

3
@GariBN Không phải: "trong ví dụ này, dòng thực sự không cần thiết, nó chỉ là một ví dụ."
elixenide

9
@EdCottrell Rất tốt để biết ... Tôi nghĩ rằng tôi đã bỏ lỡ một số điều cơ bản ...
Gari BN

2
Vì vậy, nó cần thiết. Ví dụ. :-)
Florian F

1
Tôi đang bỏ phiếu để đóng câu hỏi này dưới dạng ngoài chủ đề vì các thử thách ngầm không còn thuộc chủ đề trên trang web này. meta.codegolf.stackexchange.com/a/8326/20469
mèo

Câu trả lời:


33

C

int main(int argc, char **argv) {
    switch(argc) {
        case 2:
            ;
            int allowed = 0;
        case 3:
            argc--;
            break;
        default:
            argc = 3;
    }
    return 0;
}

Sẽ không biên dịch nếu chúng tôi loại bỏ đơn ;.

CHỈNH SỬA :

Giải pháp dưới đây:

Điều này xảy ra bởi vì một casecâu lệnh chỉ là một nhãn và, do đó, phải được theo sau bởi một câu lệnh (mà tiêu chuẩn gọi là "chỉ định cho các hành động được thực hiện", quy định khai báo). Để ngăn chặn điều này, chúng tôi tiền tố tuyên bố với một ;, một lệnh rỗng . Thông số kỹ thuật cho casenhãn có thể được tìm thấy ở đây tại trang 142 (tài liệu 131)


4
GCC nói rằng "nhãn chỉ có thể là một phần của tuyên bố và tuyên bố không phải là tuyên bố".
Vortico

1
Tôi vừa bị cắn bởi điều này trong một chương trình tôi đang viết cho trường học.
Kevin - Tái lập lại

Điều này làm cho các chương trình thực sự trông rất xấu xí thực sự: \.
val nói Phục hồi lại

23

C / C ++

Chỉ cần một số mã được viết theo phong cách giới thiệu / hướng dẫn ...

Hướng dẫn nr. 2 : đọc số, thực hiện các phép toán trên chúng và in kết quả.

//////////////////////////////////////////////////
///////////////////////////////////////////////////
/////                                            //
/////           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);

}

Loại bỏ dòng result = 42;mà thoạt nhìn trông có vẻ không cần thiết, và, xem xét mục tiêu đã nêu, thực sự sai, sẽ thực sự khiến chương trình không thực hiện được những gì mô tả.

Tại sao?

Chiến thuật tấn công một lần nữa! ?? / sẽ được thay thế bởi bộ tiền xử lý bằng \ , đến lượt nó sẽ nối dòng tiếp theo vào bình luận. Các kết quả = 42; trở thành một phần của bình luận, vì vậy nó "tiết kiệm" dây chuyền in. Với kết quả = 42; dòng bị xóa, dòng printf sẽ bị nuốt bởi bình luận. Một số trình biên dịch có thể đưa ra cảnh báo hoặc các phần tử có thể bị tắt như mặc định và phải được bật để ví dụ này hoạt động. Làm nổi bật cú pháp cũng có thể phản bội nó, nhưng có các trình biên dịch và IDE xung quanh khiến bạn không khôn ngoan hơn.


Ít nhất là trong gcc, bạn phải xác định rằng bạn muốn sử dụng các biểu tượng bằng cách thêm cờ này (-tricles). Không có điều này, gcc tăng cảnh báo và bỏ qua các bộ ba.
Gari BN

4
Đẹp quá Tôi rất vui vì tôi đã không cuộn xuống quá xa trước khi tìm ra nó. Bạn có thể thay đổi blockquote của mình thành văn bản spoiler bằng cách bắt đầu bằng >!thay vì chỉ >.
squossish ossifrage

@squeamishossifrage: cảm ơn, đây là ý định ban đầu của tôi, tôi >!chỉ sử dụng không phải trong mỗi dòng. Tôi mặc dù họ không hiển thị cho tôi khi tôi viết chúng. Thật thú vị, trình phân tích cú pháp SE không làm hỏng nó :)
vsz

1
Tôi biết một cái gì đó lén lút đang diễn ra trong lần thứ hai tôi thấy một địa phương bao gồm "stdio.h"thay vì thư viện thực tế bao gồm,<stdio.h>
Braden Best

1
Khoảnh khắc tôi nhìn thấy những lời bình luận thừa thãi tôi đã nói to, "Bức tượng ở đâu? Phải có một trigrap-- À, nó đây rồi."
mèo

19

Khoảng trắng

Thật không may, tôi không thể hiển thị chương trình của mình ở đây vì StackExchange loại bỏ tất cả các khoảng trắng ở cuối. Điều tương tự cũng đúng với pastebin.com và pastie.org, vì vậy tôi cũng không thể liên kết với nó.

Tất nhiên, toàn bộ chương trình, trông có vẻ vô dụng, nhưng nếu bạn loại bỏ bất kỳ dòng nào, nó sẽ làm một cái gì đó khác đi.


41
Nhưng may mắn thay, không có gì có giá trị sẽ bị mất, bởi vì toàn bộ ngôn ngữ là vô dụng :-)
squossish ossifrage

1
@Timwi còn hộp "dữ liệu dán thô" thì sao?
Braden hay nhất

1
@Timwi Tôi mới thử nó ở đây , và tôi hiểu ý của bạn. Nhưng nếu bạn đặt văn bản không phải khoảng trắng, nó sẽ gửi và dữ liệu dán thô sẽ không được xử lý. Ví dụ: bạn có thể đặt thêm một dòng có nội dung "Sao chép dữ liệu dán thô và xóa dòng này"
Braden Best

8
thay thế \ t bằng t. Thay thế "" bằng s, thay thế \ n bằng n
Cruncher

7
Trò đùa hay nhất từ ​​trước đến nay: Đăng một cái gì đó mà không thực sự viết mã.
Kaz Wolfe

9

JavaScript:

for (var a = 0, b = 4; ++a < b; a++)b+-

2 + 2; // This line is needed, or it will alert twice!
alert(a);

Lý do nó hoạt động là bởi vì cơ thể của forb+-, không b++hay b--; do đó, nếu bạn loại bỏ dòng yêu cầu, nó sẽ thêm vào bgiá trị của -alert(a).


"nó sẽ thêm vào bgiá trị của alert(a)": Vì vậy, không nên b+-b+=?
Gaurang Tandon

@GaurangTandon Không; ý tưởng là nó trông giống như b++hoặc b--.
Bàn chải đánh răng

b + - thực tế có nghĩa là gì?
Mhmd

5
@ người dùng689 b + -2 + 2. Đó là lý do tại sao nếu bạn xóa dòng với 2 + 2;, nó sẽ đánh giá b + -alert(a);.
Bàn chải đánh răng

8

C:

#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;
}

Nếu bạn xóa dòng i = i;thì mã sẽ không hoạt động. Đó là vì ...

... Thực tế nó sẽ không được biên dịch. Theo tiêu chuẩn C, các nhãn như bỏ qua trong ví dụ trên phải được liên kết với một tuyên bố. Ngay cả một dấu chấm phẩy đơn cũng sẽ có hiệu lực, nhưng nếu bạn xóa toàn bộ dòng thì nhãn không có câu lệnh liên quan và quá trình biên dịch thất bại. Câu trả lời này giải thích chi tiết hơn một chút.


7

APL

Đây là một chức năng APL:

i_←{
  ⍺←⎕IO ⋄ ⎕IO←⍺
  ⍵⍴⍳×/⍵
}

Nó làm điều tương tự như đơn điệu của J 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

Nó có thể lấy một đối số bên trái tùy chọn cung cấp bù:

      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

Dòng này ⍺←⎕IO ⋄ ⎕IO←⍺trông vô dụng ("gán ⎕IOcho , sau đó gán cho ⎕IO"), nhưng phần đầu tiên chỉ chạy nếu không có đối số bên trái nào được đưa ra, vì vậy trên thực tế, nó thực hiện một số thứ:

  • nếu không được đưa ra, đặt thành (toàn cầu) ⎕IO.
  • đặt (cục bộ) ⎕IOthành

7

C #

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);

Biến fibophải được chỉ định trước khi bạn có thể sử dụng nó trong lambda, ngay cả khi bạn gán lambda đó cho fibochính nó. Nếu bạn loại bỏ phép gán (dường như vô dụng), sẽ xảy ra lỗi trình biên dịch (Sử dụng biến cục bộ không được gán 'fibo' ').


Đây không phải là ngoại lệ tham chiếu null, đó là lỗi trình biên dịch biến chưa được khởi tạo. Ngoài ra, tốt hơn nên di chuyển khai báo đến dòng riêng của nó, bởi vì khai báo không vô dụng.
Kendall Frey

@KendallFrey Điểm tốt! Đã sửa.
Ben Reich

5

Batch Windows:

echo hello
pause
echo world

Đặt chương trình đang chạy và sửa đổi tệp thành:

rem test01
pause
echo hello world

Nếu bạn xóa hoặc thay đổi kích thước nhận xét, nó sẽ gây ra sự tàn phá khi phiên bản đầu tiên của chương trình tạm dừng và sau đó tiếp tục diễn giải từ byte thứ 19 trở đi.


Tôi không thấy bất kỳ ý kiến.
orion

4
REM (nhận xét) là toán tử nhận xét - stackoverflow.com/questions/11269338
OJW

4

Java

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");
    }
}

Đây là một chương trình làm việc lấy một trang web từ một URL. Bạn có thể ngạc nhiên rằng dòng

            http://codegolf.stackexchange.com

biên dịch mà không có một cảnh báo. Trong thực tế, chương trình không biên dịch mà không có nó.

Nó thực sự là một nhãn hiệu http:, theo sau là một bình luận , //codegolf.... Nhãn áp dụng cho thời gian và được sử dụng trong break http;tuyên bố.


1
Xin vui lòng giải thích, hoặc tôi sẽ xóa dòng đó bất cứ điều gì bạn nói.
Bill Woodger

3

Hồng ngọc

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

Một điều tương tự đã xuất hiện gần đây - một đồng nghiệp thực sự đã đánh dấu việc khởi tạo dường như không cần thiết của tôi trong quá trình xem xét mã, và tôi thực sự bị cám dỗ để đưa ra lời giải thích bên trong một khối spoiler. Vì vậy, tôi sẽ làm điều đó ở đây.

Dòng này là cần thiết bởi vì một biến được khởi tạo bên trong một khối là cục bộ của khối đó. Nếu chúng ta khởi tạo nó bên ngoài khối, thì giá trị có thể thoát khỏi phạm vi phương thức.

Đầu ra là:

/4/:    41 (4)
/1+2/:  127 (12)
/[02468]{2,}/:  223 (22)

Đầu ra với dòng đầu tiên của phương thức được loại bỏ:

không xác định biến cục bộ hoặc phương thức 'khớp' cho hàm chính: Object (NameError)


1
Rõ ràng là tại sao điều đó lại cần thiết ... và dù sao đi nữa, cách tốt hơn để viết nó sẽ chỉ làmatch = Prime.find { |n| n.to_s[regexp] }
Doorknob

1
Điều đó sẽ không làm những gì tôi muốn ... Prime.findtrả về n(ví dụ: 223) và matchcần phải là n.to_s[regexp](ví dụ: "22"). Rõ ràng tôi đã đặt ra vấn đề để làm cho điều đó cần thiết.
lịch sử

Ah, xin lỗi, không để ý bạn được gọi findvào Primevà không phải là một mảng. Dù sao, vẫn khá dễ dàng để nhận ra lý do tại sao dòng đó là cần thiết ...
Doorknob

Đủ công bằng. Có lẽ đồng nghiệp của tôi chỉ là không quan tâm.
lịch sử

Huh. Không có khai báo biến, nhưng cách tiếp cận ngược lại với mặc định cục bộ / không tập trung vào những gì Python làm. Điều đó sẽ cảm thấy kỳ lạ nếu tôi quyết định học Ruby.
user2357112 hỗ trợ Monica

3

PHP

<?php
$some_html_text= <<<EOT
<h1>This is a Header </h1>
<body> This is a body </body>
EOT;
//This is a comment    

Đây, \n//This is a comment là cần thiết. Không có nó, mã sẽ không chạy.

Ít nhất một \nchar là cần thiết sau khi EOT;chạy nó đúng cách


3

JAVASCRIPT

var a = function(b) {
    return b;
}

; // This must be here

(function() {
    // more code
}());

Nếu không có dấu chấm phẩy thì asẽ trở thành giá trị trả về từ hàm thứ 2 - trong trường hợp này là undefined. Bởi vì hàm ban đầu được gán asẽ được thực thi ngay với hàm thứ hai làm đối số b.


2

COBOL (Máy tính lớn của 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 
       . 

Nếu bạn chạy chương trình trên (bất kỳ COBOL Mainframe nào của IBM kể từ COBOL II (trình biên dịch IBM đầu tiên theo tiêu chuẩn 1985, có thể là các COBOL khác của IBM) thì đầu ra là:

22/2/14 13.11.02 THẾ GIỚI HELLO!

Tuy nhiên, nếu bạn loại bỏ dòng ba lần vô dụng "DI CHUYỂN SPACE TO W-WHEN-COMPILED." (trường có giá trị ban đầu của không gian và có nội dung khác được đặt trong hướng dẫn tiếp theo và dù sao nó cũng được phân nhánh), chương trình không tạo ra đầu ra và thực sự là Abends (U4038) (có nghĩa là nó gặp sự cố) với thông báo sau :

 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. 

(mã thông báo và văn bản sẽ khác nhau giữa các trình biên dịch, độ lệch phụ thuộc vào trình biên dịch thực tế được sử dụng và các tùy chọn biên dịch, địa chỉ phụ thuộc vào nơi chương trình được tải khi EXECuting).

Lý do là NEXT SENTENCE. Đây là mộtSecret GO TO . Trình biên dịch tìm kiếm toàn bộ điểm dừng / thời gian tiếp theo trong nguồn và tạo một nhánh theo hướng dẫn sau. Từ COBOL II, việc sử dụng toàn bộ điểm dừng / thời gian đã được nới lỏng. Một chương trình phải kết thúc với một điểm dừng / thời gian đầy đủ. Trong trường hợp này, chi nhánh sẽ kết thúc chương trình.

Cả hai chương trình đều biên dịch sạch 100% (không có thông báo chẩn đoán, Mã trả về bằng 0).

Hành vi này là một "Phần mở rộng IBM" ngu ngốc đối với COBOL. Tiêu chuẩn 1985 không cho phép NEXT SENTENCEtrong IF/ END-IF( CONTINUEđược sử dụng thay thế, đó là không có op). IBM đã cho phép nó - gây ra Gotchas khủng khiếp theo thời gian.


2
#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");
}

Vấn đề tràn chuỗi đơn giản.


1
Bất kỳ trình biên dịch tử tế nào cũng sẽ cung cấp cho bạn chẩn đoán "quá nhiều trình khởi tạo".
Ben Voigt

Mà nền tảng segfaults không có blah ? Ở đây với OpenBSD 5.5 / amd64 và hệ thống gcc, nó không bao giờ phân tách, dù có hay không blah. Chương trình đã biên dịch phân bổ 16 byte không gian ngăn xếp và sao chép giá trị 16 bit "ok" sang 2 byte đầu tiên. Byte thứ 3 chưa được khởi tạo có '\ 0' do may mắn. Nếu blahcó, nó ở byte thứ 16 và vẫn không kết thúc chuỗi.
hạt nhân

2

~ - ~!

Đây có lẽ là điều ngu ngốc nhất, rõ ràng nhất ở đây.

'=|hello\|:
'=~!|Useless?\|:
@'[|y|]|n|:

Nó ném một lỗi mà không có dòng thứ hai, với nó được in y.

dấu gạch chéo ngược không phải là một ký tự thoát, hehe.


Làm thế nào để bạn phát âm tên ngôn ngữ?

8
@professorfish~-~!
TimTech

1
@professorfish Đó là "không bình luận".
cjfaure

1

Batch Windows

Đây là một tệp bó in các số từ 1 đến 10 với một dòng trống sau mỗi dòng:

@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

Điều này thực sự sử dụng hack bẩn để lưu trữ một dòng mới bên trong một biến (việc sử dụng các mở rộng bị trì hoãn sẽ thoát khỏi dòng NL trông đáng sợ hơn trong câu trả lời được liên kết). Nếu bạn loại bỏ hoặc thay đổi hai dòng trống trông hoàn toàn vô dụng phía trên bình luận, thì nó sẽ không hoạt động.


0

troff

Troff là hệ thống xử lý văn bản tuyệt vời nhất. Tôi sử dụng nó cho các tài liệu của tôi. Nó đòi hỏi một hệ thống macro để sẵn sàng sử dụng và nổi tiếng nhất là msgói macro. Hãy biên dịch đoạn mã sau với -mstùy chọn cổ điển .

.\" -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.

Dòng thứ ba dường như là vô dụng, và thực sự sẽ vô dụng nếu không có gói macro. Vì nó được theo sau hai dòng bên dưới bởi một vị trí thẳng đứng tuyệt đối, nên có vẻ như không có gì để in trước đó. Nhưng nếu không có nhân vật vô hình này, việc định vị dọc sẽ không có hiệu lực, mặc dù tôi không chắc chắn mình có thể giải thích tại sao (xem chủ đề này nếu bạn muốn xem lướt qua cuộc thảo luận). Điều này làm cho người dùng mới phát điên, nhưng sau đó thủ thuật sẽ trở nên quen thuộc với người dùng thử nghiệm nhiều hơn.

Chỉ cần kiểm tra với phiên bản troff yêu thích của tôi không được biết đến nhiều (troff gia truyền), nhưng tôi khá chắc chắn rằng nó vẫn hoạt động tương tự với troff GNU.


Một điều tuyệt vời, điều này cũng xảy ra trong LaTeX. Không có hộp trống hoặc thứ gì đó tương tự, khoảng cách dọc không hoạt động đúng.
orion
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.