for문에 의한 문장의 반복 for문의 구조와 이해 일부 컴파일러는 여전히 초기식에서의 변수 선언을 허용하지 않는다. for문의 반복영역도 한 줄이면 중괄호 생략 가능! for문의 흐름 이해 for문의 구성요소 √ 초기식 본격적으로 반복을 시작하기에 앞서 딱 한번 실행된다. √ 조건식 매 반복의 시작에 앞서 실행되며, 그 결과를 기반으로 반복유무를 결정! √ 증감식 매 반복실행 후 마지막에 연산이 이뤄진다. for문 흐름의 핵심 int num=0에 해당하는 초기화는 반복문의 시작에 앞서 딱 1회 진행! num<3에 해당하는 조건의 검사는 매 반복문의 시작에 앞서 진행! num++에 해당하는 증감연산은 반복영역을 실행한 후에 진행! for문 int main(void) { i= 1 int i; for(i=1; i<=3; i++) printf(“i= %d \n“, i); Return 0; } 실행결과 i= 2 i= 3 for문 int main(void) { 중첩 for문에서 변수 i와 total의 변화 i total ---------------------------------------- int total=0; int i; for(i=1; i<=3; i++) total = total + i; 1 1 2 3 3 6 4 ---------------------------------------실행결과 printf(“1에서 3까지 합은 %d”, total); Return 0; } 1에서 3까지 합은 6 for문 기반의 다양한 예제 실행결과 for문 기반의 다양한 예제 실행결과 오른쪽 예제에서 보이듯이 불필요하다 면, 초기식, 조건식, 증감식을 생략할 수 있다. 단 조건식을 생략하면 참으로 인식이 되어 무한루프를 형성하게 된다. for문의 중첩 int main(void) { 중첩 for문에서 변수 C와 i의 변화 i 출력 ---------------------------------------- int i, j; 1 for(i=1; i<=2; i++) { 1 i=1 j=1 2 i=1 j=2 3 ---------------------------------------- for( j=1; j<=2; j++) 2 printf(“i=%d j=%d \n”, i, j); printf(“\n”); } Return 0; } j 1 i=2 j=1 2 i=2 j=2 3 ---------------------------------------3 for문의 중첩 int main(void) { 중첩 for문에서 변수 C와 i의 변화 c 출력 ---------------------------------------- int c, i; 2 for(c=2; c<=3; c++) { 1 2*1 2 2*2 3 2*3 4 for(i=1; i<=3; i++) printf(“%d * %d = %d \n”, c, i, c*i); ---------------------------------------3 printf(“\n”); } Return 0; } i 1 3*1 2 3*2 3 3*3 4 ---------------------------------------4 for문의 중첩 #include <stdio.h> void main() { int i, j; for(i=1; i<=5; i++) { for(j=1; j<=i; j++) printf("%d ", j); printf("\n"); } } 함수 함수 함수란 ? 함수 = 특정한 작업을 수행하기 위한 독립 된 작은 단위의 프로그램 함수를 만드는 이유 다수의 작은 단위 함수를 만들어서 프로그램을 작성하면 큰 문제를 작게 쪼 개서 해결하는 효과를 얻을 수 있다. 그러나 함수를 만드는 이유 및 이점은 이보다 훨씬 다양하다. main 함수를 포함하여 함수의 크기는 작을수록 좋다. 무조건 작다고 좋은 것은 아니지만, 불필요하게 큰 함수가 만들어지지 않도록 주의해야 한다. 하나의 함수는 하나의 일만 담당하도록 디자인 되어야 한다. 물론 하나의 일이라는 것은 매우 주관적인 기준이다. 그러나 이러한 주관적 기준 역시 프로그래밍에 대한 경험이 쌓이면 매우 명확한 기준이 된다. 전달인자는 int형 정수 둘이며, 이 둘을 이용한 덧셈을 진행한다. 덧셈결과는 반환이 되며, 따라서 반환형도 int형으로 선언한다. 마지막으로 함수의 이름은 Add라 하자! 덧셈이 선 진행되고 그 결과가 반환됨 함수호출이 완료되면 호출한 위치로 이동해서 실행을 이어간다. 실행결과 함수 함수의 예 #include <stdio.h> ② ③ int add(int a, int b) // sub 함수 ④{ ⑤ int sum; ⑥ sum = a + b; ⑦ return sum; ⑧} ⑨ ⑩ void main() ⑪{ ⑫ int a = 10, b = 20, ret; ⑬ ret = add(a, b); ⑭ printf("%d", ret); ⑮} 함수 실습1 #include <stdio.h> ② ③ void output(float avg) // sub함수 ④{ ⑤ printf("11과 12의 평균값은 %f이다\n", avg); ⑥} ⑦ ⑧ void average_11_12( ) // sub 함수 ⑨{ ⑩ float average = (11 + 12) / 2.0; ⑪ output(average); ⑫} ⑬ ⑭ void main() ⑮{ ⑯ average_11_12(); ⑰} 함수 실습3 #include <stdio.h> ② ③ int add(int a, int b); // sub함수 선언 ④ ⑤ void main() ⑥{ ⑦ int a = 10, b = 20, ret; ⑧ ret = add(a, b); ⑨ printf("%d", ret); ⑩} ⑪ ⑫ int add(int a, int b) // sub함수 ⑬{ ⑭ int sum; ⑮ sum = a + b; ⑯ return sum; ⑰} 1차원 배열(숫자) 배열이란 무엇인가? 다수의 정보를 저장하기 위해서는 다수의 배열을 선언해야 한다. 위와 같이 다수의 변수를 선언해야 하는 경우 매우 번거로울 수 있다. 그래서 다수의 변수선언을 용이하게 하 기 위해서 배열이라는 것이 제공된다. 배열을 이용하면 하나의 선언을 통해서 둘 이상의 변수를 선언할 수 있 다. 배열은 단순히 다수의 변수선언을 대신하지 않는다. 다수의 변수로는 할 수 없는 일을 배열을 선언하면 할 수 있다. 배열은 1차원의 형태로도 2차원의 형태로도 선언할 수 있다. 이번 Chapter에서는 1차원 형태의 배열에 대해 서 학습한다. 1차원 배열 선언에 필요한 것 세 가지 1차원 배열 선언의 예 생성되는 배열의 형태 다양한 배열 선언의 예 선언된 1차원 배열의 접근 1차원 배열 접근의 예 일반화 왼편의 예제를 통해서 느낄 수 있는 배열의 또 다른 매력은? 실행결과 배열! 선언과 동시에 초기화하기 초기화 리스트로 초기화 초기화 결과 초기화 값 부족한 경우 부족한 부분 0으로 채워짐 순서대로 초기화 초기화 리스트는 존재하고 배열의 길이정보 생략된 경우 컴파일러가 배열의 길이정보 채움 문자 배열 char형 배열의 문자열 저장과 널 문자 배열에 문자열 저장 저장결과 문자열의 끝에 널 문자라 불리는 \0가 삽입되었음에 주목! 널 문자는 문자열의 끝을 의미한다. 실행결과 널 문자와 공백 문자의 비교 널 문자를 %c를 이용해서 출력 시 아무것도 출력되지 않는다. 그렇다고 해서 널 문자가 공백 문자는 아니다. 널 문자의 아스키 코드 값은 0이고, 공백 문자의 아스키 코드 값은 32이다. 널 문자는 모니터 출력에서 의미를 갖지 않는다. 그래서 아무것도 출력이 되지 않을 뿐이다. 문자열의 끝에 널 문자가 필요한 이유 문자열의 시작은 판단할 수 있어도 문자열의 끝은 판단이 불가능하다! 때문에 문자열의 끝을 판단할 수 있도록 널 문자가 삽입이 된다. 배열의 시작위치에 문자열이 저장되기 시작한다. 따라서 시작위치는 확인이 가능하다. 하지만 배열의 끝이 문자열 의 끝은 아니므로 널 문자가 삽입되지 않으면 문자열의 끝은 확인이 불가능하다. 실행결과 위 예제에서 보이듯이 printf 함수도 배열 str의 시작위치를 기준으로해서 널 문자를 만날 때까지 출력을 진행한다. 따라서 널 문자가 없으면 printf 함수도 문자열의 끝을 알지 못한다. Chapter 11이 끝났습니다. 질문 있으신지요? 2차원 배열의 초기화 예) 2차원 배열의 초기화 int Tel[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; [그림 3.3] 배열 Tel에 초기값이 저장된 형태 1 2 3 4 5 6 7 8 9 예) 2차원 배열 초기화의 여러 방법 int Min[2][3] = { 1, 2, 3, 4, 5, 6 }; // 한 개의 {} 사 용 int Det[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 행별로 {} 사용 int Max[ ][3] = { 1, 2, 3, 4, 5, 6 }; // 행의 개수 생 략 char Alpha[ ][3] = { {1, a, A}, // 초기값의 행별 {2, b, B}, 배치 {3, c, C} }; 예) 2차원 배열 요소의 참조 int Imf[3][2]; // 배열 선언 Imf[0][0] = 45; // 값의 배정 Imf[1][0] = 75; // 값의 배정 Imf[2][0] = Imf[0][0] + Imf[1][0]; // 식 내에서 값의 참조 #include <stdio.h> void main() { int m[3][3]={1, 2, 3, 4, 5, 6, 7, 8, 9}; int sum = 0; for (int i=0; i<=2; i++){ for (int j=0; j<=2; j++){ if (i==j) sum +=m[i][j]; } printf(“대각선의 합은 %d이다”, sum); } 예제 9 #include <stdio.h> void main() { char city[10][48] = { "Seoul", "Busan", "Daegu", "Daejon"}; char n[10] = {"zzang"}; printf("n배열은 %s이다 \n", n); printf("city[0]행은 %s이다 \n", city[0]); printf("city[3]행은 %s이다 \n", city[3]); printf("city[0[3]은 %c이다", city[0][3]); } 3차원 배열 예) 3차원 배열의 선언 문법 형명 배열명[면의 개수][행의 개수][열의 개수]; 예) 3차원 배열의 선언 및 초기화 int Com[2][2][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; [그림 3.4] 3차원 배열의 구조 면1 7 면0 1 4 10 8 2 5 11 9 3 6 12 예) 3차원 배열 초기화의 여러 방법 int Net[ ][2][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; int Edu[ ][2][3] = { {1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12} }; int Gov[ ][2][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} }; int Org[ ][2][3] = { { {1, 2, 3}, {4, 5, 6} } }, { {7, 8, 9}, {10, 11, 12} } }; * 지난 시간 강의 정리 1. 1차 배열-숫자, 문자 2. 2차, 3차 배열 3. 왜 배열을 사용하는가? * 이번 시간 강의 목표 1. 포인터가 무엇인가? 2. 어떻게 선언하는가? 3. 어떻게 사용하는가? 4. 왜 사용하는가? 5. 포인터를 사용해야만 하는 이유 포인터 10. 포인터 포인터 변수 사용규칙 변수형 선언자 *포인터명 #include <stdio.h> void main() { int a = 10; int *ptr; ptr = &a; printf(“ptr = %d\n”, ptr); printf(“*ptr = %d\n”,*ptr); } 주소 600 주기억 장소 10 변수명 a . . 800 600 ptr 10. 포인터 #include <stdio.h> void main() { int a = 10; int *ptr; ptr = &a; printf(“ptr = %d\n”, ptr); printf(“&ptr = %d\n”,&ptr); printf(“*ptr = %d\n”, *ptr); printf(“ptr+1 = %d\n”, ptr+1); } 주소 1245052 주기억 장소 10 변수명 a . . 1245048 1245052 ptr * 이번 시간 강의 요약 1. 포인터가 무엇인가? 2. 어떻게 선언하는가? 3. 어떻게 사용하는가? * 이번 시간 강의 목표 1. 포인터와 함수 2. call by address 10. 포인터 1) Call by value #include <stdio.h> int swap(int x, int y) { int temp; temp = x; x = y; y = temp; printf(“%d %d", x, y); return 0; } void main() { int a=10, b=20; swap(a, b); printf(“%d %d", a, b); } 10. 포인터 2) Call by address #include <stdio.h> int swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; return 0; } void main() { int a=10, b=20; swap(&a, &b); printf(“%d %d", a, b); } * 이번 시간 강의 요약 1. 포인터와 함수 2. call by address * 지난 시간 강의 정리 1. 포인터가 무엇인가? 2. 어떻게 선언하는가? 3. 포인터 변수에 무엇을 넣는가? 4. 어떻게 사용하는가? * 이번 시간 강의 목표 1. 포인터와 배열과의 관계 10. 포인터 #include <stdio.h> int score[3] = { 10, 20, 30 }; void main() { printf(“&score[0] = %d\n”, &score[0]); printf(“score = %d\n”, score); printf(“*score = %d\n”, *score); printf(“*(score+1) = %d\n”, *(score+1)); printf(“*score+1 = %d\n”, *score+1); } 10. 포인터 #include <stdio.h> void main() { char name_1[6]=“PETER”; char *name_2 = “DAVID”; printf(“name_1[2] = %c\n”, name_1[2]); printf(“*(name_2+2) = %c\n”, *(name_2+2)); printf(“name_1 = %s\n”, name_1); } * 이번 시간 강의 요약 1. 포인터와 배열과의 관계 2. 포인터와 배열은 호환됨 포인터=배열명=&배열[0]