[C] 11. 배열과 포인터

Taeil Nam·2022년 6월 16일
0

C

목록 보기
11/18
post-thumbnail

1. 배열과 memory

배열

  • 하나의 변수에 여러 개의 값을 저장하기 위해 사용.
  • 여러 개의 memory 공간을 할당 받는 것과 동일.
  • 배열의 크기(memory 공간 개수) 만큼 값 저장 가능.
  • 대괄호로 배열의 크기를 선언.
  • 배열의 순서는 0부터 시작.
  • 배열안의 위치를 나타내는 것 = 인덱스(Index).
  • 배열의 크기를 넘어가는 인덱스 참조시, 런타임 에러 발생.
    💡 배열의 크기가 5인 경우 배열의 순서는 0, 1, 2, 3, 4.
#include <stdio.h>

int main()
{
    int my_numbers[5];

    my_numbers[0] = 1;	// 인덱스 = 0, 값 = 1
    my_numbers[1] = 2;	// 인덱스 = 1, 값 = 2
    my_numbers[2] = 3;	// 인덱스 = 2, 값 = 3
    my_numbers[3] = 4;	// 인덱스 = 3, 값 = 4
    my_numbers[4] = 5;	// 인덱스 = 4, 값 = 5

    return 0;
}

배열과 memory

  • 배열 선언시, 각 인덱스 당 자료형 크기 만큼의 memory 공간을 가짐.

2. 배열의 기본적인 사용방법

배열 사용

코드

#include <stdio.h>

#define MONTHS 12	// 기호적 상수 MONTHS 선언.

int main()
{
    int months[MONTHS] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };	// int 자료형의 값을 12개 저장할 수 있는 배열 months 선언 및 초기화.

    for (int i = 0; i < MONTHS; ++i)	// i = 0부터 12보다 작을 때까지 1씩 증가하며 반복 수행.
    {
        printf("%d ", months[i]);		// 배열 months의 처음 인덱스의 값부터 마지막 인덱스의 값까지 출력.
    }
    printf("\n");

    float avg = 0.0;					// 실수형 변수 avg 선언 및 초기화.
    for (int i = 0; i < MONTHS; ++i)	// i = 0부터 12보다 작을 때까지 1씩 증가하며 반복 수행.
    {
        avg += months[i];				// 변수 avg에 배열 months의 모든 값을 차례대로 더함.
    }
    printf("Average = %.2f\n", avg / (float)MONTHS);	// avg 값(78)을 실수형으로 캐스팅한 MONTHS 값(12)으로 나누고 소수점 2자리까지만 출력.

    return 0;
}

결과



배열의 memory 주소 확인

코드

#include <stdio.h>

#define MONTHS 12

int main()
{
    int months[MONTHS] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };	// 배열 months 선언 및 초기화.
    printf("%p %p %p\n", months, &months[0], &months[1]);
    // 배열 months의 memory 주소, 배열 months의 첫번 째 인덱스 memory 주소, 배열 months의 두번 째 인덱스 memory 주소 출력.

    //for (int i = 0; i < MONTHS; ++i)
    //{
    //    printf("%d ", months[i]);
    //}
    //printf("\n");

    //float avg = 0.0;
    //for (int i = 0; i < MONTHS; ++i)
    //{
    //    avg += months[i];
    //}

    //printf("Average = %.2f\n", avg / (float)MONTHS);

    return 0;
}

결과

  • 배열 months의 memory 주소 = 배열 months의 첫번 째 인덱스 memory 주소.

3. 포인터의 산술연산

  • 포인터의 더하기 빼기 = 포인터의 자료형 크기 만큼 더하고 빼는 것.

코드

#include <stdio.h>

int main()
{
    int* ptr = 0;	// 포인터 변수 ptr 초기화.

    printf("%p %lld\n", ptr, (long long)ptr);	// 포인터 변수 ptr의 memory 주소, 정수 값 출력.

    ptr++;	// 포인터 변수 ptr에 1 더함.

    printf("%p %lld\n", ptr, (long long)ptr);	// 포인터 변수 ptr의 memory 주소, 정수 값 출력.

    return 0;
}

결과

  • 포인터 변수에 1을 더하면, 포인터 변수의 자료형 크기(int = 4 bytes) 만큼 더해짐.

