AI/컴퓨터C프로그래밍

컴퓨터C프로그래밍 06 배열

Ayel 2025. 10. 9. 07:19

 

 

배열 개요와 선언

 

 

1. 배열(array)

 

1) 배열 개요

- 여러 변수들이 같은 배열이름으로 일정한 크기의 연속된 메모리에 저장되는 구조

- 배열을 이용하면 변수를 일일이 선언하는 번거로움 해소

- 배열을 구성하는 각각의 변수를 반복 구문으로 쉽게 참조 가능

 

2) 배열의 정의

- 저장공간인 원소를 동일한 크기로 지정된 배열크기만큼 확보한 연속된 저장공간

- 배열의 중요 요소: 원소 자료유형, 배열이름, 배열크기

 

3) 배열 선언 구문

원소_자료유형 배열이름[배열크기]

- 배열크기는 리터럴 상수, 매크로 상수 또는 이들의 연산식이 허용되나 변수는 사용할 수 없다

- 매크로 상수는 결국 리터럴 상수로 바뀌어 컴파일되므로 문제 없이 선언 가능

 

4) 배열 선언 문법 오류

- 변수와 const 상수는 배열크기로 사용 불가능

변수와 배열 선언 문장 설명 및 오류 원인
int n = 5;
const int size = 6;
변수 n과 const 상수 size 선언
int score[n]; 변수 n은 배열크기로 사용 불가
double point[-3];
char ch[0];
float grade[3.2];
음수는 배열크기로 사용 불가
0은 배열크기로 사용 불가
실수는 배열크기로 사용 불가
int score[n+2];
int degree[n*2];
변수 n의 연산식은 배열크기로 사용 불가
int cpoint[size];
double width[size+4];
상수 변수 size의 연산식은 배열크기로 사용 불가

 

5) 첨자(index) 활용

- 배열 이름 뒤 대괄호 사이

- 첫 번째 배열원소를 참조하는 첨자값은 0

- 다음 두 번째 원소는 1

- 유효한 첨자의 범위: 0~(배열크기-1)

 

- 배열 선언 시 대괄호 안의 수는 배열 크기

- 선언 이후 대괄호 안의 수는 원소를 참조하는 첨자 번호

int score[5];

//배열 원소에 값 저장

score[0] = 78;
score[1] = 97;
score[2] = 85;

// 배열 4번째 원소에 값을 저장하지 않아 쓰레기값 저장

score[4] = 91;
score[5] = 50;

 

score[0] score[1] score[2] score[3] score[4] score[5]
78 97 85 (쓰레기값) 91 x
배열원소는 총5개이므로 5*4바이트=20바이트 오류 발생

 

- 배열원소는 5개이므로 score[5]로 참조 불가

 

#include <stdion.h>

#define SIZE 5

int main(void) {
	// 배열 선언
	int score[SIZE]; // == int score[5]; 
    // SIZE는 리터럴 상수 또는 매크로 상수로 양의 정수여야 함

	// 배열 원소에 값 저장
	score[0] = 78;
	score[1] = 97;
	score[2] = 85;
	// 배열 4번째 원소에 값을 저장하지 않아 쓰레기값 저장
	score[4] = 91;
	// score[5] = 50; // 문법오류 발생
    
    // 배열원소 출력
    for(int i=0; i<SIZE; i++)
    	printf("%d ", score[i]);
	printf("%\n");
    
    return 0;
}

 

 

2. 배열 초기화

 

1) 배열선언 초기화

- 배열을 선언하면서 동시에 원소 값을 손쉽게 저장하는 초기화(initialization) 방법

- 중괄호 사이에 여러 원소 값을 쉼표로 구분하여 기술하는 방법

 

2) 배열 선언 방법

- 원소 값을 나열하기 위해 콤마(,)를 사용하고, 전체를 중괄호{...}로 묶는다

- 중괄호 사이에는 명시된 배열크기를 넘지 않게 원소 값 나열 가능

원소자료형 배열이름[배열크기] = {원소값1, 원소값2, 원소값 3, 원소값 4, 원소값 5, ... };

* 배열크기는 생략 가능하며, 생략 시 원소값의 수가 배열 크기가 된다

 

2) 배열 크기는 생략 가능

- 배열 크기 생략 시 중괄호 사이에 기술된 원소 수가 배열의 크기가 된다

 

3) 배열 초기화 기본값

- 지정한 배열크기가 초기값 원소 수보다 크면 지정하지 않은 원소의 초기값은 자동으로 모두 기본값이 저장된다

