C언어 공부

C언어 기초 - 10. 포인터&배열 연습문제 5개

Client Side 2025. 8. 16. 00:41

 

🌟 C언어 핵심 개념 마스터! 포인터 & 배열 실력 확인 문제 🌟

안녕하세요! 오늘은 C언어 학습자라면 반드시 거쳐야 할 핵심 개념인 '포인터'와 '배열'에 대한 이해도를 점검하고, 그 활용 능력을 높일 수 있는 실전 연습문제들을 준비했습니다. 각 문제와 함께 상세한 해설이 제공되니, 스스로의 코드를 점검하고 부족한 부분을 보완하는 데 활용하시길 바랍니다!


문제 1. 변수 선언과 기본적인 출력

age라는 int 변수를 선언하고 31을 저장하십시오. initial이라는 char 변수를 선언하고 'S'를 저장하십시오. pi라는 double 변수를 선언하고 3.14159를 저장하십시오.

세 변수에 저장된 값들을 각각 한 줄씩 printf 함수를 사용하여 출력하십시오. 출력 시 각 변수에 맞는 서식 지정자를 사용해야 합니다.

[코드 예시]

c

#include <stdio.h>

int main()
{
    int age = 31;
    char initial = 'S';
    double pi = 3.14159;

    printf("%d\n", age);
    printf("%c\n", initial);
    printf("%f\n", pi);

    return 0;
}

[해설] 이 문제는 C언어의 가장 기초적인 부분인 변수 선언과 데이터 출력 방식을 다룹니다. int age = 31;은 정수형 변수 age를 선언하고 초기값 31을 할당하는 코드입니다. char initial = 'S';는 문자형 변수 initial을 선언하고 문자 'S'를 할당하는 코드입니다. 문자는 작은따옴표로 표기하는 것이 특징입니다. double pi = 3.14159;는 실수형 변수 pi를 선언하고 초기값 3.14159를 할당하는 코드입니다. printf("%d\n", age);는 age 변수에 저장된 정수 값을 화면에 출력하는 명령입니다. 이때 %d는 정수 출력을 위한 서식 지정자입니다. printf("%c\n", initial);은 initial 변수에 저장된 문자 값을 출력하는 명령입니다. 이때 %c는 문자 출력을 위한 서식 지정자입니다. printf("%f\n", pi);는 pi 변수에 저장된 실수 값을 출력하는 명령입니다. 이때 %f는 실수 출력을 위한 서식 지정자입니다. 각 printf 문 뒤에 \n을 사용하여 줄 바꿈을 수행합니다.


문제 2. 포인터의 기본 활용

my_value라는 int 변수를 선언하고 123을 저장하십시오. value_ptr이라는 int 포인터를 선언하여 my_value의 주소를 저장하십시오. value_ptr을 역참조(*value_ptr)하여 my_value의 값을 출력하고, my_value의 주소(&my_value)와 value_ptr 포인터 변수의 값(즉, 주소)을 각각 %p 서식 지정자를 사용하여 출력하십시오.

[코드 예시]

c

#include <stdio.h>

int main()
{
    int my_value = 123;
    int* value_ptr = &my_value;

    printf("my_value의 값 (역참조): %d\n", *value_ptr);
    printf("my_value의 주소: %p\n", &my_value);
    printf("value_ptr이 가리키는 주소: %p\n", value_ptr);

    return 0;
}

[해설] 이 문제는 포인터의 기본적인 선언, 주소 할당, 역참조 방법을 다룹니다. int my_value = 123;은 정수형 변수 my_value를 선언하고 123으로 초기화하는 코드입니다. int* value_ptr = &my_value;는 int형 포인터 value_ptr을 선언하고, &my_value를 사용하여 my_value 변수의 메모리 주소를 value_ptr에 할당하는 코드입니다. 즉, value_ptr은 이제 my_value의 메모리 위치를 가리킵니다. *value_ptr은 value_ptr이 가리키는 메모리 주소에 저장된 '값'을 의미합니다. printf("%d\n", *value_ptr);는 이 값을 출력하므로 123이 출력됩니다. &my_value는 변수 my_value의 실제 메모리 주소를 의미합니다. value_ptr은 그 자체가 my_value의 주소값을 저장하고 있는 변수이므로, &my_value와 value_ptr은 동일한 주소값을 출력합니다. %p는 메모리 주소 출력을 위한 서식 지정자입니다.