4. 포인터와 배열

코드

#include <stdio.h>

int main()
{
    int arr[10];	// 배열 arr 선언.
    int num = sizeof(arr) / sizeof(arr[0]);	// 배열의 크기 판별.
    										// 변수 num = 배열 arr의 전체 크기 / 배열 arr[0]의 크기

    for (int i = 0; i < num; ++i)	// i = 0부터 num 까지 1씩 증가하며 for문 실행.
    {
        arr[i] = (i + 1) * 100;		// arr[0] = 100, arr[1] = 200 ...
    }

    int* ptr = arr;					// 포인터 변수 ptr에 배열 arr 대입.
									// 배열 이름(arr)의 값 = 배열의 대표 memory 주소 = 배열의 첫번 째 인덱스의 memory 주소.
    printf("%p %p %p\n", ptr, arr, &arr[0]);
    // 포인터 변수 ptr, 배열 arr의 대표 memory 주소, 배열 arr의 첫번 째 인덱스의 memory 주소 출력.

    ptr += 2;	// 포인터 변수 ptr에 2를 더함.
    printf("%p %p %p\n", ptr, arr + 2, &arr[2]);
    // 포인터 변수 ptr, 배열 arr의 대표 memory 주소 + 2, 배열 arr의 세번 째 인덱스의 memory 주소 출력.

    printf("%d %d %d\n", *(ptr + 1), *(arr + 3), arr[3]);
    // 포인터 변수 (ptr + 1) 에 해당하는 값, 배열 arr의 (대표 memory 주소 + 3)에 해당하는 값, 배열 arr의 네번 째 인덱스의 값 출력.

    return 0;
}

결과


5. 2차원 배열과 memory

  • 2차원 배열 선언시 '[]'를 두 개 사용하여 선언.
  • 1차원 배열과 마찬가지로, 배열 선언시 사용한 '[]' 값은 배열의 크기를 나타냄.
  • 배열의 순서는 0부터 시작하며, 인덱싱할 때 헷갈리지 않도록 주의.

코드

#include <stdio.h>

int main()
{
    int arr[2][3] = { {1, 2, 3},
                      {4, 5, 6} };
    /*
    int arr[2][3] = {1, 2, 3,
                     4, 5, 6}; 과 같이 선언 가능
    */

    printf("%d\n\n", arr[1][1]);    // 2차원 배열 arr의 2번째줄 2번째칸 값 출력.

    for (int j = 0; j < 2; ++j)
    {
        for (int i = 0; i < 3; ++i)
        {
            printf("%d", arr[j][i]);	// arr[0][0] 값 출력, arr[0][1] 값 출력 ... arr[1][2] 값 출력.
        }	// for문 사용시, 배열의 가장 오른쪽 '[]' 부분을 제일 안쪽의 for문으로 넣어줘야 memory를 사용하는데에 효율적임.
        printf("\n");
    }
    printf("\n");
    
	int* ptr = &arr[0][0];		// 포인터 변수 ptr에 배열 arr의 첫번 째 memory 주소 저장.
    for (int k = 0; k < 6; ++k)
    {
        printf("%d ", ptr[k]);	// ptr[0]의 값 출력, ptr[1]의 값 출력 ...
    }							// 2차원 배열이어도 내부적으로는 1차원이기 때문에 이처럼 1차원 배열같이 사용 가능.
    printf("\n\n");

    printf("%zd bytes %zd bytes\n", sizeof(arr), sizeof(arr[0]));
    // 배열 arr의 전체 memory 크기 출력, 배열 arr의 첫째 줄 memory 크기 출력.
    
    return 0;
}

결과


6. 2차원 배열 연습문제

  • 기상청 홈페이지에서 3년 동안의 월 평균 기온을 가져옴.
  • 연도 별 월 평균 기온을 배열에 저장 후 2차원 배열로 만듬.
    1. 만든 2차원 배열을 보기 좋게 출력.
    2. 3년간 연 평균 기온 출력.
    3. 3년간 월 평균 기온 출력.

코드

#include <stdio.h>

#define MONTHS 12	// 기호적 상수 MONTHS 선언(12).
#define YEARS 3		// 기호적 상수 YEARS 선언(3).

