Skip to content

CHAPTER 11

Tony Kim edited this page Oct 30, 2019 · 20 revisions

변수, 함수의 활용 및 동적 메모리

  • 1번 문제

재귀 함수를 사용해 정수의 자릿수를 구하는 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int count_digits(int a) {
	if (a == 0)
		return 0;
	else
		return count_digits(a / 10) + 1;
}
int main(void) {
	int a;

	for (;;) {
		printf("정수? ");
		scanf("%d", &a);

		if (a == 0)
			break;

		printf("count of dihits: %d\n", count_digits(a));
		getchar();
	}
	return 0;
}
[실행 결과]

정수? 12345
count of dihits: 5
정수? 10000000
count of dihits: 8
정수? 0
  • 2번 문제

재귀 함수를 사용해 정수에 있는 모든 수의 합을 구하는 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int sum_digits(int num, int a) {
	if (num == 0)
		return 0;
	else
		return num % a + sum_digits((num - num % a) / 10, a);
}
int main(void) {
	int n, a = 10;
	for (;;) {
		printf("정수? ");
		scanf_s("%d", &n);

		if (n == 0)
			break;

		printf("sum of digits: %d\n", sum_digits(n, a));
		getchar();
	}
	return 0;
}
[실행 결과]

정수? 12345
sum of digits: 15
정수? 1000000
sum of digits: 1
정수? 0
  • 3번 문제

재귀 함수를 사용해 피보나치 수열의 n번 항까지를 출력하는 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int fibonacci(int num) {
	if (num == 0)
		return 0;
	else if (num == 1)
		return 1;
	else return fibonacci(num - 1) + fibonacci(num - 2);
}
int main(void) {
	printf("피보나치 수\n");

	for (int i = 1; i <= 20; i++) {
		printf("%d ", fibonacci(i));
	}
	return 0;
}
[실행 결과]

피보나치 수
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
  • 4번 문제

3번 문제의 피보나치 프로그램을 'Dynamic Programming'을 사용해 개선시킨 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
long long fibo[1000] = { 0,1,1, };
long long fibonacci(int num) {
	if (num == 1 || num == 2)
		return 1;
	else if (fibo[num])
		return fibo[num];
	else
		return fibo[num] = fibonacci(num - 1) + fibonacci(num - 2);
}
int main(void) {
	int n;

	printf("피보나치 수를 입력하세요 ");
	scanf("%d", &n);

	for (int i = 1; i <= n; i++) {
		printf("%lld ", fibonacci(i));
	}
	return 0;
}
[실행 결과]

피보나치 수를 입력하세요 50
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 4807526976 7778742049 12586269025
  • 5번 문제

재귀 함수를 사용하여 N의 거듭제곱을 구하는 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int power(int num, int i) {
	if (i == 0)
		return 1;
	else
		return num * power(num, i - 1);
}
int main(void) {
	int num;

	printf("밑(base)? ");
	scanf("%d", &num);

	for (int i = 0; i < 10; i++) {
		printf("%d ^ %d = %d\n", num, i, power(num, i));
	}
	return 0;
}
[실행 결과]

밑(base)? 2
2 ^ 0 = 1
2 ^ 1 = 2
2 ^ 2 = 4
2 ^ 3 = 8
2 ^ 4 = 16
2 ^ 5 = 32
2 ^ 6 = 64
2 ^ 7 = 128
2 ^ 8 = 256
2 ^ 9 = 512
  • 6번 문제

5번 문제의 거듭제곱 프로그램을 'Dynamic Programming'을 사용해 개선시킨 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int arr[10][10];
int power(int num, int i) {
	if (i == 0)
		return 1;
	else
		return arr[num][i] = num * power(num, i - 1);
}
int main(void) {
	int num;

	printf("밑(base)? ");
	scanf("%d", &num);

	for (int i = 0; i < 10; i++) {
		printf("%d ^ %d = %d\n", num, i, power(num, i));
	}
	return 0;
}
[실행 결과]

밑(base)? 3
3 ^ 0 = 1
3 ^ 1 = 3
3 ^ 2 = 9
3 ^ 3 = 27
3 ^ 4 = 81
3 ^ 5 = 243
3 ^ 6 = 729
3 ^ 7 = 2187
3 ^ 8 = 6561
3 ^ 9 = 19683
  • 7번 문제