문제 3. 배열 초기화와 반복문을 이용한 값 채우기 & 출력

numbers라는 int 배열을 선언하는데, 크기는 10으로 하십시오. for 반복문을 사용하여 numbers 배열의 각 요소에 0부터 9까지의 값을 순서대로 저장하십시오. (예: numbers[0] = 0; numbers[1] = 1;...) 다른 for 반복문을 사용하여 배열에 저장된 모든 값을 한 줄에 하나씩 출력하십시오.

[코드 예시]

c

#include <stdio.h>

int main()
{
    int numbers[10]; // 10개의 int형 요소를 저장할 수 있는 배열 선언

    // 첫 번째 for 반복문: 배열에 0부터 9까지의 값 채우기
    for (int i = 0; i < 10; i++)
    {
        numbers[i] = i; // numbers[0]에는 0, numbers[1]에는 1, ... numbers[9]에는 9 저장
    }

    // 두 번째 for 반복문: 배열에 저장된 모든 값 출력하기
    printf("배열 numbers의 요소들:\n");
    for (int j = 0; j < 10; j++)
    {
        printf("%d\n", numbers[j]); // 각 인덱스의 값을 출력
    }

    return 0;
}

[해설] 이 문제는 배열의 선언, 인덱스 접근, 그리고 for 반복문을 활용한 배열 요소 조작 방법을 다룹니다. int numbers[10];은 int형 데이터를 10개 저장할 수 있는 numbers라는 이름의 배열을 선언하는 코드입니다. 배열의 인덱스는 0부터 시작하므로 numbers[0]부터 numbers[9]까지 존재합니다. 첫 번째 for 반복문 for (int i = 0; i < 10; i++)은 변수 i를 0부터 9까지 증가시키며 반복합니다. numbers[i] = i;는 각 반복에서 배열의 i번째 요소에 i 값을 할당하여 배열을 0부터 9까지의 숫자로 채웁니다. 두 번째 for 반복문 for (int j = 0; j < 10; j++)은 첫 번째 반복문과 유사하게 j를 0부터 9까지 증가시키며 반복합니다. printf("%d\n", numbers[j]);는 각 반복에서 배열의 j번째 요소에 저장된 값을 출력합니다.


문제 4. 포인터와 배열의 관계

scores라는 int 배열을 [80, 90, 75, 95, 85]로 선언하고 초기화하십시오. ptr_scores라는 int 포인터를 선언하고 scores 배열의 첫 번째 요소의 주소를 저장하십시오. (즉, &scores[0] 또는 scores 사용) ptr_scores와 포인터 연산(+)을 사용하여 배열의 **세 번째 요소(75)**와 **다섯 번째 요소(85)**를 *()와 printf를 이용하여 출력하십시오. 이때 scores[2]나 scores[4]처럼 직접 인덱스 번호를 사용하지 않고, 포인터 연산을 사용하여 접근해야 합니다.

[코드 예시]

c

#include <stdio.h>

int main()
{
    int scores[5] = {80, 90, 75, 95, 85};
    int* ptr_scores = scores; // 배열 이름 scores는 첫 번째 요소의 주소를 의미합니다.

    // 세 번째 요소 (인덱스 2)에 접근: scores[2]
    printf("세 번째 요소의 값: %d\n", *(ptr_scores + 2)); // 포인터 + 2는 scores[2]의 주소를 가리킵니다.

    // 다섯 번째 요소 (인덱스 4)에 접근: scores[4]
    printf("다섯 번째 요소의 값: %d\n", *(ptr_scores + 4)); // 포인터 + 4는 scores[4]의 주소를 가리킵니다.

    return 0;
}