int main()
{
    double year_2019[MONTHS] = { -0.9, 1.0, 7.1, 12.1, 19.4, 22.5, 25.9, 27.2, 22.6, 16.4, 7.6, 1.4 };
    double year_2020[MONTHS] = { 1.6, 2.5, 7.7, 11.1, 18.0, 23.9, 24.1, 26.5, 21.4, 14.3, 8.0, -0.4 };
    double year_2021[MONTHS] = { -2.4, 2.7, 9.0, 14.2, 17.1, 22.8, 28.1, 25.9, 22.6, 15.6, 8.2, 0.6 };

	// 세 개의 1차월 배열을 한 개의 2차원 배열로 통합.
    double all_years[YEARS][MONTHS] = { { -0.9, 1.0, 7.1, 12.1, 19.4, 22.5, 25.9, 27.2, 22.6, 16.4, 7.6, 1.4 },
                              { 1.6, 2.5, 7.7, 11.1, 18.0, 23.9, 24.1, 26.5, 21.4, 14.3, 8.0, -0.4 },
                              { -2.4, 2.7, 9.0, 14.2, 17.1, 22.8, 28.1, 25.9, 22.6, 15.6, 8.2, 0.6 } };

    // 1. 2차원 배열 all_years 출력.
    printf("[Temperature Data]\n");
    printf("Year index\t :\t");	// \t = 들여쓰기(tap)
    for (int m = 1; m <= MONTHS; ++m)
        printf("%d\t", m);	// 1부터 12까지 들여쓰기를 사용하여 출력.
    printf("\n");

    for (int y = 0; y < YEARS; ++y)	// 2차원 배열 all_years의 왼쪽 [] 부분.
    {
        printf("Year %d\t\t :\t", y);
        for (int m = 0; m < MONTHS; ++m)	// 2차원 배열 all_years의 오른쪽 [] 부분.
        {
            printf("%.1f\t", all_years[y][m]);	// all_years[0][0] 출력 ... all_years[2][11] 출력.
        }
        printf("\n");
    }
    printf("\n");

    //2. 3년 동안의 연 평균 기온 출력.
    printf("[Yearly average temperatures of 3 years]\n");
    for (int y = 0; y < YEARS; ++y)
    {
        double avr = 0.0;

        for (int m = 0; m < MONTHS; ++m)
        {
            avr += all_years[y][m];	// avr = avr + all_years[0][0] ... avr + all_years[2][11]
        }
        avr /= (double)MONTHS;
        printf("Year %d : average temperature = %.1f\n", y, avr);	// 연 평균 계산 값 출력.
    }
    printf("\n");

    //3. 3년 동안의 월 평균 기온 출력.
    printf("Monthly average temperatures for 3 years]\n");
    printf("Year index\t :\t");
    for (int m = 1; m <= MONTHS; ++m)
        printf("%d\t", m);
    printf("\n");

    printf("Avr temperature :\t");
    for (int m = 0; m < MONTHS; ++m)
    {
        double avr = 0.0;

        for (int y = 0; y < YEARS; ++y)
        {
            avr += all_years[y][m];	// avr = avr + all_years[0][0] ... avr + all_years[2][11]
        }
        avr /= (double)YEARS;
        printf("%.1f\t", avr);	// 3년 동안의 월 평균 온도 출력.
    }
    printf("\n");

    return 0;
}

결과


7. 배열을 함수에 전달하는 방법

함수의 매개변수로 포인터 사용

  • 배열을 함수에 전달하면, 함수에서는 포인터로 인식해서 받음.
  • 배열을 함수에 전달할 때, 배열의 이름과 배열의 크기를 같이 전달.

코드

#include <stdio.h>

double avr_cal(double *, int n);	// 배열 값들의 평균을 구하는 함수 avr_cal 프로토타입.

int main()
{
    double arr1[5] = { 10, 13, 12, 7, 8 };	// 배열 arr1 선언.
    double arr2[3] = { 1.8, -0.2, 6.3 };	// 배열 arr2 선언.

    printf("Address = %p\n", arr1);			// 배열 arr1의 memory 주소 출력.
    printf("Size = %zd\n", sizeof(arr1));	// 배열 arr1의 크기 출력.
    printf("Address = %p\n", arr2);			// 배열 arr2의 memory 주소 출력.
    printf("Size = %zd\n", sizeof(arr2));	// 배열 arr2의 크기 출력.

    printf("Avg = %f\n", avr_cal(arr1, 5));	// 배열 arr1에 있는 값들의 평균 값 출력.
    printf("Avg = %f\n", avr_cal(arr2, 3));	// 배열 arr2에 있는 값들의 평균 값 출력.

    return 0;
}

