학습 기록/C

(6) 배열

romi__ 2024. 11. 10. 20:49

/C

 

배열이란 같은 타입의 변수로 이루어진 유한한 집합을 의미한다. 배열을 구성하는 각각의 값은 요소(element), 배열에서의 위치는 인덱스(index)라고 부른다. 인덱스는 늘 0부터 시작하며, 0을 포함하는 양의 정수만을 갖는다.

 

📌 1차원 배열

- 1차원 배열을 선언하는 방법은 아래와 같다.

타입 배열이름[배열길이];

 

참고로 위와 같이 선언 후 초기화하지 않는다면 배열에는 쓰레기값이 저장된다. 주의할 것.

#include <stdio.h>

int main(void)
{
	int i;
	int sum = 0;
	int grade[3];			// 길이가 3인 int형 배열 선언 
	
	/* 배열의 초기화 */
	grade[0] = 85;			// 국어 점수 
	grade[1] = 65;			// 영어 점수 
	grade[2] = 90;			// 수학 점수 
	
	for (i = 0; i < 3; i++)
	{
		sum += grade[i];	// 인덱스를 이용한 배열의 접근 
	}
	
	printf("국영수 과목 총 점수 합계는 %d점이고, 평균 점수는 %f점입니다.\n", sum, (double)sum/3);
	return 0;
}

 

위의 예제에서 배열 grade는 메모리 상에서 아래 그림처럼 저장된다.

배열의 이름은 언제나 배열의 첫 번째 요소와 같은 주소임을 다시 한번 확인할 수 있다.

 

 

- 선언과 동시에 초기화하는 방법은 아래와 같다.

타입 배열이름[배열길이] = {배열요소1, 2, 3, ...);

 

초기화 리스트보다 배열 길이가 길다면 앞에서부터 차례로 초기화되고, 나머지는 0으로 자동 초기화된다. C 컴파일러는 배열 길이를 딱히 신경 쓰지 않는다. 때문에 배열 길이를 벗어나게 하는 요소를 추가해도 정상적으로 추가된다. 다만 이는 개발자가 의도하지 않은 요소 추가일 가능성이 높으므로 사전에 방지하는 것이 좋다.

 

앞 예제 코드와 동일한 배열을 선언과 동시에 초기화하면 아래와 같다.

#include <stdio.h>

int main(void)
{
	int i;
	int sum = 0;
	int grade[3] = {85, 65, 90};	// 길이가 3인 int형 배열의 선언과 동시에 초기화
	
	for (i = 0; i < 3; i++)
	{
		sum += grade[i];			// 인덱스를 이용한 배열의 접근 
	}
	
	printf("국영수 과목 총 점수 합계는 %d이고, 평균 점수는 %f입니다.\n", sum, (double)(sum/3));
	return 0;
}

 

- 배열의 길이를 자동으로 설정하게 할 수도 있다.

타입 배열이름[] = {배열요소1, 2, 3, ...};

 

위와 같이 코드를 작성하면 자동으로 배열 요소 수에 맞춰서 초기화된다.

 

 

- 배열이 차지하는 메모리의 크기는 배열 길이*sizeof(타입)으로 구할 수 있다. 배열의 길이는 sizeof(배열이름)/sizeof(배열이름[0])이다. 여기서 배열이름[0]은 배열/요소의 타입을 표현한다.

 

 

📌 다차원 배열

- 배열의 요소로 또 다른 배열을 갖는 배열을 다차원 배열이라고 한다. 메모리상에 아래와 같은 형식으로 저장된다.

 

- 2차원 배열은 배열의 요소로 1차원 배열을 갖는 배열이다. 선언은 아래와 같은 형태로 진행한다.

타입 배열이름[행의길이][열의길이];

 

 

- 초기화의 방식에는 세 가지가 있다.

- 1차원 배열의 초기화 형태 따르기

타입 배열이름[행의길이][열의길이] = {배열요소[0][0], 배열요소[0][1], ...};

 

만약에 초기화하는 배열 요소의 개수가 배열의 총 길이보다 적으면, 나머지 배열 요소는 모두 0으로 초기화된다.

 

- 배열의 모든 요소 초기화하기

타입 배열이름[행의길이][열의길이] =

{

    {배열요소[0][0], 배열요소[0][1], ...},

    {배열요소[1][0], 배열요소[1][1], ...},

    {배열요소[2][0], 배열요소[2][1], ...},

    ...

};

 

직관적인 2차원 배열의 모습을 보여주기에 이 초기화 방식을 가장 많이 사용한다. 위의 두 가지 방법을 이용하여 같은 배열을 선언해 보자.

#include <stdio.h>

int main(void)
{
	int arr01[2][3] = {10, 20, 30, 40, 50,60};
	int arr02[2][3] = {
		{10, 20, 30},
		{40, 50, 60}
};

 

 

- 배열의 일부 요소 초기화하기: 2차원 배열의 원하는 요소만을 초기화할 수 있고, 여기서 초기화되지 않은 요소는 자동으로 0으로 초기화된다. 

 

- 2차원 배열 열의 길이를 구할 때는 아래와 같은 수식을 활용한다.

arr_col_len = sizeof(arr[0]) / sizeof(arr[0][0]);

 

- 열의 길이를 이용하면 행의 길이도 구할 수 있다.

arr_row_len = (sizeof(arr) / arr_col_len) / sizeof(arr[0][0]);

 

 

- 1차원 배열과 마찬가지로 2차원 배열도 길이를 자동 설정하도록 할 수 있다. 다만 행의 길이는 생략 가능하지만, 열의 길이는 반드시 명시해야 한다는 점을 유의해야 한다.

#include <stdio.h>

int main(void)
{
	int i, j, arr_col_len, arr_row_len;
	int arr[][4] = {
		{10, 20},
		{30, 40, 50, 60},
		{0, 0, 70, 80}
	};
	
	arr_col_len = sizeof(arr[0]) / sizeof(arr[0][0]);				// 2차원 배열의 열의 길이를 계산함 
	arr_row_len = (sizeof(arr) / arr_col_len) / sizeof(arr[0][0]);	// 2차원 배열의 행의 길이를 계산함 
	
	/* 2차원 배열의 출력 */
	for (i=0; i<arr_row_len; i++)
	{
		for (j=0; j<arr_col_len; j++)
		{
			printf("%4d", arr[i][j]);
		}
		printf("\n");
	}
	
	return 0;
}

/*
  10  20   0   0
  30  40  50  60
   0   0  70  80
*/

 

위의 예제에서 행의 길이를 명시하고, 열의 길이를 생략하면 컴파일할 때 오류가 발생하는 것을 확인할 수 있다.

'학습 기록 > C' 카테고리의 다른 글

(8) 포인터와 배열  (1) 2024.11.12
(7) 포인터  (0) 2024.11.11
(5) 함수  (0) 2024.11.09
(4) 제어문  (0) 2024.11.08
(3) 연산자  (0) 2024.11.07