610 likes | 859 Views
제 6 장 배열 (Array) 및 포인터 (Pointer). 주홍택 계명대학교 , 정보통신대학 컴퓨터네트워크연구실 juht@kmu.ac.kr. 서론. 계산한 값을 저장하고 처리하기 위해서는 적당한 자료형을 가진 변수가 필요함 같은 성질의 값을 여러 개 저장하고 처리해야하는 경우 ? 예 1: 한 학급 모든 학생의 점수를 저장하기 위한 변수 예 2: 전국민의 주민등록번호를 저장하기 위한 변수 배열 (Array) 같은 자료형 을 가진 데이터를 하나의 변수 이름을 사용하여 저장하고 처리하기 위한 방법 제공
E N D
제6장배열(Array) 및 포인터(Pointer) 주홍택 계명대학교,정보통신대학 컴퓨터네트워크연구실 juht@kmu.ac.kr
서론 • 계산한 값을 저장하고 처리하기 위해서는 적당한 자료형을 가진 변수가 필요함 • 같은 성질의 값을 여러 개 저장하고 처리해야하는 경우? • 예1: 한 학급 모든 학생의 점수를 저장하기 위한 변수 • 예2: 전국민의 주민등록번호를 저장하기 위한 변수 • 배열(Array) • 같은 자료형을 가진 데이터를 하나의 변수 이름을 사용하여 저장하고 처리하기 위한 방법 제공 • 거의 모든 고급언어에서 제공함 • 포인터(Pointer) • 자료가 저장된 주소의 값 • 같은 자료형일 경우 포인터를 이용하면 매우 편리함 • 배열과 매우 밀접한 관련이 있음
배열: 일차원 배열(1-dimensional array) • 같은 자료형을 가진 데이터를 저장하고 처리하기 위한 자료구조 • 배열의 선언 자료형 배열이름[크기] • 배열의 크기는 항상 정수이며 상수이어야 함 • 예: 5명의 점수(정수)를 저장하기 위한 배열 int std[5]; • 선언과 동시에 초기화 가능 • 예: 5명의 점수(정수)를 저장하기 위한 배열에 점수 저장 int std[5] = {78, 56, 24, 98, 35 }; int std[5] = {78, 56}; ? int std[5] = {78, 56, 24, 98, 35, 55}; ?
배열: 일차원 배열(1-dimensional array) • 배열은 연속된 메모리에 저장됨 • 원소(element): 배열에 저장된 각 개체 • 색인(index): 배열에 저장된 각 개체의 위치 • Index는 0부터 시작함 • 배열의 원소에 값을 저장 • Index를 사용함 • 예: std[1] = 88; • std[5] = 78; ? • 배열의 원소의 값을 읽어 내기 • Index를 사용함 • 예: score = std[3]; • score = std[6]; ?
배열에 저장된 각 학생의 점수에 5점씩 증가 #include <stdio.h> int main(void) { int num[5] = {12, -23, 45, 8, -2}; int i; for(i=0; i < 5; i++) num[i] = num[i] + 5; printf("\nnum[] = { "); for(i=0; i < 5; i++) printf("%d ", num[i]); printf("}"); }
배열에 저장된 점수의 총점 및 평균 int std[5] = {78, 56, 24, 98, 35}; int sum; float avg; int count; sum = 0; avg = 0.0; for( count = 0; count < 5 ; count++) sum = sum + ___________ ; avg = (float) sum / 5; printf(“ sum = %d, average = %f\n”, sum, avg);
다차원 배열(multi-dimensional array) • 한반의 5명 학생의 국어, 영어, 수학 각 과목에 대한 점수를 저장하기 위한 변수 선언방법 int korean[5]; int english[5]; int mathmatics[5]; • 하나의 변수를 사용하는 방법은? 다차원 배열 int score[3][5]; • 일차원 배열의 계속적인 확장 • 배열의 값을 저장하기와 읽기도 일차원 배열의 확장 • Index 사용 • 예 score[subject][id] = 89; sum = sum + score[subject][id];
다차원 배열(multi-dimensional array) • 다차원 배열 선언과 초기화 int score[3][5] = { {78, 56, 24, 98, 35}, {56, 45, 23, 67, 78}, {89, 34, 23, 67, 89} };
각 과목의 총점과 평균을 구하기 • 앞에서 정의한 score 점수의 각 과목 총점과 평균을 구하는 프로그램 작성
각 과목의 총점과 평균을 구하기 int score[3][5] = { {78, 56, 24, 98, 35}, {56, 45, 23, 67, 78}, {89, 34, 23, 67, 89} }; int sum; float avg; int student, subject ; for( subject = 0; subject < 3 ; subject++){ sum = 0; for( student = 0; student < 5 ; student++) sum = sum + score[subject][student]; avg = (float) sum / 5; printf(“ sum = %d, average = %f\n”, sum, avg); }
배열에 점수를 입력 받아서 총점 및 평균 int score[5]; int sum; float avg; int count; sum = 0; avg = 0.0; for( count = 0; count < 5 ; count++){ printf(“ Input score of student %d: “,count); scanf(“%d”, _________ ); } for( count = 0; count < 5 ; count++) sum = sum + ___________ ; avg = (float) sum / 5; printf(“ sum = %d, average = %f\n”, sum, avg);
3차원 배열 선언 방법은? • 예: 각반이 5명으로 구성된 1반 부터 2반까지의 모든 학생의 국어, 영어, 수학 점수를 저장하기 위한 변수는? #define CLASS 2 #define SUBJECT 3 #define STUDENT 5 int score[CLASS][SUBJECT][STUDENT];
각 반의 각 과목 총점 및 평균 구하기 • 각반이 5명으로 구성된 1반 부터 2반까지의 모든 학생의 국어, 영어, 수학 점수를 저장하기 위한 변수 score를 선언하고 초기화 한 후 각 반의 각 과목에 대한 총점 및 평균 구하기
각 과목의 총점과 평균을 구하기 #define CLASS 2 #define SUBJECT 3 #define STUDENT 5 int score[CLASS][SUBJECT][STUDENT] = {{ {78, 56, 24, 98, 35}, {56, 45, 23, 67, 78}, {89, 34, 23, 67, 89} }, { {87, 65, 42, 89, 53}, {65, 54, 32, 76, 87}, {98, 43, 32, 76, 98} }}; int sum; float avg; int class, student, subject ; for( class = 0; class < CLASS ; class++){ for( subject = 0; subject < SUBJECT ; subject++){ sum = 0; for( student = 0; student < STUDENT ; student++) sum = sum + score[class][subject][student]; avg = (float) sum / 5; printf(“ Class %d, Subject %d: sum = %d, average = %f\n”, class, subject, sum, avg); }
문자열 배열 선언 • 문자열 배열은 많이 사용됨 • 문자열 배열 선언 char str[10]; • 초기화와 함께 선언 char str[10] = {‘s’,’t’,’r’,’i’,’n’,’g’,’\0’}; • 더 쉬운 방법 char str[10] = “string”; • 크기는 반드시 저장해야 할 스트링의 길이 더하기 1보다 크게 char str[7] = “string”; • 2차원 배열은? char str[3][10] = { “string1”, “string2”, “string3” };
문자열 배열에 값 저장 • 치환연산자로 한번에 저장이 안됨 char str[10]; str[10] = “string” ; str = “string”; • 하나씩 저장해야 함 char str[10]; str[0]= ‘s’; str[1]= ‘t’; str[2]= ‘r’; str[3]= ‘i’; str[4]= ‘n’; str[5]= ‘g’; str[6]= ‘\0’; • 문자열 표준 라이브러리 사용 #include <string.h> char str[10]; strcpy(str,”string”);
문자열 배열 출력 • printf 사용 char str[10]=“string”; printf(“%s”, str); • putchar 사용 char str[10]; for( i =0 ; i <= 9 ; i++) { if( str[i] == ‘\0’)break; putchar(str[i]); }
문자열 배열 입력 • scanf 사용 char str[10]; scanf(“%s”, str); • getchar 사용 char str[10]; for( i =0 ; i <= 9 ; i++) { str[i] = getchar(); if( str[i] == ‘\n’ || str[i] == ‘ ‘) break; } str[i] =‘\0’;
문자열 배열 입력 • 문자열을 하나 입력 받아서 출력하는 앞의 프로그램에 10자 이상의 문자열을 입력하면? • 스패이스를 포함한 한 줄을 입력 받으려면? • Hint: getline 또는 비교문
배열에 저장된 학생 총점 및 평균 int score[3][5] = { {78, 56, 24, 98, 35}, {56, 45, 23, 67, 78}, {89, 34, 23, 67, 89} }; char name[5][10] = {“Steve”,“Bob”,“John”,“Michele"," Merry”,”Tom”}; int sum; float avg; int student, subject ; for( student = 0; student < 5 ; student++){ sum = 0; for( subject = 0; subject < 3 ; subject++) sum = sum + score[subject][student]; avg = (float) sum / 3; printf(“ %s : sum = %d, average = %f\n”, name[student], sum, avg); }
배열에 저장된 과목총점 및 평균 • 앞의 프로그램을 변경하여 과목의 이름과 각 과목의 총점 및 평균을 출력하는 프로그램 작성
포인터 • C 언어의 독특한 특성 중에 하나 • 프로그래밍 하는데 많은 유연성을 줌 • 특히 시스템 프로그램에서 매우 유용함 • 포인터를 잘 써야 효율적인 프로그램 가능 • 포인터는 배열과 매우 밀접한 관계가 있음 • 모든 값은 메모리에 저장되며 반드시 주소가 있음 0x100000 0x10002 0x10004 12 22 33 ….
그림으로 표현 • 포인터란? • 값이 저장된 주소(Address)를 저장하는 변수 0x100000 1000 정수형(int) 0x100002 문자형(char) ‘p’ 0x100003 문자형(char) ‘q’ 0x100004 3.141592 실수형(float) 0x10000C 0x100002 문자 포인터(float)
포인터 선언 방법 • 자료형 * 변수 • 예: 정수 포인터 int *iptr; 0x100000 1000 정수형(int) 0x100002 문자형(char) ‘p’ 0x100003 문자형(char) ‘q’ 0x100004 3.141592 실수형(float) 0x10000C 0x100000 iptr
포인터와 * 연산자 • * 연산자를 사용하여 포인터가 가리키는 값에 • 예: 정수 포인터 int *iptr; int i; *iptr = 98; i = *ptr; 0x100000 98 정수형(int) 0x100002 문자형(char) ‘p’ 0x100003 문자형(char) ‘q’ 0x100004 3.141592 실수형(float) 0x100008 i (int) 98 0x10000C 0x100000 iptr
포인터와 & 연산자 • & 연산자는 변수의 주소 • 예: 정수 포인터 int *iptr; int score=50; iptr = &score; *iptr = 99; 0x100000 93712 50 score (int) 99 0x100002 문자형(char) ‘p’ 0x100003 문자형(char) ‘q’ 0x100004 3.141592 실수형(float) 0x10000C 0x234821 0x100000 iptr
포인터 사용 예 • 예: 정수 포인터 int *iptr; int score=50; int sum =0; iptr = &score; *iptr = 99; sum += *iptr; 0x100000 93712 50 score (int) 99 0x100002 문자형(char) ‘p’ 0x100003 문자형(char) ‘q’ 0x100004 3.141592 실수형(float) 0x100008 sum (int) 0 99 0x10000C 0x234821 0x100000 iptr
두 수의 값을 서로 바꾸기 main() { int i = 50, j = 80, temp; printf(“ i = %d, j = %d\n”,i,j); temp = i ; i = j; j = temp; printf(“ i = %d, j = %d\n”, i , j); }
실행 과정 50 80 i 80 50 j 897432 50 temp swap
포인터를 사용하여 정수 값 변경하고 확인 main() { int i = 50, j = 80, temp; int *iptr1=&i, *iptr2=&j; printf(“ i= %d, j = %d\n”,i,j); printf(“ i = %d, j = %d\n”,i,j); } 포인터, iptr1과 iptr2만을 사용할 것
포인터 값 출력: 예제 6.3 int num1, num2; int *p_num1, *p_num2; num1 = 23; num2 = 45; p_num1 = &num1; p_num2 = &num2; printf("\nnum1 = %d, num2 = %d",num1, num2); printf("\naddress of num1 = %u, address of num2 = %u", &num1, &num2); printf("\np_num1 = %u, p_num2 = %u", p_num1, p_num2); printf("\ncontent of p_num1 = %d, content of p_num2 = %d",*p_num1, *p_num2);
문자 포인터 • 문자형 변수를 선언하고 이 변수의 값을 입력 받는다. 입력 받은 문자가 소문자이면 대문자로 포인터를 사용하여 변경한 후 출력한다.
포인터와 함수 사용: 프로그램의 출력은? void swap(int, int); int main(void) { int x = 5, y = 500; printf("x = %d, y = %d\t”, x, y); printf("addr of x = %u, addr of y = %u \n ", &x,&y); swap(x, y); printf("x = %d, y = %d\t”, x, y); printf("addr of x = %u, addr of y = %u \n ", &x,&y); }
포인터와 함수 사용: 프로그램의 출력은? void swap(int a, int b) { int temp; printf(“a = %d, b = %d\t”, a, b); printf("addr of a = %u, addr of a = %u \n ", &a,&b); temp = a; a = b; b = temp; printf(“a = %d, b = %d\t”, a, b); printf("addr of a = %u, addr of a = %u \n ", &a,&b); }
5 500 a 500 5 b 500 temp swap C 언어의 매개변수 전달 방법 • 값에 의한 호출(Call-by-Value) x 5 y 500 main
포인터와 함수 사용: 프로그램의 출력은? void swap(int, int); int main(void) { int x = 5, y = 500; printf("x = %d, y = %d\t”, x, y); printf("addr of x = %u, addr of y = %u \n ", &x,&y); swap(&x, &y); printf("x = %d, y = %d\t”, x, y); printf("addr of x = %u, addr of y = %u \n ", &x,&y); }
포인터와 함수 사용: 프로그램의 출력은? void swap(int *a, int *b) { int temp; printf(“a = %u, b = %u\t”, a, b); printf(“content of a = %u, content of b = %u \n ", *a,*b); temp = *a; *a = *b; b = temp; printf(“a = %u, b = %u\t”, a, b); printf(“content of a = %u, content of b = %u \n ", *a,*b); }
0x100004 *a 0x100008 *b 98345 temp swap C 언어의 매개변수 전달 방법 • 참조에 의한 호출(Call-by-Reference) x (0x100004) 500 5 y (0x100008) 500 5 5 main
실습: 두수의 합과 곱를 구하는 함수 void sum_mul(int, int); int main(void) { int x = 5, y = 500; int sum, mul; printf("x = %d, y = %d\t”, x, y); sum_diff(x, y, &sum, &mul); printf(“ x + y = %d, x * y = %d\t”, sum, mul); }
배열과 포인터 • 배열의 이름은 포인터이다. • 예: int score[3]; • Score는 배열의 첫째 칸을 가리키는 포인터이다. • 즉 score 는 &score[0] 와 같다 • *score = 12; // score[0] = 12; • *(score+1) = 24; // score[1] = 26; • *(score+2) = 56; // score[2] = 45;
배열과 포인터 사용 예 main(){ int score[2] = { 12, 24}; int temp; printf(“ score[0] = %d, socore[1] = %d\n”, score[0], score[1]); temp = *score; // score[0] , *(&score[0]) *score = *(score + 1); *(score + 1) = temp; printf(“ score[0] = %d, socore[1] = %d\n”, score[0], score[1]); }
배열과 포인터 사용 예 main(){ int score[2] = { 12, 24}; int temp; int *iptr = score; // &score[0]; 와 동일 printf(“ score[0] = %d, socore[1] = %d\n”, score[0], score[1]); temp = *iptr; *iptr = *(iptr + 1); *(iptr + 1) = temp; printf(“ score[0] = %d, socore[1] = %d\n”, score[0], score[1]); }
배열과 포인터 사용 예 main(){ int score[2] = { 12, 24}; int temp; int *iptr = score; // &score[0]; 와 동일 printf(“ score[0] = %d, socore[1] = %d\n”, score[0], score[1]); temp = iptr[0]; iptr[0] = iptr[1]; iptr[1] = temp; printf(“ score[0] = %d, socore[1] = %d\n”, score[0], score[1]); }
배열의 이름을 이용하여 주소 출력 • 3개의 정수를 저장할 수 있는 배열을 선언하고 이 배열의 각 칸의 주소를 출력한다. 이때 & 연산자를 쓰지 않고 출력해야 한다.
포인터 연산 • 포인터는 증가, 감소, 덧셈, 뺄셈, 곱셈, 나눗셈이 가능하다. • 곱셈과 나눗셈은 거의 사용하지 않음 • 증가, 감소는 가리키는 자료의 크기 만큼씩 증가, 감소를 한다.
아래의 프로그램의 결과는? int score[5] = {10,20,30,40,50}; int *iptr=score; printf(“ iptr=0x%8X, *iptr=%2d\n”, iptr,*iptr); iptr = iptr + 1; // 포인터 증가, iptr++과 동일 printf(“ iptr=0x%8X, *iptr=%2d\n”, iptr,*iptr);
아래의 프로그램의 결과는? char name[10] = “james”; char *cptr=name; printf(“ cptr=0x%8X, *cptr=%c\n”, cptr,*cptr); cptr = cptr + 1; // 포인터 증가, cptr++과 동일 printf(“ cptr=0x%8X, *cptr=%c\n”, cptr,*cptr);
아래의 프로그램의 결과는? char avg[3] = {78.9, 67.8, 99.8}; char *fptr=avg; printf(“ fptr=0x%8X, *fptr=%f\n”, fptr,*fptr); fptr = fptr + 1; // 포인터 증가, fptr++과 동일 printf(“ fptr=0x%8X, *fptr=%c\n”, fptr,*fptr);
포인터를 이용한 배열의 내용 출력 • while문과 iptr를 이용하여 아래에 있는 배열 score의 내용을 출력하는 프로그램을 작성하세요. 더 이상의 변수 사용 하지 않고… int score[5] = {10,20,30,40,50}; int *iptr=score;
다차원 배열과 포인터 • 다차원 배열은 행 우선 순위로 저장됨 #define SUBJECT 3 #define STUDENT 5 int score[SUBJECT][STUDENT] = { {78, 56, 24, 98, 35}, {56, 45, 23, 67, 78}, {89, 34, 23, 67, 89} }; 주소 증가 78 56 24 98 35 56 45 23 67 78 89 34 23 67 89 78 56 45 56 45 34 24 23 23 98 67 67 35 78 89