활동 목표: C언어 표준 문법과 함수 및 라이브러리 학습
활동 결과
1. C언어 표준 문법
표준 문법이라고 표기를 해두었는데 사실은 코딩 규칙에 관한 것을 학습하고 싶었다.
함수나 변수 명명법이나 들여쓰기 등에 관한 규칙 말이다.
언어마다 각 언어에 맞는 스타일대로 코드를 작성하는 것 또한 중요하기 때문이다.
- 작성법
프로그램의 시작은 main 함수를 호출하여 시작한다.
블록 구조({}) 를 사용하며 문장 단위로 세미콜론(;)을 사용하여 끝맺는다.
- 명명법
영문자와 숫자의 조합으로 만든다.
명칭의 첫 문자는 문자나 언더바(_)여야 한다.
특수문자를 사용하면 안 된다.(단, 언더바(_)는 사용 가능)
문자 사이에 공백이 있으면 안 된다.
예약어를 사용하면 안 된다.
영문자 대문자와 소문자는 구분되어 사용된다.
명칭의 길이는 컴파일러에 따라 제한이 있다. (일반적으로 32자까지 가능)
변수: 모두 소문자로 적으며 단어 사이에 언더바(_)를 적는다.
전역변수: g_와 같이 구분할 수 있는 접두어를 붙인다.
상수 이름: k라는 접두어를 붙여 구분할 수 있고 매 단어의 첫 번째 글자를 대문자로 적는다.
함수 이름: 대문자로 시작하고 매 단어의 첫 번째 글자를 대문자로 적으며 언더바(_)를 사용하지 않는다.
매크로 이름: 대문자와 언더바만 사용한다
- 주석
한 줄 주석: //
여러 줄 주석 /* */
2. 함수 및 라이브러리
여기에서도 라이브러리라고 명칭을 하였는데 실제로 궁금했던 내용은 전처리기 혹은 선행처리기에 대한 내용이었다. 물론 이는 비슷한 내용이기 때문에 라이브러리를 설명하기 위해 전처리기 혹은 선행처리기에 대해 설명해야 한다.
-전처리기 혹은 선행처리기(preprocessor)
1회차 때 #include <stdio.h>와 헤더 파일에 대해 설명하면서 나왔던 내용에서 조금 더 깊게 들어가보자
#include 구문에서 #으로 시작하고 왜 세미콜론(;)을 사용하지 않을까?
또한 main 함수 안에 있지도 않다. 그러면 프로그램이 실행되지 않는 것 아닐까?
#으로 시작하는 이 구문은 전처리기 혹은 선행처리기라고 부르며 컴파일 이전에 실행되는 것이다.
#include - 파일
#defind - 매크로
#if, #else, #elif, #endif - 조건부 컴파일
#include를 통해 헤더파일을 가져올 수 있다. <stdio.h>, <math.h>
여기서 의문점이 생길 수 있다. 헤더파일을 가져오는데 헤더파일은 정확히 무엇이고 파이썬에서는 라이브러리를 불러와서 사용하면 됐는데 여기선 왜 헤더파일을 불러오는지.
헤더 파일이란 함수의 존재를 컴파일러에게 알리는 역할이다. 1회차 때 #include <stdio.h> 없이 printf 함수를 사용했을 때 printf를 이해하지 못했던 것처럼 헤더파일을 가져오지 못했다면 컴퓨터가 그 함수의 존재를 몰라 컴파일이 되지 않는다.
그러면 라이브러리는 어디서 쓰일까?
컴파일이 완료되고 링크 과정에서 라이브러리를 불러온다.
#define을 통해 매크로를 설정할 수 있다.
매크로는 무엇이냐 하면, 변수와 비슷한 느낌이다.
#include <stdio.h>
#define NAME "홍길동"
#define mul(a, b) (a * b)
int main(){
printf("%s\n", NAME);
printf("%d", mul(2, 3));
return 0;
}
어? 그러면 변수는 왜 쓰나요?
변수는 값이 변할 수 있지만 위 매크로는 변하지 않는다.
하지만 C에서는 Python과 달리 상수 선언(const(리터럴))이 존재한다.
그러면 상수는 왜 쓰나요?
하지만 여기서도 구분지은 데에는 이유가 있을 것이다.
const에 저장되면 타입을 체크할 수 있고 그 값은 메모리에 할당된다. 또한 디버깅에 용이하다.
하지만 define은 타입을 체크할 수 없고 디버깅이 불가능하다. 하지만 define은 메모리에 저장되지 않아 메모리를 절약할 수 있고 속도가 빠르다.
이유는 define은 전처리기이기 때문에 컴파일 이전에 실행된다는 점에서 이점이 있는 것이다. 하지만 그렇기에 단점도 명확하고 메모리를 아끼는 것 보다 코드의 유지 보수를 중요시하게 생각하는 현대적 입장에서는 const를 주로 사용한다.
#if, #elif, #else, #endif 를 통해 조건부 컴파일을 진행할 수 있다.
말 그대로 조건에 부합하면 컴파일을 할 수 있다는 의미이다.
#include <stdio.h>
#define VERIFY 1
int main(){
#if VERIFY
printf("1번 컴파일");
#else
printf("2번 컴파일");
#endif
}
>> 1번 컴파일
#endif는 조건부 컴파일 구문이 끝났다는 것을 표시해주는 부분이다.
조건부 컴파일은 디버깅, 성능 향상 등 여러 점에서 큰 이점을 제공할 수 있다.
void main(), int main() 차이점
앞서 설명하던 것에서 좀 벗어나긴 했지만 함수에 관련한 학습에서 매우 궁금해서 찾아보았다.
여러 코드를 찾아보지만 int main으로 쓰는 사람도 있고 void main으로 쓰는 사람도 있다.
맨 처음에 접한 것은 int main이었다. 이는 return 0;으로 작성되었기 때문에 return값이 0으로 되어있으니까 int로 해두었구나 라고 예상하였다.
예상 결과대로 0으로 리턴하므로 int를 사용하는 것이다. return 0;을 쓰지 않더라도 코드 상으로 작동은 하지만 명시적으로 쓰는 것을 권장하는 것이다. 하지만 반환 값이 없는데도 굳이 작성을 해야 하므로 원칙적으로 return 0; 을 작성하지 않는것은 잘못된 코드이다. 따라서 return 0; 을 작성하지 않기 위해 void main이라고 작성하면 되는 것이다.
하지만 C언어 표준에서는 main 함수에서 int 0 을 return하라고 명시하고 있다.
표준대로 써야지!
'모각코' 카테고리의 다른 글
[2025 하계 모각코] 5회차 결과 - 구조체 (3) | 2025.07.29 |
---|---|
[2025 하계 모각코] 4회차 결과 - 메모리 구조와 동적 메모리 할당 (2) | 2025.07.24 |
[2025 하계 모각코] 3회차 활동 결과 - C언어 포인터 (3) | 2025.07.22 |
[2025 하계 모각코] 1회차 활동 결과 - C 언어 개발환경 및 기본 문법 (1) | 2025.07.15 |
[2025 하계 모각코] 모각코 활동 계획 (0) | 2025.07.14 |