재귀 함수를 사용해 피보나치 수열과 거듭제곱을 구하는 함수의 함수포인터를 사용한 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int fibonacci(int num) {
	if (num == 0)
		return 0;
	else if (num == 1)
		return 1;
	else return fibonacci(num - 1) + fibonacci(num - 2);
}
int power(int num, int i) {
	if (i == 0)
		return 1;
	else
		return num * power(num, i - 1);
}
int main(void) {
	int (*fibo)(int);
	int (*po)(int, int);
	int num;
	int result;

	fibo = fibonacci;
	po = power;

	printf("밑(base)? ");
	scanf("%d", &num);

	for (int i = 0; i < 10; i++) {
		result = po(num, i);
		printf("%d ^ %d = %d\n", num, i, result);
	}

	printf("\n\n");
	printf("피보나치 수를 입력하세요 ");
	scanf("%d", &num);

	for (int i = 1; i <= num; i++) {
		result = fibo(i);
		printf("%d ", result);
	}
	return 0;
}
[실행 결과]

밑(base)? 10
10 ^ 0 = 1
10 ^ 1 = 10
10 ^ 2 = 100
10 ^ 3 = 1000
10 ^ 4 = 10000
10 ^ 5 = 100000
10 ^ 6 = 1000000
10 ^ 7 = 10000000
10 ^ 8 = 100000000
10 ^ 9 = 1000000000


피보나치 수를 입력하세요 20
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
  • 8번 문제

함수 포인터를 이용해 콜백 함수를 사용해, 정수형 배열을 특정 값으로 채우는 프로그램

#include <stdio.h>
typedef int (*fill_array)(int);
int increment_it(int num) {
	return num;
}
int increase_from_0(int num) {
	return num + 1;
}
int squared(int num) {
	return num * num;
}
int fill_0(int num) {
	return num = 0;
}
int Function(int num, fill_array func) {
	return func(num);
}
int main(void) {
	fill_array func = NULL;
	int num;

	printf("배열을 0부터 1씩 커지는 값으로 채울 때:\n");

	for (int i = 0; i < 10; i++) {
		func = increment_it;
		num = Function(i, func);
		printf("%d ", num);
	}

	printf("\n배열을 현재 원소보다 1만큼 큰 값으로 채울 때:\n");

	for (int i = 0; i < 10; i++) {
		func = increase_from_0;
		num = Function(i, func);
		printf("%d ", num);
	}

	printf("\n배열을 현재 원소의 제곱으로 채울 때:\n");

	for (int i = 1; i <= 10; i++) {
		func = squared;
		num = Function(i, func);
		printf("%d ", num);
	}

	printf("\n배열을 0으로 채울 때:\n");

	for (int i = 0; i < 10; i++) {
		func = fill_0;
		num = Function(i, func);
		printf("%d ", num);
	}
	return 0;
}
[실행 결과]

배열을 0부터 1씩 커지는 값으로 채울 때:
0 1 2 3 4 5 6 7 8 9
배열을 현재 원소보다 1만큼 큰 값으로 채울 때:
1 2 3 4 5 6 7 8 9 10
배열을 현재 원소의 제곱으로 채울 때:
1 4 9 16 25 36 49 64 81 100
배열을 0으로 채울 때:
0 0 0 0 0 0 0 0 0 0
  • 9번 문제

문자열 배열을 'qsort' 함수를 이용해 오름차순으로 정렬하는 프로그램

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(const void* a, const void* b) {
	return (strcmp((char*)a, (char*)b));
}
int main(void) {
	char MOVIE[5][20] = {
	{"Avengers"},
	{"MI:Fallout"},
	{"Ant-Man"},
	{"Bohemian Rhapsody"},
	{"Insidious"}
	};

	printf("<<정렬 전>>\n");

	for (int i = 0; i < 5; i++) {
		printf("%s\n", MOVIE[i]);
	}

	qsort((void*)MOVIE, 5, sizeof(MOVIE[0]), compare);
	printf("\n<<정렬 후>>\n");

	for (int i = 0; i < 5; i++) {
		printf("%s\n", MOVIE[i]);
	}
	return 0;
}
[실행 결과]

<<정렬 전>>
Avengers
MI:Fallout
Ant-Man
Bohemian Rhapsody
Insidious

<<정렬 후>>
Ant-Man
Avengers
Bohemian Rhapsody
Insidious
MI:Fallout
  • 10번 문제

