[C89] C언어 기본 문법
목차
1. 헬로월드
2. C언어의 기본 문법
2-1. 다양한 것
2-2. 스택 메모리
헬로월드
#include
#include의 동작 방법
C의 #include는 헤더 파일(*.h)을 열어서 그 내용을 복붙
main(void) 함수
C 코드를 빌드해서 나온 실행파일(.exe 또는 .out)을 실행하면 자동으로 실행(프로그램의 진입점)
반드시 int 반환 -> return 0; /* 프로그램에 문제가 없었다는 뜻 */
프로그램 종료 코드 확인하기
- echo %errorlevel%(윈도우 CMD 기준)
- $ echo $?(Shell)
C언어의 기본 문법
기본 자료형

signed가 기본(char는 예외)
unsigned는 사용하려면 명시해줘야함
char
최소 8비트
1바이트 = CHAR_BIT(char 크기)
ASCII 문자(0~127인 숫자) 표현 충분
기본이 signed/unsigned인지 컴파일러 구현에 따라 달라짐
이유?
ASCII는 부호 상관없이 표현 가능
단, 8비트 정수형으로 쓸 때는 signed나 unsigned 넣어주는 게 좋음

short
최소 16비트 && sizeof(char) <= sizeof(short)
안전 범위
크기: 16비트
범위:
- 부호 없는 경우: 0 ~ 65535
- 부호 있는 경우: -32768 ~ 32767
int
최소 16비트 && sizeof(short) <= sizeof(short)
왜 최소 16비트?
int는 그냥 '정수'라는 의미
CPU가 딱 아는 크기 = 워드 크기
예전에는 16비트 CPU가 흔했음 그래서 최소 16비트
32비트 컴퓨터가 나오면서 int 크기는 32비트가 됨
안전 범위
크기: 32비트
범위:
- 부호 없는 경우: 0 ~ 4294967295
- 부호 있는 경우: -2147483648 ~ 2147483647
리터럴
부호 있는 수의 최댓값보다 큰 값을 unsigned int에 대입할 경우 U를 붙여야함
long
포팅 안전 범위: -2147483648 ~ 2147483647
int와 같음
float
32비트
double
64비트
long double
크기는 컴파일러마다 다른데 대충 위의 크기 안전
셋다 unsigned형 없음 -> 접미사 u 안씀
리터럴 UL
bool
없음
0이면 false, 0이 아니면 true
enum
int와 섞어서 사용 가능
int -> enum, enum -> int, enum -> 또 다른 enum
C에서 열거형은 그냥 정수에 별명 붙이는 수준
enum color { COLOR_BLACK, COLOR_WHITE, /* 생략 */ };
enum day { DAY_MONDAY, DAY_THESDAY, /* 생략 */ };
enum day hump_day = DAY_WEDNESDAY;
enum color favorite_color = hump_day /* 컴파일 됨 */
sizeof()
함수 아님 연산자임(피연산자의 크기를 바이트로 반환)
- 컴파일 도중 찾음(컴파일 할 때 모르는 크기는 못찾음)
- size_t 반환(보통 unsigned int)
비트패턴 -1 반환
signed int -1 = unsigned int 4294967295
size_t get_students_index(const char* name)
{
if(!/*조건*/) {
return (size_t)-1;
}
return 올바른_인덱스;
}
switch/case 문
- case에 정수형(int, char, enum)만 가능
- break 빼먹으면 -> fall-through
주의 사항
fall-through 의도한 거면
/* intentional fallthrough */ 주석 달아주기
함수
- C의 함수는 기본적으로 모두 전역 함수
- 오버로딩 안됨
- 함수 선언 -> 링크: 선언 없으면 C89 컴파일러는 int 반환한다고 가정
평가순서
- 한 줄에 있는 피연산자들은 기본적으로 평가 순서 보장 X
예외
- &&
- ||
- 삼항 연산자
- ;
파일 범위
- 블록, 매개변수 목록에 안 속하고 파일 안에 있는 것
- 스택X, 데이터 섹션에 들어감

goto
베스트 프랙티스
- 아래쪽으로만 점프
- 내포된 루프에서 빠져나올 때
- 한 함수 안에 있는 여러 개의 조건문이 공통된 코드를 실행해야 할 때
배열
스택 메모리
- 함수의 지역 변수 등을 임시적으로 저장하는 공간
- 스택 메모리의 크기는 프로그램 빌드 시에 결정
- 스택 메모리의 위치는 실행 시에 결정

- 기본 자료형을 함수 매개변수로 전달하면 스택에 복사본을 만듦 -> 이게 바로 값형
- new로 만든 데이터는 힘 메모리에 할당
배열을 매개변수로 전달할 때는 셀제 모든 요소를 스택에 넣지 않음
배열의 시작 위치(주소)를 넣어줌
매개변수에 배열의 길이를 명시해 주면?
void process(int nums[5])
{
size_t i;
for(i = 0; i < 5; ++i) {
nums[i] *= 2;
}
}
- 이건 그냥 프로그래머의 가독성을 위한 것
- 컴파일 하면 void process(int nums[])와 동일
그러면 함수에서 배열의 요소에 접근하려면 길이를 알아야하는데 이건 어찌앎?
- 다음처럼 배열의 길이 n을 매개 변수로 받아야함
void process(size_t n, int nums[])
{
size_t i;
for(i = 0; i < n; ++i) {
nums[i] *= 2;
}
}
배열 초기화
- C는 배열 요소의 값 초기화 안해줌 -> 그전에 그 메모리에 남아있던 값 그대로 사용(쓰레기 값)
- 직접 초기화 해야함
int nums[10] = { 0, };
버퍼 오버플로도 조심
다차원 배열
1차원 vs 2차원 vs 3차원 (메모리)
메모리상에선 똑같음