[해설] 이 문제는 배열 이름이 포인터처럼 동작하는 C언어의 특성을 이해하고 포인터 연산을 활용하는 방법을 다룹니다. int scores[5] = {80, 90, 75, 95, 85};는 5개의 int형 요소를 가지는 scores 배열을 선언하고 초기값을 할당하는 코드입니다. int* ptr_scores = scores;는 int형 포인터 ptr_scores를 선언하고 scores 배열의 첫 번째 요소의 주소를 할당하는 코드입니다. C언어에서 배열의 이름(scores)은 그 자체로 첫 번째 요소의 주소값을 의미하기 때문에 &scores[0]와 동일하게 사용됩니다. *(ptr_scores + 2)는 ptr_scores가 가리키는 주소에서 int 타입 크기의 2배만큼 떨어진 메모리 위치를 역참조하는 표현입니다. 이는 scores[2]와 동일한 값을 가져옵니다. 따라서 75가 출력됩니다. *(ptr_scores + 4)는 ptr_scores가 가리키는 주소에서 int 타입 크기의 4배만큼 떨어진 메모리 위치를 역참조하는 표현입니다. 이는 scores[4]와 동일한 값을 가져옵니다. 따라서 85가 출력됩니다.


문제 5. 함수와 포인터를 이용한 값 교환 (Swap)

두 개의 int 변수 x와 y를 선언하고 각각 10과 20으로 초기화하십시오. main 함수 외부에서 void swap_values(int* val1, int* val2) 이라는 함수를 직접 만드십시오. 이 함수는 두 개의 int 포인터를 인자로 받아서, 그 포인터가 가리키는 두 변수의 값을 서로 교환하도록 구현해야 합니다. main 함수 안에서 x와 y의 값을 swap_values 함수를 호출하기 전과 후에 각각 출력하여 값이 성공적으로 교환되었는지 확인하십시오!

[코드 예시]

c

#include <stdio.h>

// 두 정수 포인터가 가리키는 값을 서로 교환하는 함수
void swap_values(int* val1, int* val2)
{
    int temp;       // 값을 임시로 저장할 변수 선언
    temp = *val1;   // val1이 가리키는 값(x의 값)을 temp에 저장
    *val1 = *val2;  // val1이 가리키는 곳(x의 위치)에 val2가 가리키는 값(y의 값)을 넣음
    *val2 = temp;   // val2이 가리키는 곳(y의 위치)에 temp에 저장된 원래 val1의 값을 넣음
}

int main()
{
    int x = 10;
    int y = 20;

    printf("swap_values 호출 전: x = %d, y = %d\n", x, y);

    // swap_values 함수 호출 시, x와 y의 '주소'를 전달 (Call by Reference)
    swap_values(&x, &y);

    printf("swap_values 호출 후: x = %d, y = %d\n", x, y);

    return 0;
}

[해설] 이 문제는 C언어에서 함수를 통해 변수의 값을 직접 변경하는 'Call by Reference' 개념과 포인터의 활용을 다룹니다. int x = 10;과 int y = 20;은 두 정수형 변수를 선언하고 초기값을 할당하는 코드입니다. void swap_values(int* val1, int* val2) 함수는 두 개의 int형 포인터(val1, val2)를 인자로 받습니다. 이 포인터들은 main 함수에서 넘겨준 x와 y의 주소를 저장하게 됩니다. 함수 내부에서 temp = *val1;은 val1이 가리키는 값(즉, x의 현재 값)을 temp에 임시로 저장합니다. *val1 = *val2;는 val1이 가리키는 메모리 위치(즉, x의 위치)에 val2가 가리키는 값(즉, y의 값)을 복사합니다. 이로써 x의 값은 y의 값으로 변경됩니다. *val2 = temp;는 val2이 가리키는 메모리 위치(즉, y의 위치)에 temp에 저장된 원래 x의 값을 복사합니다. 이로써 y의 값은 x의 원래 값으로 변경됩니다. main 함수에서 swap_values(&x, &y);와 같이 & 연산자를 사용하여 변수 x와 y의 '주소'를 swap_values 함수에 전달합니다. 이렇게 함으로써 함수는 원본 변수들의 메모리 위치에 직접 접근하여 값을 변경할 수 있게 됩니다.