블로그 이미지
Starrysky1101

Tag

Notice

Recent Post

Recent Comment

Recent Trackback

Archive

calendar

1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
  • total
  • today
  • yesterday
2010. 11. 29. 09:46 Programming/C++
1. 출력을 하다보면 모양새 좋게.. 혹은 원하는 포맷으로 출력하고 싶을 때가 있다.

setiosflags

먼저 - http://www.cplusplus.com/reference/iostream/manipulators/setiosflags/
를 참고 하자.

위 링크에 아래쪽을 보면

See also


구문들이 있다.
이들도 보는 참고하는 것이 좋겠다.


cout.flags ( ios::left );



posted by Starrysky1101
2010. 11. 28. 02:08 Programming/C++
C++에서 ifstream으로 파일을 읽다가 다시 그 위치를 처음으로 돌리고 싶을때

가끔 is.seekg(0, ios::beg); 이게 먹히지 않는 경우가 발생한다.

처음에는 결국 해결 방법을 못 찾아서 파일을 닫고 다시 열어서 읽었던 기억이있다.

혹시나 다음과 같은 경우라면 해결 방법이 있다.

다음->     파일을 끝까지 읽어 EOF(End Of File) 까지 간경우 bad() state 이기 때문에 clear()를 seekg 전에 써줘야 한다.

-      data.clear();

-      data.seekg(0);

Since you've gone till the EOF, the stream is now in a bad() state. You need to clear() it before you can seekg():

Reference : http://www.gamedev.net/community/forums/topic.asp?topic_id=447865

posted by Starrysky1101
2010. 3. 28. 07:24 Programming/C++
 

이 글은 Visual Studio에서 프로젝트 작성시 #pragma once 가 붙는 이유의 궁금증에서 시작된 http://second815.tistory.com/entry/pragma-once-why-it-is-always-attached-when-we-making-new-class-file-in-visual-studio 글에서 시작된 관련 포스트이다.



Reference
:
원문
http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040101&docId=66305804&qb=I2lmbmRlZg==&enc=utf8&section=kin&rank=2&sort=0&spq=0&pid=fIH9fg331xCssaC5UHVssv--070546&sid=S652MnMdrksAAD-ZjGM

Abstract:

Ex Code :


자 하나씩 설명에 들어간다. 먼저 #define

#define WORD 1 = 이것은 WORD를 1로 치환
너무나 잘 알고있는 매크로 ..

그리고 궁극적으로 알고자 했던 명령어
#ifdef WORD
 printf("Hello, ");
#endif

 여기서 #ifdef WORD 라는것은
                              'WORD란 단어가 define가 되어있다면' 
즉 WORD란 단어가 위에서 #define WORD 으로 define되어 있으므로 참이 되고
그 다음줄 printf("Hello, ");가 실행

endif는 '{' 가 쓰이면 '}' 로 항상 닫아주는 녀석과 같은 역할을 한다!
#endif 
#ifdef 구문이 끝났음을 알림.

이 문은 #ifdef 나 #ifndef를 선언했을때 필수적으로 짝을 맞춰야 한다.
즉 #ifdef 를 한번 선언했다면 #endif 한번, #ifdef를 두번 선언했다면 #endif를 두번 선언해야
한다.

#ifndef .. 이걸 이용함으로써 컴파일러가 헤더파일을 두번 컴파일 하지 않게 한다!
 #ifndef WORD2 도 비슷.
이것은 #ifdef와는 반대로
                           'WORD2란 단어가 define되어 있지 않다면'
이란 뜻.
즉 WORD2란 단어는 위에서 #define에 의해 define된 적이 없으므로 참이되고
그 다음줄 printf("world/n");이 실행.

 #ifndef WORD
 printf("HaHa\n");

에서는 #ifndef WORD에서 WORD는 이미 define되어 있으므로 거짓이 되서
그 다름줄인  printf("HaHa\n"); 가 실행되지 않는다

즉 출력결과는 Hello world 가 된다!