- 기본값: 자료형에 맞는 0

eg. 정수형은 0, 실수형은 0.0, 문자형은 \0인 널문자(문자코드 번호가 0인 문자)

 

ex.

int dist[5] = {12, 23, 17};
dist[0] dist[1] dist[2] dist[3] dist[4]
12 23 17 0 0

 

4) 배열 선언 초기화 주의점

- 초기화에서도 변수와 const 상수는 배열크기로 사용 불가

- 반드시 배열 선언 시에만 이용 가능

- 배열 선언 이후에는 사용 불가

eg.

변수와 배열 선언 문장 설명 및 오류 원인
int n = 5;
const int size = 6;
변수 n과 const 상수 size 선언
int score[n] = {89, 92, 91};
int cpoint[size] = {3, 5, 7};
변수 n은 배열크기로 사용 불가
상수 변수 size는 배열크기로 사용 불가
int grade[3] = {98, 88, 92, 95}; 원소 수 4가 배열크기 3보다 큼
int cpoint[size] = {99 76 84 76 68 93}; 원소값을 구분하는 콤마(,)가 빠짐
char ch[] = {a, b, c}; 원소값인 a, b, c가 문자여야 함
-> {'a', 'b', 'c'}
double width[4];
width = {23.5, 32.1};
배열 선언 이후에는 중괄호를 사용한 초기화를 할 수 없음
* 배열 선언 시 double width[4] = {23.5, 32.1};형태는 가능

 

5) 예제

배열 선언 초기화를 이용한 합과 평균 출력

#include <stdio.h>
#define SIZE 6

int main(void) {
	// 배열 socre 선언 및 초기화
	double score[] = { 89.3, 79.2, 84.83, 76.8, 92.52, 97.4 };
	/*
		배열 선언과 초기화는 두 문장을 나누어 할 수 없다
		double score[6];
		score = { 89.3, 79.2, 84.83, 76.8, 92.52, 97.4 };
		이런식으로 작성하는 경우 컴파일 오류 발생
	*/

	double sum = 0;

	// for문을 이용해 합 구하기
	for (int i = 0; i < SIZE; i++) {
		sum += score[i];
		printf("socre[%d] = %.2f\n", i, score[i]);
	}

	printf("성적의 합: %.2f 평균: %.2f\n", sum, sum / SIZE);

	return 0;
}

 

 

3. C99버전

 

: 배열 첨자 초기화(designated initializer)의 다양한 지원

 

1) 배열의 크기가 지정된 배열 a

- 지정한 첨자에 대해서는 초기값이, 그 외의 원소는 0으로 저장됨

ex. int a[8] = { [1] = 10, [3] = 30, [5] = 50 };

0 10 0 30 0 50 0 0

 

2) 배열의 크기가 지정되지 않은 배열 b

- 지정한 첨자에 대해서는 초기값이, 그 외의 원소는 0으로 저장됨

- 가장 큰 첨자가 마지막 원소가 되어 배열의 크기가 결정됨

ex. int b[] = { [1] = 10, [3] = 30, [5] = 50};

0 10 0 30 0 50

 

3) 일반적인 배열 초기화 방법인 배열 c

- 순서대로 초기값이 저장되며 지정한 첨자에 대해서는 초기값이 저장됨

- 그 외의 원소는 0으로 저장됨

ex. int c[] = {1, 2, [2] = 10, [5] = 50 };

1 2 10 0 0 50

 

 

다차원 배열

 

 

1. 2차원 배열 개요

 

1) 2차원 배열은 테이블 형태의 구조

- 행(row)과 열(column)의 구조로 표현

 

2) 배열 선언

: int td[2][3];

- td[0][0]으로 첫 번째 원소를 참조

- 두 번째 원소는 td[0][1]

- 두 번째 행의 첫 번째 항목인 네 번째 원소는 td[1][0]으로 행 첨자 1 증가

- 행 첨자는 0에서 (행 크기-1)까지 유효

- 열 첨자는 0에서 (열 크기 -1)까지 유효

 

3) 2차월 배열 선언

원소자료형 배열이름[배열행크기][배열열크기];

- 배열 선언 시 배열 크기는 생략할 수 없음

- 배열 크기는 리터럴상수, 매크로상수, 그것들의 연산식 허용

- 변수와 카스트변수는 허용되지 않음

 

4) 행 우선 배열

- 행을 먼저 배치하는 특징

