Young & Rich

 

오늘은 배열과 포인터를 좀 더 깊게 알아보는 시간입니다.

 

[2차원 배열, N차원 배열]

 

앞에서는 1차배열 int num[10]; 과 같은 배열을 다뤘습니다.

오늘은 int num[10][20]; 과 같은 1차원 배열을 넘는 배열에 대해서 다뤄보려고 합니다.

 

만약에 30명의 학생의 국영수 과목을 관리하는 프로그램을 만든다고 가정해봅시다.

 

그러면, 각각 1명 당 국영수 3과목에 대한 변수가 존재해야합니다.

또한, 30명의 이름이 필요합니다. 1명당 이름의 최대길이를 16 byte로 제한한다고 하면, 배열은

char student_name[30][16]; 이렇게 선언을 해야겠죠.

아래는 30명의 학생의 이름과 국영수 점수를 입력받은 뒤, 입력받은 숫자를 출력하는 예제 프로그램입니다.

#include<stdio.h>

#define ST_NUM 30		// 학생 수 30명으로 정의

void main()
{
    int i = 0;
    int st_math[ST_NUM] = {0,};
    int st_kor[ST_NUM] = {0,};
    int st_eng[ST_NUM] = {0,};
    char st_name[ST_NUM][16];
    
    for ( i = 0; i < ST_NUM; i++)
    {
    	printf("%d번째 학생의 이름 : ", i+1);
        scanf("%s", st_name[i]);	// st_name[i] == &st_name[i][0]
        fflush(stdin);		// 문자열을 입력받은 뒤, 버퍼 비우기
        printf("국영수 순으로 점수를 입력(ex: 10 20 30) : ");
        scanf("%d %d %d", &st_kor[i], &st_eng[i], &st_eng[i]);
    }
    
    for ( i = 0; i < ST_NUM; i++)
    {
    	printf("%s 점수 : 국[%d] 영[%d] 수[%d]\n", st_name[i], st_kor[i], st_eng[i], st_math[i]);
    }
    
}

문자를 출력 및 입력 받을 때, %s 를 사용하고 매칭되는 것은 입출력할 문자열의 주소값이여야 합니다.

2차원 배열 char st_name[][];  2차원의 배열을 선언하고

이것을 마치 1차원 배열 처럼 사용하면, 주소값을 의미합니다.

st_name == st_name[0] == &st_name[0] == &st_name[0][0] 모두 같은 의미입니다.

 

자 여기서 30명의 학급이 아닌, 30명의 학급이 있는 A / B / C 반의 성적을 입력받는다고 가정해봅시다.

그럼 배열이 1차원 더 증가합니다.

 

int st_kor[3][30];

char st_name[3][30][16]; 이럴 땐 for문을 이중으로 사용하면 편합니다.

#include<stdio.h>

#define CLASS_NUM 3		// 1반 2반 3반
#define ST_NUM 30		// 학생 수 30명으로 정의

void main()
{
    int i = 0, j = 0;
    int st_math[ST_NUM] = {0,};
    int st_kor[ST_NUM] = {0,};
    int st_eng[ST_NUM] = {0,};
    char st_name[ST_NUM][16];
    
    for ( i = 0; i < CLASS_NUM; i++)
	{
    	printf("%d 반의 학생들 정보를 입력하세요\n", i+1);
    	for ( j = 0; j < ST_NUM; j++)
    	{
            printf("%d번째 학생의 이름 : ", j+1);
            scanf("%s", st_name[i][j]);	// st_name[i] == &st_name[i][0]
            fflush(stdin);		// 문자열을 입력받은 뒤, 버퍼 비우기
            printf("국영수 순으로 점수를 입력(ex: 10 20 30) : ");
            scanf("%d %d %d", &st_kor[i][j], &st_eng[i][j], &st_eng[i][j]);
    	}
    }
    for ( i = 0; i < CLASS_NUM; i++)
    {
    	printf("%d반 학생들의 정보입니다.\n" i+1);
    	for ( j = 0; j < ST_NUM; j++)
        {
            printf("%s 점수 : 국[%d] 영[%d] 수[%d]\n", st_name[i][j], st_kor[i][j], st_eng[i][j], st_math[i][j]);
        }
    }
}

