문(Statements)
문(Statements)
C 프로그램은 순서대로 실행되는 문(statement)들의 조각으로 이루어져요. 어떤 함수의 몸통도 복합 문(compound statement)인데, 이는 다시 문과 선언의 나열이에요:
int main(void)
{ // start of a compound statement
int n = 1; // declaration (not a statement)
n = n+1; // expression statement
printf("n = %d\n", n); // expression statement
return 0; // return statement
} // end of compound statement, end of function body
C에는 다섯 종류의 문이 있어요:
- 복합 문(compound statements)
- 표현식 문(expression statements)
- 선택 문(selection statements)
- 반복 문(iteration statements)
- 점프 문(jump statements)
속성 지정자 시퀀스(attr-spec-seq)는 레이블이 붙지 않은 문에 적용할 수 있고, 그 경우(표현식 문을 제외하고) 속성은 해당 문에 적용돼요. (C23부터)
레이블(Labels)
어떤 문이든 문 앞에 이름 뒤에 콜론을 붙여 레이블을 달 수 있어요.
attr-spec-seq(선택)(C23부터) identifier : |
(1) |
attr-spec-seq(선택)(C23부터) case constant-expression : |
(2) |
attr-spec-seq(선택)(C23부터) default : |
(3) |
goto의 대상.switch문 안의 case 레이블.switch문 안의 default 레이블.
선언이 아닌 어떤 문이든 앞에 레이블을 몇 개든 붙일 수 있고, 각 레이블은 identifier를 레이블 이름으로 선언해요. 레이블 이름은 자신을 감싸는 함수 안에서 유일해야 해요(다시 말해 레이블 이름은 함수 범위(function scope)를 가져요).
레이블 선언 자체는 아무 효과가 없고, 제어 흐름을 바꾸지도 않고, 뒤따르는 문의 동작을 바꾸지도 않아요.
레이블 뒤에는 문이 따라와야 해요. (C23 이전)
레이블은 뒤따르는 문 없이 단독으로 올 수 있어요. 레이블이 블록 안에 홀로 있으면 마치 뒤에 널 문이 따라오는 것처럼 동작해요. (C23부터)
선택적인 attr-spec-seq는 레이블에 적용돼요. (C23부터)
복합 문(Compound statements)
복합 문, 또는 블록은 중괄호로 감싼 문과 선언의 나열이에요.
{ statement | declaration... (선택) } |
(C23 이전) |
attr-spec-seq(선택) { unlabeled-statement | label | declaration...(선택) } |
(C23부터) |
복합 문은 선언과 문의 집합을 하나의 단위로 묶어주고, 단일 문이 필요한 어디에든(예: if 문이나 반복 문 안에) 쓸 수 있게 해줘요:
if (expr) // start of if-statement
{ // start of block
int n = 1; // declaration
printf("%d\n", n); // expression statement
} // end of block, end of if-statement
각 복합 문은 자기 자신의 블록 범위(block scope)를 도입해요.
블록 안에 선언된 자동 저장 기간(automatic storage duration) 변수의 이니셜라이저와 VLA 선언자는, 마치 문인 것처럼 제어 흐름이 그 선언들을 순서대로 지나갈 때 실행돼요:
int main(void)
{ // start of block
{ // start of block
puts("hello"); // expression statement
int n = printf("abc\n"); // declaration, prints "abc", stores 4 in n
int a[n*printf("1\n")]; // declaration, prints "1", allocates 8*sizeof(int)
printf("%zu\n", sizeof(a)); // expression statement
} // end of block, scope of n and a ends
int n = 7; // n can be reused
}
표현식 문(Expression statements)
표현식 뒤에 세미콜론을 붙이면 그것이 문이 돼요.
expression(선택) ; |
(1) |
attr-spec-seq expression ; |
(2) (C23부터) |
일반적인 C 프로그램의 대부분의 문은 대입이나 함수 호출 같은 표현식 문이에요.
표현식이 없는 표현식 문을 널 문(null statement)이라고 불러요. for나 while 루프에 빈 몸통을 제공하는 데 자주 쓰이고, 복합 문의 끝이나 선언 앞에 레이블을 붙이는 데도 쓸 수 있어요:
puts("hello"); // expression statement
char *s;
while (*s++ != '\0')
; // null statement
선택적인 attr-spec-seq는 표현식에 적용돼요. (C23부터)
attr-spec-seq 뒤에 ;가 오는 것은 표현식 문을 만들지 않아요. 대신 속성 선언(attribute declaration)을 만들어요. (C23부터)
선택 문(Selection statements)
선택 문은 표현식의 값에 따라 여러 문 중 하나를 골라요.
attr-spec-seq(선택)(C23부터) if ( expression ) statement |
(1) |
attr-spec-seq(선택)(C23부터) if ( expression ) statement else statement |
(2) |
attr-spec-seq(선택)(C23부터) switch ( expression ) statement |
(3) |
- if 문
- else 절이 있는 if 문
- switch 문
반복 문(Iteration statements)
반복 문은 문을 반복해서 실행해요.
attr-spec-seq(선택)(C23부터) while ( expression ) statement |
(1) |
attr-spec-seq(선택)(C23부터) do statement while ( expression ) ; |
(2) |
attr-spec-seq(선택)(C23부터) for ( init-clause ; expression(선택) ; expression(선택) ) statement |
(3) |
- while 루프
- do-while 루프
- for 루프
점프 문(Jump statements)
점프 문은 제어 흐름을 무조건적으로 옮겨요.
attr-spec-seq(선택)(C23부터) break ; |
(1) |
attr-spec-seq(선택)(C23부터) continue ; |
(2) |
attr-spec-seq(선택)(C23부터) return expression(선택) ; |
(3) |
attr-spec-seq(선택)(C23부터) goto identifier ; |
(4) |
- break 문
- continue 문
- 선택적인 표현식이 붙은 return 문
- goto 문