C 프로그래밍및실습 7. 배열 세종대학교 목차 1) 배열개요 3) 배열활용예제 4) 다차원배열 2
1) 배열개요 변수를여러개만들어야하는상황을생각해보자. 사용자로부터 5개의정수를입력받아변수에저장하고, 이값을출력하는프로그램은다음과같이작성할수있다. 하지만, 정수가 100개라면? 배열을사용하여해결 int main(void){ int x0, x1, x2, x3, x4; scanf("%d%d%d%d%d", &x0, &x1, &x2, &x3, &x4); printf("%d %d %d %d %d\n", x0, x1, x2, x3, x4); return 0; } 3 1) 배열개요 배열이란? 같은자료형의변수여러개를하나로묶은자료형 배열을이용하여많은변수를한번에선언하고, 저장된데이터를처리할수있음 앞예에서사용한 5개의변수를배열형식으로표현하면 x0, x1, x2, x3, x4 x[0], x[1], x[2], x[3], x[4] 배열 x x[0] x[1] x[2] x[3] x[4] 4
배열의선언 변수이름뒤에필요한변수의개수 ( 배열크기 ) 를명시 배열선언구문자료형변수명 [ 배열크기 ]; 예시 ) int x[5]; - 자료형은정수형, 이름은 x, 크기는 5 인배열 - 5 개의정수를저장하는배열 x x[0] x[1] x[2] x[3] x[4] 배열 x int x[5], y[3]; double a, b, c[10]; 여러개의배열함께선언가능 일반변수와함께선언가능 5 배열의원소 (or 요소 ): 배열을구성하는각변수를지칭 대괄호 [ ] 안에번호를넣어서구분 : x[0], x[1], x[2], x[3], x[4] 배열의첨자 or 인덱스 (index) 배열에서각원소의위치를나타내는대괄호 [ ] 안의번호를지칭 배열의인덱스는 0부터시작함 예 ) 크기가 5인배열의인덱스는 0~4까지임 x[0] x[1] x[2] x[3] x[4] 배열 x 배열의각원소는하나의일반변수와동일하게취급 x[1] = 10; x[0] = x[0] + 3; printf("%d", x[4] ); a = 10; b = b + 3; printf("%d", c ); 6
앞서본예제프로그램을배열을이용하여작성해보자. 사용자로부터 5개의정수를입력받아변수에저장하고, 이값을출력하는프로그램 int x[5]; scanf("%d%d%d%d%d", &x[0], &x[1], &x[2], &x[3], &x[4]); printf("%d %d %d %d %d\n", x[0], x[1], x[2], x[3], x[4]); 실행예시 3 5 1 3 4 3 5 1 3 4 x[4] 를하나의변수처럼사용 scanf 에서변수앞에 & 붙여줌 부동소수형, 문자형에대해서도동일한방법으로배열선언및사용 7 앞프로그램에서입력되는정수가 100개라면? 배열을사용해서변수선언은간단히해결됨 하지만, 입출력부분은? 반복문을이용하여해결 배열과반복문과의만남 배열원소의인덱스가 0부터시작하여 1씩증가한다는규칙을이용하여배열의원소에접근 참고 ) 배열첨자로결과값이정수인수식은모두가능 printf("%d ", x[0]); printf("%d ", x[1]); printf("%d ", x[2]); printf("%d ", x[3]); printf("%d ", x[4]); for( i=0 ; i<5 ; i++ ) printf("%d ", x[i]); 8
배열을이용하여작성된최종프로그램 사용자로부터 5개의정수를입력받아변수에저장하고, 이값을출력하는프로그램 int x[5], i; // 배열선언 for( i=0 ; i<5 ; i++ ) scanf("%d", &x[i]); // 입력된정수를배열에저장 for( i=0 ; i<5 ; i++ ) printf("%d ", x[i]); // 배열에저장된정수출력 printf("\n"); 배열사용시주의점 컴파일러는배열의첨자가유효한범위인지검사하지못함 유효하지않은첨자범위 런타임오류를유발시킴 9 [ 실습1] 크기가 7인배열 x에아래점수를저장하시오. for문 80, 71, 91, 95, 77, 79, 88 for 문을이용하여 80점이상의학생의인덱스와점수를모두출력하는프로그램을작성하시오. 출력예시 0 80 2 91 3 95 6 88 [ 실습2] 크기가 9인배열 x를선언하시오. 구구단 3단의계산값을배열에저장한후, for문 배열내용을화면에출력하시오. for문 3 6 9... 27 출력예시 10
배열초기화 배열전체를선언과동시에초기화하기 중괄호 { } 안에배열이초기화값을쉼표로구분하여나열 배열전체값을한꺼번에대입하는것은선언시에만가능 int i, x[5] = {0, 10, 20, 30, 40} ; for(i=0;i<5;i++) printf(" %d", x[i]); 0 10 20 30 40 11 배열의크기보다초기값의개수가작으면? 앞원소부터차례로채워지고, 배열의뒷부분은 0 으로채워짐 int i, x[5] = {1, 2, 3} ; for(i=0;i<5;i++) printf(" %d", x[i]); 1 2 3 0 0 배열전체를 0 으로초기화하기 int i, x[5] = {0} ; for(i=0;i<5;i++) printf(" %d", x[i]); int i, x[5] = {0,} ; for(i=0;i<5;i++) printf(" %d", x[i]); 주의 ) 배열의크기보다초기값의개수가크면? int x[5] = { 1, 2, 3, 4, 5, 6 }; 컴파일오류발생 12
배열의크기를초기값의개수로정하기 배열의크기를지정하지않으면? 배열크기가초기화에사용된원소수로결정됨 int x[ ] = {10, 20, 30}; for( i=0 ; i<3 ; i++ ) printf(" %d", x[i]); 10 20 30 배열크기 = 3 printf("\n 배열크기 = %d\n", sizeof(x)/sizeof(x[0])); sizeof 연산자 (2장참조 ) sizeof(x) : 배열 x의전체크기 sizeof(x[0]) : 원소하나의크기 13 목차 1) 배열개요 3) 배열활용예제 4) 다차원배열 14
3) 배열활용예제 [ 예제 7.1] 5 개의실수를입력받아배열에저장하고, 합과평균출력 참고 ) scanf() 함수에서 double 형서식지정자 : %lf 입력예시 1 출력예시 1 1.0 2.0 3.0 4.0 5.0 합 = 15.000000, 평균 = 3.000000 [ 예제 7.2] 5 개의실수를입력받아배열에저장하고, 최댓값출력 입력예시 1 출력예시 1 5.0 0.7 13.4 4 9.5 max = 13.400000 ( 응용 ) 최댓값이저장된배열원소의첨자출력하기 위예에서는 2 15 3) 배열활용예제 [ 예제 7.3] 크기가 10인두배열 X와 Y에정수를입력받아서저장한후, X[0] 과 Y[9] 의합을 Z[0] 에저장하고, X[1] 과 Y[8] 의합을 Z[1] 에저장하고,, X[9] 와 Y[0] 의합을 Z[9] 에저장한후, 배열 Z의원소를출력하자. z[0] = x[0]+y[9] = 1 + 9 = 10 z[1] = x[1]+y[8] = 2 + 7 = 9 hint) 배열 x, y, z의첨자가변화는규칙을찾아보라. 참고 ) 첨자에는결과값이정수인어떤수식이든사용가능 입력예시 1 출력예시 1 1 2 3 4 5 6 7 8 9 10 2 4 6 8 0 1 3 5 7 9 10 9 8 7 7 6 6 15 14 13 12 16
3) 배열활용예제 [ 예제 7.4] 9개의영어소문자를입력받아배열에저장하고, 입력문자순서대로각문자가나타난횟수출력 예 ) levelfive l 2번, e 3번, v 2번, e 3번, hint) 이중반복 입력예시 1 출력예시 1 levelfive 2 3 2 3 2 1 1 2 3 17 3) 배열활용예제 [ 예제 7.5] 0~5 사이의정수를 10개입력받아배열 x( 크기 10) 에저장하고, 0~5 사이의수가각각몇개인지계산하여배열 cnt( 크기 6) 에저장한후, cnt에저장된값출력하기 예시설명 ) 0은 1번, 1은 1번, 2는 4번, 3은 0번, 4는 1번, 5는 3번 입력예시 1 출력예시 1 2 4 2 5 2 1 5 5 0 2 1 1 4 0 1 3 hint) 프로그램동작방식 버전 A: 각정수마다배열 x 전체를훑어서계산 ( 배열 x를총 6번훑어야함 ) 버전 B: 배열 x를훑으면서, 각배열원소에해당하는정수의 cnt 증가 ( 배열한번만훑어도됨 : 더효율적 ) 18
목차 1) 배열개요 3) 배열활용예제 4) 다차원배열 19 '3 명학생 ' 의 '5 개과목성적 ' 을처리해야한다면? ' 정수 ' 를여러개묶어 ' 정수배열 ' 을만들었듯이 ' 정수배열 ' 을여러개묶어 ' 정수배열의배열 ' 을만들면효과적 score0 int score0[5]; int score1[5]; int score2[5]; 과목의미 학생의미과목의미 int score[3][5]; score score1 score2 다차원배열 : 첨자가두개이상인배열 (2 차원배열, 3 차원배열등 ) cf. 일차원배열 20
2차원배열의선언 구문자료형변수명 [ 크기 ][ 크기 ]; 예시 ) int x[3][5]; - 자료형은정수형, 이름은 x, 크기는 3x5 인 2 차원배열 - 총 3x5=15 개의정수저장 int x[3][5], y[7][6]; 다양한크기의배열함께선언 double a, b, c[10], d[9][9]; 다른차원배열도함께선언 ( 코드가독성나빠질수있음 ) 21 2차원배열의원소 두개의첨자를이용하여원소표현 각차원의첨자는 0 부터시작 예시 ) int x[3][5]; // 선언 0 1 2 3 4 0 x[0][0] x[0][1] x[0][2] x[0][3] x[0][4] 1 x[1][0] x[1][1] x[1][2] x[1][3] x[1][4] 첫번째차원의첨자는 0~2 두번째차원의첨자는 0~4 2 x[2][0] x[2][1] x[2][2] x[2][3] x[2][4] 2 차원배열의각원소는하나의일반변수와동일하게취급 x[1][2] = 10; x[0][3] = x[0][3] + 5; printf("x[1][4] = %d", x[1][4] ); 22
2차원배열과반복문 선언 ) int score[3][5]; //3명의학생, 5개의과목점수저장 1번학생의모든과목점수출력 0 1 2 3 4 for( j=0; j < 5 ; ++j ) 0 0 1 2 3 4 printf(" %d", score[1][j]); 1 10 11 12 13 14 10 11 12 13 14 2 20 21 22 23 24 2 번과목의모든학생점수출력 for( i=0; i < 3 ; ++i ) printf(" %d", score[i][2]); 2 12 22 0 1 2 3 4 0 0 1 2 3 4 1 10 11 12 13 14 2 20 21 22 23 24 23 2차원배열과반복문 각학생별로모든과목점수출력 즉, 학생을기준으로모든점수처리 for( i=0; i < 3 ; ++i ) { for( j=0; j < 5 ; ++j ) printf(" %d", score[i][j]); printf("\n"); } 0 1 2 3 4 0 0 1 2 3 4 1 10 11 12 13 14 2 20 21 22 23 24 0 1 2 3 4 10 11 12 13 14 20 21 22 23 24 24
2차원배열과반복문 각과목별로모든학생점수출력 즉, 과목을기준으로모든점수처리 for( j=0; j < 5 ; ++j ) { for( i=0; i < 3 ; ++i ) printf(" %d", score[i][j]); printf("\n"); } 0 1 2 3 4 0 0 1 2 3 4 1 10 11 12 13 14 2 20 21 22 23 24 0 10 20 1 11 21 2 12 22 3 13 23 4 14 24 25 2차원배열초기화 중첩중괄호를사용하여행별로초깃값설정 값이지정되지않은원소는 0으로초기화 한줄에쓴형태 int x[3][5] = { {10, 20, 30}, {40, 50, 60, 70} } ; 0 1 2 3 4 0 10 20 30 0 0 1 40 50 60 70 0 행별로나눠쓴형태 2 0 0 0 0 0 int x[3][5] = { {10, 20, 30}, // 0번행 {40, 50, 60, 70} } ; // 1번행 참고 ) 하나의중괄호를사용하는형태도가능 ( 교재 p.193 참조 ) 26
배열전체를 0으로초기화하기 int x[3][5] = { { 0 } }; 중첩중괄호사용형태 int x[3][5] = { 0 }; 단일중괄호사용형태 배열의크기를초깃값개수로정하기 첫번째첨자만생략가능, 두번째첨자는생략불가능 int x[ ][2] = { {0,1}, {0}, {0} }; x[3][2] 와동일 ( 정상 ) int x[3][ ] = { {0,1}, {0}, {0} }; (X) 컴파일오류 int x[ ][ ] = { {0,1}, {0}, {0} }; (X) 컴파일오류 27 [ 예제 7.6] 학생 3 명의국어, 영어성적을저장하기위한 2 차원배열을선언하고아래와같이초기화한후, 국어와영어과목의평균을각각계산하여출력하기 국어 영어 학생 A 20 100 학생 B 70 36 학생 C 30 50 40.000000 국어평균 62.000000 영어평균 28
[ 예제 7.7] 4 4 크기의행렬을나타내는 2차원배열 A를아래왼쪽과같이초기화하고, 행렬 A와 A의전치행렬을나란히출력 전치행렬이란? 행과열을바꾼행렬 전치행렬을저장하기위한배열을따로선언해도무방 0.0 0.1 0.2 0.3 0.0 1.0 2.0 3.0 1.0 1.1 1.2 1.3 0.1 1.1 2.1 3.1 2.0 2.1 2.2 2.3 0.2 1.2 2.2 3.2 3.0 3.1 3.2 3.3 0.3 1.3 2.3 3.3 ( 행렬 A) (A 의전치행렬 ) ( 응용 ) 전치행렬을저장하기위한배열을따로선언하지않고 A 를이용하여직접전치행렬출력하기 29 3차원이상의배열 2차원배열과비슷한방법으로확장 예시 ) 반별로학생 3명의국어와영어성적처리 1반 국어 영어 학생 A 20 90 학생 B 70 36 학생 C 30 50 2반 국어 영어 학생 D 30 90 학생 E 80 40 학생 F 40 60 int score[2][3][2] = { { {20,90}, {70,36}, {30,50} }, // 1반 { {30,90}, {80,40}, {40,60} } }; // 2반 30
두반의국어성적전체출력하기 int i, j; int score[2][3][2] = { { {20,90},{70,36},{30,50} }, { {30,90},{80,40},{40,60} } }; for( i=0 ; i<2 ; i++ ) { // 각반에대해서 printf("%d반국어 :", i+1); for( j=0 ; j<3 ; j++ ) // 각학생에대해서 printf(" %d", score[i][j][0]); printf("\n"); } 1 반국어 : 20 70 30 2 반국어 : 30 80 40 31