[C언어] 2차원 배열과 배열포인터

이가영·2023년 9월 22일
0

C언어

목록 보기
15/16

2차원 배열의 선언과 초기화

  • 2차원 배열은 1차원 배열을 배열요소로 갖는 새로운 배열이다.
    -> 3명의 학생에 대한 4과목의 학생 점수를 처리하는 예

2차원 배열의 선언과 구조

  • 2차원 배열은 1차원 배열처럼 배열명과 첨자를 사용하여 선언
    -> 각 배열요소의 형태는 int형 변수 4개짜리 1차원 배열이다.
    -> 전체 배열은 12개의 int형 기억공간이 1차원 배열의 형태로 할당된다.
  • 2차원 배열은 논리적으로 행렬로 표현된다.
    -> 배열요소는 1차원 배열이므로 부분배열이라고 한다.
int score1[4];
int score2[4];  => int score[3][4];
int score3[4];         배열명 배열요소의 개수
// int [4] -> 배열요소의 형태
// int형 변수 4개짜리 1차원 배열이 2차원 배열의 배열요소가 된다.

배열요소의 참조

  • 2차원 배열은 부분배열의 배열요소를 다시 참조해야 한다.

    -> 첫 번째 부분배열에 4과목의 점수를 입력하는 예
int score[3][4];   //2차원 배열 선언
int j;             //반복 제어변수
printf("네 과목의 점수를 입력 : ");
for(j=0; j<4; j++)  //i는 0부터 3까지 4번 반복
{
	scanf("%d", &score[0][j]);
}  //첫 번째 부분배열의 배열요소에 각각 점수 입력
   //결국 한 학생의 모든 점수를 입력 받는다.

2중 for문으로 모든 배열요소를 처리한다.

  • 나머지 두 명의 점수를 입력 받기 위해 점수를 입력 받는 과정을 반복

2차원 배열을 사용하여 학생들의 점수를 처리하는 프로그램

2차원 배열의 sizeof

