C 10장. 함수의 활용 #include <stdio.h> int main(void) { int num; printf(“Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("Is negative.\n"); printf("num = %d\n", num); return 0; }
학습목표 ■ 함수의 인자 전달 방법 중 값에 의한 전달 방법과 포인터에 의한 전달 방법에 대해 알아본다. ■ 함수의 인자로 배열과 구조체를 전달하는 방법을 알아본다. ■ 재귀 함수의 개념과 재귀 함수를 정의하고 호출하는 방법을 알아본다. ■ 변수의 기억 부류를 지정하는 auto, register, static, extern에 대해 알아본다. ■ 표준 C 라이브러리 함수에 대해 알아본다. 10장. 함수의 활용
목차 10장. 함수의 활용 함수의 인자 전달 방법 재귀 함수 기억 부류 표준 C 라이브러리 함수 값에 의한 전달, 포인터에 의한 전달 배열의 전달, 구조체의 전달 재귀 함수 재귀 함수의 정의 재귀 함수와 반복문 기억 부류 auto, register, extern, static 함수의 범위 표준 C 라이브러리 함수 수학 관련 함수, 문자열 처리 함수, 문자 분류 함수, 데이터 변환 함수, 메모리 관련 함수, 시간 관련 함수 10장. 함수의 활용
함수의 인자 전달 방법 값에 의한 전달 값에 의한 전달 함수를 호출할 때 넘겨주는 인자의 값을 함수 정의에 있는 매개변수로 복사해서 전달하는 방식 10장. 함수의 활용
Swap 함수 - 값에 의한 전달 방법(1/2) 함수의 인자 전달 방법 값에 의한 전달 10장. 함수의 활용 01: /* Ex10_01.c */ 02: #include <stdio.h> 03: 04: void Swap(int x, int y); 05: 06: int main(void) 07: { 08: int a = 10; 09: int b = 20; 10: 11: printf("Swap 전의 a = %d, b = %d\n", a, b); 12: 13: Swap(a, b); 14: 15: printf("Swap 후의 a = %d, b = %d\n", a, b); 16: 17: return 0; 18: } 19: Swap 함수의 선언 Swap 함수의 호출 10장. 함수의 활용
Swap 함수 - 값에 의한 전달 방법(2/2) 함수의 인자 전달 방법 Swap 함수를 호출해도 a, b의 값에 변화가 없다. 20: void Swap(int x, int y) 21: { 22: int temp; 23: 24: temp = x; 25: x = y; 26: y = temp; 27: } Swap 함수의 정의 Swap 함수를 호출해도 a, b의 값에 변화가 없다. 함수 안에서 변경되어야 하는 인자는 값으로 전달해서는 안된다. 10장. 함수의 활용
Swap 함수 - 포인터에 의한 전달 방법(1/2) 함수의 인자 전달 방법 포인터에 의한 전달 Swap 함수 - 포인터에 의한 전달 방법(1/2) 01: /* Ex10_01.c */ 02: #include <stdio.h> 03: 04: void Swap(int *x, int *y); 05: 06: int main(void) 07: { 08: int a = 10; 09: int b = 20; 10: 11: printf("Swap 전의 a = %d, b = %d\n", a, b); 12: 13: Swap(&a, &b); 14: 15: printf("Swap 후의 a = %d, b = %d\n", a, b); 16: 17: return 0; 18: } 19: Swap 함수의 선언 Swap 함수의 호출 10장. 함수의 활용
Swap 함수 - 포인터에 의한 전달 방법(2/2) 함수의 인자 전달 방법 포인터에 의한 전달 Swap 함수 - 포인터에 의한 전달 방법(2/2) 20: void Swap(int *x, int *y) 21: { 22: int temp; 23: 24: temp = *x; 25: *x = *y; 26: *y = temp; 27: } Swap 함수의 정의 Swap 호출 후 a, b의 값이 올바르게 맞교환되었다. 10장. 함수의 활용
포인터에 의한 전달 방법(1/2) 함수의 인자 전달 방법 Swap 함수처럼 함수 안에서 변경되어야 하는 인자를 전달할 때는 포인터에 의한 전달 방법을 사용해야 한다. 변수의 값을 복사해서 전달하는 대신 변수의 주소를 전달하는 방식 출력인자나 입출력 인자를 전달할 때 사용 10장. 함수의 활용
포인터에 의한 전달 방법(2/2) 함수의 인자 전달 방법 포인터에 의한 전달 방법을 이용하면 함수의 처리 결과를 인자로 받아올 수 있다. 10장. 함수의 활용
인자의 의미 함수의 인자 전달 방법 입력 인자(in-parameter) : 함수 안에서 사용만 될 뿐 변경되지 않는 인자 포인터에 의한 전달 인자의 의미 입력 인자(in-parameter) : 함수 안에서 사용만 될 뿐 변경되지 않는 인자 출력 인자(out-parameter) : 함수 안에서 사용되지는 않고 변경되는 인자 입출력 인자(inout-parameter) : 함수 안에서 사용도 되고, 변경도 되는 인자 10장. 함수의 활용
출력 인자의 사용 예(1/2) 함수의 인자 전달 방법 포인터에 의한 전달 10장. 함수의 활용 01: /* Ex10_03.c */ 02: #include <stdio.h> 03: 04: void GetSumProduct(int x, int y, int *sum, int *product); 05: 06: int main(void) 07: { 08: int a = 5, b = 8; 09: int res1, res2; 10: 11: GetSumProduct(a, b, &res1, &res2); 12: 13: printf("%d + %d = %d\n", a, b, res1); 14: printf("%d + %d = %d\n", a, b, res2); 15: 16: return 0; 17: } 18: GetSumProduct 함수의 선언 GetSumProduct 함수의 호출 10장. 함수의 활용
출력 인자의 사용 예(2/2) 함수의 인자 전달 방법 포인터에 의한 전달 10장. 함수의 활용 19: void GetSumProduct(int x, int y, int *sum, int *product) 20: { 21: *sum = x + y; 22: *product = x * y; 23: } sum과 product는 출력인자 10장. 함수의 활용
출력 인자함수의 처리 결과를 받아오는 과정(1/2) 함수의 인자 전달 방법 포인터에 의한 전달 출력 인자함수의 처리 결과를 받아오는 과정(1/2) 함수를 선언할 때, 처리 결과를 받아올 매개변수를 포인터형으로 선언한다. 함수를 호출할 때, 처리 결과를 받아올 변수의 주소를 인자로 전달한다. 함수를 정의할 때, 매개변수가 가리키는 곳에 함수의 처리 결과를 저장한다. 10장. 함수의 활용
출력 인자함수의 처리 결과를 받아오는 과정(2/2) 함수의 인자 전달 방법 포인터에 의한 전달 출력 인자함수의 처리 결과를 받아오는 과정(2/2) 10장. 함수의 활용
기본적인 배열의 전달(1/4) 함수의 인자 전달 방법 배열은 항상 포인터로 전달한다. 함수의 매개변수는 배열의 원소에 대한 포인터형으로 선언한다. 함수의 인자로 배열을 전달할 때는 포인터를 전달하고, 함수 안에서는 일반 배열인 것처럼 인덱스로 사용하면 된다. 10장. 함수의 활용
기본적인 배열의 전달(2/4) 함수의 인자 전달 방법 함수를 호출할 때는, [ ] 없이 배열명만 인자로 넘겨준다. 함수 안에서 배열의 크기가 필요할 때는, 배열의 크기도 인자로 전달한다. 10장. 함수의 활용
함수의 인자 전달 방법 배열의 전달 기본적인 배열의 전달(3/4) 10장. 함수의 활용
기본적인 배열의 전달(4/4) 함수의 인자 전달 방법 특정 원소의 주소 전달 시 배열의 일부분을 인자로 전달할 수도 있다. 10장. 함수의 활용
함수의 인자로 배열을 전달하는 경우의 예(1/3) 함수의 인자 전달 방법 배열의 전달 함수의 인자로 배열을 전달하는 경우의 예(1/3) 01: /* Ex10_04.c */ 02: #include <stdio.h> 03: 04: void PrintArray(int *arr, int size); 05: int GetSumOfArray(int *arr, int size); 06: 07: int main(void) 08: { 09: int x[5] = {10, 20, 30, 40, 50}; 10: int y[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 11: 12: printf("x 배열 : "); 13: PrintArray(x, 5); 14: printf("합계 : %d\n\n", GetSumOfArray(x, 5)); 15: 배열을 인자로 갖는 함수의 선언 함수의 인자로 배열 전달 10장. 함수의 활용
함수의 인자로 배열을 전달하는 경우의 예(2/3) 함수의 인자 전달 방법 배열의 전달 함수의 인자로 배열을 전달하는 경우의 예(2/3) 16: printf("y 배열 : "); 17: PrintArray(y, 10); 18: printf("합계 : %d\n\n", GetSumOfArray(y, 10)); 19: 20: printf("y 배열의 일부분 : "); 21: PrintArray(y+2, 5); 22: printf("합계 : %d\n\n", GetSumOfArray(y+2, 5)); 23: 24: return 0; 25: } 26: 27: void PrintArray(int *arr, int size) 28: { 29: int i; 30: 31: for(i = 0 ; i < size ; i++) 32: printf("%d ", arr[i]); 33: printf("\n"); 34: } 함수의 인자로 배열 전달 함수의 인자로 배열 전달 인자로 전달받은 배열의 사용 10장. 함수의 활용
함수의 인자로 배열을 전달하는 경우의 예(3/3) 함수의 인자 전달 방법 배열의 전달 함수의 인자로 배열을 전달하는 경우의 예(3/3) 35: 36: int GetSumOfArray(int *arr, int size) 37: { 38: int i; 39: int total; 40: 41: for(i = 0, total = 0 ; i < size ; i++) 42: total += arr[i]; 43: 44: return total; 45: } 인자로 전달받은 배열의 사용 10장. 함수의 활용
배열을 인자로 갖는 함수의 원형 함수의 인자 전달 방법 배열의 전달 배열을 인자로 갖는 함수의 원형 매개변수의 데이터형으로 배열의 원소에 대한 포인터형을 지정하거나, 크기를 생략한 배열을 지정할 수 있다. 10장. 함수의 활용
배열을 입력 인자로 전달하는 경우(1/2) 함수의 인자 전달 방법 배열의 전달 배열을 입력 인자로 전달하는 경우(1/2) 배열이 함수 안에서 이용만 될 뿐 변경되지 않을 때는 매개변수의 포인터형에 const를 지정한다. 함수의 매개변수가 const 포인터이면, 함수 안에서 포인터가 가리키는 변수의 값을 읽을 수만 있고 변경할 수는 없다. 10장. 함수의 활용
함수의 인자 전달 방법 배열의 전달 배열을 입력 인자로 전달하는 경우(2/2) 10장. 함수의 활용
배열을 입력 인자나 입출력 인자로 전달하는 경우(1/3) 함수의 인자 전달 방법 배열의 전달 배열을 입력 인자나 입출력 인자로 전달하는 경우(1/3) 01: /* Ex10_05.c */ 02: #include <stdio.h> 03: 04: void PrintArray(const int *arr, int size); 05: void SortArray(int *arr, int size); 06: 07: int main(void) 08: { 09: int x[5] = {43, 6, 24, 88, 34}; 10: int y[10] = {12, 35, 7, 45, 78, 22, 98, 77, 1, 28}; 11: 12: printf("x 배열 : "); 13: PrintArray(x, 5); 14: SortArray(x, 5); 15: printf("정렬후 : "); 16: PrintArray(x, 5); 17: 배열을 입력 인자로 갖는 함수의 선언 배열을 입출력 인자로 갖는 함수의 선언 10장. 함수의 활용
배열을 입력 인자나 입출력 인자로 전달하는 경우(2/3) 함수의 인자 전달 방법 배열의 전달 배열을 입력 인자나 입출력 인자로 전달하는 경우(2/3) 18: printf("y 배열 : "); 19: PrintArray(y, 10); 20: SortArray(y, 10); 21: printf("정렬후 : "); 22: PrintArray(y, 10); 23: 24: return 0; 25: } 26: 27: void PrintArray(const int *arr, int size) 28: { 29: int i; 30: 31: //arr[0] = 100; 32: for(i = 0 ; i < size ; i++) 33: printf("%d ", arr[i]); 34: printf("\n"); 35: } 36: 배열을 입력 인자로 갖는 함수의 정의 배열을 const int *형으로 전달했으므로 변경 불가 10장. 함수의 활용
배열을 입력 인자나 입출력 인자로 전달하는 경우(3/3) 함수의 인자 전달 방법 배열의 전달 배열을 입력 인자나 입출력 인자로 전달하는 경우(3/3) 37: void SortArray(int *arr, int size) 38: { 39: int i, j, index; 40: int temp; 41: 42: for(i = 0; i < size-1 ; i++) 43: { 44: index = i; 45: for(j = i+1 ; j < size ; j++) 46: { 47: if( arr[index] > arr[j] ) 48: index = j; 49: } 50: temp = arr[i]; 51: arr[i] = arr[index]; 52: arr[index] = temp; 53: } 54: } 배열을 입출력 인자로 갖는 함수의 정의 배열을 int *형으로 전달했으므로 변경 가능 10장. 함수의 활용
함수의 인자 전달 방법 배열의 전달 배열의 전달(1/2) 배열을 인자로 전달하려면, 매개변수의 데이터형으로 포인터형을 사용하거나 크기를 생략한 배열로 선언한다. 함수 안에서 배열이 사용만 될 뿐 변경되지 않을 때는 const 포인터로 전달한다. 함수 안에서 배열의 크기가 필요할 때는 배열의 크기도 인자로 전달한다. 10장. 함수의 활용
함수의 인자 전달 방법 배열의 전달 배열의 전달(2/2) 배열을 인자로 갖는 함수를 호출할 때는, 배열의 시작 주소를 인자로 넘겨준다. 필요하다면 배열의 크기도 함께 전달한다. 배열을 인자로 갖는 함수를 정의할 때는, 매개변수인 포인터를 배열 이름인 것처럼 사용한다. 10장. 함수의 활용
구조체를 값으로 전달하는 경우(1/2) 함수의 인자 전달 방법 구조체의 전달 구조체를 값으로 전달하는 경우(1/2) 구조체를 값으로 전달하면 인자 전달 과정에서 구조체 변수가 복사되어 전달된다. 10장. 함수의 활용
함수의 인자 전달 방법 구조체의 전달 구조체를 값으로 전달하는 경우(2/2) 10장. 함수의 활용
구조체를 포인터로 전달하는 경우(1/2) 함수의 인자 전달 방법 구조체의 전달 구조체를 포인터로 전달하는 경우(1/2) 구조체를 복사하는 대신 구조체의 주소만 전달하므로 불필요한 구조체의 복사를 막을 수 있다. 크기가 큰 구조체는 포인터로 전달하는 것이 성능상 좋다. 10장. 함수의 활용
함수의 인자 전달 방법 구조체의 전달 구조체를 포인터로 전달하는 경우(2/2) 10장. 함수의 활용
함수의 인자로 구조체를 전달하는 경우(1/2) 함수의 인자 전달 방법 구조체의 전달 10장. 함수의 활용 01: /* Ex10_06.c */ 02: #include <stdio.h> 03: 04: typedef struct point { 05: int x; 06: int y; 07: } POINT; 08: 09: void PrintPoint(POINT *p); 10: 11: int main(void) 12: { 13: POINT pt1 = {100, 200}; 14: PrintPoint(&pt1); 15: 16: return 0; 17: } 18: POINT 구조체의 정의 구조체를 인자로 갖는 함수의 선언 구조체를 포인터로 전달 10장. 함수의 활용
함수의 인자로 구조체를 전달하는 경우(2/2) 함수의 인자 전달 방법 구조체의 전달 10장. 함수의 활용 19: void PrintPoint(POINT *p) 20: { 21: printf("(%d, %d)\n", p->x, p->y); 22: } 구조체를 인자로 갖는 함수의 정의 10장. 함수의 활용
구조체를 입력 인자로 전달하는 경우(1/2) 함수의 인자 전달 방법 구조체의 전달 구조체를 입력 인자로 전달하는 경우(1/2) 구조체가 함수 안에서 이용만 될 뿐 변경되지 않을 때는 const 포인터로 전달한다. 함수의 매개변수가 const 포인터이면, 함수 안에서 포인터가 가리키는 구조체 변수의 값을 읽어볼 수만 있고 변경할 수는 없다. 10장. 함수의 활용
함수의 인자 전달 방법 구조체의 전달 구조체를 입력 인자로 전달하는 경우(2/2) 10장. 함수의 활용
구조체를 출력 인자나 입출력 인자로 전달하는 경우 함수의 인자 전달 방법 구조체의 전달 구조체를 출력 인자나 입출력 인자로 전달하는 경우 구조체를 함수의 출력 인자나 입출력 인자로 전달할 때는 포인터에 의한 전달 방법을 사용한다. 구조체 포인터로 구조체 멤버에 접근할 때는 -> 연산자를 이용한다. 10장. 함수의 활용
구조체를 입력 인자, 입출력 인자로 전달하는 경우(1/2) 함수의 인자 전달 방법 구조체의 전달 구조체를 입력 인자, 입출력 인자로 전달하는 경우(1/2) 01: /* Ex10_07.c */ 02: #include <stdio.h> 03: 04: typedef struct point { 05: int x; 06: int y; 07: } POINT; 08: 09: void PrintPoint(const POINT *p); 10: void MovePoint(POINT *p, int dx, int dy); 11: 12: int main(void) 13: { 14: POINT pt1 = {100, 200}; 15: POINT pt2 = {300, 400}; 16: 17: printf("pt1 = "); 18: PrintPoint(&pt1); 19: printf("pt2 = "); 20: PrintPoint(&pt2); 구조체를 입력 인자로 갖는 함수의 선언 구조체를 입출력 인자로 갖는 함수의 선언 10장. 함수의 활용
구조체를 입력 인자, 입출력 인자로 전달하는 경우(2/2) 함수의 인자 전달 방법 구조체의 전달 구조체를 입력 인자, 입출력 인자로 전달하는 경우(2/2) 21: 22: MovePoint(&pt1, 10, 10); 23: 24: printf("변경된 pt1의 좌표: "); 25: PrintPoint(&pt1); 26: 27: return 0; 28: } 29: 30: void PrintPoint(const POINT *p) 31: { 32: //p->x = 100; 33: printf("(%d, %d)\n", p->x, p->y); 34: } 35: 36: void MovePoint(POINT *p, int dx, int dy) 37: { 38: p->x += dx; 39: p->y += dy; 40: } 구조체를 const POINT*형으로 전달했으므로 변경 불가 p는 입출력 인자이므로 변경 가능 10장. 함수의 활용
구조체의 전달(1/2) 함수의 인자 전달 방법 구조체를 인자로 갖는 함수를 선언할 때는, 포인터로 전달하는 것이 좋다. 함수 안에서 구조체가 사용만 될 뿐 변경되지 않을 때는 const 포인터로 전달한다. 구조체를 인자로 갖는 함수를 호출할 때는, 구조체 변수의 주소를 인자로 넘겨준다. 10장. 함수의 활용
함수의 인자 전달 방법 구조체의 전달 구조체의 전달(2/2) 구조체를 인자로 갖는 함수를 정의할 때는, 매개변수인 포인터를 이용해서 구조체의 멤버에 접근한다. 10장. 함수의 활용
재귀 함수(recursive function) 재귀 함수의 정의 재귀 함수(recursive function) 자기 자신을 다시 호출하는 함수 큰 문제를 비슷한 종류의 작은 문제들로 나누어 처리하는 분할 정복(divide-and-conquer) 알고리즘을 구현할 때 주로 사용 재귀 기법(recursion) 어떤 문제를 비슷한 유형의 다른 문제로 바꾸어 처리하는 방법 10장. 함수의 활용
재귀 함수 재귀 함수의 정의 재귀 함수의 정의 최대공약수를 구하는 함수 10장. 함수의 활용
재귀 함수 재귀 함수의 정의 재귀 함수의 호출 과정 10장. 함수의 활용
GetGCD을 재귀 함수로 정의하는 경우(1/2) 재귀 함수의 정의 GetGCD을 재귀 함수로 정의하는 경우(1/2) 01: /* Ex10_08.c */ 02: #include <stdio.h> 03: 04: int GetGCD(int m, int n); 05: 06: int main(void) 07: { 08: int x, y; 09: 10: printf("두 정수를 입력하세요 : "); 11: scanf("%d %d", &x, &y); 12: printf("%d과 %d의 최대 공약수는 %d입니다.\n", x, y, GetGCD(x, y)); 13: 14: return 0; 15: } 16: 재귀 함수의 선언 재귀 함수의 호출 10장. 함수의 활용
GetFactorial을 재귀 함수로 정의하는 경우(2/2) 재귀 함수의 정의 GetFactorial을 재귀 함수로 정의하는 경우(2/2) 17: int GetGCD(int m, int n) 18: { 19: if( m % n == 0 ) 20: return n; 21: return GetGCD(n, m % n); 22: } 재귀 함수의 정의 10장. 함수의 활용
재귀 함수와 반복문 재귀 함수 재귀 함수보다 반복문으로 구현하는 것이 성능 면에서는 더 좋다. 재귀 함수를 호출하면 함수가 여러 번 반복적으로 호출되므로, 함수 호출시 오버헤드가 크다. 재귀 기법은 문제를 해결하기 위한 알고리즘을 단순화한다. 재귀 함수 호출 시 함수 호출의 깊이(depth)가 너무 깊어지지 않도록 주의한다. 10장. 함수의 활용
기억 부류(storage class) 기억 부류 변수나 함수를 선언할 때 사용되는 키워드 변수나 함수의 저장 위치와 사용 범위를 결정한다. 변수나 함수 선언 시 맨 앞에 지정한다. 변수의 디폴트 기억 부류는 auto이고, 함수의 디폴트 기억 부류는 extern이다. 10장. 함수의 활용
auto 변수 기억 부류 지역 변수는 디폴트로 auto 기억 부류를 사용한다. 10장. 함수의 활용
register 변수 기억 부류 변수를 메모리에 할당하는 대신 CPU의 레지스터에 할당한다. 변수를 레지스터에 할당하면 변수에 좀더 빠르게 접근할 수 있다. 보통 루프 제어 변수를 레지스터 변수로 선언한다. register 변수로 선언해도 변수가 레지스터에 할당되지 않을 수 있다. 레지스터 변수에 대해서는 주소 구하기 연산자를 사용할 수 없다. 10장. 함수의 활용
기억 부류 extern 변수 extern 변수 다른 곳에 선언된 변수에 대하여 별도의 메모리 할당 없이 해당 변수의 이름을 사용할 수 있게 해준다. 전역 변수를 코드 중간에 선언하면, 전역 변수가 선언된 뒤쪽에 정의된 함수에서만 전역 변수를 사용할 수 있다. 10장. 함수의 활용
전방 선언(forward declaration) 기억 부류 extern 변수 전방 선언(forward declaration) 전역 변수에 대한 extern 선언이 있으면 실제로 전역 변수가 선언된 위치에 관계없이 전역 변수를 사용할 수 있다. 10장. 함수의 활용
기억 부류 extern 변수 전역 변수의 extern 선언 전역 변수에 대한 extern 선언이 있으면 실제로 전역 변수가 선언된 위치에 관계없이 전역 변수를 사용할 수 있다. 10장. 함수의 활용
기억 부류 static 변수 static 지역 변수(1/) 정적 지역 변수는 함수가 리턴하더라도 해제되지 않고 남아있다가 그 다음번 함수 호출에 다시 이용된다. 10장. 함수의 활용
정적 지역 변수의 사용 예(1/2) 기억 부류 static 변수 10장. 함수의 활용 01: /* Ex10_09.c */ 02: #include <stdio.h> 03: 04: void TestStatic(void); 05: 06: int main(void) 07: { 08: int i; 09: 10: for(i = 0 ; i < 5 ; i++) 11: TestStatic( ); 12: 13: return 0; 14: } 15: TestStatic 함수를 다섯 번 호출 10장. 함수의 활용
정적 지역 변수의 사용 예(2/2) 기억 부류 static 변수 10장. 함수의 활용 16: void TestStatic(void) 17: { 18: int num = 0; 19: static int count = 0; 20: 21: printf("num = %d, ", ++num); 22: printf("count = %d\n" , ++count); 23: } 지역 변수의 선언 정적 지역 변수의 선언 10장. 함수의 활용
기억 부류 static 변수 static 지역 변수(2/) 정적 지역 변수는 전역 변수처럼 프로그램이 시작할 때 메모리에 할당되고 프로그램이 종료할 때 해제된다. 전역 변수와는 달리 정적 지역 변수는 선언된 함수 안에서만 사용할 수 있다. 10장. 함수의 활용
정적 지역 변수가 필요한 경우(1/2) 기억 부류 문자열을 역순으로 만들어서 리턴하는 함수 static 변수 정적 지역 변수가 필요한 경우(1/2) 문자열을 역순으로 만들어서 리턴하는 함수 포인터를 리턴하는 함수를 정의할 때는 함수 안에 선언된 지역 변수의 주소를 리턴하지 않도록 주의해야 한다. 10장. 함수의 활용
기억 부류 static 변수 정적 지역 변수가 필요한 경우(2/2) Reverse 함수 안에 있는 지역 변수 result를 정적 지역 변수로 선언한다. result를 정적 지역 변수로 선언하면 함수가 리턴하더라도 해제되지 않으므로 올바른 실행 결과를 얻을 수 있다. 10장. 함수의 활용
지역 변수의 주소를 리턴하는 경우(1/3) 기억 부류 static 변수 10장. 함수의 활용 01: /* Ex10_10.c */ 02: #include <stdio.h> 03: #include <string.h> 04: 05: char* Reverse(const char *str); 06: 07: int main(void) 08: { 09: char s1[ ] = "abc"; 10: char *res = NULL; 11: 12: res = Reverse(s1); 13: printf("res = %s\n", res); 14: 15: return 0; 16: } 17: char*형을 리턴하는 함수의 선언 char*형을 리턴하는 함수의 호출 10장. 함수의 활용
지역 변수의 주소를 리턴하는 경우(2/3) 기억 부류 해제된 지역 변수의 주소를 리턴하므로 실행 에러가 발생한다. static 변수 지역 변수의 주소를 리턴하는 경우(2/3) 18: char* Reverse(const char *str) 19: { 20: char result[80]; 21: int i; 22: int len = strlen(str); 23: 24: for( i = 0 ; i < len ; i ++) 25: result[i] = str[len - i - 1]; 26: result[i] = '\0'; 27: 28: return result; 29: } char*형을 리턴하는 함수의 정의 해제된 지역 변수의 주소를 리턴하므로 실행 에러가 발생한다. 지역 변수의 주소 리턴 10장. 함수의 활용
기억 부류 static 변수 지역 변수의 주소를 리턴하는 경우(3/3) 10장. 함수의 활용
정적 지역 변수의 주소를 리턴하는 경우(1/3) 기억 부류 static 변수 10장. 함수의 활용 01: /* Ex10_11.c */ 02: #include <stdio.h> 03: #include <string.h> 04: 05: char* Reverse(const char *str); 06: 07: int main(void) 08: { 09: char s1[ ] = "abc"; 10: char *res = NULL; 11: 12: res = Reverse(s1); 13: printf("res = %s\n", res); 14: 15: return 0; 16: } 17: char*형을 리턴하는 함수의 선언 char*형을 리턴하는 함수의 호출 10장. 함수의 활용
정적 지역 변수의 주소를 리턴하는 경우(2/3) 기억 부류 정적 지역 변수를 이용하면 올바른 실행 결과를 얻을 수 있다. static 변수 정적 지역 변수의 주소를 리턴하는 경우(2/3) 18: char* Reverse(const char *str) 19: { 20: static result[80]; 21: int i; 22: int len = strlen(str); 23: 24: for( i = 0 ; i < len ; i ++) 25: result[i] = str[len - i - 1]; 26: result[i] = '\0'; 27: 28: return result; 29: } char*형을 리턴하는 함수의 정의 정적 지역 변수의 주소 리턴 정적 지역 변수의 주소 리턴 정적 지역 변수를 이용하면 올바른 실행 결과를 얻을 수 있다. 10장. 함수의 활용
기억 부류 static 변수 정적 지역 변수의 주소를 리턴하는 경우(3/3) 10장. 함수의 활용
Reverse 함수를 구현하는 또 다른 방법 기억 부류 static 변수 Reverse 함수를 구현하는 또 다른 방법 함수를 호출할 때 결과를 받아올 문자 배열의 주소를 출력 인자로 전달하고, 함수 안에서는 매개변수로 전달된 배열에 역순으로 된 문자열을 저장한다. 10장. 함수의 활용
static 전역 변수 기억 부류 정적 전역 변수는 정적 전역 변수가 선언된 소스 파일에서만 사용할 수 있다. 정적 전역 변수는 전역 변수를 다른 소스 파일에서 접근하지 못하도록 제한한다. 10장. 함수의 활용
지역 변수, 정적 지역 변수, 전역 변수, 정적 전역 변수의 비교 기억 부류 static 변수 지역 변수, 정적 지역 변수, 전역 변수, 정적 전역 변수의 비교 10장. 함수의 활용
함수의 범위 기억 부류 함수의 디폴트 기억 부류는 extern이다. 해당 함수를 다른 소스 파일에서 접근할 수 있다. 정적 함수 : 함수가 정의된 소스 파일에서만 함수를 호출할 수 있고, 다른 소스 파일에서는 호출할 수 없다. 10장. 함수의 활용
표준 C 라이브러리 표준 C 라이브러리의 대표적인 기능 표준 C 라이브러리 함수 수학 관련 : abs( ), pow( ), sqrt( ), rand( ) 등 문자열 처리 : strcpy( ), strlen( ), strcmp( ), strcat( ) 등 문자 분류 : isalnum, isdigit( ), isalpha( ) 등 데이터 변환 : tolower( ), toupper( ) 등 메모리 관련 : memcpy( ), memset( ), memmove( ) 등 시간 처리 : time( ), localtime( ), asctime( ) 등 10장. 함수의 활용
수학 관련 함수 : <math.h> 포함 표준 C 라이브러리 함수 수학 관련 함수 수학 관련 함수 : <math.h> 포함 10장. 함수의 활용
문자열 처리 함수: <string.h> 포함 표준 C 라이브러리 함수 문자열 처리 함수 문자열 처리 함수: <string.h> 포함 10장. 함수의 활용
문자 분류 함수: <ctype.h> 포함 문자 분류함수 문자 분류 함수: <ctype.h> 포함 10장. 함수의 활용
데이터 변환 함수: <stdlib.h>나 <ctype.h> 포함 10장. 함수의 활용
메모리 관련 함수: <memory.h> 포함 표준 C 라이브러리 함수 메모리 관련 함수 메모리 관련 함수: <memory.h> 포함 10장. 함수의 활용
시간 관련 함수: <time.h> 포함 표준 C 라이브러리 함수 시간 관련 함수 시간 관련 함수: <time.h> 포함 10장. 함수의 활용
함수의 인자 전달 방법 학습정리 값에 의한 전달: 함수 안에서 변경되지 않는 인자(입력 인자)를 전달할 때 사용 포인터에 의한 전달 : 함수 안에서 변경되어야 하는 인자(출력 인자)를 전달할 때 사용 매개변수는 포인터 형으로 선언하고, 함수 호출 시 변수의 주소를 전달한다. 함수 안에서는 매개변수가 가리키는 곳에 값을 저장한다. void GetSumProduct(int x, int y, int *sum, int *product) { *sum = x + y; *product = x * y; } 배열의 전달: 배열은 포인터로 전달한다. 함수 안에서 변경되지 않는 배열을 전달할 때는 const 포인터로 전달한다. 함수 안에서 배열의 크기가 필요할 때는 배열의 크기도 함께 전달한다. 함수 안에서는 일반 배열처럼 사용한다. 구조체의 전달 : 구조체를 복사하지 않고 전달하려면 포인터로 전달한다. 함수 안에서 변경되지 않는 구조체를 전달할 때는 const 포인터로 전달한다. 10장. 함수의 활용
학습정리 재귀 함수 자기 자신을 호출하는 함수 기억부류 10장. 함수의 활용
10장. 함수의 활용 수고하셨습니다. 질문 있습니까? NEXT Chapter 11장. 포인터의 활용