챕터 9 함수
리스트 9.1 lethead1.c 프로그램
// lethead1.c
#include<stdio.h>
#define NAME "GIGATHINK, INC."
#define ADDRESS "101 Megabuck Plaza"
#define PLACE "Megapol is, CA 94904"
#define WIDTH 40
void starbar(void); // 함수 프로토타입
int main(void)
{
starbar();
printf("%s\n",NAME);
printf("%s\n",ADDRESS);
printf("%s\n",PLACE);
starbar();
return 0;
}
void starbar(void) // 함수의 정의
{
int count;
for (count = 1; count <= WIDTH; count++)
putchar('*');
putchar('\n');
}
<출력>
****************************************
GIGATHINK, INC.
101 Megabuck Plaza
Megapol is, CA 94904
****************************************
<코드분석>
간단한 함수를 부르는 형식이다. 프로그램은 starbar() 함수를 main 위에 둔다 그뒤 starbar(); 함수를 호출 할 때마다
starbar 함수를 찾아서 그 곳에 있는 명령들을 수행한다.
리스트 9.2 lethead2.c 프로그램
// lethead2.c
#include<stdio.h>
#include<string.h>
#define NAME "GIGATHINK, INK"
#define ADDRESS "101 Megabuck Plaza"
#define PLACE "Megapolis, CA 94904"
#define WIDTH 40
#define SPACE ' '
void show_n_char(char ch, int num);
int main(void)
{
int spaces;
show_n_char('*',WIDTH); // 기호 상수를 전달인자로 사용한다.
putchar('\n');
show_n_char(SPACE,12); // 기호 상수를 전달인자로 사용한다
printf("%s\n",NAME);
spaces = (WIDTH - strlen(ADDRESS)) / 2;
// 몇개의 스페이스가 필요한지
// 프로그램이 계산하게 한다
show_n_char(SPACE,spaces); // 변수를 전달인자로 사용한다
printf("%s\n",ADDRESS);
show_n_char(SPACE,(WIDTH - strlen(PLACE)) / 2);
// 표현식을 전달인자로 사용한다
printf("%s\n",PLACE);
show_n_char('*',WIDTH);
putchar('\n');
return 0;
}
// show_n_char() 함수의 정의
void show_n_char(char ch,int num)
{
int count;
for (count = 1; count <= num; count++)
putchar(ch);
}
<출력>
****************************************
GIGATHINK, INK
101 Megabuck Plaza
Megapolis, CA 94904
****************************************
<코드 분석>
함수로 호출해서 * 을 40개 출력
그뒤 공백을 계산해서 앞 뒤 간격 조절
리스트 9.3 lesser.c 프로그램
// lesser.c -- 둘 중에서 작은 것을 구한다
#include<stdio.h>
int imin(int,int);
int main(void)
{
int evil1, evil2;
printf("두 정수를 입력하시오(끝내려면q): \n");
while (scanf("%d %d",&evil1,&evil2) == 2)
{
printf("(%d,%d)에서 작은 것은 %d\n",evil1,evil2,imin(evil1,evil2));
printf("두 정수를 입력하시오(끝내려면 q): \n");
}
printf("종료!\n");
return 0;
}
int imin(int n, int m)
{
int min;
if(n < m)
min < n;
else
min = m;
return min;
}
<출력>
두 정수를 입력하시오(끝내려면q):
509 333
(509,333)에서 작은 것은 333
두 정수를 입력하시오(끝내려면 q):
q
종료!
<코드분석>
간단한 함수를 만들어서 둘 중 누가 더 작은지 보여주는 프로그램이다.
리스트 9.4 misuse.c 프로그램
// misuse.c -- 부정확하게 함수를 사용한다
#include<stdio.h>
int imax(); //ANSI C 이전 형식의 함수 선언
int main(void)
{
printf("(%d %d)에서 큰 것은 %d\n",3,5,imax(3));
printf("(%d %d)에서 큰 것은 %d\n",3,5,imax(3.0,5.0));
return 0;
}
int imax(n,m)
int n,m;
{
return (n > m ? n : m);
}
<코드분석>
잘못된 코드다.
printf()의 첫 번째 호출은 imax()의 전달인자를 하나 빼먹었다. 두 번째 호출은 전달인자로 정수 대신에 부동소수점
수를 선택했기 때문에 실해이 되지않는다.
리스트 9.5 proto.c 프로그램
// proto.c -- 함수 프로토타입을 사용한다.
#include<stdio.h>
int imax(int,int); //프로토타입
int main(void)
{
printf("(%d,%d)에서 큰 것은 %d\n",3,5,imax(3,5));
printf("(%d,%d)에서 큰 것은 %d\n",3,5,imax(3.0,5.0));
return 0;
}
int imax(int n,int m)
{
return (n > m ? n : m);
}
<출력>
(3,5)에서 큰 것은 5
(3,5)에서 큰 것은 5
<코드분석>
함수를 부를 때 int로 선언 했기 때문에 3.0 5.0 혹은 3.9 4.9를 주더라도
3 5 , 3 4 만 출력이 되서 데이터 손실이될수 있다를 보여주는 예시 프로그램
리스트 9.12 loccheck.c 프로그램
// locheck.c -- 변수들이 어디에 저장되는지 확인한다.
#include<stdio.h>
void mikado(int);
int main(void)
{
int pooh = 2, bah = 5; // main()의 지역 변수
printf("main()에 있는 pooh = %d, &pooh = %p\n",pooh,&pooh);
printf("main()에 있는 bah = %d, &bah = %p\n",bah,&bah);
mikado(pooh);
return 0;
}
void mikado(int bah) // 함수정의
{
int pooh = 10; // mikado()의 지역 변수
printf("mikado()에 있는 pooh = %d, &pooh = %p\n",pooh,&pooh);
printf("mikado()에 있는 bah = %d, &bah = %p\n",bah,&bah);
}
<코드분석>
주소를 출력하기 위해 ANSI C의 %p 포멧을 이용한 프로그램
9.13 swap1.c 프로그램
/* swap1.c -- 맞교환 함수 제1버전 */
#include <stdio.h>
void interchange(int u, int v); /* 함수 선언 */
int main(void)
{
int x = 5, y = 10;
printf("교환 전 x = %d, y = %d.\n", x , y);
interchange(x, y);
printf("교환 후 = %d, y = %d.\n", x, y);
return 0;
}
void interchange(int u, int v) /* 함수 정의 */
{
int temp;
temp = u;
u = v;
v = temp;
}
맞교환이 원하는대로 이루어지지 않았다는 예시 프로그램
리스트 9.14 swap2.c 프로그램
/* swap2.c -- swap1.c에서 무엇이 잘못되었는지 조사 */
#include <stdio.h>
void interchange(int u, int v);
int main(void)
{
int x = 5, y = 10;
printf("교환 전 x = %d, y = %d.\n", x , y);
interchange(x, y);
printf("교환 후 x = %d, y = %d.\n", x, y);
return 0;
}
void interchange(int u, int v)
{
int temp;
printf("교환 전 u = %d, v = %d.\n", u , v);
temp = u;
u = v;
v = temp;
printf("교환 후 u = %d, v = %d.\n", u, v);
}
<코드분석>
interchange()로 u와 v의 값이 맞교환되는 프로그램이지만 잘못되었다.
리스트 9.15 swap.c 프로그램
// swap3.c -- 포인터를 사용하여 맞교환을 바르게 수행한다.
#include<stdio.h>
void interchange(int * u, int * v);
int main(void)
{
int x =5,y = 10;
printf("교환 전 x = %d, y = %d\n",x,y);
interchange(&x,&y); // 함수에 주소를 전달한다.
printf("교환 후 x = %d, y = %d\n",x,y);
return 0;
}
void interchange(int * u, int * v)
{
int temp;
temp = *u; // temp는 u가 가르키는 값을 얻는다.
*u = *v;
*v = temp;
}
<출력>
교환 전 x = 5, y = 10
교환 후 x = 10, y = 5
<코드분석>
1. 기본 개념: 변수와 메모리
변수: 컴퓨터 프로그램에서 데이터를 저장하는 장소. 예를 들어, int x = 5;는 정수형 변수 x에 5를 저장.
메모리 주소: 각 변수는 메모리에서 특정 위치를 차지하고 있다. 이 위치를 메모리 주소라고 한다. 포인터는 이 주소를 저장하는 변수.
2. 포인터 소개
포인터 변수: 포인터는 특정 데이터 형식의 변수의 메모리 주소를 저장하는 변수입니다. 예를 들어, int *p는 정수형 변수의 주소를 저장할 수 있는 포인터입니다.
3. 코드 분석
interchange 함수의 선언
void interchange(int * u, int * v);
interchange 함수는 두 개의 포인터를 인자로 받습니다. int *u는 정수형 변수의 주소를 가리키는 포인터입니다.
마찬가지로 int *v도 정수형 변수의 주소를 가리킵니다.
이 함수는 void로 선언되어 있는데, 이는 반환값이 없음을 의미합니다.
함수는 단순히 두 변수의 값을 교환하는 역할만 합니다.
main 함수
int main(void)
{
int x = 5, y = 10;
printf("교환 전 x = %d, y = %d\n", x, y);
interchange(&x, &y); // 함수에 주소를 전달한다.
printf("교환 후 x = %d, y = %d\n", x, y);
return 0;
}
int x = 5, y = 10;에서 x는 5를, y는 10을 저장한다.
printf("교환 전 x = %d, y = %d\n", x, y);는 x와 y의 값을 교환하기 전에 출력한다.
interchange(&x, &y);에서 &x와 &y는 x와 y의 주소를 interchange 함수에 전달합니다.
주소를 전달함으로써, 함수가 원래의 변수를 직접 수정할 수 있습니다.
교환 후 printf("교환 후 x = %d, y = %d\n", x, y);에서 바뀐 값을 출력합니다.
interchange 함수의 정의
void interchange(int * u, int * v)
{
int temp;
temp = *u; // temp는 u가 가르키는 값을 얻는다.
*u = *v;
*v = temp;
}
int *u와 int *v는 각각 x와 y의 주소를 가리킨다.
temp = *u;에서 *u는 u가 가리키는 주소에 있는 값을 의미합니다.이 값을 temp에 저장합니다. 예를 들어, u가 x의 주소를 가리키고 있으면 *u는 x의 값을 나타냅니다.
*u = *v;는 v가 가리키는 값(예를 들어, y의 값)을 u가 가리키는 변수에 저장합니다. 즉, x에 y의 값을 저장하는 것입니다.
*v = temp;에서 temp는 원래 u가 가리키던 값(x의 값)을 가지고 있으므로, 이 값을 v가 가리키는 변수(y)에 저장합니다.
이 과정을 통해 x와 y의 값이 교환됩니다.
4.전체적인 흐름
- main 함수에서 x와 y에 각각 5와 10이 저장됩니다.
- interchange(&x, &y);를 호출하여 x와 y의 주소를 함수에 전달합니다.
- interchange 함수에서 포인터를 사용하여 x와 y의 값을 교환합니다.
- main 함수로 돌아와서 교환된 x와 y의 값을 출력합니다.