double avr_cal(double *data_array, int n)
{
    printf("Size = %zd in fuction average\n", sizeof(data_array));
    // 배열을 포인터로 받은 후 해당 포인터의 크기 출력. (x86 = 4 bytes, x64 = 8 bytes)

    double avg = 0.0;
    for (int i = 0; i < n; ++i)
    {
        avg += data_array[i];	// avg = 배열의 모든 값의 합.
    }
    avg /= (double)n;	// avg를 배열의 크기로 나눔.

    return avg;	// avg 값 반환.
}

결과



함수의 매개변수로 두 개의 포인터 사용

코드

#include <stdio.h>

double avr_cal(double* start, double* end);	// 배열에 속한 값들의 평균 값을 구하는 함수 avr_cal 프로토타입.

int main()
{
    double arr1[5] = { 10, 13, 12, 7, 8 };	// 배열 arr1 선언.
    
    printf("Avg = %f\n", avr_cal(arr1, arr1 + 5));	// avr_cal 함수를 사용하여 배열 arr1의 평균 값 출력.

    return 0;
}

double avr_cal(double* start, double* end)	// avr_cal 함수 정의. 매개변수 = 두 개의 포인터.
{
    int count = end - start;	// 포인터 end의 값 - 포인터 start의 값 = 두 포인터 간의 거리 = 배열의 크기.
    double avg = 0.0;
    
    while (start < end)	// 배열의 첫번 째 값부터 마지막 값까지
    {
        avg += *start++;	// 1. avg = avg + *start 연산 후 2. start++ 수행.
    }
    avg /= (double)count;	// avg를 배열의 크기로 나눔. 

    return avg;	// avg 값 반환.
}

결과


8. 포인터 연산 총정리

#include <stdio.h>

int main()
{
    /*
    Pointer operations
    - Assignment
    - Value finding (dereferencing)
    - Taking a pointer address
    - Adding an integer to a pointer
    - Incrementing a pointer
    - Subtracting an interger from a pointer
    - Decrementing a pointer
    - Differencing
    - Comparisons
    */

    int arr[5] = { 100, 200, 300, 400, 500 };
    int* ptr1, * ptr2, * ptr3;
       
    ptr1 = arr;     // 포인터 변수 ptr1에 배열 arr의 memory 주소 저장.(Assignment)
                    // 배열의 이름 = 포인터처럼 동작.
                    
    printf("%p %d %p\n", ptr1, *ptr1, &ptr1);
    // ptr1의 값(memory 주소), ptr1이 가리키는 memory 주소의 값(dereferencing), ptr1 자체의 memory 주소 값(Taking a pointer address) 출력.

    ptr2 = &arr[2]; // 포인터 변수 ptr2에 배열 arr의 세번 째 memory 주소 저장. Address-of operator = &.
    printf("%p %d %p\n", ptr2, *ptr2, &ptr2);

    ptr3 = ptr1 + 4;
    // 포인터 변수 ptr1에 4를 더함 = ptr1의 memory 공간에서 4칸 이후의 memory 공간 = ptr3 = Adding an integer to a pointer.
    printf("%p %d %p\n", ptr3, *ptr3, &ptr3);

    // Differencing
    printf("%td\n", ptr3 - ptr1);   // \t는 pointer difference 출력을 위한 형식지정자.
    // 포인터간 뺄셈 = 두 포인터가 가르키는 memory 주소간 차이.

    ptr3 = ptr3 - 4;    
    // 포인터 변수 ptr3에 4를 뺌 = ptr3의 memory 공간에서 4칸 이전의 memory 공간 = Subtracing an integer from a pointer.

    printf("%p %d %p\n", ptr3, *ptr3, &ptr3);

    ptr1++;     // Incrementing, ptr1 = ptr1 + 1. 후위연산 = 다른 연산 먼저 수행 후 증감 연산자 수행.
    ptr1--;     // Decrementing, ptr1 = ptr1 - 1. 후위연산 = 다른 연산 먼저 수행 후 증감 연산자 수행.
    ++ptr1;     // Incrementing, ptr1 = ptr1 + 1. 전위연산 = 증감 연산자 먼저 수행 후 다른 연산 수행.
    --ptr1;     // Decrementing, ptr1 = ptr1 - 1. 전위연산 = 증감 연산자 먼저 수행 후 다른 연산 수행.

    // Comparisons
    if (ptr1 == ptr3)
        printf("Same\n");
    else
        printf("Different\n");

    return 0;
}