문자열 배열을 오름차순으로 정리하고, 특정 문자열을 'bsearch'를 사용해 검색한 후 수정하는 프로그램

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(const void* a, const void* b) {
	return (strcmp((char*)a, (char*)b));
}
int main(void) {
	char key_word[20];
	char fixed_title[20];
	char MOVIE[5][20] = {
	{"Avengers"},
	{"MI:Fallout"},
	{"Ant-Man"},
	{"Bohemian Rhapsody"},
	{"Insidious"}
	};

	qsort((void*)MOVIE, 5, sizeof(MOVIE[0]), compare);

	printf("<<영화 목록>>\n");

	for (int i = 0; i < 5; i++) {
		printf("%s\n", MOVIE[i]);
	}

	printf("제목? ");
	scanf_s("%s", key_word, 20);

	char* found = (char*)bsearch(key_word, MOVIE, 5, 20, compare);

	getchar();

	for (int i = 0; i < 5; i++) {
		if (*found == *MOVIE[i]) {
			printf("수정할 제목? ");
			scanf_s("%s", MOVIE[i], 20);
			goto A;
		}
	}
A:
	printf("\n");
	qsort((void*)MOVIE, 5, sizeof(MOVIE[0]), compare);

	printf("<<영화 목록>>\n");

	for (int i = 0; i < 5; i++) {
		printf("%s\n", MOVIE[i]);
	}
	return 0;
}
[실행 결과]

<<영화 목록>>
Ant-Man
Avengers
Bohemian Rhapsody
Insidious
MI:Fallout
제목? Ant-Man
수정할 제목? Ant-Man and the Wasp

<<영화 목록>>
Ant-Man
Avengers
Bohemian Rhapsody
Insidious
MI:Fallout
  • 11번 문제

메인 함수의 문자열을 변경시키지 않기위해 동적 메모리를 할당하고, 전달받은 문자열을 합쳐서 리턴하는 함수 프로그램.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* join_string(char* A, char* B) {
	char* AB = NULL;
	AB = (char*)malloc(sizeof(char) * 100);
	if (AB == NULL)
		return 0;
	AB = strcat(A, B);
	return AB;
}
int main(void) {
	char A[100] = { "first string for join string function " };
	char B[100] = { "second string for join string function " };

	printf("첫 번째 문자열? %s\n", A);
	printf("두 번째 문자열? %s\n", B);

	printf("%s", join_string(A, B));

	return 0;
}
[실행 결과]

첫 번째 문자열? first string for join string function
두 번째 문자열? second string for join string function
first string for join string function second string for join string function
  • 12번 문제

동적 메모리를 사용하여, 크기가 다른 정수형 배열을 'memcpy' 함수를 사용해 하나의 배열로 합치고 정렬 후 리턴하는 함수 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(const void* a, const void* b) {
	return (strcmp((char*)a, (char*)b));
}
int* merge_array(int* A, int* B, int* AB) {
	memcpy(AB, A, 40);
	memcpy(AB + 5, B, 40); // A배열의 크기인 5를 더해 그 이후의 배열에 B값을 저장
	qsort((void*)AB, 40, sizeof(AB[0]), compare); // 오름차순 정렬
	return AB;
}
int main(void) {
	int A[5] = { 1,3,5,7,9 };
	int B[6] = { 2,4,6,8,10,12 };
	int* AB = NULL;
	AB = (int*)malloc(sizeof(int) * 40);

	printf("arr1: ");
	for (int i = 0; i < 5; i++) {
		printf("%d ", A[i]);
	}
	printf("\narr2: ");
	for (int i = 0; i < 6; i++) {
		printf("%d ", B[i]);
	}
	merge_array(A, B, AB);
	printf("\nmerged array: ");
	for (int i = 0; i < 11; i++) {
		printf("%d ", AB[i]);
	}
	free(AB); // 동적 메모리 할당 해제

	return 0;
}
[실행 결과]

arr1: 1 3 5 7 9
arr2: 2 4 6 8 10 12
merged array: 1 1 2 3 3 4 5 6 7 8 9
  • 13번 문제

배열의 행과 열의 크기를 입력받아 2차원 배열을 동적 메모리에 할당하고 0~9사이의 난수를 입력받아 출력하는 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(void) {
	// 호출할 때마다 다른 난수를 입력받기 위해 srand로 초기화
	srand((unsigned)time(NULL));
	int height, width;
	printf("배열의 행 크기? ");
	scanf("%d", &height);
	printf("배열의 열 크기? ");
	scanf("%d", &width);

	int** AB = NULL;
	// 2번 malloc()을 호출하면 2차원 동적 메모리를 할당 받을 수 있다.
	AB = (int**)malloc(sizeof(int*) * height); 
	for (int i = 0; i < height; i++) {
		AB[i] = (int*)malloc(sizeof(int) * width);
	}
	for (int i = 0; i < height; i++) {
		for (int k = 0; k < width; k++) {
			AB[i][k] = rand() % 10;
			printf("%d ", AB[i][k]);
		}
		printf("\n");
	}
	// 동적 메모리 할당 해제
	free(AB);
}
[실행 결과]

