변수나 함수의 사용시 특정 모듈이 아닌 프로그램을 구성하는 모든 모듈에서 한 전역 변수 / 전역 함수를 접근 할 수 있도록 지정자 (specifier)를 사용할 수 있고, extern을 사용해서 이 선언을 할 수 있습니다.

 

예를 들면 아래처럼 두 개의 파일이 각각 있습니다.

 

Main.c 파일

 

extern int value = 0;

 

Int main( void)

{

value = 3;

}

Ex.c 파일

 

void Print_data( void)

{

Printf("%d", value);

}

 

Main.c에서 선언된 value파일은 원래는 main.c 파일에서만 사용이 가능하지만, extern선언을 통해서 ex.c 파일에서도 사용이 가능하게 됩니다.

 

Posted by 고무함지
,

 

 

Static 변수는 변수 선언 시 앞에 static을 추가하여 선언하여 사용하며, 다음과 같은 특징이 있습니다.

 

  1. 선언 위치는 지역변수와 같을 수 있다.
  2. 특정 선언 지역에서만 접근 할 수 있다.
  3. 메모리 저장공간에서 변수의 저장 공간은 전역변수와 그 위치가 같다.
  4. 초기값을 주지 않을 경우 항상 0으로 초기화 되며, 프로그램을 실행 시킬 때 단 한 번만 초기화 된다.

 

아래와 같은 코드가 있다고 가정하면서 위의 static의 특징을 살펴보겠습니다.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

void call();

   

int main()

{

    call();

    call();

    call();

    return 0;

}

   

void call(void)

{

    static int count = 0;

    count ++;

    printf("%d ", count);

}

cs

 

 

위의 call함수에서 static int count라는 변수가 선언되었습니다. 4번에 의하면 초기화는 딱 한 번만 하므로, main문에서 3번 call이 호출되었다고, 매번 count가 0으로 초기화 되지는 않습니다. 이 점을 주의해야 합니다.

 

또한, 2번의 특징처럼 count라는 변수는 선언이 된 call함수에서만 사용이 가능하며, 다른 위치에서는 사용을 할 수 없습니다. 만약 다른 함수에서 사용하고 싶다면, global변수처럼 main문 밖에서 선언하게 되면, main에서도 call에서도 사용이 가능합니다. 그래서 선언 위치는 자유롭지만, 그에 따른 제약에 주의가 필요합니다.

 

3번의 설명처럼 전역변수와 변수의 저장 공간이 같습니다.

 

 

이러한 특징을 토대로 결과 값은

1 2 3 이 나오게 됩니다.

 

만약 call에서 static int count 대신…. int count로 일반 변수로 선언되었다면, (static이 아니라)

값은 1 1 1 이 됩니다.

 

이러한 static의 특징 때문에 저의 경우는 static으로 선언 한 것은 어떤 동작의 count를 하는 목적으로 사용하고 있습니다. 예를 들면 특정 동작이 몇번 반복되었는지를 기록하여, 그에 따른 처리를 할 때 static int count라는 변수를 만들어 그 동작을 기록하도록 합니다.

   

  

Posted by 고무함지
,


포인터 연산자의 경우 다른 연산자와 같이 사용되면, 정말 이해하기 힘들어집니다.

저도 이런 상황에서 항상 잘못 이해해서 오류를 만들곤 했습니다.

 

아래의 예는 사실 이렇게 혼란스럽게 사용하면 안 되지만, 일부로 공부를 위해 극단적인 예를

들어서 설명하려 합니다.

 

1

2

3

4

5

6

7

8

9

int array[5={1020304050};

int * p = array + 3;  // array의 3번째 항목의 주소를 대입. 즉 {40, 50}

   

++*p++;

   

printf("%d \n"*p);

   

// 과연 다음의 값은 어떻게 될까요?

   

Colored by Color Scripter

cs

 

 

여기서 프린트 되는 값은 "50" 입니다.

 

이유를 설명하기 전에, 연산자 우선 순위에 대해 알고 있어야 합니다.

아래의 연산자 우선 순위(c언어 기준) 를 보면, '++(후위증가)' 연산자가 2 순위이며,

'++(전위증가)'와 '*' 우회(역참조)연산자가3순위입니다.

즉 2 순위를 먼저 해석해야 하며, 2 순위의 경우 … 결합 법칙상 왼쪽먼저

해석을 진행합니다. 그러나 p의 왼쪽엔 후위증가 연산자가 없으므로,

P의 오른쪽의 후위증가 연산자를 해석합니다.

그러면, ++*p++ 을 해석의 순서대로 나눠 보면…

 

++*p++ // 1. ++ 후위 증가를 한다.

++*p++ // 2. p++라는 값이 후위 증가가 된다. p는 {40, 50}을 가르키는 포인터이므로,

포인터 값이 증가된다면, { 50 } 을 가리키게 됩니다. 다만…. 후위 증가이므로, 현재라인에서는

변화가 없고, 아래 print문에서 변경사항이 적용됩니다.

 

// 3. 이제 나머지 3순위 연산자를 해석해봅니다. 3순위의 경우 오른쪽에서 왼쪽으로 해석합니다.

++*p++ // 3. *p …p가 가르키는 값이므로, { 40 }이 됩니다. 이 값을 ++ 전위 증가를 합니다.

그러면, 40은 1이 증가됩니다. (포인터의 주소값이 증가되는 것이 아니라, 그 값이… 증가됨)

그러므로, 41이 됩니다.

 

코드에 주석으로 각 라인마다 결과를 보면 아래와 같게 됩니다.

1

2

3

4

5

6

7

int array[5={1020304050};

int * p = array + 3;  // array의 3번째 항목의 주소를 대입. 즉 {40, 50}

   

++*p++;   // p는 {41, 50} 

   

printf("%d \n"*p);  // p는 { 50 } , array[5]는 { 10, 20, 30, 41, 50} 

   

Colored by Color Scripter

cs

 

역시나 그래도 어렵고 복잡하긴 한데,

연산자 우선 순위를 이해하는 것을 공부하기에 좋은 문제 인 듯합니다. ^^

 

< 출처 : wiki https://ko.wikipedia.org/wiki/C%EC%99%80_C%2B%2B%EC%97%90%EC%84%9C%EC%9D%98_%EC%97%B0%EC%82%B0%EC%9E%90 >

Posted by 고무함지
,