쉽게 풀어쓴 C언어 Express 제10장 배열 C Express Slide 1 (of 32)
배열의 필요성 학생이 10명이 있고 이들의 평균 성적을 계산한다고 가정하자. Slide 2 (of 32)
배열의 선언 자료형: 배열 원소들이 int형라는 것을 의미 배열 이름: 배열을 사용할 때 사용하는 이름이 grade 배열 크기: 배열 원소의 개수가 10개 인덱스(배열 번호)는 항상 0부터 시작한다. int score[60]; // 60개의 int형 값을 가지는 배열 grade float cost[12]; // 12개의 float형 값을 가지는 배열 cost char name[50]; // 50개의 char형 값을 가지는 배열 name char src[10], dst[10]; // 2개의 문자형 배열을 동시에 선언 int index, days[7]; // 일반 변수와 배열을 동시에 선언 Slide 3 (of 32)
배열 원소 접근 인덱스 grade[5] = 80; grade[1] = grade[0]; grade[i] = 100; // i는 정수 변수 grade[i+2] = 100; // 수식이 인덱스가 된다. grade[index[3]] = 100; // index[]는 정수 배열 Slide 4 (of 32)
배열의 초기화 int grade[5] = { 10,20,30,40,50 }; Slide 5 (of 32)
배열의 초기화 배열의 크기가 주어지지 않으면 자동적으로 초기값의 개수만큼이 배열의 크기로 잡힌다. Slide 6 (of 32)
배열 초기화 예제 #include <stdio.h> int main(void) { int grade[10] = { 31, 63, 62, 87, 14, 25, 92, 70, 75, 53 }; int i; printf("====================\n"); printf("인덱스 값\n"); printf("====================\n"); for(i = 0; i < 10; i++) printf("%5d %5d\n", i, grade[i]); return 0; } ==================== 인덱스 값 0 31 1 63 2 62 3 87 4 14 5 25 6 92 7 70 8 75 9 53 Slide 7 (of 32)
배열 원소 참조 예제 #include <stdio.h> ==================== #include <stdlib.h> #define SIZE 10 int main(void) { int grade[SIZE]; int i; for(i = 0; i < SIZE; i++) grade[i] = rand() % 100; printf("====================\n"); printf("인덱스 값\n"); printf("%5d %5d\n", i, grade[i]); return 0; } ==================== 인덱스 값 0 41 1 67 2 34 3 0 4 69 5 24 6 78 7 58 8 62 9 64 Slide 8 (of 32)
잘못된 인덱스로 접근하는 경우 #include <stdio.h> #define SIZE 5 int main(void) { int array[SIZE] = {1, 2, 3, 4, 5}; int i; for(i = 0; i <= SIZE; i++) printf("array[%d] %d\n", i, array[i]); return 0; } array[0] 1 array[1] 2 array[2] 3 array[3] 4 array[4] 5 array[5] 1245120 Slide 9 (of 32)
배열의 복사 int grade[SIZE]; int score[SIZE]; 잘못된 방법 score = grade; // 컴파일 오류! 잘못된 방법 #include <stdio.h> #define SIZE 5 int main(void) { int i; int a[SIZE] = {1, 2, 3, 4, 5}; int b[SIZE]; for(i = 0; i < SIZE; i++) b[i] = a[i]; return 0; } 올바른 방법 Slide 10 (of 32)
배열의 비교 #include <stdio.h> #define SIZE 5 int main(void) { int i; int a[SIZE] = { 1, 2, 3, 4, 5 }; int b[SIZE] = { 1, 2, 3, 4, 5 }; if( a == b ) // ① 올바르지 않은 배열 비교 printf("잘못된 결과입니다.\n"); else for(i = 0; i < SIZE ; i++) // ② 올바른 배열 비교 { if ( a[i] != b[i] ) { printf("a[]와 b[]는 같지 않습니다.\n"); return 0; } } printf("a[]와 b[]는 같습니다.\n"); return 0; } Slide 11 (of 32)
최소값 탐색 #include <stdio.h> #define SIZE 10 int main(void) { int grade[SIZE]; int i, min; for(i = 0; i < SIZE; i++) { printf("성적을 입력하시오: "); scanf("%d", &grade[i]); } min = grade[0]; for(i = 1; i < SIZE; i++) if( grade[i] < min ) min = grade[i]; printf("최소값은 %d입니다.\n", min); return 0; } 숫자를 입력하시오: 50 숫자를 입력하시오: 40 숫자를 입력하시오: 30 숫자를 입력하시오: 20 숫자를 입력하시오: 10 숫자를 입력하시오: 60 숫자를 입력하시오: 70 최소값은 10입니다. Slide 12 (of 32)
배열과 함수 #include <stdio.h> #define STUDENTS 5 int get_average(int score[], int n); // ① int main(void) { int grade[STUDENTS] = { 1, 2, 3, 4, 5 }; int avg; avg = get_average(grade, STUDENTS); printf("평균은 %d입니다.\n", avg); return 0; } int get_average(int score[], int n) // ② int i; int sum = 0; for(i = 0; i < n; i++) sum += score[i]; return sum / n; 배열이 인수인 경우, 참조에 의한 호출 배열의 원본이 score[]로 전달 Slide 13 (of 32)
원본 배열의 변경을 금지하는 방법 #include <stdio.h> #define SIZE 20 void copy_array(char dest[], const char src[], int count); int main(void) { char s[SIZE] = { 'H', 'E', 'L', 'L', 'O', '\0' }; char d[SIZE]; copy_array(d, s, SIZE); printf("%s\n", d); return 0; } void copy_array(char dest[], const char src[], int size) int i; for(i = 0; i < size; i++) { dest[i] = src[i]; } 배열 원본의 변경 금지 HELLO Slide 14 (of 32)
정렬이란? 정렬은 물건을 크기순으로 오름차순이나 내림차순으로 나열하는 것 정렬은 컴퓨터 공학분야에서 가장 기본적이고 중요한 알고리즘중의 하나 정렬은 자료 탐색에 있어서 필수적이다. (예) 만약 사전에서 단어들이 정렬이 안되어 있다면? Slide 15 (of 32)
선택정렬(selection sort) 선택정렬(selection sort): 정렬이 안된 숫자들중에서 최소값을 선택하여 배열의 첫번째 요소와 교환 Slide 16 (of 32)
선택 정렬 1/2 #include <stdio.h> #define SIZE 10 void selection_sort(int list[], int n); void print_list(int list[], int n); int main(void) { int grade[SIZE] = { 3, 2, 9, 7, 1, 4, 8, 0, 6, 5 }; // 원래의 배열 출력 printf("원래의 배열\n"); print_list(grade, SIZE); selection_sort(grade, SIZE); // 정렬된 배열 출력 printf("정렬된 배열\n"); return 0; } Slide 17 (of 32)
선택 정렬 2/2 void print_list(int list[], int n) { int i; for(i = 0;i < n; i++) printf("%d ", list[i]); printf("\n"); } void selection_sort(int list[], int n) int i, j, temp, least; for(i = 0; i < n-1; i++) { least = i; for(j = i + 1; j < n; j++) // 최소값 탐색 if(list[j] < list[least]) least = j; // i번째 원소와 least 위치의 원소를 교환 temp = list[i]; list[i] = list[least]; list[least] = temp; } } 원래의 배열 3 2 9 7 1 4 8 0 6 5 정렬된 배열 0 1 2 3 4 5 6 7 8 9 Slide 18 (of 32)
버블정렬(bubble sort) 인접한 레코드가 순서대로 되어 있지않으면 교환 전체가 정렬될때까지 비교/교환계속 Slide 19 (of 32)
버블 정렬 void bubble_sort(int list[], int n) { int i, scan, temp; // 스캔 회수를 제어하기 위한 루프 for(scan = 0; scan < n-1; scan++) { // 인접값 비교 회수를 제어하기 위한 루프 for(i = 0; i < n-1; i++) { // 인접값 비교 및 교환 if( list[i] > list[i+1] ) { temp = list[i]; list[i] = list[i+1]; list[i+1] = temp; } } } } Slide 20 (of 32)
순차 탐색 #include <stdio.h> #define SIZE 6 int seq_search(int list[], int n, int key); int main(void) { int key; int grade[SIZE] = { 10, 20, 30, 40, 50, 60 }; printf("탐색할 값을 입력하시오:"); scanf("%d", &key); printf("탐색 결과 = %d\n", seq_search(grade, SIZE, key)); return 0; } int seq_search(int list[], int n, int key) int i; for(i = 0; i < SIZE; i++) if(list[i] == key) return i; // 탐색이 성공하면 인덱스 반환 return -1; // 탐색이 실패하면 -1 반환 Slide 21 (of 32)
이진 탐색 이진 탐색(binary search): 정렬된 배열의 중앙에 위치한 원소와 비교 되풀이 Slide 22 (of 32)
이진 탐색 int binary_search(int list[], int n, int key) { int low, high, middle; low = 0; high = n-1; while( low <= high ){ // 아직 숫자들이 남아있으면 middle = (low + high)/2; // 중간 요소 결정 if( key == list[middle] ) // 일치하면 탐색 성공 return middle; else if( key > list[middle] )// 중간 원소보다 크다면 low = middle + 1; // 새로운 값으로 low 설정 else high = middle - 1; // 새로운 값으로 high 설정 } return -1; } Slide 23 (of 32)
2차원 배열 int s[10]; // 1차원 배열 int s[3][10]; // 2차원 배열 Slide 24 (of 32)
2차원 배열의 구현 2차원 배열은 1차원적으로 구현된다. Slide 25 (of 32)
2차원 배열의 초기화 int s[3][5] = { { 0, 1, 2, 3, 4 }, // 첫 번째 행의 원소들의 초기값 { 0, 1, 2, 3, 4 }, // 첫 번째 행의 원소들의 초기값 { 10, 11, 12, 13, 14 }, // 두 번째 행의 원소들의 초기값 { 20, 21, 22, 23, 24 } // 세 번째 행의 원소들의 초기값 }; Slide 26 (of 32)
2차원 배열의 초기화 int s[ ][5] = { { 0, 1, 2, 3, 4 }, // 첫 번째 행의 원소들의 초기값 { 0, 1, 2, 3, 4 }, // 첫 번째 행의 원소들의 초기값 { 10, 11, 12, 13, 14 }, // 두 번째 행의 원소들의 초기값 { 20, 21, 22, 23, 24 }, // 세 번째 행의 원소들의 초기값 }; Slide 27 (of 32)
2차원 배열의 초기화 int s[ ][5] = { { 0, 1, 2 }, // 첫 번째 행의 원소들의 초기값 { 0, 1, 2 }, // 첫 번째 행의 원소들의 초기값 { 10, 11, 12 }, // 두 번째 행의 원소들의 초기값 { 20, 21, 22 } // 세 번째 행의 원소들의 초기값 }; Slide 28 (of 32)
2차원 배열의 초기화 int s[ ][5] = { 0, 1, 2, 3, 4, // 첫 번째 행의 원소들의 초기값 0, 1, 2, 3, 4, // 첫 번째 행의 원소들의 초기값 5, 6, 7, 8, 9, // 두 번째 행의 원소들의 초기값 }; Slide 29 (of 32)
3차원 배열 #include <stdio.h> int main(void) { int s[3][3][3]; // 3차원 배열 선언 int x, y, z; // 3개의 인덱스 변수 int i = 1; // 배열 원소에 저장되는 값 for(z=0;z<3;z++) for(y=0;y<3;y++) for(x=0;x<3;x++) s[z][y][x] = i++; return 0; } Slide 30 (of 32)
다차원 배열 인수 #include <stdio.h> #define YEARS 3 #define PRODUCTS 5 int sum(int grade[][PRODUCTS]); int main(void) { int sales[YEARS][PRODUCTS] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; int total_sale; total_sale = sum(sales); printf("총매출은 %d입니다.\n", total_sale); return 0; } int sum(int grade[][PRODUCTS]) int y, p; int total = 0; for(y = 0; y < YEARS; y++) for(p = 0; p < PRODUCTS; p++) total += grade[y][p]; return total; 첫번째 인덱스의 크기는 적지 않아도 된다. Slide 31 (of 32)
Q & A Slide 32 (of 32)