변수 이름에 주석을 쓸 수 있습니까?


144

위의 코드가 있고 토큰을 세고 싶다면 토큰이 14 개 또는 13 개입니까?

변수 이름 내에 주석을 쓰는 것이 유효합니까? 당신은 가정 수 int i, int a, int ia전역으로 정의된다.


13
ANSI 이전의 "전통적인"C에서는 최소한 GNUcpp -traditional 에 의해 구현 된대로 ia = 10;.
Nate Eldredge

37
흥미로운 질문입니다. 왜 그런 일이 전에 발생하지 않았습니까?
StephenBoesch

178
@javadba : 현명한 사람들은 그런 일을 생각하지 않기 때문에?
jamesqf

5
정말로 그렇게하고 싶다면 Fortran으로 전환 할 수 있습니다. 문자열 외부의 공백은 첫 번째 구문 분석 단계에서 제거됩니다.
mpez0

3
제목을 ".... 변수 이름 내에서 ..." 로 편집 하려고했지만 실제로 "사이"를 의미 할 수 있음을 깨달았습니다. (원래 제목에 대한 답이 "왜, 당연히!"이기 때문에 편집하고 싶었습니다. 중요한 부분은 "공백 없음"입니다.) 제목 "주석 (주변 공백없이)이 C에서 토큰을 분리합니까?" 실제 질문을 표현 하시겠습니까?
피터 - 분석 재개 모니카

답변:


198

주석은 프로그램 번역 1의 3 단계에서 제거됩니다 . 각 주석은 하나의 공백 문자로 대체됩니다. 따라서 댓글 /*nt*/은 확실히 토큰이 아닙니다.

없음의 경우 int, main, i, a또는 return프로그램 구문 분석 생산 매크로 전처리로서 정의된다 (14 개) 의 토큰 (되지 13) :

int main ( ) { i a = 10 ; return 0 ; }

하지 않는 한 i기호가있는 유형으로 정의 typedef문 구문 오류로 거기 i a는 C 문법의 규칙과 일치하지 않습니다.

따라서 변수 이름 안에 주석을 쓸 수 없으며 주석은 식별자를 2 개의 개별 토큰으로 분할합니다. 이것은 모든 전처리 및 C 언어 토큰 2에 해당 됩니다.

그러나 단항 연산자와 피연산자 사이 또는 #및 전처리 지시문과 인수 사이와 같이 비정상적인 위치에 주석을 삽입 할 수 있습니다 .

그러나 매크로 정의 위는 매크로 같은 기능-하지만 일반 매크로 정의하지 않습니다 STAT팽창에 그 ( a ) - 1.

다른 토큰과 마찬가지로 변수 이름은 이스케이프 된 줄 바꿈으로 분할 할 수 있습니다. 이스케이프 된 개행은 시퀀스이거나 개행 \바로 뒤에옵니다. 이러한 시퀀스는 프로그램 번역의 2 단계 동안 소스 코드에서 제거됩니다. 주요 목적은 긴 매크로 정의를 여러 줄로 나누는 것입니다.

다음은 동일한 14 개의 토큰을 생성 하는 코드 조각 3 입니다.

코드 colorizer가 슬라이스 및 diced 키워드 및 주석을 어떻게 놓쳤는 지 확인하십시오. :)


1)이 동작은 ANSI-C 일명 C89에서 지정되었습니다. 일부 고대 컴파일러는 토큰 붙여 넣기로 인해 미묘하게 다른 동작을 보였지만 이러한 특성은 역사적으로 만 관심이 있습니다.

2) 프로그램 번역의 6 단계에서 인접한 문자열 상수가 연결된다는 사실을 이용하여 문자열 상수 안에 주석을 거의 삽입 할 수 있습니다. printf("Hello "/* my name is Luca */"world!\n");

3)이 크리스마스 트리 프레젠테이션 스타일은 실제 프로그램에서 사용하기위한 것이 아니라 C의 입력 처리 기능을 남용하는 방법을 보여줍니다. 더 정교한 트릭이 The International Obfuscated C Code Contest 에서 우승했습니다 .


