2014-08-27 16 views
14

Ten kod może być skompilowany przez gcc -g -o main main.c, bez ostrzeżeń.Język C: znaczenie operatora "#"?

// main.c 
# 41 "stdio.h" 
# 22 
# 
int main(void){ 
    (void)printf("foo"); 
    return 0; 
} 

Moje pytanie brzmi:

  1. Jaki jest sens operatora "#" przed "to". Używamy #include <stdio.h>, aby dołączyć plik nagłówkowy, dlaczego nie include <stdio.h>?

  2. Dlaczego można skompilować # 22 lub # 41, nigdy wcześniej tego nie widziałem.

Ktoś może mi pomóc?

+4

http://stackoverflow.com/questions/7110683/what-is-the-use-of-in-c-or-c czeku to bro –

+1

@mkpchiran: Twój link nie wyjaśnia powyższego problemu. – deepmax

Odpowiedz

8

Wygląda jak wyjście preprocesora. Linia

# 41 "stdio.h" 

można interpretować następująco:

  • 41 ma znaczenie:

To określa liczbę linii, które powinny być zgłaszane do następnej linii wejścia. Kolejne wiersze są liczone od płótna.

  • "stdio.h" jest tylko nazwa pliku, z którego podejmowane są linie.

Poniższy wiersz i wszystkie kolejne linie są zgłoszone pochodzą z pliku to określa, aż coś innego dzieje się zmienić. nazwa pliku jest interpretowana zgodnie z normalnymi regułami dla ciągu znaków stała: interpretowane są odwrotne ukośniki odwrotne.

I wszystkie te informacje są pobierane z https://gcc.gnu.org/onlinedocs/cpp/Line-Control.html#Line-Control i https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html#Preprocessor-Output

Jednolitego #:

null dyrektywa składa się z „#” zakończoną nową linią, tylko białe znaki (w tym komentarze) pomiędzy. Dyrektywa zerowa jest rozumiana jako dyrektywa dotycząca przetwarzania wstępnego, ale nie ma wpływu na dane wyjściowe preprocesora. Podstawowym znaczeniem istnienia dyrektywy zerowej jest to, że linia wejściowa składająca się tylko z "#" nie będzie produkować żadnego wyjścia, a linia wyjścia zawierająca tylko "#". Podobno niektóre stare programy C zawierają takie linie.

zaczerpnięte z https://gcc.gnu.org/onlinedocs/cpp/Other-Directives.html#Other-Directives

2

Na początku linii wprowadzono dyrektywę preprocesora. Preprocessing jest koncepcyjnie wcześniejszym etapem tłumaczenia niż kompilacją, dlatego używa łatwo rozpoznawalnej składni.

Jeśli # następuje niczym innym niżinclude, define, undef, line, error lub pragma, to jest to zakaz dyrektywa (6.10p1) i jest ignorowane.

Oznacza to, że # na początku linii jest prostym sposobem dla kompilatora do przekazywania informacji między etapami tłumaczenia; tutaj jest używany do przekazywania informacji o pliku źródłowym i numerze linii.