posted by Starrysky1101
2010. 3. 28. 07:13 Programming/C++
#pragma once 를 쓰는 이유에 대해 포스팅했었다.
간단하게 이유를 설명하자면 여러개의 헤더파일과 cpp파일이 있을때
컴파일시 h파일을 중복되서 컴파일함을 없애주기 위해서이다.

http://second815.tistory.com/3  #pragma once 를 쓰는 이유

그러나 #pragma once는 표준이 아니다!

http://ptah.tistory.com/16
에서 다음과 같은 내용을 퍼왔다. 아래에 카피해두었다.

http://neodreamer.tistory.com/310
확실히 개념이 서질 않는다면 이 링크의 글을 읽어본다. 가장 명확한듯하다.


그전에  #ifdef, #ifndef, #endif 에 대해 알고싶다면
http://second815.tistory.com/5 를 읽어본다.



http://neodreamer.tistory.com/310 의 내용

보통 Visual Studio 계통의 소스에서는 #progma once를 자주 보게 됩니다.
그러나 GCC 계통의 소스에서는 보기가 힘들죠. (전 아직 뵌적이 없습니다.)

결론부터 말하자면 저라면 #ifndef 를 사용하겠습니다.
아직 #progma once는 표준이 아니기 때문이죠.
C99는 다음과 같은 표준을 가지고 있다고 합니다.

#pragma STDC FP_CONTRACT on-off
#pragma STDC FENV_ACCESS on-off
#pragma STDC CX_LIMITED_RANGE on-off

on-off := ON | OFF | DEFAULT

추가적으로 VS에서는 #progma가 컴파일 속도가 더 빠르다고 합니다.
#progma once를 만나자마자 건너뛰어서라는데 얼마나 빠를지는...

따라서 저의 경우 헤더에 다음과 같이 적습니다.

#progma once
#ifndef __ANY_THING__
#define __ANY_THING__
...
#endif






http://neodreamer.tistory.com/310의 내용

C++ 프로그래밍에서 헤더의 중복 #include 를 방지하는 방법으로 #pragma once 와 #ifndef 를 활용하는 방법이 있다. 이 두 방법은 모든 컴파일러에서 동작하는 것은 아니다.

우선 사용법을 보면 #pragma once 의 경우 헤더의 상단에 한번 적용 하면 된다.


그리고 #ifndef 를 활용하는 방법은 아래 처럼 define 이 되지 않았을 경우 지정된 값을 지정하여 이후에 다시 불러 들이는 것을 방지한다.


위 두 가지 방법은 여러가지 면에서 차이가 있다.

우선 첫 번째의 경우인 #pragma once 의 경우 컴파일러 지시자로 이를 한번 인식한 후 다음부터 같은 파일의 경우 파일을 읽기조차 하지 않는다. 그래서 컴파일 단계의 파일 해석 단계는 두 번째 방법보다 빠르다. 하지만 컴파일러 지시자로 특정 컴파일러에서만 동작을 한다. 이 지시자는 Visual C++ 5.0 이상에서만 동작을 한다.

두 번째의 경우 모든 컴파일러에서 동작을 하지만 헤더 파일을 여러번 include 를 할 경우 매번 헤더 파일을 열어서 define 여부를 확인해야 하기 때문에 컴파일 과정인 파일 해석 단계에서 첫 번째 방법보다 다소 느리다.

두 가지 방법은 속도와 호환성 문제가 얽혀 있는데 무지 큰 프로젝트가 아닐 경우 속도에서는 크게 차이가 나지 않을 것 같고 Visual C++ 에서만 작업하는 것이 아니라면 호환성을 고려하여 두번째 방법을 사용하는 것이 좋아 보인다.


posted by Starrysky1101
2010. 3. 28. 06:41 Programming/C++

#pragma once

Specifies that the file will be included (opened) only once by the compiler in a build. This can reduce build times as the compiler will not open and read the file after the first #include of the module.

For example,

// header.h 

#pragma once

 

C의 헤더 파일 최상단에서 자주 볼 수 있는 이 코드는 컴파일러에게 이 헤더 파일이 한번만 빌드되도록 알려주는 명령입니다.

 