9. const와 배열, 포인터의 관계

  • 배열 선언시 const를 사용하면, 선언 이후 배열의 값을 바꿀 수 없음.
  • 포인터를 사용하면 const로 선언된 배열의 값 수정 가능.

코드

#include <stdio.h>

int main()
{
    const int arr[5] = { 1, 2, 3, 4, 5 };	// const 배열 arr 선언.
    int* ptr1 = arr;	// 포인터 변수 ptr1 에 배열 arr의 첫번 째 memory 주소 저장.
    *ptr1 = 10;	//	포인터 변수 ptr1 이 가리키는 memory 주소에 해당하는 값을 10으로 변경. (arr[0] = 10; 과 동일)

    int* ptr2 = &arr[4];	// 포인터 변수 ptr2 에 배열 arr의 다섯번 째 memory 주소 저장.
    *ptr2 = 50;	//	포인터 변수 ptr2 이 가리키는 memory 주소에 해당하는 값을 50으로 변경. (arr[4] = 50; 과 동일)

    for (int i = 0; i < 5; ++i)
        printf("%d ", arr[i]);	// 배열 arr의 값 출력.

    return 0;
}

결과


10. const와 배열 매개변수

  • 함수에서 매개변수를 const로 선언하면, 전달 받은 배열의 값을 함수에서 수정되지 않도록 함.
  • 함수에서 프로그래머의 실수로 배열의 값이 바뀌는 것을 방지하기 위해 사용.
#include <stdio.h>

void print_array(const int arr[], const int n)	
// 배열의 값을 출력만 해주고 수정할 필요는 없는 함수이므로 배열 매개변수에 const 사용. 
{
    for (int i = 0; i < n; ++i)
        printf("%d ", arr[i]);
    printf("\n");
}

void add_value(int arr[], const int n, const int val)
// 배열의 값을 수정해야 되는 함수이므로, 배열 매개변수에 const 제외. 
{
    int i;
    for (i = 0; i < n; i++)
        arr[i] += val;
}

int sum(const int arr[], const int n)
// 배열의 값을 더해서 반환해주는 함수이므로 배열 매개변수에 const 사용. 
{
    int i;
    int total = 0;

    for (i = 0; i < n; i++)
        total += arr[i];

    return total;
}

int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);

    print_array(arr, 5);
    add_value(arr, 5, 100);
    print_array(arr, 5);

    int s = sum(arr, n);

    printf("sum is %d\n", s);
    print_array(arr, 5);

    return 0;
}

11. 이중 포인터

  • 포인터 변수의 memory 주소를 저장하는 포인터.
  • 이중 포인터 선언은 변수 앞에 '**'을 사용.
  • 이중 포인터는 두 번의 dereferencing을 수행.
  • 이중 포인터 또한 값 저장을 위한 memory 공간을 가지고 있으므로, 이를 이용한 삼중 포인터도 가능.

12. 포인터의 배열

  • 포인터를 원소로 가지는 배열.
    Ex) int* parr[2] = { arr[0], arr[1] };
  • 2차원 배열이 포인터의 배열의 원소로 저장될 경우, 각 원소는 2차원 배열의 행(row)을 나타내며, 행의 첫번 째 memory 주소를 가리킴.
  • 2차원 배열은 내부적으로 1차원 구조임.

1차원 배열을 원소로 가질 경우

코드

#include <stdio.h>

