Team Curio

비주얼 노벨 한국어 패치 팀 큐리오

프로그래밍

7.c 언어강좌 (4)

연이v 2009. 7. 4. 12:10
반응형
SMALL

=============================================================================
C 프로그래밍 4회
=============================================================================
이번 강좌 에서는 지역 변수와 전역 변수, 정적 변수 그리고 입출력 함수인 printf, scanf를 배워 보겠습니다.

1. 지역 변수
지역 변수란 어떤 한정되 지역 에서만 사용할수 있는 변수를 말합니다.
블럭 안에서 선언된 변수는 모두 지역 변수이고, 이때 이 블럭이라는 한정된 지역에서만 이 변수를 사용할수 있습니다.
그리고 지역 변수는 그 변수가 선언된 블럭이 끝나면 그 변수에 들어있는 값을 잃게 됨니다.
참고로 지역 변수를 선언할때는 블럭의 윗부분에 선언을 해야 합니다.
모든 작업 전에 선언해야 하죠.
그렇지 않으면 에러가 납니다.
예제 소스 하나를 보도록 하죠.
/* 파일 이름 : C4-1.C 프로그램 내용 : 지역 변수를 설명하는 프로그램. */
void main() { int a; { int b; a=5; b=10; } a=10; }
이 소스는 지역 변수를 설명하기 위한 간단한 소스 입니다.
우선 a라는 변수는 main함수의 블럭 안에 있으므로 지역 변수가 됨니다.
그러므로 main함수의 블럭 안에서만 사용 가능하죠.
그리고 main함수 안에는 또 블럭이 있습니다.
그리고 그 블럭 안에는 변수 b가 선언 되어 있는데 이것두 블럭 안에 있으므로 지역 변수가 되죠 또한 이거 역시 그 블럭 안에서만 사용할수 있습니다.
그런데 그 블럭에서 변수 a에 5를 대입하고 있는데 a는 이 블럭 밖에 선언되어 있죠..?
이렇게 블럭 밖에 있는 변수에 대해서는 모두 사용이 가능합니다.

2. 전역 변수
전역 변수는 지역 변수와는 다르게 한정된 지역이 아닌 모든 지역에서 사용이 가능한 변수를 말하는 것 입니다.
블럭 밖에서 선언된 변수는 모두 전역 변수 이죠.
그리고 전역 변수는 프로그램이 끝날때까지 들어있는 값을 계속 유지합니다.
그럼 예제 소스를
/* 파일 이름 : 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라는 변수 선언을 위에 해 주는 것이 좋겠죠?

3. 정적 변수
정적 변수에는 크게 두가지로 나눌수 있는데 정적 지역 변수와 정적 전역 변수 입니다.

(1) 정적 지역 변수
지역변수를 배울때 지역변수는 그 변수가 선언된 블럭이 끝나면 그 변수안에 들어있는 값을 잃는다고 했습니다. 그런데 이걸 잃게 하지 않을때 쓰는 것이 정적 지역 변수 입니다. 정적 지역 변수는 지역 변수 선언 앞에 static키워드만 붙여 주면 됨니다. 예를 들어 static int a; 이런 식으로 이렇게 해주면 이 변수가 선언된 블럭이 끝나도 그 안에 들어있는 값을 잃지 않죠.
/* 파일 이름 : C4-5.C 프로그램 내용 : 정적 지역 변수를 설명하는 프로그램. */
#include 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 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키워드를 붙여 전역 변수를 선언하면 즉 정적 전역 변수를 선언하면 외부 소스에서 이 변수를 엑세스 할수 없게 되죠 그게 정적 전역 변수의 주 목적 입니다.
그런데 외부 소스의 전역 변수 엑세스를 배우지 않았으므로 아직 이해가 되지 않으실 겁니다.
자세한건 나중에 배우기로 하고 넘어가죠.
이것으로 C언어의 데이터 부분은 마치도록 하죠.

4. 입출력 함수
이제 입출력 함수 2가지를 배워 보죠. 화면에 입출력 하는 함수로 가장 많이 쓰이는 것이 printf함수와 scanf함수 입니다. 이것들에 대해 자세히 공부해 보도록 하죠.