그렇다면, 여기서 한 단계 더 나아가서 학년별로 범위를 넓히면 또 +1차원이 늘어납니다.

학교단위로 넓히면 +1 이렇게 N차원 배열이 될 수 있습니다.

이름과 같은 문자열은 이미 1차원 배열이므로, 다른 정수형 실수형 보다 +1차원이 더 많게 선언되어져서 쓰입니다.

 

[2차원 포인터, N차원 포인터]

 

지난 번에 int *num; 와 같이 1차원 포인터에 대해서 알아보았습니다.

오늘은 이제 한 단계 더 나아가서 2차원 포인터에 대해서 알아보겠습니다.

 

우선, 2차원 포인터 변수를 선언하면 1차원 포인터 변수의 주소값만을 넣을 수 있습니다.

즉 N차원 포인터 변수에는 N-1차원 포인터의 주소값만 저장할 수 있습니다. 예를 들어보겠습니다.

 

#include <stdio.h>

void main()
{
    int num = 10;
    int *p_num = &num;
    int **pp_num = &p_num;
    
    printf("num[%d] &num[%x], p_num[%x], *p_num[%d], &p_num[%x]\n",
    num, &num, p_num, *p_num, &p_num);

    printf("&pp_num[%x], pp_num[%x], *pp_num[%x], **pp_num[%d]\n", 
    &pp_num, pp_num, *pp_num, **pp_num);
}

 

프로그램 실행결과
프로그램 실행결과

 

 

포인터 설명
포인터 설명

위의 그림과 같은 구조를 가지게 됩니다.

**pp_num 은 2번 참조하라는 겁니다. * 한 번 갔더니 p_num에는 &num 의 주소값이 있죠? &num 의 주소값은 참조하는거니 num 이 되게 되는겁니다.

좀 더 쉽게 이해하시려면 *p_num 은 사실 *&num 과 같죠? *이 참조하면 &을 없애버립니다. 즉, num 이 되는거죠.

**pp_num 을 비슷하게 대입해봅시다. pp_num 에는 &p_num의 주소값이 있기 때문에  **&p_num 이 됩니다.

**&p_num == *p_num 이 되고, 위에서와 똑같이 num 이 됩니다.

 

num[i][j] == *( *(num + i ) ) + j) 이렇게 사용할 수 있습니다.

앞장에서 포인터 변수에 + 는 ( X 자료형의 크기) 라고 말씀드렸었습니다.

배열을 포인터로 바꾸고, 포인터를 배열로 바꾸는 걸 연습을 많이 해보시는 걸 추천드립니다.

 

포인터는 C언의 꽃이라고 불릴만큼(제가 C언어를 배울 때 C언어를 가르쳐준 선배의 말입니다.^^) 엄청 중요하면서도 유용한 개념이지만 이해하기가 쉽지 않습니다.

 

다들 배열과 포인터에서 C언어가 너무 어렵다며 포기하거나... 힘들어합니다.

하지만, 이것만 명심하세요. 포인터 변수의 원론의 정의만 잊지 말고 단계 별로 논리적으로 생각하면 좀 더 쉬우실 겁니다.

 

★ 포인터 변수는 주소값만(Only)을 저장할 수 있는 변수이다.

=> N차 포인터 변수는 N-1차 포인터변수의 주소값을 저장하는 거겠죠. 1차는 변수의 주소값이고요.

 

★ * 은 참조의 뜻입니다. 즉, 해당 포인터 변수의 주소값을 찾아갑니다. 포인터 변수에 어떤 변수의 주소값이 있고 *은 그 주소를 따라가서 문을 두드리는 상상을 해보세요. 마치 우편배달부처럼요. 그럼 좀 더 쉽게 이해가 되실까요??^^

 

그럼 배열과 포인터 포스팅을 마치겠습니다. 포인터는 뒤에 함수라는 것을 배우면서 또 등장할 것 같습니다.

 

그럼 20000.

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band