왜 넣어야 하냐면, A.h라는 파일이 여러 곳에서 복잡하게 #include 되어 쓰이게 된다면 그때마다 각각 정의가 추가되게 되어 중첩되는 경우가 발생됩니다. 이 경우 중복 정의되었다는 에러가 발생하게 되지요. 즉 같은 내용이 여러번 빌드되게 되는겁니다. 이를 막기위해 #pragma once가 필요합니다. 물론 컴파일시간도 줄여주므로 대부분의 헤더파일에 추가하기를 추천합니다.

 

#pragma는 C언어에서 컴파일러에 직접 정보를 전하기 위해 사용합니다.

MSDN에서 발췌한 내용입니다.

posted by Starrysky1101
2010. 3. 14. 11:01 Programming/C++

이번 시간은 union(공용체)와 BitField에 대해서 알아보도록 하자.

예전에 번외편으로 Little Endian방식을 쓸때 구조체, union과 비트필드를 이용했다.

개별로는 많이 쓰이지 않기 때문에 이번시간에도 통틀어서 설명하겠다.

 

union에 대해서 간략하게 알아보자.

union은 공용체라고 불리운다.

선언 방식은 위의 코드처럼 전역으로 쓰이는 경우가 대부분이며, 구조체와 같은 형태를 가진다.

하지만 구조체와는 다른방식으로 데이터를 관리한다.

 

모든 공용체안의 멤버변수들은 같은 메모리 공간안에 자리를 잡고 쓰여지게 된다.

이걸 도식화해서 보기로 하자.

 

옆에 파란글씨고 써있는 부분이 도식화 할때 쓰인 코드다.

4Byte의 int형 iNum이란 변수 하나와 1Byte char형 ch란 변수

총 두개의 변수를 U란 공용체 안에 멤버로 선언했다.

메모리의 도식화는 저런 방식으로 된다.

공용체의 모든 멤버변수들은 같은 메모리의 공간을 공요하게 된다.

그래서 공용체의 크기는 제일큰 멤버변수의 DataType의 크기를 가지게 된다.

여기에서는 int형이 제일 커서 4Byte를 가진 공용체가 만들어 지는 것이다.

 

간략하게 공용체의 설명과 도식화를 보여드렸다.

 

자 이쯤에서 예제코드등장!

 

 

이제 이 소스코드를 보기로 하자.

제일 처음에 공용체 U를 선언했다 그리고 그 안에 구조체로 int형 변수 4개를 선언했다.

 

 

위의 코딩을 도식화 해보면 이렇게 나타나게 된다.

union안에는 Total이라는 int형 변수를 선언하고 구조체로 int형 변수를 4개 선언했다. 이때 주의할 점은, 구조체 안의 int형 변수는 각각 1Byte씩만 사용할수 있게 비트필드로 제한을 두었다. 비트필드란 변수의 특정비트만 사용할수 있게 만들수 있는 일종의 기법이다.

변수명 뒤에 " : 사용할 Bit수"를 적어주게 되면, 그에 해당하는 Bit만 사용할수 있게 된다. 여기서 보면 int형은 총 32Bit를 사용하지만 비트필드로 8Bit만 사용할수 있게끔 만들어 놓았다.

 

*BitField란! 하나의 메모리를 여러개의 Label을 붙여 쓰는것을 의미한다.

 

이게 뜻하는건 뭘까?

union안에 있는 Total이란 변수에 자료를 넣으면, 8Bit단위로 쉽게 꺼내올수 있다는걸 의미한다.

 

결과를 보도록 하자.

 

 

Ttotal 12345687를 넣었는데 union과 BitFIeld의 특성 때문에 1Byte씩 액세스 되는걸 볼수 있다.

숫자가 뒤집어 들어가는건 Little Endian때문인데, 그건 번외편을 보도록 하자.

 

공용체와 BitField는 이쯤에서 설명을 마치도록 하겠다.