(1) 출력 함수
printf 화면 출력 함수중 가장 많이 쓰이는 printf함수를 배워 보겠습니다.
이 함수는 지금까지 예제 소스에 많이 나왔던 것 이지만 따로 배운적은 없습니다.
이제 그 printf함수에 대해 알아보죠.
printf함수는 stdio.h라는 헤더 파일에 정의되어 있습니다.
그리고 사용법을 간단히 본다면 다음과 같죠
printf(포맷문자열[,인수,인수..]);
여기서 포맷 문자열이란 출력하는 형태를 지정하는 문자열이고 인수는 출력할 내용들 입니다.
그럼 포맷문자열을 자세히 알아볼까요 포맷문자열을 구성하는 것은 일반 문자와 변환지정이 있습니다. 일반 문자에 대해서는 화면에 그냥 출력되게 됨니다.
예를 들어
printf("Example");
이렇게 하면 Example이 그냥 화면에 출력되죠 그런데 printf에서 중요한건 변환지정 입니다.
변환지정은 %로 시작합니다.
사실 변환지정은 정말 무지무지하게 복잡하지만 지금은 간단한 것들만 배우도록 하죠.
나머지는 나중에 더 자세히 배우기로 합시다.
사실 자세하게 알 필요도 없지만.. 변환지정은 간단히 %[크기]타입 이런 구조를 가진다고 보시면 됨니다. 우선 타입부터 배우도록 하죠 타입 지정은 여러가지가 있는데 다음을 보도록 하세요.
문자 인수 형태 출력
------------------------------------------------------------------
d 또는 i 정수 부호있는 10진 정수 u 정수 부호없는 10진 정수 o 정수 부호없는 8진 정수 x 정수 부호없는 16진 정수(a,b,c,d,e,f사용) X 정수 부호없는 16진 정수(A,B,C,D,E,F사용) f 소수 부호있는 소수([-]???.??형태) e 소수 부호있는 소수([-]???.??..e[+/-]???형태) g 소수 주어진 값에 따라.. f또는 e를 자동으로 선택.. E 소수 부호있는 소수([-]???.??..E[+/-]???형태) G 소수 주어진 값에 따라.. f또는 E를 자동으로 선택.. c 문자 1문자 s 문자열 문자열 % None %를 출력 p 포인터 포인터를 출력(????:????형태)
------------------------------------------------------------------
(e와 E의 차이는 지수 표시에 e를 쓰느냐와 E를 쓰느냐의 차이) 이것을 잘 읽어 보세요.
그럼 한가지 예를 들어 보죠. printf("%d",10); 이렇게 하면 10이 출력 됨니다.
물론 int a=10; printf("%d",a); 이렇게 해도 10이 출력되죠.
이런 식으로 다른 것들도 사용하면 됨니다.
printf함수는 직접 해보는 것이 가장 쉽게 배우는 방법입니다.
그런데 만약 long int형이라면 어떻게 출력할까요?
이런걸 지정하는 것이.. %[크기]타입 여기서 크기 입니다.
크기를 지정하는 문자는 2가지만 알아두도록 하세요.
h와 l두가지 말입니다. h를 써 주면 short int가 되고 l을 쓰면 long int가 됨니다.
예를 들어
short a=10; long b=20; printf("%hd",a); printf("%ld",b);
이럴때 사용합니다.
그리고 인수는 여러개일수도 있는데 변환지정이 여러개이면 인수도 여러개이어야 합니다.
예를 들어
printf("%d %c %f",10,'A',1.1);
이런 식으로.. 이제 예제 하나만 보죠
/* 파일 이름 : C4-7.C 프로그램 내용 : printf를 설명하는 프로그램. */
#include
void main() { int a=10; long int b=12345678;
float c=0.2934;
double d=0.193303944665433356;
char e='C'; char f[]="String";
printf("%d\n%ld\n",a,b);
printf("%f\n%e\n",c,d);
printf("%c\n%s\n",e,f); }
이 프로그램은 printf를 사용하여 여러가지 형태로 출력하는 프로그램인데 잘 보시면 금방 이해 되실 겁니다.
특별히 설명을 필요 없겠죠? 그럼 결과를 볼까요?
C:\>C4-7.EXE
10
12345678
0.293400
1.933039e-01
C String
C:\>

