모든 변수들은 블럭의 시작에 선언되어야 한다.
C언어는 함수를 사용하기 전에 함수를 선언해줘야 한다. (전방선언)
한 줄에 있는 피연산자들은 평가순서를 보장하지 않는다
함수 매개변수의 평가 순서는 컴파일러마다 다를 수 있다.
/* add(), substract(), divide() 코드 생략*/
int result = add(num1, num2) + substract(num1, num2) * divide(num1, num2);
위와 같은 코드에서 어떤 함수가 먼저 실행될지? 알수없다.
연산자 우선순위가 높은 함수가 먼저 호출될까? 관계없다.
다음 코드의 실행 순서는 어떻게될까?
if (++i || ++j && ++k)
||
, &&
연산자는 시퀀스 포인트 (실행 순서를 보장해주는 포인트)++i
|| ( ++j && ++k)
)true
|| (++ j && ++k)
)true
반환 종료한 함수의 매개변수들이 동일한 변수를 수정할 경우, 결과가 정의되지 않음
;
를 사용해서 명확히 순서를 정의하자./* 안 좋은 사용 예 */
int main(void){
int num = 10;
num = ++num + num++;
printf("num : %d\n", num);
}
i = ++i + i++;
i = i++ + 1;
array[i] = i++;
전역 변수
전역 변수는 어디서든 접근할 수 있다 (장점이자 단점)
스택 메모리에 들어가지 않고 데이터 섹션에 들어간다.
C 메모리 구조
스택 | 힙 | 데이터 | 코드 |
---|
extern
extern
extern
키워드는 다른 파일에 정의된 전역 변수들을 사용할 수 있게 해준다.extern
키워드를 붙여서 선언 하면 A 파일에 있는 전역변수에 접근할 수 있다.extern
변수를 선언해주고 해당 헤더를 include해서 사용하면 된다.static
extern
키워드 써서 접근하려고 해도 링커 오류 발생static
변수는 함수 내에서만 접근 가능하지만, 함수가 리턴되도 값이 초기화 되지 않는다. static
변수는 스택 메모리에 저장되지 않고 데이터 영역에 저장된다. const
상수를 선언할 때 붙이는 키워드로서 변수의 값을 변경할 수 없도록 한다.
변경하지 말아야할 변수를 변경하는 오류를 방지할 수 있다.
int calculate_risk(const int id){
int age = db_get_age(id);
int amount;
/* 코드 생략 */
id += 2; /* 컴파일 오류 */
/* 코드 생략 */
amonut = db_get_deposit_amount(id);
return amount;
}
goto
코드를 실행 후 특정한 위치로 이동해서 코드를 실행시키고 싶을 때 사용하는 키워드
goto <label_name>;
/* */
<label_name>:
goto
를 사용하는 코드 goto
goto
C언어는 배열요소의 값을 알아서 초기화해주지 않는다. (변수도 마찬가지)
배열의 모든 요소 0으로 초기화하는 best practice
int nums[10] = {0, } /* ,가 있어서 이해가 쉽고 가독성이 좋다. */
다차원 배열
아래의 두 배열은 실제 메모리 상에서 볼 때 똑같은 배열이다. 2차원 배열도 메모리 상에서는 순서대로 저장된다.
/* 2차원배열 */
int buffer[3][2];
int i;
int j;
for (i = 0; i < 3; i++){
for (j = 0; j < 2; j++){
buffer[i][j] = 0;
}
}
/* 1차원 배열 */
int buffer[3 * 2];
int i;
int j;
for (i = 0; i < 3; i++){
for (j = 0; j < 2; j++){
buffer[i * 2 + j] = 0;
}
}