int main()
{
    int arr0[3] = { 1, 2, 3 };	// 1차원 배열 arr0.
    int arr1[3] = { 4, 5, 6 };	// 1차원 배열 arr1.

    int* parr[2] = { arr0, arr1 };  // parr = 포인터가 담길 수 있는 공간이 2개인 포인터의 배열.

    for (int j = 0; j < 2; ++j)
    {
        for (int i = 0; i < 3; ++i)
            printf("%d(==%d(==%d)) ", parr[j][i], *(parr[j] + i), *(*(parr + j) + i));
            // parr[j][i], *(parr[j] + i), *(*(parr + j) + i) 값 출력. (전부 동일한 값을 가짐)
        printf("\n");
    }
    printf("\n");

    return 0;
}
💡 포인터의 배열을 2차원 배열처럼 사용할 때 해석.
parr[0][0] = arr0[0] = 1, parr[0][1] = arr0[1] = 2, parr[0][2] = arr0[2] = 3.
parr[1][0] = arr1[0] = 4, parr[1][1] = arr1[1] = 5, parr[1][2] = arr1[2] = 6.

결과



2차원 배열을 원소로 가질 경우

코드

#include <stdio.h>

int main()
{
    int arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };	// 2차원 배열 arr

    int* parr[2] = { arr[0], arr[1] };  // 배열 arr의 첫번 째 차열을 차례대로 원소에 저장.

    for (int j = 0; j < 2; ++j)
    {
        for (int i = 0; i < 3; ++i)
            printf("%d(==%d(==%d)) ", parr[j][i], *(parr[j] + i), *(*(parr + j) + i));
        // parr[j][i], *(parr[j] + i), *(*(parr + j) + i) 값 출력. (전부 동일한 값을 가짐)
        printf("\n");
    }
    printf("\n");

    <return 0;
}

결과

💡 추후 동적할당 부분에서는 *(*(parr + j) + i) 의 표현을 사용.


13. 다차원 배열을 함수에 전달하는 방법

코드

#include <stdio.h>

#define ROWS 3
#define COLS 4

int sum2d_1(int ar[ROWS][COLS]);		// 함수 프로토타입.
int sum2d_2(int ar[][COLS], int row);	// 함수 프로토타입.
int sum2d_3(int* ar, int row, int col); // 함수 프로토타입. 동적할당에서 사용하는 방식.

int main()
{
    int data[ROWS][COLS] = { {1,2,3,4},			// 2차원 배열 data 선언.
                             {5,6,7,8},
                             {9,0,1,2} };

    printf("%d\n", data[2][3]);		// 2차원 배열 data의 3 번째줄 4 번째칸 원소 출력.

    int* ptr = &data[0][0];			// 포인터 변수 ptr에 2차원 배열 data의 첫 번째 memory 주소 저장.
    printf("%d\n", *(ptr + 3 + COLS * 2));  // 포인터의 산술연산을 사용하여 2차원 배열 data의 3 번째 줄 4 번째칸 원소 출력.
    										// 이게 이해되면 포인터와 배열, memory 상관 관계를 이해한 것.

    printf("Sum of all elements = %d\n", sum2d_1(data));				// sum2d_1 함수 결과 값 출력.
    printf("Sum of all elements = %d\n", sum2d_2(data, ROWS));			// sum2d_2 함수 결과 값 출력.
    printf("Sum of all elements = %d\n", sum2d_3(data, ROWS, COLS));	// sum2d_3 함수 결과 값 출력.

    return 0;
}

int sum2d_1(int ar[ROWS][COLS])			// sum2d_1 함수 정의.
{
    int r, c, tot = 0;
    for (r = 0; r < ROWS; r++)
        for (c = 0; c < COLS; c++)
            tot += ar[r][c];	// 배열의 모든 원소를 더해서 변수 tot에 저장.
    return tot;
}

int sum2d_2(int ar[][COLS], int row)	// sum2d_2 함수 정의.
{
    int r, c, tot = 0;
    for (r = 0; r < ROWS; r++)
        for (c = 0; c < COLS; c++)
            tot += ar[r][c];			// 배열의 모든 원소를 더해서 변수 tot에 저장.
    return tot;
}

int sum2d_3(int* ar, int row, int col)	// sum2d_3 함수 정의.
{
    int r, c, tot = 0;
    for (r = 0; r < row; r++)
        for (c = 0; c < col; c++)
            tot += *(ar + c + col * r); // 포인터의 산술연산을 사용하여 2차원 배열의 모든 원소 값을 더함.
    return tot;
}

결과


🚩 출처 및 참고자료 : 홍정모의 따라하며 배우는 C 언어 (따배씨)

0개의 댓글