chapter10 프로그래밍 연습

milpy·2022년 6월 20일
0

C 기초 플러스 6판

목록 보기
16/18

01

리스트 10.7의 강우량 프로그램을 수정하라. 계산하는 데 인덱스 대신 포인터를 사용하라.(여전히 배열을 선언하고 초기화시켜야 한다.)

#include <stdio.h>

#define MONTHS 12
#define YEARS 5

int main(void)
{
	const float rain[YEARS][MONTHS] = 
	{
		{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
		{8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
		{9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
		{7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
		{7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
	};

	int year,month;
	float subtot, total;

	printf("년도	강우량(인치)\n");
	for(year = 0, total = 0; year < YEARS; year++)
	{
		for(month = 0, subtot = 0; month < MONTHS; month++)
			subtot += *(*(rain + year) + month);
		printf("%5d %15.1f\n",2010 + year, subtot);
		total += subtot;
	}
	printf("\n연평균 강우량은 %.1f인치입니다.\n",
		total / YEARS);

	printf("월평균 강우량은 다음과 같습니다.\n\n");
	printf("Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec\n");

	for(month = 0; month < MONTHS; month++)
	{
		for(year = 0, subtot = 0; year < YEARS; year++)
			subtot += *(*(rain + year) + month);
		printf("%4.1f ", subtot / YEARS);
	}
	printf("\n");

	return 0;
}

02

double형의 배열을 초기화하고 그 배열의 내용을 다른 세 배열에 복사하는 프로그램을 작성하라.(네 개의 배을을 모두 메인 프로그램에서 선언해야 한다.) 첫 번째 복사를 위해서는 배열 표기를 가지는 함수를 사용하라. 처음 두 함수로 타깃 배열의 이름, 소스 배열의 이름, 복사할 원소의 개수를 원소 뒤에 오는 원소에 대한 포인터를 전달인자로 삼게 하라. 즉, 선언이 다음과 같이 주어졌을 때 각각의 함수 호출은 다음과 같아야 한다.

#include <stdio.h>

#define SIZE 5

void copy_arr(double [], double [], int );
void copy_ptr(double *, double *, int);
void copy_ptr2(double *, double *, double *);
void print_arr(double *, int len);

int main(void)
{
	double source[SIZE] = {1.1, 2.2, 3.3, 4.4, 5.5};
	double target1[SIZE];
	double target2[SIZE];
	double target3[SIZE];

	copy_arr(target1, source, SIZE);
	copy_ptr(target2, source, SIZE);
	copy_ptr2(target3, source, source + SIZE);

	print_arr(source, SIZE);
	print_arr(target1, SIZE);
	print_arr(target2, SIZE);
	print_arr(target3, SIZE);

	return 0;
}

void copy_arr(double target[], double source[], int len)
{
	for(int i = 0; i < len; i++)
		target[i] = source[i];
}

void copy_ptr(double *target, double *source, int len)
{
	for(int i = 0; i < len; i++)
		*(target + i) = *(source + i);
}

void copy_ptr2(double *target, double *source, double *len)
{
	for(int i = 0;source < len; i++, source++)
		target[i] = *source;
}

void print_arr(double *array, int len)
{
	for(int i = 0; i < len; i++)
		printf("%lf ", *(array + i));
	printf("\n");
}

03

int형의 배열에 저장된 값 중 가장 큰 값의 인덱스를 리턴하는 함수를 작성하고, 간단한 프로그램으로 그 함수를 테스트하라.

#include <stdio.h>

#define SIZE 10

int get_max(int [], int );

int main(void)
{
	int list[SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int max_idx;

	max_idx = get_max(list, SIZE);

	printf("max_idx : %d, max_val : %d\n", max_idx, list[max_idx]);

	return 0;
}

int get_max(int list[], int len)
{
	int max_idx = 0;

	for(int i = 1; i < len; i++)
		if(list[max_idx] < list[i])
			max_idx = i;

	return max_idx;
}

04

double형의 배열에 저장된 값 중 가장 큰 값의 인덱스를 리턴하는 함수를 작성하고, 간단한 프로그램으로 그 함수를 테스트 하라.

#include <stdio.h>

#define SIZE 10

int get_max(double [], int );

int main(void)
{
	double list[SIZE] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0};
	int max_idx;

	max_idx = get_max(list, SIZE);

	printf("max_idx : %d, max_val : %2.1lf\n", max_idx, list[max_idx]);

	return 0;
}

int get_max(double list[], int len)
{
	int max_idx = 0;

	for(int i = 1; i < len; i++)
		if(list[max_idx] < list[i])
			max_idx = i;

	return max_idx;
}

05

double형의 배열에 저장된 값 중에서 가장 큰 값과 가장 작은 값의 차를 리턴하는 함수를 작성하고, 간단한 프로그램으로 그 함수를 테스트하라.

#include <stdio.h>

#define SIZE 10

double cal_res(double [], int );

int main(void)
{
	double list[SIZE] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0};
	double result;

	result = cal_res(list, SIZE);

	printf("max - min : %2.1lf\n", result);

	return 0;
}

double cal_res(double list[], int len)
{
	double max, min, result;

	max = min = list[0];

	for(int i = 1; i < len; i++)
	{
		if(max < list[i])
			max = list[i];
		else if(min > list[i])
			min = list[i];
	}

	result = max - min;

	return result;
}

06

double형의 배열의 내용들을 반전시키는 함수를 작성하고 간단한 프로그램으로 그 함수를 테스트 하라.

#include <stdio.h>

#define SIZE 5

void set_reversal(double [], int len);

int main(void)
{
	double list[SIZE] = {1.1, 2.2, 3.3, 4.4, 5.5};

	set_reversal(list, SIZE);

	for(int i = 0; i < SIZE; i++)
		printf("%2.1lf ", list[i]);
	printf("\n");

	return 0;
}

void set_reversal(double list[], int len)
{
	for(int i = 0; i < len; i++)
		list[i] *= -1;
}

07

double형의 2차원 배열을 초기화 시키고, 문제 2에서 작성한 복사 함수중 하나를 사용하여 또 다른 2차원 배열에 복사하는 프로그램을 작성하라. (2차원 배열은 배열의 배열이기 때문에, 각각의 하위 배열의 1차원 복사 함수를 사용할 수 있다.)

#include <stdio.h>

#define SIZE1 3
#define SIZE2 5

void copy_arr(double [], double [], int );

int main(void)
{
	double list1[SIZE1][SIZE2] = 
	{ {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15} };
	double list2[SIZE1][SIZE2];

	for(int i = 0; i < SIZE1; i++)
		copy_arr(list2[i], list1[i], SIZE2);

	for(int i = 0; i < SIZE1; i++)
	{
		for(int j = 0; j < SIZE2; j++)
			printf("%2.1lf ", list2[i][j]);
		printf("\n");
	}

	return 0;
}

void copy_arr(double target[], double source[], int len)
{
	for(int i = 0; i < len; i++)
		target[i] = source[i];
}

08

문제 02에서 작성한 복사 함수를 사용하여, 원소 7개짜리 배열의 세 번째 원소부터 다섯 번째 원소까지를 원소 3개짜리 배열에 복사하라. 함수 자체를 수정할 필요는 없다. 실전달인자만 제대로 선택하면 된다.(실전달인자가 꼭 배열이름과 배열크기일 필요가 없다. 실전달인자로 배열 원소의 주소와 처리될 원소의 개수를 사용해야 한다.)

#include <stdio.h>

#define SIZE1 7
#define SIZE2 3

void copy_ptr(double [], double [], int);

int main(void)
{
	double list1[SIZE1] = {1, 2, 3, 4, 5, 6, 7};
	double list2[SIZE2];

	copy_ptr(list2, list1 + 3, SIZE2);

	for(int i = 0; i < SIZE2; i++)
		printf("%2.1lf ", list2[i]);
	printf("\n");

	return 0;
}

void copy_ptr(double *target, double *source, int len)
{
	for(int i = 0; i < len; i++)
		target[i] = *(source + i);
}

09

double형의 2차원 3X5 배열을 초기화하고, VLA에 기반을 둔 함수를 사용하여 또 다른 2차원 배열에 복사하는 프로그램을 작성하라. 두 배열의 내용을 VLA에 기반을 둔 함수로 출력해야 한다. (사용자는 컴파일러가 VLA 기능을 지원하지 않는 다면 NX5배열을 처리할 수 있는 전동적인 방식의 함수를 작성하라)

#include <stdio.h>

#define SIZE1 3
#define SIZE2 5

void copy_arr(int , int , double[*][*], double[*][*]);
void print_arr(int , int , double[*][*]);

int main(void)
{
	double list[SIZE1][SIZE2] = {
		{ 1, 2, 3, 4, 5 },
		{ 6, 7, 8, 9, 10 },
		{ 11, 12, 13, 14, 15 }
	};
	double list2[SIZE1][SIZE2];

	copy_arr(SIZE1, SIZE2, list, list2);
	print_arr(SIZE1, SIZE2, list2);

	return 0;
}

void copy_arr(int n1, int n2, double mainArr[n1][n2], double subArr[n1][n2])
{
	for(int i = 0; i < n1; i++)
		for(int j = 0; j < n2; j++)
			subArr[i][j] = mainArr[i][j];
}

void print_arr(int n1, int n2, double array[n1][n2])
{
	for(int i = 0; i < n1; i++)
	{
		for(int j = 0; j < n2; j++)
			printf("%2.1lf ", array[i][j]);
		printf("\n");
	}
}

10

두 배열에서 서로 대응하는 원소들의 합을 또 다른 배열에 원소로 저장하는 함수를 작성하라. 예를 들어, 배열 1이 2, 4, 5, 8 값을 가지고, 배열 2가 1, 0, 4, 6을 가진다면, 그 함수는 배열 3에 3, 4, 9, 14를 저장해야 한다. 그 함수는 세 개의 배열 이름과 하나의 배열 크기를 전달인자로 전달받아야 한다. 간단한 프로그램으로 그 함수를 테스트하라.

#include <stdio.h>

#define SIZE 5

void plus_insert_arr(int , int[*], int[*], int[*]);
void print_arr(int , int[*]);

int main(void)
{
	int list1[SIZE] = {1, 2, 3, 4, 5};
	int list2[SIZE] = {6, 7, 8, 9, 10};
	int list3[SIZE];

	print_arr(SIZE, list1);
	print_arr(SIZE, list2);
	
	plus_insert_arr(SIZE, list1, list2, list3);

	print_arr(SIZE, list3);

	return 0;
}

void plus_insert_arr(int len, int list1[len], int list2[len], int list3[len])
{
	for(int i = 0; i < len; i++)
	{
		list3[i] = list1[i] + list2[i];
	}
}

void print_arr(int len, int list[len])
{
	for(int i = 0; i < len; i++)
		printf("%2d ", list[i]);
	printf("\n");
}

11

3X5 배열을 선언하고 적당한 값으로 초기화시키는 프로그램을 작성하라. 프로그램은 배열의 값들을 출력하고, 2배로 곱한 다음, 새로운 값을 출력해야 한다. 배열의 내용을 표시하는 함수와, 배열을 2배로 곱하는 함수를 따로 작성해야 한다. 그 함수들은 배열 이름과 행의 개수를 전달인자로 사용해야 한다.

#include <stdio.h>

#define SIZE1 3
#define SIZE2 5

void doubleUp_arr(int [][SIZE2], int );
void print_arr(int [][SIZE2], int );

int main(void)
{
	int list[SIZE1][SIZE2] = {
		{ 1, 2, 3, 4, 5 },
		{ 6, 7, 8, 9, 10 },
		{ 11, 12, 13, 14, 15 }
	};

	print_arr(list, SIZE1);

	doubleUp_arr(list, SIZE1);

	print_arr(list, SIZE1);

	return 0;
}

void doubleUp_arr(int list[][SIZE2], int len)
{
	for(int i = 0; i < len; i++)
		for(int j = 0; j < sizeof(list[i]) / sizeof(list[i][0]); j++)
			list[i][j] *= 2;
}

void print_arr(int list[][SIZE2], int len)
{
	for(int i = 0; i < len; i++)
	{
		for(int j = 0; j < sizeof(list[i]) / sizeof(list[i][0]); j++)
			printf("%2d ", list[i][j]);
		printf("\n");
	}
}

12

리스트 10.7의 rain.c 프로그램을 다시 작성하라. 이번에는 필요한 작업들을 main()이 아니라 함수들을 사용하여 처리하라.

#include <stdio.h>

#define MONTHS 12
#define YEARS 5

void aver_year_rain(int , int , float[*][*]);
void aver_month_rain(int , int , float[*][*]);

int main(void)
{
	const float rain[YEARS][MONTHS] = 
	{
		{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
		{8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
		{9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
		{7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
		{7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
	};

	aver_year_rain(YEARS, MONTHS, rain);
	aver_month_rain(YEARS, MONTHS, rain);

	return 0;
}

void aver_year_rain(int year, int month, float rain[year][month])
{
	float subtot, total;

	printf("년도	강우량(인치)\n");
	for(int y = 0; y < year; y++)
	{
		for(int m = 0; m < month; m++)
			subtot += rain[y][m];
		printf("%5d %15.1f\n",2010 + y, subtot);
		total += subtot;
	}
	printf("\n연평균 강우량은 %.1f인치입니다.\n",
		total / year);

}

void aver_month_rain(int year, int month, float rain[year][month])
{
	float subtot;

	printf("월평균 강우량은 다음과 같습니다.\n\n");
	printf("Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec\n");

	for(int m = 0; m < month; m++)
	{
		for(int y = 0; y < year; y++)
			subtot += rain[y][m];
		printf("%4.1f ", subtot / year);
	}
	printf("\n");
}

13

5개의 double형 값을 세 번 입력하도록 요구하는 프로그램을 작성하라. 프로그램은 다음과 같은 사항들을 처리해야 한다.

a. 벙보를 3X5 배열에 저장하라.
b. 5개의 값으로 이루어진 각 집합에 대해 평균값을 구하여라
c. 전체 값을에 평균을 구하여라
d. 15개의 값 중에서 최대값을 구하여라
e. 그 결과를 출력하라.

각각의 주요 작업은, C의 전통적인 배열 처리 방식을 사용하는 개별적인 함수로 처리해야 한다. 작업 "b"는, 1차원 배열의 평균값을 계산하고 리턴하는 함수를 사용하여 처리하라. 이 함수를 세 번 호출하는 루프를 사용하라. 그 밖에 작업들은 전체 배열을 전달인자로 전달하라. 작업 "c"와"d"를 수행하는 함수는 호출 프로그램에 결과를 리턴해야 한다.

#include <stdio.h>
#include <ctype.h>

#define SIZE1 3
#define SIZE2 5

void input_number(int , double[][SIZE2]);
double aver_arr(int , double[]);
double aver_arr2(int , double[][SIZE2]);
double find_max(int , double[][SIZE2]);

int main(void)
{
	double list[SIZE1][SIZE2];
	double arr_aver[SIZE1];
	double arr_aver2;
	double max;
	
	input_number(SIZE1, list);

	for(int i = 0; i < SIZE1; i++)
		arr_aver[i] = aver_arr(SIZE2, list[i]);
	arr_aver2 = aver_arr2(SIZE1, list);
	max = find_max(SIZE1, list);

	for(int i = 0; i < SIZE1; i++)
		printf("%d번 행 평균 : %4.2lf\n", i, arr_aver[i]);
	printf("\n");
	printf("전체 평균 : %4.2lf\n\n", arr_aver2);
	printf("최대값 : %4.2lf\n", max);

	return 0;
}

void input_number(int size1, double list[][SIZE2])
{
	for(int i = 0; i < size1; i++)
	{
		for(int j = 0; j < SIZE2; j++)
		{
			scanf("%lf", &list[i][j]);
		}
	}

	for(int i = 0; i < size1; i++)
	{
		for(int j = 0; j < SIZE2; j++)
			printf("%4.2lf ", list[i][j]);
		printf("\n");
	}
}

double aver_arr(int size2, double list[])
{
	double aver = 0;

	for(int i = 0; i < size2; i++)
		aver += list[i];

	return (aver / size2);
}

double aver_arr2(int size1, double list[][SIZE2])
{
	double aver = 0;
	
	for(int i = 0; i < size1; i++)
		for(int j = 0; j < sizeof(list[i]) / sizeof(list[i][0]); j++)
			aver += list[i][j];
	
	aver /= size1;
	aver /= (sizeof(list[0]) / sizeof(list[0][0]));
	return aver;
}

double find_max(int size1, double list[][SIZE2])
{
	double max = list[0][0];

	for(int i = 0; i < size1; i++)
		for(int j = 0; j < sizeof(list[i]) / sizeof(list[i][0]); j++)
			if(max < list[i][j])
				max = list[i][j];
	
	return max;
}

14

가변 길이 배열을 함수 배개변수로 하여, 프로그래밍 연습 13번을 다시 하라.

#include <stdio.h>
#include <ctype.h>

#define SIZE1 3
#define SIZE2 5

void input_number(int , int , double[*][*]);
double aver_arr(int , double[*]);
double aver_arr2(int , int , double[*][*]);
double find_max(int , int , double[*][*]);

int main(void)
{
	double list[SIZE1][SIZE2];
	double arr_aver[SIZE1];
	double arr_aver2;
	double max;
	
	input_number(SIZE1, SIZE2, list);

	for(int i = 0; i < SIZE1; i++)
		arr_aver[i] = aver_arr(SIZE2, list[i]);
	arr_aver2 = aver_arr2(SIZE1, SIZE2, list);
	max = find_max(SIZE1, SIZE2, list);

	for(int i = 0; i < SIZE1; i++)
		printf("%d번 행 평균 : %4.2lf\n", i, arr_aver[i]);
	printf("\n");
	printf("전체 평균 : %4.2lf\n\n", arr_aver2);
	printf("최대값 : %4.2lf\n", max);

	return 0;
}

void input_number(int size1, int size2, double list[size1][size2])
{
	for(int i = 0; i < size1; i++)
	{
		for(int j = 0; j < size2; j++)
		{
			scanf("%lf", &list[i][j]);
		}
	}

	for(int i = 0; i < size1; i++)
	{
		for(int j = 0; j < size2; j++)
			printf("%4.2lf ", list[i][j]);
		printf("\n");
	}
}

double aver_arr(int size2, double list[size2])
{
	double aver = 0;

	for(int i = 0; i < size2; i++)
		aver += list[i];

	return (aver / size2);
}

double aver_arr2(int size1, int size2, double list[size1][size2])
{
	double aver = 0;
	
	for(int i = 0; i < size1; i++)
		for(int j = 0; j < size2; j++)
			aver += list[i][j];
	
	aver /= (size1 * size2);
	return aver;
}

double find_max(int size1, int size2, double list[size1][size2])
{
	double max = list[0][0];

	for(int i = 0; i < size1; i++)
		for(int j = 0; j < size2; j++)
			if(max < list[i][j])
				max = list[i][j];
	
	return max;
}

0개의 댓글