후행 공백이나 그 부족이 의미 상 중요한 다른 상황이없고 일부 텍스트 파일 형식이 그렇지 않을 수 있다는 점을 감안할 때 표준에서 줄 연속 백 슬래시 문자가 다른 공백 문자에 의해 개행 문자와 분리되지 않도록 요구하는 이유가 궁금합니다. 공백으로 끝나는 줄과 그렇지 않은 줄을 구분할 수 있습니까?
supercat

@supercat : 동의합니다. 이것은 또한 CR LF 시퀀스를 줄 끝으로 사용하는 레거시 시스템에서 오는 파일의 경우를 포함 \r하여 \n. 그러나 이것이 역효과를 const char *path = "C:\\"; // the default path is C:\ 
내는

표준은 텍스트 파일이 줄 끝에서 공백 문자를 지원할 수 있도록 요구하지 않습니다. The path is "C:\"코드의 의미가 후행 줄 바꿈에 의존하는 것보다 더 나은 것처럼 보이는 주석을 작성하십시오 .
supercat

1
Teeeechnically, 표준은 이러한 요구 사항을 만들지 않습니다. 왜냐하면 자주 무시되는 번역 단계 1 은이 동작이 문서화되어있는 한 모든 줄 에서 후행 공백을 제거 할 수 있기 때문 입니다.
zwol

4
이 대답은 어리석은 질문이 없음을 증명하기 위해 먼 길을갑니다. 잘 했어.
Overbryd

65

어휘 관점에서 주석은 공백과 동일합니다.

어휘 요소 상태에 관한 C 표준 의 섹션 6.4p3 :

... 전처리 토큰은 공백 으로 구분할 수 있습니다 . 이것은 주석 (나중에 설명) 또는 공백 문자 (공백, 수평 탭, 줄 바꾸기, 수직 탭 및 용지 공급) 또는 둘 다로 구성됩니다. ...

보다 구체적으로 설명은 단일 공간으로 번역됩니다. 이것은 섹션 5.1.1.2p3에 지정되어 있습니다.

소스 파일은 사전 처리 토큰과 일련의 공백 문자 (주석 포함)로 분해됩니다. 소스 파일은 부분 전처리 토큰이나 부분 주석으로 끝나서는 안됩니다. 각 주석은 하나의 공백 문자로 대체됩니다. 개행 문자는 유지됩니다. 줄 바꾸기가 아닌 공백 문자의 비어 있지 않은 각 시퀀스가 ​​유지되거나 하나의 공백 문자로 대체되는지 여부는 구현에서 정의됩니다.

이를 설명하기 위해 코드를 전처리기를 통해 전달하면 다음과 같은 결과를 얻을 수 있습니다.

따라서 공백과 같은 주석은 별도의 토큰 역할을합니다.

이는 코드에 13 개가 아닌 14 개의 토큰이 포함된다는 것을 의미합니다.


25

결과는 다음과 같이 작성되었습니다.

아니:


12

번역 (컴파일이라고도 함) 3 단계, 2 단계 : "각 주석이 하나의 공백 문자로 대체 됨"을 참조하십시오 .

그래서 개념적으로 i/*nt*/ai a그 지점이됩니다.


의견은 확장 된 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Machavity

1

코드의 형태를 확인하십시오.

전처리 후 있습니다. 컴파일러 gcc -E myscript.c에 "-E"플래그를 추가하면 결과를 얻을 수 있습니다.

그리고 분명히 실수가 있다는 결론을 내릴 수 있습니다.


-9

예, 할 수 있습니다. 컴파일러는 주석을 건너 뜁니다. 변수에 영향을주지 않습니다. 주석 태그를 끝내는 것을 잊지 마십시오.


5
"변수에 영향을주지 않습니다. 동일합니다" 무엇과 동일 i a또는 ia?
HolyBlackCat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.