#include <stdio.h>
int main()
{
	int score[3][6];
    printf("%d\n", sizeof(score));  //72=3*6*4(int) 배열 전체의 크기
    //배열요소 3개, 각각의 배열요소는 6개의 배열로 이루어진 부분배열, 부분배열의 각각의 요소는 int
    printf("%d\n", sizeof(score[0])); //24=6*4
    // 부분배열이니까 int 6개
    printf("%d\n", sizeof(score[0][0])); //4 부분배열요소
    return 0;
|

2차원 배열의 초기화

  • 기본적으로 1차원 배열을 초기화하는 방식과 같다.
    -> 초기화 값은 행 단위로 차례로 저장된다.
int nums[3][4]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
               nums[0]    |  nums[1]   |     nums[2]
->
1  2  3  4 
5  6  7  8  => 첫번째 행이 먼저 초기화된 후에 두 번째, 세 번째 행이 차례로 초기화됨
9 10 11 12
  • 기억공간의 수보다 초기화 값이 적으면 남는 기억공간은 0으로 초기화
int nums[3][4]={1, 2, 3, 4, 5, 6};
만약 전체를 0으로 초기화 하고 싶다면 ={0}; 하면 된다.
->
1  2  3  4
5  6  0  0
0  0  0  0
  • 초기화 값을 논리적 구조에 맞게 행으로 구분하고자 하면 중괄호를 한번 더 사용
int nums[3][4]={{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
                // 첫번째행      두번째 행        세번쨰 행
  • 행 초기화 괄호를 사용하면 행 단위로 초기값을 생략할 수 있다. -> 부족분은 0으로 초기화
int nums[3][4]={{1}, {5, 6}, {9, 10, 11}};
->
1  0  0  0
5  6  0  0
9 10 11  0
  • 1차원 배열과 마찬가지로 배열의 첨자를 생략할 수 있다.

    행 초기화 괄호를 사용한 경우

    int nums[][4]={{1}, {2, 3}, {4, 5, 6}}; //행의 수 3개
            행 열(열 첨자는 생략 불가능)
    ->
    1  0  0  0 
    2  3  0  0   //3행 4열의 기억공간 할당
    4  5  6  0

    행 초기화 괄호를 사용하지 않은 경우

    int nums[][4] = {1, 2, 3, 4, 5, 6};
              //첫번째 행 초기값 / 두 번째 초기값
    -> 
    1  2  3  4  
    5  6  0  0  //2행 4열의 기억공간 할당

2차원 문자배열

  • 여러 개의 문자열을 저장하기 위해서는 2차원 문자배열이 필요
    -> 5개의 문자열을 저장할 2차원 문자배열
char animals[5][20];

-> 마지막 부분배열에 문자열을 입력할 때(부분배열명을 전달인자로 준다)

scanf("%s", animal[4]); //gets함수를 사용하면 gets(animal[4])
           // 전체가 배열명임
  ★부분배열명 = 포인터★

-> 반복문을 사용하여 모든 부분배열에 문자열을 입력

for(i=0; i<5; i++)
{
	printf("문자열을 입력 : ");
    scanf("%s", animal[i]); //i의 값이 변하면서 각 부분배열명이 된다.
}

2차원 문자배열의 초기화

  • 기본적으로 각 기억공간들을 문자상수로 초기화할 수 있다.
char animal[5][10]={{'c', 'a', 't', '\0'}, {'t', 'i', 'g', 'e', 'r', '\0'}};
  • 각 행은 문자열상수로 직접 초기화할 수 있다.
char str[10]="cat"; //하나의 문자열 상수는 1차원 문자배열을 초기화할 수 있다.
char animal[5][10]={"cat", "tiger", "dog", "lion", "turtle"};5개의 문자열 상수는 5개의 부분배열을 초기화한다.
->
cat \0 \0 \0 \0 \0 \0 \0
tiger \0 \0 \0 \0 \0
dog \0 \0 \0 \0 \0 \0 \0 -> 남은 기억공간들은 널문자로 채워진다.
lion \0 \0 \0 \0 \0 \0
turtle \0 \0 \0 \0

2차원 문자배열을 초기화하고 출력하는 프로그램

문자열 개수 계산 ->sizeof(animal) / sizeof(animal[0]);
                전체 배열의 크기    부분배열 하나의 크기

포인터 배열

  • 포인터배열 = 포인터변수들을 배열요소로 갖는 배열
    -> 배열에 저장되는 데이터가 특정 타입의 포인터
특정 타입 : 배열은 동일 형태의 데이터를 저장하기 때문
char *ptr_ary[5];
->
char *ptr : 배열요소의 자료형
ptr_ary : 배열명
[5] : 배열요소의 개수

-> 세 번째 배열요소에 문자열상수를 대입하고 출력할 때

ptr_ary[2]="tiger";  //문자열상수는 포인터이므로 포인터만을 저장하는 것이다.
printf("%s", ptr_ary[2]);

#include <stdio.h>
int main()
{
	char *ptr_ary[5];
    int i;
    ptr_ary[0]="dog";
    ptr_ary[1]="elephant";
    ptr_ary[2]="horse";
    ptr_ary[3]="tiger";
    ptr_ary[4]="lion";
    for(i=0; i<5; i++)
    {
		printf("%s\n", ptr_ary[i]);
        //배열요소를 하나씩 참조하여 모든 문자열을 출력
    }
	return 0;
}

포인터배열의 초기화

  • 문자열상수는 포인터이므로 포인터배열에 초기값으로 사용
char *ptr_ary[5]={"dog", "elephant", "horse", "tiger", "lion"};
-> "dog"은 임시영역에 저장
-> "dog"가 저장된 임시 영역의 주소값이 ptr_ary[0]에 저장
  • 문자배열 초기화와 포인터배열 초기화의 차이점
char animal[5][10]={"dog", "elephant", "horse", "tiger", "lion"};
char *ptr_ary[5]={"dog", "elephant", "horse", "tiger", "lion"};
->
char animal[5][10]
char *ptr_ary[5]  //배열의 형태에 따라 문자열을 복사하거나 포인터를 저장

-> 2차원 문자배열에 초기화하는 것은 모든 문자열이 배열에 복사되는 것이고
-> 포인터배열에 초기화하는 것은 포인터만 초기화되는 것이다.
★위 2개의 차이를 이해해야 함★

포인터배열은 2차원 배열처럼 활용된다

  • 1차원 배열의 배열명을 포인터배열에 저장하면 포인터배열을 2차원 배열처럼 사용할 수 있다.
int ary1[4]={1,2,3,4};
int ary2[4]={11,12,13,14};
int ary3[4]={21,22,23,24};
int *ptr_ary[3]={ary1, ary2, ary3};
//각 배열명을 포인터배열에 초기화한다.

-> ary3배열의 세 번째 배열요소(23값)을 참조하는 과정
1. 먼저 ptr_ary배열의 세 번째 배열요소를 참조 -> ptr_ary[2] -> 부분배열명
2. 참조된 배열요소 ptr_ary[2]는 배열명 ary3를 저장한 포인터변수이므로 배열명처럼 사용하여 ary3의 세 번째 배열요소를 참조 -> printf("%d", ptr_ary[2][2]);

반복문으로 모든 배열요소의 값을 출력


연습문제

  • 4행 5열의 2차원 배열 두 개를 선언, 1부터 20까지 저장한 후 출력하는 프로그램

연습문제

  • 2차원 배열의 초기화와 행/열의 합

연습문제

  • 기억 공간의 몇 퍼센트를 차지하는지 계산하는 프로그램

연습문제

  • 2차원 문자배열과 포인터배열이 연결될 수 있도록 배열을 선언하고 초기화하는 프로그램
    (1) 포인터배열을 이용하여 가장 길이가 긴 동물 이름 출력
    (2) 포인터배열을 이용하여 문자열을 사전 순서에 따라 sorting한다.

profile
gy’s portfolio

0개의 댓글