많이 쓰이진 않지만, 주로 쓰이는 곳을 보자면, 위와 같은 특성때문에,

패킷연산이나, 고스톱알고리즘에 쓰이게 된다.

 

여기서 주의할점은 BitFiled가 진짜로 메모리에 어떻게 작용하는지 알려면,

#pragma pack(1)을 해주고 BitFiled가 정확히 메모리를 어떻게 쓰는지 알수 있다.

#pragma pack()의 기본 디폴트값은 4다.

예전에도 말했듯이 Intel CPU는 4Byte씩 메모리를 액세스 하기 때문에, 제대로된 내용을 파악하기 힘들다.

하지만 #pragma pack(1) 이것을 선언후에 하면 메모리 액세스를 1Byte씩 하게 된다.

그래서 정확한 BitField의 모습을 볼수 있다. 하지만, 액세스가 1Byte씩 일어나기 때문에, 전체적인

퍼포먼스가 떨어진다. 그래서 만약 실제 코딩때 쓴다면, 원래대로 #pragma pack(4), #pragma pack()

으로 돌려줘야 한다.

 

이쯤에서 이번장은 마치기로 하자.

뭔가 빨리 지나간 느낌이 있지만, 그만큼 드물게 쓰이기 때문에, 좀더 자세한 내용을 알고 싶다면,

따로 공부하시는걸 추천한다. 지금껏은 맛배기!


posted by Starrysky1101
2010. 3. 14. 07:09 Programming/C++



일단 기초적인 내용부터 파악해보자.
아래 코드는 C에서 가장 기초적인 static개념을 설명해줄 수 있는 코드이다.

#include 
void fct (void);
int main(void)
{
	int i;
	for(i=0;i<5;i++)
	{
		fct();
	}
	return 0;
	

}

void fct(void)
{
	static int val1 = 0;
	int val2 = 0;
	val1++;
	val2++;
	printf("Static val = %d\n", val1);
	printf("NOT Static val = %d\n\n", val2);
	
}




  



Result:

 Static val = 1
NOT Static val = 1

Static val = 2
NOT Static val = 1

Static val = 3
NOT Static val = 1

Static val = 4
NOT Static val = 1

Static val = 5
NOT Static val = 1


보다시피 static으로 선언된 값은 함수 호출시마다 val 값이 1식 증가하는데 반해
그냥 선언된 변수는 함수가 종료되면서 메모리상에서 사라짐에 따라 출력결과는 계속 1이 된다.

함수 내에 선언된 static 변수는 그 특성이 전역 변수와 비슷하다. 전역 변수는 메모리 공간을 할당받고 초기화가 이뤄지면
프로그램이 종료될 때까지 소멸되지도 않고 초기화도 두 번 다시 일어나지 않는다. static변수도 마찬가지이다.
비록 함수 내에 선언되어 있음에도 불구하고 그 특징은 전역 변수에 가깝다. 지역 내에서만 접근을 허용한다는 지역 변수의 특징을 제외하면 오히려 전역변수에 가깝다.

17번째 줄의 처음 호출시 static 변수 val1은 메모리공간을 할당받으며 0으로 초기화된다.
그러나 두번째 호출 시에는 17번째 줄은 완전히 무시되어 버린다. static변수는 한번만 초기화된다! 마치 전역변수처럼 말이다.

이 내용이 c에서 static변수의 기본적인 내용이다.
-------------------------------------------------------------------------------------------------------------------------
MAR/28/10 updated




extern 과 static 이 함수에 사용될때와 변수에 사용될때에 따라 구분해보자.

 

하나의 프로그램을 개발할때 하나의 파일만으로 개발하는것이 아니라, 여러사람이 여러개의

파일을 이용해서 개발할것이다. 즉, 여러파일로 개발을 하고 나중에 통합할때 이용될수 있겠다.

 

=== 함수일때

 

1. 함수에 사용될때  extern을 사용하면 다른 함수에서 해당 함수를 호출할수 있다. 이것은 디폴트 방식이기도 하다(아무것도 써주지않을때 기본적으로 extern 이다.) . 함수를 작성할때 extern 을 써주지 않아도, 다른 파일에서 해당 함수를 호출

