C 언어에서 배열과 함수의 활용: 실습 가이드

1. 배열 메모리 구조 이해

다음 코드는 1차원 및 2차원 정수 배열의 메모리 할당 방식을 분석합니다.

#include <stdio.h>
#define N 4
#define M 2

void test1() {
    int arr[N] = {1, 9, 8, 4};          
    int i;
    printf("sizeof(arr) = %d\n", sizeof(arr));
    for (i = 0; i < N; ++i)
        printf("%p: %d\n", &arr[i], arr[i]);
    printf("arr = %p\n", arr); 
}

void test2() {
    int matrix[M][N] = {{1, 9, 8, 4}, {2, 0, 4, 9}};
    int i, j;
    printf("sizeof(matrix) = %d\n", sizeof(matrix));
    for (i = 0; i < M; ++i)
        for (j = 0; j < N; ++j)
            printf("%p: %d\n", &matrix[i][j], matrix[i][j]);
    printf("\n");
    printf("matrix = %p\n", matrix);
    printf("matrix[0] = %p\n", matrix[0]);
    printf("matrix[1] = %p\n", matrix[1]);
    printf("\n");
}

int main() {
    printf("1차원 int 배열 테스트\n");
    test1();
    printf("\n2차원 int 배열 테스트\n");
    test2();
    return 0;
}

핵심 분석:

  • 1차원 배열은 메모리에 연속적으로 저장됩니다.
  • 2차원 배열은 행 우선(row-major) 방식으로 연속 저장되며, matrix[0]matrix는 같은 주소를 가리킵니다.
  • matrix[0]matrix[1]의 주소 차이는 각 행이 차지하는 바이트 크기(여기서는 16바이트, int 4개)와 일치합니다.

2. 함수를 활용한 배열 처리

2.1 평균 계산 (최대/최소 제외)

#include <stdio.h>
#define MAX 100

void read_array(int data[], int size);
double compute_trimmed_mean(int data[], int size);

int main() {
    int values[MAX];
    int count;
    double result;

    while (printf("개수 입력: "), scanf("%d", &count) != EOF) {
        read_array(values, count);
        result = compute_trimmed_mean(values, count);
        printf("결과 = %.2f\n\n", result);
    }
    return 0;
}

void read_array(int data[], int size) {
    for (int i = 0; i < size; ++i)
        scanf("%d", &data[i]);
}

double compute_trimmed_mean(int data[], int size) {
    int maxVal = data[0], minVal = data[0];
    double sum = 0;

    for (int i = 0; i < size; ++i) {
        sum += data[i];
        if (data[i] > maxVal) maxVal = data[i];
        else if (data[i] < minVal) minVal = data[i];
    }
    return (sum - maxVal - minVal) / (size - 2);
}

설명:

  • read_array 함수는 사용자 입력을 배열에 저장합니다.
  • compute_trimmed_mean 함수는 최대값과 최소값을 제외한 평균을 계산하여 반환합니다.

2.2 2차원 배열 초기화 및 출력

#include <stdio.h>
#define DIM 100

void display_matrix(int grid[][DIM], int size);
void fill_matrix(int grid[][DIM], int size, int fill_value);

int main() {
    int matrix[DIM][DIM];
    int n, val;

    while (printf("크기와 값 입력: "), scanf("%d%d", &n, &val) != EOF) {
        fill_matrix(matrix, n, val);
        display_matrix(matrix, n);
        printf("\n");
    }
    return 0;
}

void display_matrix(int grid[][DIM], int size) {
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j)
            printf("%d ", grid[i][j]);
        printf("\n");
    }
}

void fill_matrix(int grid[][DIM], int size, int fill_value) {
    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size; ++j)
            grid[i][j] = fill_value;
}

참고: 2차원 배열을 함수 인자로 전달할 때 두 번째 차원 크기는 반드시 명시해야 합니다.

2.3 중간값(Median) 계산

#include <stdio.h>
#define MAX 100

void read_array(int data[], int size);
double find_median(int data[], int size);

int main() {
    int values[MAX];
    int count;
    double med;

    while (printf("개수 입력: "), scanf("%d", &count) != EOF) {
        read_array(values, count);
        med = find_median(values, count);
        printf("중간값 = %g\n\n", med);
    }
    return 0;
}

void read_array(int data[], int size) {
    for (int i = 0; i < size; ++i)
        scanf("%d", &data[i]);
}

double find_median(int data[], int size) {
    // 버블 정렬 (오름차순)
    for (int i = 0; i < size - 1; ++i) {
        for (int j = 0; j < size - 1 - i; ++j) {
            if (data[j] > data[j + 1]) {
                int temp = data[j];
                data[j] = data[j + 1];
                data[j + 1] = temp;
            }
        }
    }

    if (size % 2 == 1)
        return (double)data[size / 2];
    else
        return (double)(data[size / 2 - 1] + data[size / 2]) / 2.0;
}

