2011-1 학기프로그래밍입문 (1) chapter 06-5 참고자료 변수의영역과데이터의전달 박종혁 Tel: 970-6702 Email: jhpark1@seoultech.ac.kr h k 한빛미디어 출처 : 뇌를자극하는 C프로그래밍, 한빛미디어 -1- ehanbit.net
자동변수 지금까지하나의함수안에서선언한변수는자동변수이다. 사용범위는하나의함수내부이다. 생존기간은함수가호출되어실행되는동안이다. 메모리에서의위치는스택영역이다. 자동초기화되지않으므로쓰레기값이존재한다. 한빛미디어 -2- ehanbit.net
자동변수의생존기간 자동변수는함수가호출되어변수선언문이실행될때메모리에기억공간이할당된다. - 세개의자동변수를사용하는함수의예 ( 매개변수도자동변수이다 ). int sum(int a, int b) int res; res=a+b; return res; 자동변수는함수가리턴되고나면더이상사용되지않는기억공간이므로리턴될때메모리에서사라진다. 한빛미디어 -3- ehanbit.net
기억공간의할당과회수 자동변수의할당과회수는하나의함수내에서도발생한다. - 함수내에서새로운블록을열고변수를선언하면그블록이끝날때 변수는사라진다. 결국변수의사용범위는블록내부이다. int a=10, b=20; // 메인함수블록에선언된변수 printf(" 바꾸기전 a : %d, b: %d n", a, b); // 새로운블록의시작 int temp; // 안쪽블록에선언된변수 temp=a; a=b; b=temp; // 블록이끝나면서 temp변수는사라진다. printf(" 바꾼후 a : %d, b : %d n", a, b); 한빛미디어 -4- ehanbit.net
중첩된블록에서같은이름의변수를사용할경우 중첩된블록에서같은이름의변수를선언하면가장가까운블록에선언된변수에우선권이있다. int val=10; int val=20; val++; 1 2 printf("val : %d n", val); printf("val : %d n", val); 각변수의사용범위는변수가선언된블록의끝까지이다. 가장가까이선언된 2 번변수를사용한다. 출력결과 val : 21 // 2 번출력 val : 10 // 1 번출력 한빛미디어 -5- ehanbit.net
자동변수가메모리에할당되는방법 자동변수는함수의호출순서에따라할당되고리턴될때회수된다. 따라서가장나중에할당된자동변수가가장먼저사라진다. - 메인함수와 A, B 로구성된함수들의호출과리턴예 자동변수는함수의호출과리턴규칙에맞게메모리의스택 (stack) 영역에할당된다. 한빛미디어 -6- ehanbit.net
함수들간의데이터전달방법 자동변수는사용범위가하나의함수로제한되기때문에 함수들간의데이터공유방법이필요하다. 값을복사해서넘겨주는방법 (call by value) 포인터를사용하는방법 (call by pointer) 한빛미디어 -7- ehanbit.net
값을복사해서넘겨준다 (call by value) 일반적인함수의호출방법으로호출함수의전달인자가피호출함수의매개변수에복사된다. 피호출함수는리턴할때리턴값을복사하여호출함수로전달한다. int add_ten(int); int a=10; a=add_ten(a); printf("a : %d n", a); int add_ten(int b) b=b+10; return b; 한빛미디어 -8- ehanbit.net
포인터를사용한다 (call by pointer) 호출함수에서변수의포인터를전달인자로주고피호출함수에서는이포인 터를받아호출함수의변수를참조하는방식이다. intadd add_ten(int ten(int*); int a=10; a=add_ten(&a); printf("a : %d n", a); void add_ten(int *b) *b=*b+10; 한빛미디어 -9- ehanbit.net
포인터를리턴하는함수 피호출함수에서포인터를리턴하여호출함수가피호출함수의기억 공간을참조할수있도록할수있다. 포인터를리턴하는함수는리턴값의형태가포인터형이된다. - int 형변수의포이터를리턴하는경우 한빛미디어 -10- ehanbit.net
포인터를리턴하는함수 자동변수의포인터를리턴하여호출함수에서다시참조하는것은위험하다. int *add_ten(int); int a=10; int *ap; ap=add_ten(a); printf("a : %d n", *ap); // 포인터변수 ap로 add_ten함수의변수를참조한다. int *add_ten(int b) b=b+10; return &b; // add_ten 함수의자동변수 b 의포인터를리턴한다. 한빛미디어 -11- ehanbit.net
포인터를리턴하는함수 포인터를리턴하는경우는함수가리턴된후에도그기억공간이계속유지되는경우만가능하다. - 호출함수로부터포인터를받아서다시리턴하는경우 ( 문자열처리함수들의예 ) char *strcpy(char *A, char *B); // B의문자열을 A에복사하고 A를리턴한다. char *strcat(char *A, char *B); char *gets(char *A); // B의문자열을 A에붙인후에 A를리턴한다. // A에문자열을입력하고 A를리턴한다. 포인터를리턴하면좀더다양한방식으로프로그램을작성할수있다. - 두문자열을붙인후에그결과를바로확인하는예 #include <string.h> char src[80]= 빈대 ; printf( 결과 : %s n, strcat(src, 떡 )); 한빛미디어 -12- ehanbit.net
정적변수 (static variable) 정적변수는함수가리턴된후에도기억공간이존재한다. 정적변수는자료형앞에 static 예약어를사용하여선언한다. 정적변수는기억공간의할당과초기화가함수의호출과무관하다. void increase(); int i; for(i=0; i<5; i++) increase(); void increase() static int sum=0; sum++; printf( sum : %d n, sum); 출력결과 sum : 1 sum : 2 sum : 3 sum : 4 sum : 5 한빛미디어 -13- ehanbit.net
정적변수는포인터를리턴할수있다. 정적변수는함수가리턴된후에도그기억공간이유지되기때문에그포인터를리턴하여호출하는함수에서참조할수있다. int *increase(); int i; int *sp; for(i=0; i<5; i++) sp=increase(); printf( sum : %d n, *sp); int *increase() static int sum=0; sum++; return 출력결과 sum : 1 sum : 2 sum : 3 sum : 4 sum : 5 한빛미디어 -14- ehanbit.net
외부변수 (extern variable) 외부변수는하나의함수에속해있지않으므로여러함수에서자유롭게사용할수있다. 외부변수는변수를함수밖에선언한다. 외부변수를사용하여두변수의값을바꾸는예 void exchange(); int a, b; // 변수를함수밖에선언한다. printf( 정수값두개를입력하세요 : ); scanf( %d%d, &a, &b); exchange(); // 전달인자없이호출한다. printf( a : %d, b : %d n, a, b); void exchange() int temp; temp=a; a=b; b=temp; // 외부변수 a, b를 // 자신의변수인것처럼 // 사용한다. 외부변수도기억공간의생존기간이함수의호출여부와무관하다. 한빛미디어 -15- ehanbit.net
외부변수를사용할때주의할점 외부변수는여러함수가공유하므로데이터의안전성을보장받을 수없다. 따라서외부변수의값에변화가생긴다면다른함수에미 치는영향도살펴야한다. 외부변수와같은이름의변수를함수내에서선언하는경우는함수 내에서선언된변수를우선적으로참조한다. exchange함수내에 a, b가선언되어있다면내부에선언된변수의값을바꾼다. 한빛미디어 -16- ehanbit.net