할수 있는방식이다. 즉, extern 지정은 함수가 정의된 화일외에 다른 화일에서 함수의 호출을 허용한다.

 

2. static 지정을 하면 함수가 정의된 파일에서만 이 함수를 호출할수 있다. 즉 다른파일에서는

이 함수를 호출할수 없는것이다. 즉 여러파일에 같은 함수 이름이 존재한다고 해도 에러를 발생시키지 않는다는것이다.

 

 

=== 변수일때

 

3. 외부변수 (extern)는 함수밖에서 선언되어 선언된 시점이후 모든 함수에서 사용가능한 변수이다.

외부변수의 선언은 각 함수간에 자료를 공유하는 경우에 사용되는 변수이다.

 

4. 외부변수는 함수의 밖에서 선언되어 선언된 시점이후 화일의 끝가지 모든 함수에서 사용가능하고 프로그램의 종료시 까지 메모리에 할당되어 소멸되지 않는다.

 

5. 여러개의 파일을 이용해서 개발할때

AAA 파일에 int erp; 라는 변수가 외부변수라 선언되어 있다면

BBB, CCC 파일에서 erp 라는 변수를 사용하고 싶다면

BBB, CCC 파일에 extern 으로 선언한다. 이렇게 하면 erp라는 변수를 참조할수 있다. 이것을

BBB, CCC 에서는 extern int erp; 라고 해서 사용한다.

 

외부파일을 참조한다는것을 선언하면 메모리 할당은 하지 않고, 각 화일 간에는 자료를 공유하게 된다.

 

또한 참조를 함수내에서 하게되면 해당 함수내에서만 사용가능하다. 물론 외부참조를 하면

해당 파일내에서 전부사용가능하다.

 

즉, extern 이라고 한다면 자기파일이 아닌 다른파일에 외부변수로 선언되었다는것을 알수있고,

여기서는 그것을 사용하기만 하면된다.

 

me) 외부변수를 많이 사용하면 부작용(side-effect)가 발생할 확률이 높고, 함수간의 독립성을

저해시킬수 있다.

 

6. 정적변수(static)변수에도 내부 정적변수와 외부정적변수가 있다.

내부정적변수는 함수내부에 선언되어 사용되는 변수로서 자료의 값이 소멸되지 않고, 메모리에

영구적으로 존재하는 변수이다. 함수실행후에 값이 유지되기 때문에 이전값을 알수 있고, 모듈의 독립성을 보장을 위해 사용되는 변수이다.

 

void sum()

{

  static int sdt = 0; 처음에만 0 값이고 처음에만 초기화 되고, 다음함수에 들어올때는 초기화되지 않고 사용가능하다. 값이 유지된다.

 

7. 외부정적변수는 함수의 외부에 선언된 정적변수로서 해당 파일내에서만 사용가능하고, 전체

함수에서 사용될수 있는 변수이다. 다른파일에서는 사용불가능하다. 즉 외부 참조할수 없다.

그러므로, 다른 파일에 같은 이름이 존재하는 외부정적변수가 있더라도 서로 영향을 미치지 않는다.

 

B.======================================================================================

static 변수는 정적 변수하고 하고,
내부 static과 외부 static으로 나누어 집니다.
extern 변수와 static 변수는 한번 선언되어 지면
0 또는 null로 초기화 되어 있고,
그 프로그램이 끝날 때 까지 존재합니다.


내부 static 변수는
{,} (<-중괄호) 안에 선언되어 있는 static 변수이고
대부분 함수나 클래스 내에서 선언되어 있습니다.
선언되어진 그 함수나 클래스가 아닌
다른 함수에서는 사용이 불가능하다.

외부 static 변수는
함수 밖에서 선언된 static 변수입니다.
외부 static 변수는 함수 밖에서 선언되어 있지만
그 변수가 선언된 이후의 모든 함수 내부에서
접근, 사용이 가능합니다.



예)

