: A variable declared in the body of function
int a;(함수 내부)
: Putting the word "static" in the declaration of a local variable
static int a;
(얘는 초기화할때 initializer가 constant여야한다. chapter 18.5)
Local Variable과 다른 점은, parameter는 함수가 호출될때 자동으로 initialize된다는 것 말고는 없다.
: A vriable that are declared outside the body of any function
함수들끼리 무조건 공유해야 하는 큰 변수가 있거나 하는 경우라면 external variable이 편하지만, 대부분의 경우에서는 그냥 함수들끼리 매개변수를 통해서 넘겨받도록 하는게 낫다.
왜냐하면
1. external variable을 수정해야 될 경우, 해당 변수를 사용하는 모든 함수를 다 점검해야한다.
2. external variable에 잘못된 값이 들어갈 경우, 어떤 함수에서 일어난 일인지 찾기가 힘들다.
3. external variable에 너무 의존하는 함수는 다른 프로그램에서 재사용하기 어렵다.
많은 프로그래머들이 external variable에 너무 의존한다. 특히 하나의 external variable을 다른 용도로 여러 함수에서 사용하는게 가장 많이 일어나는 남용이다.
external variable을 사용할 때는, 의미 있는 이름을 지어야한다. 만약 external variable에 i나 temp 같은 이름을 지었다면, 이는 local variable로도 충분히 쓰일 수 있다는 뜻이다.
{ declarations statements }
임시로 사용할 variable이 필요할 때 block이 유용하다.
Function body is Block.
(p.459, p.475)
추가로 selection statements와 iteration statements의 inner statemets도 Block이다.
왜냐하면..
compound literal이 조건문과 반복문 안에서 쓰일 때 생기는 비일관성 때문에 생긴 rule이다.
C99에서는 compound literal이 function 밖에서 만들어지면 static storage duration을 가지도록 하고 있다.(그게 아니면 automatic storage duration)
그렇기 때문에 함수 안에서 만들어진 compound literal을 그냥 return한다면 automatic storage duration이라 메모리에선 사라져도 값이 copy되므로 별 문제가 생기지 않지만, 해당 compound literal의 pointer를 return 한다면 함수가 끝날때 같이 사라지므로 문제가 된다.
이걸 조건문에서 보면
ex1)
double *a, value;
if (i == 1)
a = (double[3]) {0.5, 1.0, 1.5};
else
a = (double[3]) {1.5, 2.0, 2.5};
value = calcu(a);
ex1은 마지막에 a를 넘겨줄때 전혀 문제가 없다. 하지만,
ex2)
double *a, value;
if (i == 1) {
a = (double[3]) {0.5, 1.0, 1.5};
} else {
a = (double[3]) {1.5, 2.0, 2.5};
}
value = calcu(a);
이렇게 braces하나만 생겨도 맨 마지막 줄 함수 호출이 UB가 돼버린다.(ex2는 block을 사용했으니까 마지막 줄 실행할 때는 a가 가리키는 메모리가 어떻게 됐을지 모름)
이런 비일관성을 없애기 위해 C99에서는 조건문과 반복문 모두를 그냥 block으로 고려되도록 했다. 즉, ex1과 ex2 모두 UB인 것이다.
controlling expression에서도 같은 문제가 발생할 수 있기 때문에 거기까지 포함해서 전부 block처럼 처리한다.
즉, 조건문과 반복문 전체를 braces로 씌웠다고 생각하면 된다.
block이나 compound statement나 그게 그거인듯
위 내용은 그냥 if문 같은 애들은 전체에 braces 씌웠다고 생각하란거고
Scope rule : block 내에서 선언된 identifier의 이름이 already visible identifier의 이름과 같다면, 이전의 것을 "hide"한다. 그리고 block이 종료될 때 hide된 것이 다시 쓰일 수 있게 된다.
여러 C의 major elements들 간에 순서는 몇가지만 정의하고 있다.
1. preprocessing directive는 그 line이 나타날때까지는(그 line 위로는) 아무 효과가 없다.
2. variable은 쓰이기 전에 declare 해야 한다.
이정도..?
이렇게 자유를 좀 보장해주지만, 되도록 아래 순서에 맞게 쓰도록 (한 파일 안에서) 강하게 권장한다.
recursive function에서 static storage duration을 가진 변수가 있으면?
: automatic variable은 함수 호출 될 때마다 만들어지지만, static
이라면 recursive로 하든 그냥 호출을 하든 같은 static variable을 공유한다.
아래 code는 legal인가?
int i = 1;
void f(void) {
int j = i;
int i = 2;
}
indeed legal.
local variable의 scope는 선언 전에는 시작하지 않는다. 따라서 j에는 1이 저장된다.