(2) 입력 함수
scanf scanf는 printf와 사용법이 매우 비슷 하지만, 출력용이 아니라 입력용 함수 입니다.
scanf함수 역시 printf함수와 마찬가지로 stdio.h라는 헤더 파일에 정의되어 있습니다.
사용법은 scanf(포멧문자열[,주소,주소..]); 이런식으로 알아두시면 편합니다.
printf와 똑같죠? 여기서 포멧 문자열은 입력받을 형태를 지정하는 문자열 입니다.
그리고 주소는 입력받은 데이터를 저장할 변수의 주소이죠.
그런데 변수의 주소는 어떻게 알수 있을까요?? 이건 사실 포인터를 베울때 베우는 건데 그냥 주소를 알아내는 방법만 가르쳐 드리죠.
어떤 변수의 주소를 알아낼때는 &연산자를 씁니다.
예를 들어 a라는 변수가 있다면, a의 주소는 &a가 됨니다.
그런데 문자열을 입력 받기 위해 문자 배열을 만들었을경우
예를 들어
char str[10];
이런 변수가 있을때는 str그 자체가 주소가 됨니다.
이유는 배열명은 배열의 시작 주소를 가지고 있기 때문이죠.
그러므로 이때만은 &str로 사용해서는 안됨니다.
그럼 포멧 문자열에 대해 자세히 알아보죠.
포멧 문자열을 구성하는 문자는 printf와 비슷한데.. 일반 문자와, 입력 지정 문자가 있습니다.
일반 문자는 그냥 입력 형태를 지정할때 쓰이는데 그냥 베우다 보면 아시게 됨니다.
그리고 입력 지정 문자는 printf에서와 완전히 똑같습니다. 모두 %로 시작하고 %[크기]타입 이런 구조로 되어 있죠 printf를 베울때 가르쳐 드렸지만.
그래도 다시 한번 타입 지정하는 문자들을 보여 드리죠. 문자 인수 형태 출력
------------------------------------------------------------------
d 또는 i 정수
부호있는 10진 정수
u 정수 부호없는 10진 정수
o 정수 부호없는 8진 정수
x 정수 부호없는 16진 정수(a,b,c,d,e,f사용)
X 정수 부호없는 16진 정수(A,B,C,D,E,F사용)
f 소수 부호있는 소수([-]???.??형태)
e 소수 부호있는 소수([-]???.??..e[+/-]???형태)
g 소수 주어진 값에 따라.. f또는 e를 자동으로 선택..
E 소수 부호있는 소수([-]???.??..E[+/-]???형태)
G 소수 주어진 값에 따라.. f또는 E를 자동으로 선택..
c 문자 1문자 s 문자열 문자열 % None %를 입력
p 포인터 포인터를 입력(????:????형태)
------------------------------------------------------------------
이것들을 한번 보시고.......
한가지 예를 들어 보죠.
만약 정수를 입력받고 싶다면 어떻게 할까요?
바로 int a; scanf("%d",&a); 이런 식으로 하면 되겠죠?
그럼 다음으로 넘어가서 입력 지정 문자의 %[크기]타입 이 형식에서 크기는 printf에서와 똑같은 의미 입니다.
크기 지정 문자는 h와 l이 있는데, h를 쓰면 short int를 입력 받을때 쓰는 것이고, l을 쓰면 long int를 입력 받을때 쓰는 것 입니다.
예를 들어 보면
short a; long b; scanf("%hd",&a);
scanf("%ld",&b);
이렇게 사용하는 것 이죠
scanf함수도 printf함수처럼 많이 사용해보는 것이 가장 쉽게 배우는 길 입니다.
그러므로 많이 연습해보시길 바랍니다.
scanf함수를 쓰면 여러가지 형태의 데이터를 쉽게 입력받을수 있습니다.
만약 1, 2, 3 이런 형식의 데이터를 입력받고 싶다면 포멧 문자열을 "%d,%d,%d" 이렇게 만들어 주면 됨니다.
int a,b,c; scanf("%d,%d,%d",&a,&b,&c);
이런 식으로 하면 되겠죠?
이정도면 scanf함수도 이해 하셨으리라 봅니다.
그리고 마지막으로 한가지 알아두실 점이 있는데 scanf로 문자열을 입력 받을때

char str[100]; scanf("%s",str);
이런 식으로 할 때 입력 받을 문자열에는 공백이 없어야 합니다.
scanf라는 함수로 문자열 입력을 받을때는 공백을 허용하지 않는다는 것 이죠.
만약 공백이 있을 경우 심각한 현상이 발생하는데, 직접 경험해 보시기 바랍니다..!
이것으로 이번 강좌를 마치겠습니다.
다음 강좌때는 기타 입출력 함수들을 배우고, 연산자 공부에도 들어가도록 하죠.
반응형

'프로그래밍' 카테고리의 다른 글

9.c 언어강좌 (6)  (0) 2009.07.04
8.c 언어강좌 (5)  (0) 2009.07.04
6.c 언어강좌 (3)  (0) 2009.07.04
5.c 언어강좌 (2)  (1) 2009.07.03
4.c 언어 강좌(초보프로그래머는 여길 먼저 공부하시길...)  (0) 2009.07.03