본문 바로가기

C/쉽게 풀어쓴 C언어 Express

쉽게 풀어쓴 C언어 Express 11장 Programming

01 포인터를 이용하여 자기가 사용하는 CPU의 바이트 순서를 살펴보는 프로그램을 작성해보자. 바이트 순서(byte ordering, endian)은 컴퓨터의 메모리에 바이트를 배열하는 방법이다. 바이트 순서는 큰 단위가 앞에 나오는 빅 엔디언(Big-endian)과 작은 단위가 앞에 나오는 리틀 엔디언(Little-endian)으로 나눌 수 있다. 아래의 프로그램에 주석을 추가하라.

종류 0x12345678의 표현
빅 엔디언 12 34 56 78
리틀 엔디언 78 56 34 12
1
2
3
4
5
6
7
8
#include <stdio.h>
int main() {
    int x = 0x12345678;
    unsigned char* xp = (char*)&x;
 
    printf("바이트순서: %x %x %x %x\n", xp[0], xp[1], xp[2], xp[3]);
    return 0;
}
cs

 

1
2
3
4
5
6
7
8
9
10
// 프로그램 실행 후 인텔 CPU는 리틀 엔디언임을 알 수 있다.
#include <stdio.h>
 
int main() {
    int x = 0x12345678;
    unsigned char* xp = (unsigned char*)&x;
 
    printf("바이트순서: %x %x %x %x\n", xp[0], xp[1], xp[2], xp[3]);
    return 0;
}
cs

 

 

 

02 2개의 정수의 합과 차를 동시에 반환하는 함수를 작성하고 테스트하라. 포인터 매개 변수를 사용한다.