- 첫 번째 행의 모든 원소가 메모리에 할당된 이후 두 번째 행의 원소가 순차적으로 할당

(* 포트란, R언어: 열 우선 배열 지원)

 

5) 2차원 배열 원소 참조

- 외부 반복 제어변수 i: 0에서 (행의 수-1)까지 행을 순차적으로 참조

- 내부 반복 제어변수 j: 0에서 (열의 수-1)까지 열을 순차적으로 참조

for (i=0; i<ROWSIZE; i++) {
	for (j=0; j<COLSIZE; j++) {
    	printf("%d"), td[i][j];
        puts("");
    }
}

 

 

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

 

1) 중괄호를 중첩되게 이용

- 2차원 구조를 행과 열로 표현할 수 있는 장점

- 중괄호 내부에 행에 속하는 값을 다시 중괄호로 묶고, 중괄호와 중괄호 사이에는 쉼표로 분리

- 행인 중괄호 내부의 초기값들은 쉼표로 분리

ex. int score[2][3] = { {30, 44, 67}, {87, 43, 56} };

30 44 67
87 43 56

 

2) 1차원 배열과 같이 하나의 중괄호로 모든 초기 값을 쉼표로 분리

ex. int score[2][3] = { 30, 44, 67, 87, 43, 56 };

30 44 67
87 43 56

- 배열원소를 순차적으로 2행 4열의 원소값으로 인지

 

ex2. int score[][3] = { 30, 44, 67, 87, 43, 56 };

30 44 67
87 43 56

- 행은 생략 가능, 열은 반드시 있어야 한다

- 명시된 열 수를 보고 행이 2인 것을 알 수 있다

 

 

3. 3차원 배열 선언

 

1) int threed[2][2][3];

- 총 2*2*3=12개 배열 원소

- 2행 3열의 2차원 배열 2개

- 대괄호 내부의 세 개 크기 모두 필요

 

2) 3차원 배열 초기화

- 3차원 배열, 학생의 점수를 초기값으로 저장

- score[2][4][2]

ex.

[강좌1] 중간 기말   [강좌2] 중간 기말
학생1 95 85   학생1 88 77
학생2 85 83   학생2 72 95
학생3 92 75   학생3 88 92
학생4 90 88   학생4 93 83
int score[2][4][2] = {
	{ { 95, 85 },
      { 85, 83 }
      { 92, 75 }
      { 90, 88 }},
    { { 88, 77 },
      { 72, 95 }
      { 88, 92 }
      { 93, 83 }}
};

 

 

배열 크기

 

 

1. 배열 크기 연산

 

1) 연산자 sizeof(변수), sizeof(자료형)

- 저장공간의 크기를 바이트 수로 반환하는 연산

 

2) 배열크기 계산 방법(1차원 배열)

- sizeof(배열이름): 배열 전체 공간의 바이트 수

- sizeof(배열원소): 배열원소 하나의 바이트 수

- sizeof(배열이름)/sizeof(배열원소): 배열크기(배열원소 수) 반환

배열크기(배열원소 수) 반환  = sizeof(배열이름)/sizeof(배열원소)
int arraysize = sizeof(data)/sizeof(data[0]);

 

ex.

int data[] = {12, 23, 17, 32, 55};

배열원소 크기(바이트 수): sizeof(data[0]) == 4 

배열전체 크기(바이트 수): sizeof(data) == 20

 

 

2. 배열크기 계산 방법(2차원 배열)

 

1) 2차원 배열의 행의 수

- sizeof(x)/sizeof(x[0])

- sizeof(x): 배열 전체 공간의 바이트 수

- sizeof(x[0]): (첫) 행의 바이트 수

 

2) 2차원 배열의 열의 수

- sizeof(x[0])/sizeof(x[0][0])

- sizeof(x[0][0]): (첫) 원소의 바이트 수

 

3) 예시

4행 3열, 2차원 배열

x[0][0] x[0][1] x[0][2]
x[1][0] x[1][1] x[1][2]
x[2][0] x[2][1] x[2][2]
x[3][0] x[3][1] x[3][2]

- 배열의 전체 원소 수: sizeof(x)/sizeof(x[0][0])=12

- 배열의 행 수: sizeof(x)/sizeof(x[0])=4

- 배열의 열 수: sizeof(x[0])/sizeof(x[0][0])=3

- 배열 전체 크기: 48

 

 


 

 

* 배열 선언에서 배열크기는 리터럴 상수와 매크로 상수로 지정

* 배열 크기는 변수로 지정할 수 없다