[c] - 42서울을 위한 C공부 - 이중 배열

devicii·2021년 8월 15일
1

c

목록 보기
2/6
post-thumbnail

1차원 배열은 질리게 사용해봤다.
2차원 배열은 사용할 때 가끔 헷갈리는 점이 있어 정리해보려 한다.

❗ 2차원 배열의 구조

아주 쉽게 요약하자면 아파트와 같다고 생각하면 쉽다.
1차원 배열은 예를 들어 쭉 뻗은 기차라고 생각하고, 2차원 배열은 아파트라고 외우자.

이런 배열을 선언하게 된다면 위 그림과 같은 이런 구조를 가진 배열이 생길 것이다. (이렇게 선언한다면 그림에서 값으로 적은 것은 0으로 다 초기화된다.)
int arr[5][5];

우리가 일반적으로 생각하는 가로-세로 순서가 아닌 세로-가로 순서로 진행된다.
arr[세로][가로]라고 머리에 박아두자 그냥

2차원 배열 선언

이런 식으로 선언하면 제일 보기 편하다.
1.  int arr[2][3] = {
		{1, 1, 1,},
                {2, 2, 2} 
                };

2. int arr[2][3] = { 1, 1, 1, 2, 2, 2};
이와 같은 선언도 물론 가능하다.


3. int arr[4] = { 1, 2, 3, 4 };

기존의 우리가 사용하던 방식.

4. int arr[] = {1, 2, 3, 4,};
일차원 배열을 생성할 시 이렇게 배열을 선언하는 것도 가능하다.
컴파일러가 알아서 사이즈를 넣어준다. 개인적으로 이게 더 편한 거 같다.

5. int arr[]; 
이렇게는 선언이 불가능하다. 컴파일러가 배열의 사이즈를 가늠할 수 없기 때문이다.

6. int arr[][2] = { {1, 2} , {3, 4} , {5, 6}, {7} };
놀랍게도 이 배열은 컴파일된다.
이유는 처음 선언시 arr[][2]라고 두 번째 괄호에 2라고 입력했기에 원소가 2인 1차원 배열이 생기기 때문이다. 따라서 배열의 마지막 원소는 0이다.
//   arr[3][0] == 7 
//  arr[3][1]  == 0


7. int arr[2][0] = { {1,1,1}, {2,2,2,} };
이 선언은 또 다르게 컴파일링 되지 않는다.
c의 경우에는 맨 앞의 크기를 제외한 나머지 크기를 정확히 지정해줘야 한다는 룰이 있다.
따라서 6번 예제는 성공했지만, 7번의 경우에는 실패이다.

2차원 배열 예제


#include <stdio.h>

int main(){

    int score[3][2];
    int i,j;
    int length = 3;

    for(int i = 0; i < 3; i++){
       
        for(int j = 0; j < 2; j++){
            
            if(j == 0){
               printf("%d번째 학생의 국어 성적을 입력하세요. \n", i+1);
                scanf("%d", &score[i][j]);
               
            }else if(j == 1){
                printf("%d번째 학생의 수학 성적을 입력하세요. \n", i+1);
                scanf("%d", &score[i][j]);
            }
        }
    } 


    for(int i = 0; i < 2; i++){
        printf("%d번째 학생의 국어 성적은: %d 입니다. 수학 성적은: %d 입니다. \n", i + 1, score[i][0] , score[i][1]);
    }

    return 0;
}

🐛문제해결

위의 예제를 하던 중 두 번째 for에서 scanf를 입력하고 난 후, 프로그램이 종료됐다.
생각해보니 scanf("%d", &score[i][j]);가 아닌 scanf("%d", score[i][j]);를 입력했다.
그래서 왜 주소를 의미하는 &. 즉 ampersand를 입력하지 않으면 scanf함수가 실행되지 않는지에 대해서 의문이 들었고, 구글링 해보았다.

- &(ampersand)는 변수의 주소를 의미한다.
- scanf()의 실행원리는 아래와 같다.
1. 값을 입력받음
2. 그 값을 레지스터에 저장. (레지스터는 일종의 임시 공간이다)
3. 해당 변수의 주소로 가서 그 조소가 가리키는 메모리에 현재 레지스터에 저장된 값으로 바꾼다.
4. 레지스터에 존재하던 값을 삭제한다.

int a;
char b[20];

문자열의 경우는 &를 입력하지 않아도 된다. 문자열 자체가 주소기 때문이다.
scanf("%d" , &a);

scanf("%s" , b);
profile
Life is a long journey. But code Should be short :)

0개의 댓글