1
2
3
void get_sum_diff(int x, int y, int* p_sum, int* p_diff) {
        ...
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
void get_sum_diff(int x, int y, int* p_sum, int* p_diff) {
    *p_sum = x + y;
    *p_diff = x - y;
}
 
int main() {
    int a = 100, b = 200;
    int sum, diff;
    get_sum_diff(a, b, &sum, &diff);
    printf("원소들의 합=%d\n", sum);
    printf("원소들의 차=%d\n", diff);
    return 0;
}
cs

 

 

 

03 정수 배열을 받아서 요소들을 난수로 채우는 함수를 작성하고 테스트하라. 난수는 라이브러리 함수인 rand()를 사용하여 생성한다.

1
2
3
4
5
6
void array_fill(int* A, int size) {
    int i;
    for (i = 0; i < size; i++) {
        ...
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
 
void array_fill(int* A, int size) {
    for (int i = 0; i < size; i++)
        A[i] = rand();
}
 
int main() {
    int a[10];
    array_fill(a, 10);
    for (int i = 0; i < 10; i++)
        printf("%d ", a[i]);
    return 0;
}
cs

 

 

 

04 정수 배열의 요소들을 화면에 출력하는 함수를 작성하고 테스트하라. 출력 형식은 A[] = { 1, 2, 3, 4, 5 }와 같은 형식이 되도록 하라.

1
2
3
4
5
6
7
8
void array_print(int* A, int size) {
    int i;
    printf("A[] = { ");
    for (i = 0; i < size; i++) {
        ...
    }
    printf("A[] = }\n");
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
void array_print(int* A, int size) {
    printf("A[]={ ");
    for (int i = 0; i < size; i++) {
        printf("%d ", A[i]);
    }
    printf("}\n");
}
 
int main() {
    int A[10= { 1,2,3,4 };
    array_print(A, 10);
    return 0;
}
cs

 

 

 

05 학생들의 평점은 4.3점이 만점이라고 하자. 배열 grades[]에 학생 10명의 학점이 저장되어 있다. 이것을 100점 만점으로 변환하여서 배열 scores[]에 저장하는 함수를 작성하고 테스트하라.

1
2
3
4
5
6
void convert(double* grades, double* scores, int size) {
    int i;
    for (i = 0; i < size; i++) {
        ...
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
void convert(double* grades, double* scores, int size) {
    for (int i = 0; i < size; i++)
        scores[i] = grades[i] / 4.3 * 100;
}
 
int main() {
    double grades[10= { 0.00.51.01.52.02.53.03.54.04.3 };
    double scores[10];
    convert(grades, scores, 10);
    for (int i = 0; i < 10; i++)
        printf("%05.2lf ", grades[i]);
    printf("\n");
    for (int i = 0; i < 10; i++)
        printf("%05.2lf ", scores[i]);
    return 0;
}
cs

 

 

 

06 정수 배열 A[]를 다른 정수 배열 B[]에 복사하는 함수를 작성하고 테스트하라.

1
2
3
4
5
6
void array_copy(int* A, int* B, int size) {
    int i;
    for (i = 0; i < size; i++) {
        ...
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
 
void array_copy(int* A, int* B, int size) {
    for (int i = 0; i < size; i++)
        B[i] = A[i];
}
 
int main() {
    int A[10= { 1,2,3 };
    int B[10];
    array_copy(A, B, 10);
 
    printf("A[] = ");
    for (int i = 0; i < 10; i++)
        printf("%d ", A[i]);
    printf("\nB[] = ");
    for (int i = 0; i < 10; i++)
        printf("%d ", B[i]);
    return 0;
}
cs

 

 

 

07 직원들의 기본급이 배열 A[]에 저장되어 있다. 배열 B[]에는 직원들의 보너스가 저장되어 있다. 기본급과 보너스를 합하여 이번달에 지급할 월급의 총액을 계산하고자 한다. A[]와 B[]를 더하여 배열 C[]에 저장하는 함수를 작성하고 테스트하라. 즉 모든 i에 대하여 C[i] = A[i] + B[i]가 된다.

1
2
3
4
5
6
void array_add(int* A, int* B, int* C, int size) {
    int i;
    for (i = 0; i < size; i++) {
        ...
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
 
void array_add(int* A, int* B, int* C, int size) {
    for (int i = 0; i < size; i++)
        C[i] = A[i] + B[i];
}
 
int main() {
    int A[10= { 1,2,3 };
    int B[10= { 0 };
    int C[10];
    array_add(A, B, C, 10);
 
    printf("A[] = ");
    for (int i = 0; i < 10; i++)
        printf("%d ", A[i]);
    printf("\nB[] = ");
    for (int i = 0; i < 10; i++)
        printf("%d ", B[i]);
    printf("\nC[] = ");
    for (int i = 0; i < 10; i++)
        printf("%d ", C[i]);
    return 0;
}
cs

 

 

 

08 직원들의 월급이 배열 A[]에 저장되어 있다고 가정하자. 이번 달에 회사에서 지급할 월급의 총액을 계산하고자 한다. 정수형 배열 요소들의 합을 구하여 반환하는 함수를 작성하고 테스트하라.

1
2
3
4
5
6
7
int array_sum(int* A, int size) {
    int i, sum = 0;
    for (i = 0; i < size; i++) {
        ...
    }
    return sum;
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
int array_sum(int* A, int size) {
    int sum = 0;
    for (int i = 0; i < size; i++)
        sum += A[i];
    return sum;
}
 
int main() {
    int A[10= { 1,2,3 };
    printf("A[] = ");
    for (int i = 0; i < 10; i++)
        printf("%d ", A[i]);
    printf("\n월급의 합=%d", array_sum(A, 10));
    return 0;
}
cs

 

 

 

09 직원들의 월급이 저장된 배열에서 월급이 200만 원인 사람을 찾고 싶을 때가 있다. 주어진 값을 배열 A[]에서 탐색하여 배열 요소의 인덱스를 반환하는 함수를 작성하고 테스트하라.

1
2
3
4
5
6
int search(int* A, int sizeint search_value) {
    int i;
    for (i = 0; i < size; i++) {
        if (A[i] == search_value) ...
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int search(int* A, int sizeint search_value) {
    for (int i = 0; i < size; i++) {
        if (A[i] == search_value)
            return i;
    }
}
 
int main() {
    int A[10= { 100,200,300 };
    printf("월급이 200만원인 사람의 인덱스=%d", search(A, 10200));
    return 0;
}
cs

 

 

 

10 2개의 정수를 입력받아서 최대 공약수와 최소 공배수를 반환하는 함수를 작성하고 테스트하라. 최대 공약수는 유클리드의 방법을 사용하여서 계산한다.

1
2
3
void get_lcm_gcd(int x, int y, int* p_lcm, int* p_gcd) {
        ...
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
void get_lcm_gcd(int x, int y, int* p_lcm, int* p_gcd) {
    static int mul = x * y;
    if (y == 0) {
        *p_gcd = x;
        *p_lcm = mul / x;
    }
    else
        get_lcm_gcd(y, x % y, p_lcm, p_gcd);
}
 
int main() {
    int n, m, lcm, gcd;
    printf("두개의 정수를 입력하시오: ");
    scanf("%d %d"&n, &m);
    get_lcm_gcd(n, m, &lcm, &gcd);
    printf("최소공배수는 %d입니다.\n", lcm);
    printf("최대공약수는 %d입니다.\n", gcd);
    return 0;
}
cs

 

 

 

11 2개의 정렬된 정수 배열 A[]와 B[]가 있다고 가정하자. 이 2개의 배열을 합쳐서 하나의 정렬된 배열 C[]로 만드는 함수를 작성하고 테스트 한다. 다음과 같은 함수 원형을 가진다고 가정하라.

1
2
3
void merge(int* A, int* B, int* C, int size) {
        ...
}
cs

 

여기서 배열 A[], B[]는 똑같은 크기로 정의되어 있다고 가정한다. 배열 C[]에는 충분한 공간이 확보되어 있다고 가정하자. 합치는 알고리즘은 다음과 같다. 먼저 A[0]와 B[0]를 비교한다. 만약 A[0]가 B[0]보다 작으면 A[0]를 C[0]에 복사한다. 다음에는 A[1]과 B[0]를 비교한다. 이번에는 B[0]가 A[1]보다 작다면 B[0]를 C[1]에 저장한다. 똑같은 방식으로 남아있는 요소들을 비교하여 더 작은 요소를 C[]로 복사한다. 만약 A[]나 B[]중에서 어느 하나가 먼저 끝나게 되면 남아있는 요소들을 전부 C[]로 이동한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
 
void merge(int* A, int* B, int* C, int size) {
    int j = 0, k = 0;
    for (int i = 0; i < size; i++) {
        if (A[j] < B[k] || k == 4) {
            C[i] = A[j];
            j++;
        }
        else {
            C[i] = B[k];
            k++;
        }
    }
}
 
int main() {
    int A[4= { 2,5,7,8 };
    int B[4= { 1,3,4,6 };
    int C[8];
    merge(A, B, C, 8);
 
    printf("A[] = ");
    for (int i = 0; i < 4; i++)
        printf("%d ", A[i]);
    printf("\nB[] = ");
    for (int i = 0; i < 4; i++)
        printf("%d ", B[i]);
    printf("\nC[] = ");
    for (int i = 0; i < 8; i++)
        printf("%d ", C[i]);
    return 0;
}
cs

 

 

 

12 우리가 프로그램을 하다보면 사용자로부터 2개의 정수를 받아오는 경우가 많다. 이것을 함수로 구현해두고 필요할 때마다 사용하면 편리할 것이다. 하지만 한 가지 문제가 있다. C에서 함수는 하나의 값만 반환할 수 있다. 2개 이상의 값을 반환하려면 다른 방법을 사용해야 하는데 다음과 같이 포인터도 사용할 수 있다.

1
void get_int(int* px, int* py);
cs

 

위와 같은 원형을 가지는 함수를 작성하고 이것을 이용해서 정수의 합을 계산하는 프로그램을 작성해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
void get_int(int* px, int* py) {
    scanf("%d %d", px, py);
}
 
int main() {
    int n, m;
    printf("2개의 정수를 입력하시오(예: 10 20): ");
    get_int(&n, &m);
    printf("정수의 합은 %d", n + m);
    return 0;
}
cs