설명: 배열을 정렬한 후 홀수 개이면 중앙값, 짝수 개이면 두 중앙값의 평균을 반환합니다.

3. 배열 변환 및 진법 변환

3.1 행 우측 회전

#include <stdio.h>
#define DIM 100

void read_matrix(int grid[][DIM], int size);
void print_matrix(int grid[][DIM], int size);
void rotate_rows_right(int grid[][DIM], int size);

int main() {
    int matrix[DIM][DIM];
    int n;

    printf("크기 입력: ");
    scanf("%d", &n);
    read_matrix(matrix, n);
    printf("원본 행렬:\n");
    print_matrix(matrix, n);
    
    rotate_rows_right(matrix, n);
    
    printf("변환된 행렬:\n");
    print_matrix(matrix, n);
    return 0;
}

void read_matrix(int grid[][DIM], int size) {
    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size; ++j)
            scanf("%d", &grid[i][j]);
}

void print_matrix(int grid[][DIM], int size) {
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j)
            printf("%4d", grid[i][j]);
        printf("\n");
    }
}

void rotate_rows_right(int grid[][DIM], int size) {
    for (int i = 0; i < size; ++i) {
        int last = grid[i][size - 1];
        for (int j = size - 1; j > 0; --j)
            grid[i][j] = grid[i][j - 1];
        grid[i][0] = last;
    }
}

설명: 각 행의 요소를 오른쪽으로 한 칸씩 이동하고, 마지막 요소는 첫 번째 위치로 옮깁니다.

3.2 진법 변환 (2진법, 8진법, 16진법)

#include <stdio.h>
#define MAX_DIGITS 100

void convert_base(int decimal, int base);

int main() {
    int number;

    while (printf("10진수 입력: "), scanf("%d", &number) != EOF) {
        convert_base(number, 2);
        convert_base(number, 8);
        convert_base(number, 16);
        printf("\n");
    }
    return 0;
}

void convert_base(int decimal, int base) {
    int digits[MAX_DIGITS], count = 0;

    if (decimal == 0) {
        printf("0\n");
        return;
    }

    while (decimal > 0) {
        digits[count++] = decimal % base;
        decimal /= base;
    }

    for (int i = count - 1; i >= 0; i--) {
        printf("%c", digits[i] < 10 ? digits[i] + '0' : digits[i] - 10 + 'A');
    }
    printf("\n");
}

설명: 10진수 입력을 받아 각각 2진수, 8진수, 16진수로 변환하여 출력합니다.

4. 마방진(Magic Square) 검증

#include <stdio.h>
#define DIM 100

void read_square(int grid[][DIM], int size);
void print_square(int grid[][DIM], int size);
int is_magic_square(int grid[][DIM], int size);

int main() {
    int square[DIM][DIM];
    int n;

    while (printf("크기 입력: "), scanf("%d", &n) != EOF) {
        printf("정사각형 입력:\n");
        read_square(square, n);
        printf("출력:\n");
        print_square(square, n);
        if (is_magic_square(square, n))
            printf("마방진입니다\n\n");
        else
            printf("마방진이 아닙니다\n\n");
    }
    return 0;
}

void read_square(int grid[][DIM], int size) {
    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size; ++j)
            scanf("%d", &grid[i][j]);
}

void print_square(int grid[][DIM], int size) {
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j)
            printf("%4d", grid[i][j]);
        printf("\n");
    }
}

int is_magic_square(int grid[][DIM], int size) {
    if (size % 2 == 0 || size <= 0) return 0;

    int target = size * (size * size + 1) / 2;
    int used[DIM * DIM + 1] = {0};

    // 1) 숫자 범위 및 중복 확인
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j) {
            int val = grid[i][j];
            if (val < 1 || val > size * size || used[val])
                return 0;
            used[val] = 1;
        }
    }

    // 2) 각 행과 열의 합 확인
    for (int i = 0; i < size; ++i) {
        int row_sum = 0, col_sum = 0;
        for (int j = 0; j < size; ++j) {
            row_sum += grid[i][j];
            col_sum += grid[j][i];
        }
        if (row_sum != target || col_sum != target)
            return 0;
    }

    // 3) 두 대각선 합 확인
    int diag1_sum = 0, diag2_sum = 0;
    for (int i = 0; i < size; ++i) {
        diag1_sum += grid[i][i];
        diag2_sum += grid[i][size - 1 - i];
    }
    if (diag1_sum != target || diag2_sum != target)
        return 0;

    return 1;
}

설명: 마방진 조건(1~n²의 유일한 숫자, 모든 행/열/대각선 합 동일)을 만족하는지 검사합니다.

태그: C 배열 포인터 함수 메모리

7월 20일 19:14에 게시됨