static int a=23; // 외부 static 변수
void main()
{
printf("%d", a); // 이전에 a가 선언되었으므로 사용 가능
printf("%d", b); // 이전에 b가 선언되어 있지 않으므로 사용 불가능

sub1();
sub2();
}

void sub1()
{
static int b=45; // 내부 static 변수

printf("%d", a);
printf("%d", b);
}

void sub2()
{
printf("%d", b); // sub1에서 선언하였기 때문에 사용할 수 없다.
}

단,
void sub1()
{
static int a=3;

void sub2()
{
printf("%d", a); // 접근, 출력 가능
}
}
이런 경우는 sub1에서 선언되어 있지만
sub2는 sub1에 포함되어 있기 때문에
sub2에서도 a를 사용할 수 있다.




extern 변수는 외부 변수로
어떠한 static 변수가 선언되어 있지만
그 프로그램 전체의 파일이 한개가 아니고 여러개인 경우
사용된다.
만약 파일이 a.c와 b.c로 나뉘어져 있지만
전역변수를 a.c에서 선언하고 b.c에서 또 선언하면
나중에 link할 때 같은 변수를 여러번 선언했다고 오류가 난다.
이럴 때 extern 변수를 사용한다.



예)
// file a.c
int temp=12; // extern 변수 선언 - 실제로 메모리가 할당되는 부분은 이곳이다. temp는 static으로 선언한 것과 동일하다.

void main()
{
printf("%d", temp);

sub();
}

// file b.c
extern int temp; // 실제로 메모리가 할당되는 것이 아니고 함께 link되는 파일 중에 temp가 선언되어 있다고 표시만 하는 것이다.

void sub()
{
printf("%d", temp);
}

 

C.======================================================================================

지역 변수
지역 변수란 어떤 한정되 지역 에서만 사용할수 있는 변수를 말합니다.
블럭 안에서 선언된 변수는 모두 지역 변수이고, 이때 이 블럭이라는
한정된 지역에서만 이 변수를 사용할수 있습니다.
그리고 지역 변수는 그 변수가 선언된 블럭이 끝나면
그 변수에 들어있는 값을 잃게 됨니다.
참고로 지역 변수를 선언할때는 블럭의 윗부분에 선언을 해야 합니다.
모든 작업 전에 선언해야 하죠. 그렇지 않으면 에러가 납니다.
예제 소스 하나를 보도록 하죠.

/* 파일 이름     : C4-1.C
   프로그램 내용 : 지역 변수를 설명하는 프로그램. */
void main()
{
   int a;
   {
      int b;
      a=5;
      b=10;
   }
   a=10;
}

이 소스는 지역 변수를 설명하기 위한 간단한 소스 입니다.
우선 a라는 변수는 main함수의 블럭 안에 있으므로 지역 변수가 됨니다.
그러므로 main함수의 블럭 안에서만 사용 가능하죠.
그리고 main함수 안에는 또 블럭이 있습니다.
그리고 그 블럭 안에는 변수 b가 선언 되어 있는데
이것두 블럭 안에 있으므로 지역 변수가 되죠 또한 이거 역시 그 블럭 안에서만
사용할수 있습니다.
그런데 그 블럭에서 변수 a에 5를 대입하고 있는데
a는 이 블럭 밖에 선언되어 있죠..?
이렇게 블럭 밖에 있는 변수에 대해서는
모두 사용이 가능합니다.


전역 변수
전역 변수는 지역 변수와는 다르게 한정된 지역이 아닌 모든 지역에서
사용이 가능한 변수를 말하는 것 입니다.
블럭 밖에서 선언된 변수는 모두 전역 변수 이죠.
그리고 전역 변수는 프로그램이 끝날때까지 들어있는 값을
계속 유지합니다.
그럼 예제 소스를

/* 파일 이름     : C4-2.C
   프로그램 내용 : 전역 변수를 설명하는 프로그램. */
int a;
void func()
{
   a=5;
}
void main()
{
   func();
   a=10;
}

