2013-04-26 37 views
10

Tôi đã xem qua chương trình này thông qua một quora answerOn hiểu cách printf ("% d n", ({int n; scanf ("% d", &n); n * n;})); hoạt động trong C

#include<stdio.h> 
int main() { 
    printf("%d\n", ({ int n; scanf("%d", &n); n*n; })); 
    return 0; 
} 

tôi đã tự hỏi làm thế nào công việc này và nếu điều này phù hợp với tiêu chuẩn?

+3

C99 Nghiêm ngặt: http://ideone.com/9K9bcV và C http://ideone.com/PdalsH Trình biên dịch IDE C của tôi khai báo một loạt các lỗi và cảnh báo về vấn đề này. Quan tâm lý do tại sao liên kết thứ hai biên dịch. –

+0

@Armin liên kết sử dụng gcc, theo mặc định, sử dụng GNU C89. – effeffe

+0

Không trả lời cho câu hỏi của bạn Nhưng nó hoạt động với gcc ở đây tôi đã viết các mã tương tự [** Đầu tiên **] (http://codepad.org/POu848fV) và [** Thứ hai **] (http://codepad.org/MFLG9sa7), Nhớ trong [** 'int i = (5, 7);' 'i' sẽ là' 7' **] (http://stackoverflow.com/questions/15302789/c-explain-ifexit0- 0-line-of-code/15303040 # 15303040) –

Trả lời

7

Mã này đang sử dụng tính năng "GNU C" được gọi là biểu thức tuyên bố, theo đó một dấu ngoặc kép có thể được sử dụng làm biểu thức, có loại và giá trị khớp với kết quả của câu lệnh cuối cùng trong câu lệnh ghép. Đây không phải là cú pháp hợp lệ C, nhưng một tính năng GCC (cũng được một số trình biên dịch khác chấp nhận) được thêm vào có lẽ vì nó được coi là quan trọng cho việc viết macro mà không đánh giá đối số của chúng nhiều hơn một lần.

Bạn nên biết nó là gì và nó làm gì trong trường hợp bạn gặp phải nó trong mã bạn phải đọc, nhưng tôi sẽ tránh sử dụng nó cho mình. Nó gây nhầm lẫn, không cần thiết và không chuẩn. Điều tương tự hầu như luôn có thể đạt được một cách ổn định với các hàm nội tuyến tĩnh.

0

tôi không tin rằng nó không làm việc ... n có phạm vi địa phương trong niềng răng ... khi bạn thoát khỏi niềng răng, n trở thành không xác định mặc dù tôi giả sử là có thể vẫn tồn tại ở đâu đó trên ngăn xếp và có thể hoạt động. Đó là xin lỗi cho các vấn đề thực hiện và tôi đảm bảo là thực hiện phụ thuộc.

Một điều tôi có thể nói với bạn là bất kỳ ai làm việc cho tôi, người đã viết đó sẽ đọc được hành động bạo động.

+2

Nó thậm chí không có cú pháp hợp lệ C. Đó là "GNU C" ... –

+0

Nó hoạt động. Chỉ cần dán nó vào một tập tin và biên dịch (thậm chí làm việc bằng cách sử dụng '-ansi' cờ trong gcc). Nó chắc chắn là phong cách xấu mặc dù. – PaulProgrammer

+0

Có rất nhiều thứ "làm việc" - không có nghĩa là chúng hợp lệ.Tôi có thể thấy cách 'n * n' cuối cùng có thể để lại một giá trị trên ngăn xếp, nhưng tôi sẽ đảm bảo không thiếu sự triển khai C mà thậm chí sẽ không biên dịch nó. –

0

Nó hoạt động. Tôi không nhận được cảnh báo từ gcc, vì vậy tôi cho rằng nó phù hợp với tiêu chuẩn.

Sự kỳ diệu là việc đóng cửa:

{ int n; scanf("%d", &n); n*n; } 

nugget này quét một số nguyên từ bàn điều khiển (không có kiểm tra lỗi) và hình vuông nó, trả lại số bình phương. Trong triển khai cổ C, số cuối cùng trên ngăn xếp được trả về. n*n đặt số trên ngăn xếp.

Đó giá trị được thông qua với printf:

printf("%d\n", <scanned>); 

Vì vậy, để giải đáp thắc mắc của bạn: Vâng, nó hoạt động. Có, đó là "tiêu chuẩn" (đến mức mà bất kỳ ai tuân theo tiêu chuẩn hoàn toàn). Không, nó không phải là một thực hành tuyệt vời. Đây là một ví dụ điển hình về phản ứng đầu gối, gọi là "thư tình biên dịch", được thiết kế chủ yếu để cho thấy lập trình viên thông minh như thế nào, không nhất thiết phải giải quyết vấn đề hoặc hiệu quả.

+4

Nó không phải là tiêu chuẩn. Đó là "GNU C". –

+1

Tôi sẽ mua nó. Làm việc với lá cờ '-ansi', vì vậy, nó đã đủ ansi. – PaulProgrammer

Các vấn đề liên quan