배열의 행 크기? 3
배열의 열 크기? 10
7 2 3 2 0 4 9 0 2 5
4 5 1 4 6 5 9 8 8 0
4 4 5 2 5 4 8 4 6 7
  • 14번 문제

13번 문제의 함수 프로그램에 같은 행의 원소의 합계와 같은 열의 원소의 합계를 출력하는 기능을 추가한 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(void) {
	// 호출할 때마다 다른 난수를 입력받기 위해 srand로 초기화
	srand((unsigned)time(NULL));
	int height, width;
	int add1 = 0;
	int add2 = 0;
	printf("배열의 행 크기? ");
	scanf("%d", &height);
	printf("배열의 열 크기? ");
	scanf("%d", &width);

	int** AB = NULL;
	// 2번 malloc()을 호출하면 2차원 동적 메모리를 할당 받을 수 있다.
	AB = (int**)malloc(sizeof(int*) * height); 
	for (int i = 0; i < height; i++) {
		AB[i] = (int*)malloc(sizeof(int) * width);
	}
	for (int i = 0; i < height; i++) {
		for (int k = 0; k < width; k++) {
			AB[i][k] = rand() % 10;
			// 행의 값을 저장
			add1 = AB[i][k] + add1;
			printf("%5d", AB[i][k]);
		}
		printf("  ==> %3d\n", add1);	
	}
	printf("--------------------------------------------------\n");
	for (int i = 0; i < width; i++) {
		for (int k = 0; k < height; k++) {
			// 열의 값을 저장
			add2 = AB[k][i] + add2;
		}
		printf("%5d", add2);
	}
	// 동적 메모리 할당 해제
	free(AB);
}
[실행 결과]

배열의 행 크기? 3
배열의 열 크기? 10
    9    7    6    3    8    8    1    3    2    4  ==>  51
    0    6    1    3    8    5    2    5    2    5  ==>  88
    3    6    8    6    7    4    5    9    9    5  ==> 150
--------------------------------------------------
   12   31   46   58   81   98  106  123  136  150
  • 15번 문제

크기가 2인 동적 메모리 생성 후 배열에 원소를 추가할때 마다 배열의 크기가 2배씩 커지고 '-1'을 입력하면 지금까지 추가된 원소들의 합을 출력하는 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
void  extend_array(int** AB, int *size) {
	int new_size = *size * 2;
	// 기존의 AB보다 배열이 2배 큰 new_AB
	int* new_AB = (int*)malloc(sizeof(int) * new_size);
	for (int i = 0; i < *size; i++) {
		// AB의 값을 new_AB로 복사
		new_AB[i] = (*AB)[i];
	}
	// AB 초기화, 기존 값보다 2배 큰 size를 main함수로 전달 
	free(*AB);
	*AB = new_AB;
	*size = (*size) * 2;
}
int main(void) {
	int* AB = NULL;
	int size = 2;
	int i = 0;
	int add = 0;
	AB = (int*)malloc(sizeof(int) * size);
	printf("배열에 추가할 원소? ");
	for (;;) {
		scanf("%d", &AB[i]);
		// -1 을 입력하면 배열 추가를 멈춤
		if (AB[i] == -1)
			break;
		// i+1 과 size가 같으면 extend_array 함수를 호출
		if (i + 1 == size)
			extend_array(&AB, &size);
		i++;
	}
	printf("배열의 최대 크기: %d, 현재 저장된 원소 수: %d\n", size, i);
	printf("배열: ");
	for (int k = 0; k < i; k++) {
		// AB의 요소를 출력하고 그 값의 합을 add에 저장
		printf("%3d", AB[k]);
		add = AB[k] + add;
	}
	printf("\n배열의 합계: %d", add);
}
[실행 결과]

배열에 추가할 원소? 10 34 22 45 65 89 34 53 99 81 -1
배열의 최대 크기: 16, 현재 저장된 원소 수: 10
배열:  10 34 22 45 65 89 34 53 99 81
배열의 합계: 532
Clone this wiki locally