일
KNK Chap.2 (2.8~Q&A) 본문
2.8 Layout of C Program
C 프로그램을 일련의 토큰token*이라고 생각할 수 있음. 식별자와 키워드는 토큰임.
*token: 의미를 구성하는 글자의 최소 단위
연산자(Ex. + or -), 구두점(Ex. , or ;), 문자열 리터럴 또한 토큰임. 다음 구문을 보면
printf("Height: %d\n", height);
총 7개의 토큰으로 구성됨
printf ( "Height: %d\n" , height ) ;
① ② ③ ④ ⑤ ⑥ ⑦
①, ⑤: 식별자
③: 문자열 리터럴
②, ④, ⑥, ⑦: 구두점
대부분의 경우, 토큰 사이에 공간을 띄우는 것은 그닥 중요치 않음.
극단적인 경우, 띄어쓰기 하나도 없이 토큰들을 다 밀어넣어서 붙일 수도 있음.
물론 두 토큰이 합쳐져서 새로운 토큰을 만드는 경우를 제외하고.
2.6 단원의 celsius.c 프로그램에서도 int와 main 사이, float과 fahrenheit 사이 제외하고
다른 띄어쓰기는 대부분 제거할 수 있음.
사실, main 함수를 한 줄로 작성할 수도 있음.
그러나 프로그램의 모든 코드를 한 줄로 쓸 수는 없음.
전처리 지시자는 개별적인 줄을 필요로 함.
그리고 이런 식으로 프로그램을 압축하는 건 좋지 않음.
띄어쓰기와 줄내림은 가독성을 높이기 때문.
C에서는 토큰 사이에 얼마든지 빈 공간을 넣을 수 있음.
이 규칙은 프로그램 레이아웃에 몇 가지 중요한 결과를 가져옴.
○ 구문statements은 몇 개의 줄이던지 나눠질 수 있음.
예를 들어, 다음 구문은 너무 길어 한줄에 넣기 어려움.
printf("Dimensional weight (pounds): %d\n",
(volume + INCHES_PER_POUND - 1) / INCHES_PER_POUND);
○ 토큰 사이의 공간은 가독성을 높여줌. 따라서 각 연산자마다 띄어쓰기를 해주면 좋음.
volume = height * length * width;
쉼표 끝에도 띄어쓰기 해주면 좋음. 괄호나 구두점 사이에도 띄어도 됨.
○ 들여 쓰기는 원하는 곳에 정보 내포화nesting를 쉽게 해줌.
예를 들어, 선언과 구문 사이에 들여 쓰기를 해주면 그 안에 main 함수가 들어 있다는 게 잘 드러남.
○ 빈 줄은 프로그램 흐름을 논리적 순서의 단위로 구분케 하여 프로그램의 구조를 파악하기 쉬움.
빈 줄 없는 프로그램은 목차 없는 책과 마찬가지로 읽기 어려움.
celsius.c 프로그램도 이 가이드라인을 잘 따르고 있음.
1. 띄어쓰기를 통해 연산자 =, -, * 가 매우 잘 보임.
2. 선언과 구문이 main 함수에 속해 있다는 것이 매우 잘 보임.
3. main 함수를 5개의 흐름 단위로 나눠줌.
1) fahrenheit 과 celsius 변수를 선언
2) 화씨 온도 입력값 받는 부분
3) celsius 변수의 값 계산
4) 섭씨 온도 출력
5) 운영 체제operating system에 값 반환
{ 토큰을 main() 밑에 놔둔 점, } 토큰은 다른 줄에 배치한 점에 주목.
} 토큰을 다른 줄에 배치함으로써 함수의 끝에 구문을 입력하거나 삭제할 수 있게 됨.
{ 토큰과 세로로 나란히 배치함으로써 main 함수가 끝나는 부분을 더 잘 알아볼 수 있음.
그리고 띄어쓰기는 반드시 토큰 사이에서만 가능함. 토큰 내에서 띄어쓰기하면 의미가 변형됨.
이렇게 띄우거나
이렇게 띄우면 컴파일할 때 에러남. 그리고 문자열 리터럴 안에서 띄어쓰기를 하면
의미는 변해도 에러는 안 나지만, 개행 문자 \n을 넣으면 에러남.
문자열을 한 줄 이상에 걸쳐 적는 것continuing a string은 나중에 배울 것임.
Q&A
Q&A는 분량이 많아서 내가 기록하고 싶은 질의응답만 기록함.
Q: What does GCC stand for?
A: 원래 GNU C Compiler였는데 이제는 지원하는 언어가 많아져서 GNU Compiler Collection 됨.
Q: What's the big deal about GCC, anyway?
A: 일단 무료고, 여러 언어를 컴파일할 수 있고, 많은 운영체제에서 돌아감.
대부분 쓰는 코드부터 다양한 CPU에 알맞는 코드까지 알아서 만들어줌.
대부분의 UNIX 기반 운영체제(Ex. 리눅스 등)에서 쓰는 컴파일러임.
상업 소프트웨어 개발 목적으로도 많이 사용됨.
→ GCC의 운영 방식이 바뀌면서 상업 목적으로는 Clang이 많이 쓰임
Q: How good is GCC at finding errors in programs?
A: GCC는 에러를 잡기 위한 여러 command-line 설정이 있음. 대표적으로 ↓
-wall)
발생 가능한 에러를 찾아내면 컴파일러가 경고 메시지를 출력하도록 함
구체적인 경고문을 보고 싶으면 -w 을 쓰면 됨. -wall의 뜻 자체가 all -w options임.
효과를 최대로 보려면 -o와 함께 쓰면 됨.
-ansi)
C의 표준 규격이 아닌 GCC의 기능을 끄고 보통은 사용 불가능한 C의 규격 기능 몇 개를 열어줌.
더 많은데 안 적음.
Q: What happens if a program reches the end of the main function without executing a return statement?
A: return 구문은 의무적인 게 아님. 이게 없어져도 프로그램은 종료됨.
그리고 이 부분은 C89와 C99가 다른데, C89에선 운영체제에 반환되는 값이 정해지지 않음.
C99에서는(C11에서도) int main 함수에선 return 0; 안 써도 됨.
main 함수가 int를 반환하라고 선언하면(int main 함수), 반환값이 0으로 정의되어 있음.
그렇지 않은 경우에서는 return 0 안 쓰면 정해지지 않은 값을 반환함.
→ 그럼 왜 써야 하는가? 에러 없이 정상적으로 함수가 끝났다는 것을 운영체제에 알려주는 것임.
그럼 왜 0을 반환하는가? 운영체제의 쉘shell에서 0을 true로 간주하기 때문. 문제가 있으면 0이 아닌 값을 반환.
어디서 true값을 받는가? 운영체제의 에러 레벨Error Level에서 받음.
에러 레벨에 반환된 값은 윈도우에서 %ERRORLEVEL%이라는 환경 변수를 통해 확인할 수 있음.
참고글1: https://devcnix.tistory.com/1
Q: Why do floating-point constants need to end with the letter of f ?
A: 완전한 설명을 듣고 싶다면 Chap 7을 보면 됨.
짧게 답하자면, 소수점 자리를 포함하지만 f로 끝나지 않은 실수 상수는 double 형을 씀.
double은 '2배 정밀도double precision'의 약어이고, float 형보다 훨씬 정밀한 값을 가짐.
심지어 값이 더 클 수도 있기 때문에, 부동 소수점 변수에 값을 할당할 때 f를 붙여주는 것.
할당값에 f를 붙이지 않으면, float 변수가 저장 가능한 최대값보다 클 경우 에러가 날 수 있음.
Q: How many spaces should I use for indentation?
A: 정해진 건 없지만, 2~4칸 정도가 적당한 듯. 책에서는 2칸을 띄움.
'C' 카테고리의 다른 글
KNK Chap.3 (3.2) (1) | 2022.12.14 |
---|---|
KNK Chap.3 (3.1) (1) | 2022.12.07 |
KNK Chap.2 (2.5~2.7) (0) | 2022.12.03 |
KNK Chap.2 (2.4) (0) | 2022.12.02 |
KNK Chap.2 (2.1~2.3) (0) | 2022.12.02 |