2019. 9. 4. 21:05 작성
혼자 풀어본 쉽게 풀어쓴 C언어 Express 9장 Programming
9장 함수와 변수
1. 덧셈, 뺄셈, 곱셈, 나눗셈을 지원하는 계산기 프로그램을 작성하여 보자. 이번에는 각 연산들이 몇 번씩 계산되었는지를 기억하게 하자. 각 연산을 지원하는 함수들은 자신이 호출된 횟수를 화면에 출력한다.
(a)정적 지역 변수를 사용하여 프로그램을 작성하라.
(b)전역 변수를 사용하여 프로그램을 작성하라.
***하나의 프로그램 안에는 여러 함수를 만들 수 있습니다. 이 때 하나의 함수 안에서만 사용되는 변수를 지역 변수, 함수에 상관없이 프로그램 전체에서 사용할 수 있는 변수를 전역 변수라고 합니다.
***지역변수는 블록의 맨 첫 부분에서 정의되어야 한다.(지역변수는 항상 초기화하도록 하자!)
**정적 지역 변수는 static int count;와 같이 선언한다.
#include <stdio.h>
int csum = 1;
int csub = 1;
int cmul = 1;
int cdiv = 1;
void sum(int a, int b);
void sub(int a, int b);
void mul(int a, int b);
void div(int a, int b);
int main() {
int x, y;
char ch1, ch2;
while (1) {
printf("연산을 입력하시오: ");
scanf("%d %c %d", &x, &ch1, &y);
fflush(stdin);
if (ch1 == '+') {
printf("덧셈은 총 %d번 실행되었습니다. \n", csum);
sum(x, y);
}
else if (ch1 == '-') {
printf("뺄셈은 총 %d번 실행되었습니다. \n", csub);
sub(x, y);
}
else if (ch1 == '*') {
printf("곱셈은 총 %d번 실행되었습니다. \n", cmul);
mul(x, y);
}
else if (ch1 == '/') {
printf("나눗셈은 총 %d번 실행되었습니다. \n", cdiv);
div(x, y);
}
}
printf("\n");
return 0;
}
void sum(int a, int b) {
printf("연산 결과: %d \n", a + b);
csum++;
}
void sub(int a, int b) {
printf("연산 결과: %d \n", a - b);
csub++;
}
void mul(int a, int b) {
printf("연산 결과: %d \n", a * b);
cmul++;
}
void div(int a, int b) {
printf("연산 결과: %d \n", a / b);
cdiv++;
}
2. 주사위를 던져서 각각의 면이 몇 번 나왔는지를 출력하는 프로그램을 작성하라. 주사위의 면은 난수를 이용하여 생성한다. 주사위를 던지는 함수 get_dice_face()를 만들고 이 함수 안에서 각각의 면이 나올 때마다 그 횟수를 정적 지역 변수를 이용하여 기억나게 하라. get_dice_face() 호출 횟수가 100의 배수일 때마다 면이 나온 횟수를 출력한다.
**주사위 면은 0에서 5까지의 정수로 표현할 수 있고 0 부터 5까지의 난수는 rand()%6으로 생성할 수 있다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int count = 0;
void get_dice_face(int dice[]);
int main() {
int dice[7] = { 0 };
int i;
for (i = 1; i < 7; i++)
printf("%5d", i);
printf("\n -----------------------------\n");
while (1) {
get_dice_face(dice);
if (count % 100 == 0) {
for (i = 1; i < 7; i++)
printf("%5d", dice[i]);
printf("\n");
}
if (count == 10000) break;
}
printf("\n");
return 0;
}
void get_dice_face(int dice[]) {
dice[1 + rand() % 6] += 1;
count++;
}
3. 정적 지역 변수가 사용되는 하나의 용도는 함수가 처음 호출될 때 초기화를 딱 한번만 수행하는 것이다.
int get_random(void) {
static int inited = 0;
if(inited == 0) { //함수를 초기화한다.
...
}
...
}
inited는 정적 변수이기 때문에 다음번의 호출에서도 그 값을 유지한다. 따라서 초기화 코드는 함수가 처음 호출될 때 한번만 실행된다. 이러한 구조를 사용하여 맨 처음 호출되는 경우에만 초기화를 수행하는 난수 발생 함수 get_random()ㅇ르 작성하여 테스트하라.
**get_random()이 처음으로 호출되는 경우에는 srand()를 호출하여서 난수의 시드를 초기화하고 그렇지 않으면 단순히 난수를 생성하여 반환한다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int get_random();
int main() {
printf("1번째 호출 = %d \n", get_random());
printf("2번째 호출 = %d \n", get_random());
printf("3번째 호출 = %d \n", get_random());
printf("4번째 호출 = %d \n", get_random());
printf("5번째 호출 = %d \n", get_random());
printf("\n");
return 0;
}
int get_random() {
static int inited = 0;
if (inited == 0) {
srand(time(NULL));
inited = 1;
}
return rand() % 100 + 1;
}
***???
4. 다음과 같은 무한 수열을 계산하는 순환적인 프로그램을 작성하라.
1/1+1/2+1/3+...+1/n
**위의 무한 수열을 계산하는 식은 return 1.0/n + recursive(n-1);이다.
#include <stdio.h>
double recursive(double x);
int main() {
double x;
printf("n의 값을 입력하시요: ");
scanf("%lf", &x);
printf("%lf", recursive(x));
printf("\n");
return 0;
}
double recursive(double x) {
if (x == 1)
return 1;
else
return ((1 / x) + recursive(x - 1));
}
5. 은행 계좌에서 저축하고 인출하는 프로그램을 작성하여 보자. save(int amount)함수는 저금할 금액 amount를 받으며 save(100)과 같이 호출된다. draw(int amount)은 예금인출을 나타낸다. 사용자에게 메뉴를 보여주고 저축 또는 인출을 선택하게 한다.
**예금 잔액은 save()와 draw()에서 동시에 사용되므로 전역 변수로 선언하는 것도 좋다.
#include <stdio.h>
int account = 0;
void save(int);
void draw(int);
int main() {
int x;
while (1) {
printf("메뉴를 선택하세요: 저축(1), 인출(2): ");
scanf("%d", &x);
int amount;
if (x == 1) {
printf("저축할 금액: ");
scanf("%d", &amount);
save(amount);
printf("현재 잔액은 %d입니다.\n", account);
}
else if (x == 2) {
printf("인출할 금액: ");
scanf("%d", &amount);
draw(amount);
printf("현재 잔액은 %d입니다.\n", account);
}
}
printf("\n");
return 0;
}
void save(int amount) {
account += amount;
}
void draw(int amount) {
account -= amount;
}
6. 오른쪽과 같은 n번째 삼각수를 계산하는 함수 get_tri_number(int n)을 순환 호출을 이용하여 작성하여 보자.
** 순환 호출 함수에서 return n+get_tri_numbr(n-1);와 같은 수식을 사용한다.
#include <stdio.h>
int get_tri_number(int t);
int main() {
int t;
printf("몇 번째 삼각수를 계산할지 숫자를 입력하시오: ");
scanf("%d", &t);
printf("%d", get_tri_number(t));
printf("\n");
return 0;
}
int get_tri_number(int t) {
if (t == 1) return 1;
else return (t + get_tri_number(t - 1));
}
7.이항 계수 (binomial coefficient)를 계산하는 순환 함수를 작성하라. 이항 계수는 다음과 같이 순환적으로 정의된다. 반복 함수로도 구현해보라.
**순환적으로 정의된 수학식을 그대로 변환하면 된다. recursive(n-1, k-1) + recursive(n-1, k);와 같이 수식을 작성한다.
#include <stdio.h>
double factorial(double k);
double P(double n, double k);
double C(double n, double k);
int main() {
double n, k;
double result;
printf("n의 값을 입력하시오: ");
scanf("%lf", &n);
printf("k의 값을 입력하시오: ");
scanf("%lf", &k);
if (k == 0 || k == n)
result = 1;
else if (k > 0 && k < n)
result = C(n - 1, k - 1) + C(n - 1, k);
printf("결과값: %f \n", result);
return 0;
}
double factorial(double k) {
if (k == 1) return 1;
else return (k * factorial(k - 1));
}
double P(double n, double k) {
double i;
double p = 1;
if (n == 1)
return 1;
else {
for (i = n; i >= n - k + 1; i--)
p *= i;
return p;
}
}
double C(double n, double k) {
double c;
c = P(n, k) / factorial(k);
return c;
}
8. 순환 호출을 이용하여 정수의 각 자리수를 출력하는 함수 show_digit(int x)를 작성하고 테스트하라. 즉 정수가 1234이면 화면에 1 2 3 4와 같이 출력한다. 함수는 일의 자리를 출력하고 나머지 부분을 대상으로 다시 같은 함수를 순환 호출한다. 예를 들어서 1234의 4를 출력하고 나머지 123을 가지고 다시 같은 함수를 순환 호출한다. 1234를 10으로 나누면 123이 되고 4는 1234를 10으로 나눈 나머지이다.
**정수 x를 10으로 나눈 값을 가지고 show_digit(x/10);와 같이 다시 순환호출하면 된다.
#include <stdio.h>
void show_digit(int n);
int main() {
int n;
printf("정수를 입력하시오: ");
scanf("%d", &n);
show_digit(n);
printf("\n");
return 0;
}
void show_digit(int n){
if (n == 0) return;
show_digit(n / 10);
printf("%d ", n % 10);
}
(C프로그래밍 8장 Programming 원글 : https://blog.naver.com/hhahee/221638888167)
'C언어' 카테고리의 다른 글
C프로그래밍 10장 Programming (0) | 2022.12.22 |
---|---|
C프로그래밍 8장 Programming (0) | 2022.12.22 |
C프로그래밍 7장 Programming (0) | 2022.12.22 |
C프로그래밍 6장 Programming (0) | 2022.12.22 |
C프로그래밍 5장 Programming (0) | 2022.12.22 |
댓글