Chapter 10. Program Organization

지환·2021년 11월 21일
0
post-custom-banner

10.1 Local Variables

Local Variables

: A variable declared in the body of function
int a;(함수 내부)

  1. Automatic storage duration : 함수(block)가 호출될때 allocate되고, 함수(block)가 종료되며 deallocate된다.
  2. Block scope : 선언될 때부터 함수(block)가 종료될때까지만 reference 할 수 있다.

Static Local Variable

: Putting the word "static" in the declaration of a local variable
static int a;
(얘는 초기화할때 initializer가 constant여야한다. chapter 18.5)

  1. Static storage duration : 프로그램이 종료될때까지 값을 유지한다.
  2. Block scope

Parameters

  1. Automatic storage duration
  2. Block scope

Local Variable과 다른 점은, parameter는 함수가 호출될때 자동으로 initialize된다는 것 말고는 없다.


10.2 External Variables

External Variables(Global Vriables)

: A vriable that are declared outside the body of any function

  1. Static storage duration
  2. File Scope : 선언될 때부터 파일이 끝나는 지점까지(to the end of the enclosing file) reference 할 수 있다.

Pros and Cons of External Variables

함수들끼리 무조건 공유해야 하는 큰 변수가 있거나 하는 경우라면 external variable이 편하지만, 대부분의 경우에서는 그냥 함수들끼리 매개변수를 통해서 넘겨받도록 하는게 낫다.
왜냐하면
1. external variable을 수정해야 될 경우, 해당 변수를 사용하는 모든 함수를 다 점검해야한다.
2. external variable에 잘못된 값이 들어갈 경우, 어떤 함수에서 일어난 일인지 찾기가 힘들다.
3. external variable에 너무 의존하는 함수는 다른 프로그램에서 재사용하기 어렵다.

많은 프로그래머들이 external variable에 너무 의존한다. 특히 하나의 external variable을 다른 용도로 여러 함수에서 사용하는게 가장 많이 일어나는 남용이다.

external variable을 사용할 때는, 의미 있는 이름을 지어야한다. 만약 external variable에 i나 temp 같은 이름을 지었다면, 이는 local variable로도 충분히 쓰일 수 있다는 뜻이다.


10.3 Blocks

{ 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 씌웠다고 생각하란거고

10.4 Scope

Scope rule : block 내에서 선언된 identifier의 이름이 already visible identifier의 이름과 같다면, 이전의 것을 "hide"한다. 그리고 block이 종료될 때 hide된 것이 다시 쓰일 수 있게 된다.


10.5 Organization a C Program

여러 C의 major elements들 간에 순서는 몇가지만 정의하고 있다.
1. preprocessing directive는 그 line이 나타날때까지는(그 line 위로는) 아무 효과가 없다.
2. variable은 쓰이기 전에 declare 해야 한다.
이정도..?
이렇게 자유를 좀 보장해주지만, 되도록 아래 순서에 맞게 쓰도록 (한 파일 안에서) 강하게 권장한다.

  1. #include directives
  2. #define directives
  3. Type definitions
  4. Declarations of external variables
  5. Prototypes for functions other than main
  6. Definition of main
  7. Definitions of other functions
    + precede each function definition by a boxed comment(함수에 대한 설명)

Q&A

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이 저장된다.

post-custom-banner

0개의 댓글