Làm thế nào để chương trình dưới đây xuất ra `C89` khi được biên dịch ở chế độ C89 và` C99` khi được biên dịch ở chế độ C99?


128

Tôi đã tìm thấy chương trình C này từ web:

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5//**/
    -4.5)));

    return 0;
}

Điều thú vị với chương trình này là khi nó được biên dịch và chạy ở chế độ C89, nó sẽ in C89và khi được biên dịch và chạy ở chế độ C99, nó sẽ in C99. Nhưng tôi không thể tìm ra cách chương trình này hoạt động.

Bạn có thể giải thích làm thế nào đối số thứ hai của printfcông việc trong chương trình trên?


47
Gợi ý: //nhận xét kiểu C ++ đã được giới thiệu trong C99.
Paul R

4
Thủ thuật hay - nhưng nó thất bại với gcc. Nếu không std=c99có cảnh báo, và nếu bạn bỏ qua nó, vẫngcc sẽ diễn giải khi bắt đầu nhận xét (ah - bạn cũng phải sử dụng . Tôi có điều đó theo mặc định.)//-pedantic
usr2564301

3
@Jongware Vâng, tôi đã nhận được C89rõ ràng std=c89trong gcc 4.9.2.
ikh

60
Chỉ trong trường hợp ai đó tìm thấy điều này trong khi tìm kiếm cách để kiểm tra hỗ trợ C99; xin vui lòng sử dụng một cái gì đó như #if __STDC_VERSION__ >= 199901L, không phải là //mẹo bình luận. =)
Arkku

10
Nó cũng in "C99" cho C11 ...
Lundin

Câu trả lời:


133

C99 cho phép //nhận xét kiểu, C89 thì không. Vì vậy, để dịch:

C99:

 printf("C%d\n",(int)(90-(-4.5     /*Some  comment stuff*/
                         -4.5)));
// Outputs: 99

C89:

printf("C%d\n",(int)(90-(-4.5/      
                         -4.5)));
/* so  we get 90-1 or 89 */

25

dòng chú thích //được giới thiệu từ C99. Do đó, mã của bạn bằng với mã này trong C89

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5/
-4.5)));

    return 0;
}
/* 90 - (-4.5 / -4.5) = 89 */

và bằng với điều này trong C99

#include <stdio.h>

int main(){

    printf("C%d\n",(int)(90-(-4.5
-4.5)));

    return 0;
}
/* 90 - (-4.5 - 4.5) = 99*/

9

Vì các //nhận xét chỉ tồn tại trong các tiêu chuẩn C99 và mới hơn, nên mã này tương đương với các điều sau:

#include <stdio.h>

int main (void)
{
  int vers;

  #if   __STDC_VERSION__ >= 201112L
    vers = 99; // oops
  #elif __STDC_VERSION__ >= 199901L
    vers = 99;
  #else
    vers = 90;
  #endif

  printf("C%d", vers);

  return 0;
}

Mã chính xác sẽ là:

#include <stdio.h>

int main (void)
{
  int vers;

  #if   __STDC_VERSION__ >= 201112L
    vers = 11;
  #elif __STDC_VERSION__ >= 199901L
    vers = 99;
  #else
    vers = 90;
  #endif

  printf("C%d", vers);

  return 0;
}

câu trả lời sai trong câu trả lời của bạn, làm thế nào để bạn nhận được 90 khi phải in 89?
Pimgd

1
@Pimgd C89 và C90 là điều tương tự. stackoverflow.com/questions/17206568/
Mạnh

3
Chúng có nghĩa tương tự nhưng nó không phải là cùng một chuỗi. Đứng trước câu hỏi ban đầu của tôi.
Pimgd

@Pimgd Mục đích của đoạn mã trên không phải là sắp xếp một số tác vụ nhân tạo để in chuỗi sau một định dạng nhất định. Mục đích là để chứng minh các ứng dụng từ thật bên ngoài IOCCC in phiên bản C mà chương trình được biên dịch với. C90 chính xác hơn để sử dụng hơn "C89" hoặc "ANSI-C".
Lundin
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.