16장 Exercise & Programming
16장 Exercise
1. #define을 이용하여 다음 매크로 SIZE를 10으로 올바르게 정의한 것을 모두 고르시오.
정답: 4번 #define SIZE 10
2. 다음의 설명에 부합하는 매크로를 정의하여보자.
// a번
#define RANGE(x, y, z)
((x) < (y) || (x) > (z) ? 0 : 1)
// b번
#define ODD_GT(x, y)
(((x) % 2 != 0) && ((x) > (y)) ? 1 : 0)
// c번
#define IS_UPPER(c)
((c) >= 'A' && (c) <= 'Z')
3. 다음의 문장에 오류가 있다면 그 이유를 적으시오.
#define SQURE(x) ((x)*(x))
#ifdef VERSION==1
#if (DEBUG > 3.00)
#undef DEBUG
#define SIZE=100
#if (VERSION*100 > 300 && DATE > 080901)
#if (LEVEL == "BASIC")
정답
1. #define SQURE(x) ((x)*(x)): "SQURE"는 "SQUARE"로 오타가 있습니다.
2. #ifdef VERSION==1: #ifdef 뒤에 비교 연산자를 사용할 수 없습니다. #ifdef는 매크로가 정의되어 있는지 검사합니다.
3. #if (DEBUG > 3.00): DEBUG의 값이 실수형으로 비교되고 있습니다. 매크로의 값을 비교할 때는 정수로 비교하는 것이 적절합니다.
4. #undef DEBUG: 문제없음.
5. #define SIZE=100: 매크로 정의에 =를 사용하면 안 됩니다. 올바른 정의는 #define SIZE 100입니다.
6. #if (VERSION*100 > 300 && DATE > 080901): 비교 조건에서 정수 값으로 제대로 비교되어야 합니다. DATE는 정수로 정의되어야 합니다.
7. #if (LEVEL == "BASIC"): 문자열 비교에는 #if를 사용할 수 없습니다. 대신 문자열 비교 함수(strcmp)를 사용해야 합니다
4. #include <header>와 #include "header"의 차이점은 무엇인가?
정답
1. #include <header>: 시스템 디렉토리에서 헤더 파일을 검색합니다.
2. #include "header": 현재 디렉토리에서 먼저 헤더 파일을 검색한 후 시스템 디렉토리에서 검색합니다.
5. 다음 프로그램에서 논리적으로 잘못된 부분을 찾아서 올바르게 수정하시오.
#define AREA(w, h) ((w) * (h)) // 수정한 부분
int main(void) {
int x = 10;
printf("%d\n", AREA(x+1, 10));
return 0;
}
6. 다음 프로그램의 결과를 예측하시오.
정답: DEBUG 버전
7. 다음 프로그램이 출력하는 것은 무엇인가?
정답: Kim and Park Hello!
8. 다음의 소스에서 오류가 있는지 살펴보고 만약 오류가 있다면 올바르게 수정하시오. 논리적인 오류도 포함한다.
정답
a) #ifndef DEBUG
b) int x = 10; 추가
9. 다음의 설명에 부합하는 문장을 작성해보자.
(a) 1비트 크기의 비트 필드 8개를 선언한다. 비트 필드의 이름은 bit1에서 bit8으로 한다.
(b) bit1에 1을 대입한다.
struct {
unsigned int bit1: 1;
unsigned int bit2: 1;
unsigned int bit3: 1;
unsigned int bit4: 1;
unsigned int bit5: 1;
unsigned int bit6: 1;
unsigned int bit7: 1;
unsigned int bit8: 1;
} bits;
int main(void) {
bits.bit1 = 1;
return 0;
}
16장 Programming
1. 다음 소스에 대한 질문에 답하라.
a) 전처리기 지시자 #ifdef를 사용하여 DEBUG가 정의되어 있는 경우에만 화면 출력이 나오도록 해보자.
double power(int x, int y) {
double result = 1.0;
int i;
for (i = 0; i < y; i++) {
#ifdef DEBUG
printf("result=%f\n", result);
#endif
result *= x;
}
return result;
}
b) #if를 사용하여 DEBUG가 2이고 LEVEL이 3인 경우에만 화면 출력이 나오도록 수정해보자.
double power(int x, int y) {
double result = 1.0;
int i;
for (i = 0; i < y; i++) {
#if (DEBUG == 2) && (LEVEL == 3)
printf("result=%f\n", result);
#endif
result *= x;
}
return result;
}
c) 문장을 수정하여 소스 파일에서 현재의 행 번호가 함께 출력되도록 해보자.
double power(int x, int y) {
double result = 1.0;
int i;
for (i = 0; i < y; i++) {
printf("Line %d: result=%f\n", __LINE__, result);
result *= x;
}
return result;
}
d) #if를 이용하여 문장을 주석 처리하여보자.
double power(int x, int y) {
double result = 1.0;
int i;
for (i = 0; i < y; i++) {
#if 0
printf("result=%f\n", result); // 이 부분은 주석 처리됨
#endif
result *= x;
}
return result;
}
2. 3개의 정수 중에서 최소값을 구하는 매크로 GET_MIN(x, y, z)를 정의하고 이것을 이용하여 사용자로부터 받은 3개의 정수 중에서 최소값을 계산하여 출력하는 프로그램을 작성하라.
#include <stdio.h>
#define GET_MIN(x, y, z) ((x) < (y) ? ((x) < (z) ? (x) : (z)) : ((y) < (z) ? (y) : (z)))
int main(void) {
int x, y, z;
printf("3개의 정수를 입력하세요: ");
scanf("%d %d %d", &x, &y, &z);
printf("최소값은 %d입니다.\n", GET_MIN(x, y, z));
return 0;
}
3. 배열 원소의 값을 모두 지정된 값으로 초기화하는 ARRAY_INIT(array, size, value)를 작성하여 테스트하여보자.
#include <stdio.h>
#define ARRAY_INIT(array, size, value) \
for (int i = 0; i < (size); i++) { \
(array)[i] = (value); \
}
int main(void) {
int array[10];
ARRAY_INIT(array, 10, 0);
for (int i = 0; i < 10; i++) {
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
4. 원기둥의 부피는 πr²h이다. 사용자로부터 반지름과 높이를 받아서 원기둥의 부피를 구하는 프로그램을 작성하라. 파이는 단순 매크로로 정의한다.
#include <stdio.h>
#define PI 3.141592
#define VOLUME(r, h) (PI * (r) * (r) * (h))
int main(void) {
double r, h;
printf("원기둥의 반지름을 입력하세요: ");
scanf("%lf", &r);
printf("원기둥의 높이를 입력하세요: ");
scanf("%lf", &h);
printf("원기둥의 부피: %.2f\n", VOLUME(r, h));
return 0;
}
5. c가 공백 문자(탭, 스페이스, 줄바꿈 문자)이면 참이 되는 매크로 IS_SPACE(c)를 정의하여 사용자가 입력한 문자열 중에서 공백 문자의 개수를 출력하여보자.
#include <stdio.h>
#define IS_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
int main(void) {
char str[256];
int count = 0;
printf("문자열을 입력하세요: ");
fgets(str, sizeof(str), stdin);
for (int i = 0; str[i] != '\0'; i++) {
if (IS_SPACE(str[i])) {
count++;
}
}
printf("공백 문자의 개수: %d\n", count);
return 0;
}
6. 정수값을 받아서 2진수 형태로 출력하는 함수 display_bit(int value)를 작성하여보자. 본문에서 정의한 함수 매크로 GET_BIT(n, pos)를 사용한다.
#include <stdio.h>
#define GET_BIT(n, pos) (((n) & (1 << (pos))) ? 1 : 0)
void display_bit(int value) {
for (int i = 31; i >= 0; i--) {
printf("%d", GET_BIT(value, i));
if (i % 8 == 0) {
printf(" ");
}
}
printf("\n");
}
int main(void) {
int value;
printf("정수값을 입력하세요: ");
scanf("%d", &value);
display_bit(value);
return 0;
}
7. 사용자로부터 입력받은 정수를 비트 이동시키는 프로그램을 작성하여보자. 먼저 정수 변수의 값을 입력받은 후에 이동시킬 방향, 이동할 거리를 사용자로부터 입력받는다. 비트 이동 전후의 정수의 값을 비트로 출력하도록 한다. 앞 문제에서 작성한 display_bit() 함수를 사용하라.
#include <stdio.h>
#define GET_BIT(n, pos) (((n) & (1 << (pos))) ? 1 : 0)
void display_bit(int value) {
for (int i = 31; i >= 0; i--) {
printf("%d", GET_BIT(value, i));
if (i % 8 == 0) {
printf(" ");
}
}
printf("\n");
}
int main(void) {
int value, direction, distance;
printf("정수값을 입력하세요: ");
scanf("%d", &value);
printf("왼쪽 이동은 0, 오른쪽 이동은 1을 입력하세요: ");
scanf("%d", &direction);
printf("이동시킬 거리: ");
scanf("%d", &distance);
printf("이동 전: ");
display_bit(value);
if (direction == 0) {
value <<= distance;
} else if (direction == 1) {
value >>= distance;
} else {
printf("잘못된 입력입니다.\n");
return 1;
}
printf("이동 후: ");
display_bit(value);
return 0;
}
8. 비트 연산자를 이용하여 대소문자를 변경할 수 있다. 대문자의 ASCII 코드는 모두 여섯 번째 비트가 0이고 소문자의 경우에는 여섯 번째 비트가 모두 1이다. 따라서 XOR 연산을 이용하여 여섯 번째 비트를 바꿔주면 대소문자가 바뀌게 된다. 이 성질을 이용하여 사용자가 입력한 문자열의 대소문자를 바꾸는 프로그램을 작성하라.
#include <stdio.h>
void toggle_case(char *str) {
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] >= 'A' && str[i] <= 'Z') {
str[i] ^= 0x20; // 대문자를 소문자로 변환
} else if (str[i] >= 'a' && str[i] <= 'z') {
str[i] ^= 0x20; // 소문자를 대문자로 변환
}
}
}
int main(void) {
char str[100];
printf("문자열을 입력하세요: ");
fgets(str, sizeof(str), stdin);
toggle_case(str);
printf("결과 문자열: %s\n", str);
return 0;
}
9. 암호화 방법 중의 하나는 암호화할 값은 키값과 비트 XOR 연산을 하는 것이다. 원래의 값을 복원하려면 다시 비트 XOR 연산을 하면 된다. 이 암호화 방법을 사용하여 사용자로부터 문자열을 암호화하고 다시 복호화하는 프로그램을 작성하라.
#include <stdio.h>
#include <string.h>
void xor_encrypt_decrypt(char *str, char key) {
for (int i = 0; str[i] != '\0'; i++) {
str[i] ^= key;
}
}
int main(void) {
char str[100];
char key = 'K';
printf("문자열을 입력하세요: ");
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0';
xor_encrypt_decrypt(str, key);
printf("암호화된 문자열: %s\n", str);
xor_encrypt_decrypt(str, key);
printf("복호화된 문자열: %s\n", str);
return 0;
}
10. 다음과 같은 2개의 파일로 이루어진 프로그램을 작성하고 컴파일하여 실행해보자.
1. 정수 2개를 받아서 합계를 반환하는 함수 add(int x, int y)를 가지고 있는 add.c
2. add()를 호출하여 10과 20의 합을 계산하는 문장이 포함된 main.c`
// add.c
int add(int x, int y) {
return x + y;
}
// main.c
#include <stdio.h>
int add(int x, int y);
int main(void) {
int sum = add(10, 20);
printf("합계=%d\n", sum);
return 0;
}
11. 배열에 관한 각종 연산을 포함하는 array.c를 작성한다. 예를 들어서 배열 원소들의 합을 계산하는 함수 get_sum_of_array(), 배열 원소들을 화면에 출력하는 함수 print_array() 등의 함수를 포함한다. 다시 main.c 파일을 생성하고, 여기서 array.c에 포함된 함수들을 호출하여 보라. array.c가 제공하는 함수들은 원형을 array.h 헤더 파일에 저장한다.
// array.h
#ifndef ARRAY_H
#define ARRAY_H
int get_sum_of_array(int a[], int size);
void print_array(int a[], int size);
#endif
// array.c
#include "array.h"
#include <stdio.h>
int get_sum_of_array(int a[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += a[i];
}
return sum;
}
void print_array(int a[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
// main.c
#include <stdio.h>
#include "array.h"
int main(void) {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int size = sizeof(arr) / sizeof(arr[0]);
print_array(arr, size);
printf("배열의 합=%d\n", get_sum_of_array(arr, size));
return 0;
}
12. 지금까지 학습한 내용을 바탕으로 화면에 달력을 출력하는 프로그램을 만들어보자. 화면에 현재 월을 출력한다. 전처리기를 사용하여 영어 버전과 한국어 버전을 작성해본다.
#include <stdio.h>
int get_day(int date, int month, int year) {
int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
if (month < 3) year -= 1;
return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + date) % 7;
}
void print_calendar(int year, int month) {
const char *days[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
days_in_month[1] = 29;
}
printf("Enter year: %d\nEnter month: %d\n", year, month);
for (int i = 0; i < 7; i++) {
printf("%s ", days[i]);
}
printf("\n");
int start_day = get_day(1, month, year);
for (int i = 0; i < start_day; i++) {
printf(" ");
}
for (int day = 1; day <= days_in_month[month - 1]; day++) {
printf("%3d ", day);
if ((start_day + day) % 7 == 0) {
printf("\n");
}
}
printf("\n");
}
int main(void) {
int year, month;
printf("연도를 입력하세요: ");
scanf("%d", &year);
printf("월을 입력하세요: ");
scanf("%d", &month);
print_calendar(year, month);
return 0;
}
17장 Exercise & Programming은 아래 클릭하시면됩니다.
[쉽게 풀어쓴 C언어 Express 개정4판] 17장 Exercise & Programming
[쉽게 풀어쓴 C언어 Express 개정4판] 17장 Exercise & Programming
17장 Exercise & Programming 17장 Exercise 1. 3번 2. 1번 3 char* p; p = (char *)malloc(1000); printf(“텍스트를 입력하시오: “); gets(p); printf(“입력된 텍스트는 %s입니다. \n”, p); 4. a) malloc(), free() b) void * c) size_t 5. a
gomszone.tistory.com
'프로그래밍 > C언어' 카테고리의 다른 글
[쉽게 풀어쓴 C언어 Express 개정4판] 15장 Exercise & Programming (3) | 2024.10.17 |
---|---|
[쉽게 풀어쓴 C언어 Express 개정4판] 14장 Exercise & Programming (1) | 2024.10.17 |
[쉽게 풀어쓴 C언어 Express 개정4판] 17장 Exercise & Programming (11) | 2024.02.13 |
[쉽게 풀어쓴 C언어 Express 개정4판] 13장 Exercise & Programming (10) | 2024.02.12 |
[쉽게 풀어쓴 C언어 Express 개정4판] 12장 Exercise & Programming (4) | 2024.02.12 |
댓글