이 소스에서 모든 블럭 밖에 a라는 변수가 선언되어 있으므로
a는 전역 변수 입니다.
그러므로 어느 곳에서든지 사용이 가능하죠
소스에소 볼수 있는것 처럼 a라는 변수는 main함수와 func라는 함수에서
모두 사용할수 있습니다.
그러면 에제 하나를 더 볼까요?

/* 파일 이름 : C4-3.C 프로그램 내용 : 전역 변수를 설명하는 프로그램. */
void func() { a=5; }
int a;
void main() { func(); a=10; }

이 소스는 위에 것과 똑같지만 전역 변수 선언을
func함수와 main함수 사이에 한 것 입니다.
전역 변수를 쓰려면 그 변수가 그것을 쓰는 부분의 위쪽에
선언되어 있어야 합니다.
func함수 안에서 a를 사용하고 있는데 a는 그 아래에 선언되어 있죠?
이럴땐 func함수 위에 a라는 전역 변수가 있다는 것을 알려주면 됨니다.
방법은 간단한데
extern 데이터형 변수명;
이렇게 해 주면 됨니다.
아까 그 소스를 고쳐보면

/* 파일 이름     : C4-4.C
   프로그램 내용 : 전역 변수를 설명하는 프로그램. */
extern int a;
void func()
{
   a=5;
}
int a;
void main()
{
   func();
   a=10;
}

이렇게 해 주면 간단히 해결 되죠 하지만 특별한 경우가 아니라면
a라는 변수 선언을 위에 해 주는 것이 좋겠죠?


정적 변수
정적 변수에는 크게 두가지로 나눌수 있는데 정적 지역 변수와
정적 전역 변수 입니다.
(1) 정적 지역 변수
지역변수를 배울때 지역변수는 그 변수가 선언된 블럭이 끝나면
그 변수안에 들어있는 값을 잃는다고 했습니다.
그런데 이걸 잃게 하지 않을때 쓰는 것이 정적 지역 변수 입니다.
정적 지역 변수는 지역 변수 선언 앞에 static키워드만 붙여 주면 됨니다.
예를 들어
static int a;
이런 식으로 이렇게 해주면 이 변수가 선언된 블럭이 끝나도
그 안에 들어있는 값을 잃지 않죠.
/* 파일 이름     : C4-5.C
   프로그램 내용 : 정적 지역 변수를 설명하는 프로그램. */
#include <stdio.h>
void func()
{
   int a=0;
   a=a+1;
   printf("%d\n",a);
}
void main()
{
   func();
   func();
   func();
}

이 프로그램의 실행 결과는 어떻게 될까요?
C:\>C4-5.EXE
1
1
1
C:\>
이렇게 나옴니다. 왜 그런줄은 다 아실꺼에요.
그런데 여기서 func함수 내의 a변수를 정적 변수로 선언하면

/* 파일 이름     : C4-6.C
   프로그램 내용 : 정적 지역 변수를 설명하는 프로그램. */
#include <stdio.h>
void func()
{
   static int a=0;
   a=a+1;
   printf("%d\n",a);
}
void main()
{
   func();
   func();
   func();
}
이렇게
그러면 결과는 어떻게 바꿜까요????
a라는 변수는 func함수가 끝나도 그 안의 값이 보관 되므로
C:\>C4-6.EXE
1
2
3
C:\>

이런 결과가 나오겠죠?
이제 정적 지역 변수에 대해서는 이해가 되셨죠??

(2) 정적 전역 변수
정적 전역 변수를 하기 전에 한가지 의문정이 생기실 겁니다.
변수는 프로그램이 끝날때까지 그 값이 유지되는데
정적 전역 변수라는게 왜 따로 있을까요???
사실 정적 전역 변수와 정적 지역 변수의 의미는 크게 다름니다.
static키워드를 붙여 전역 변수를 선언하면
즉 정적 전역 변수를 선언하면
외부 소스에서 이 변수를 엑세스 할수 없게 되죠
그게 정적 전역 변수의 주 목적 입니다.

 


posted by Starrysky1101