배열 (Array)
대용량데이터 대용량데이터를다루는기법 배열 (Array) 포인터 (Pointer) 구조체 (Structure) 파일 (File)
변수 (Variable) 변수및메모리할당 변수선언 : int imsi; imsi 4 Bytes 변수선언 : char imsi2; imsi2 1 Byte
배열 (Array) 배열 동일한데이터형을가지고있는데이터들을처리할때사용 연속적인메모리공간할당 50 명의학생성적을출력 #include <stdio.h> void grade(int score); int main() int score0, score1,., score49; scanf( %d, &score0); grade(score0); grade(score49); return 0; // 50 번호출 void grade(int score) if(score>=90 && score<100) printf("your grade is A \n"); else if(score>=80 && score<90) printf("your grade is B \n"); else if(score>=70 && score<80) printf("your grade is C \n"); return 0;
1 차배열 배열선언 ( 연속적인메모리공간할당 ) 타입 배열이름 배열크기 ( 0부터시작 ) 배열초기화 imsi[0]=0; imsi[1]=0; imsi[2]=0; for(i=0; i<3; i++) int imsi [3]; imsi[i]=0; imsi[0] imsi[1] imsi[2] 0 0 0 0 0 0 0 0 0 0 0 0 0x08047c64 0x08047c65 0x08047c66 0x08047c67 0x08047c68 0x08047c69 0x08047c6a 0x08047c6b 0x08047c6c 0x08047c6d 0x08047c6e 0x08047c6f int imsi[3]=0;
1 차배열 배열초기화 imsi int imsi[3]=5, 3, 7; ( 배열명 ) - 주소를저장할수없다. - 메모리를할당받지않아허공에떠있는것 imsi[0] 5 0x08047c64 &imsi[0] imsi[1] 3 0x08047c68 &imsi[1] imsi[2] 7 0x08047c6c &imsi[2] 배열의주소 배열이름 배열의시작주소를가리키는값 & 연산자를사용하여표시 &imsi[1] : imsi[1] 의주소
문자열과배열 문자열초기화 char arrstr[]= sungkyul ; char arrstr[9]= s, u, n, g, k, y, u, l, \0 ; \0 (null character) - 문자열의끝을나타냄 - 사용하는문자열보다 1 개더큰값으로사용 s u n g k y u l \0 0x08047c60 0x08047c64 0x08047c68 0x08047c6c 0x08047c70 0x08047c64 0x08047c68 0x08047c6c 0x08047c70
1 차배열 8_1.c ( 성적합산프로그램 ) #include <stdio.h> int main() int i, sum, average; int score[10]; for(i=0; i<10; i++) scanf( %d, &score[i]); for(i=0, sum=0; i<10; i++) sum+=score[i]; printf( sum = %d\n, sum); average = sum/10; printf( average = %d\n, average); return 0;
2 중배열 (2 차배열 Two Dimensional Array) 2 차원배열선언 int imsi [3][2]; 타입배열이름배열크기 [ 행 ][ 열 ] 2 차원배열예 한학년에 12 개학급 각학급에 35 명의학생 int score[12][35]; // 12 학급의 35 명의학생 총학생수 : 420 명 메모리관리 : 35 명단위로처리가능
2 중배열 (2 차배열 Two Dimensional Array) 2 차배열초기화 int imsi[3][2]=6, 3, 9, 1, 7, 2; 2 차배열의주소 imsi[0][0] imsi[0][1] 6 3 0x08047c60 0x08047c64 배열이름 imsi[1][0] 9 0x08047c68 배열의시작주소를가리키는값 imsi[1][1] 1 0x08047c6c imsi[2][0] 7 0x08047c70 & 연산자를사용하여표시 imsi[2][1] 2 0x08047c74 &imsi[0][1] : imsi[0][1] 의주소
2 차배열 2 차행렬의합을구하시오! #include <stdio.h> int main() int i, j, result[3][3]; int a[3][3] = 1, 2, 3, 4, 5, 6, 7, 8, 9; int b[3][3] = 1, 2, 3, 1, 2, 3, 1, 2, 3; for(i=0; i<3; i++) for(j=0; j<3; j++) result[i][j ]= a[i][j] + b[i][j]; printf( The result of Matrix sum\n ); for(i=0; i<3; i++) for(j=0; j<3; j++) printf( %d, result[i][j]); printf( \n ); return 0;
프로그램작성방법 문제 => 문제분석 => flow chart => 프로그램작성 ( 코딩 ) => 디버깅 => 실행프로그램
프로그램작성방법 순서도 (Flow Chart) 시작과끝 처리 판단 ( 조건문 ) 데이터 ( 입력및출력 )
문제 : 1부터 5까지합을구하여화면에출력하시오! 문제분석 기능확인 : 1 + 2 + 3 + 4 + 5 변수결정 : 숫자를나타내는변수 : I 합을저장하는변수 : sum 각변수들의변화관찰 i의변화 : 1씩증가 sum의변화 : i만큼증가
Flow Chart 시작 i = 0 sum = 0 i=1 #include <stdio.h> int main() int i=0; int sum=0; i<=5? sum 출력 i=i+1 sum=sum+i for(i=1; i<=5; i++) sum=sum+i; printf( sum = %d\n, sum); return 0; 끝
!!
포인터
차례 포인터개념 배열포인터 문자열선언 2중포인터 포인터배열과이중포인터 함수포인터
변수 (Variable) 변수및메모리할당 변수선언 : int imsi; imsi 4 Bytes 변수선언 : char imsi2; imsi2 1 Byte
포인터 포인터변수 포인터를저장할수있는변수 메모리의특정위치 ( 주소값 ) 를저장 *imsip 포인터변수선언 int *imsip; 값 ( 정수 ) 이저장된곳의주소를저장하기위해 4Bytes 메모리할당됨 imsi 5 0x8047c200 #include <stdio.h> int main() int imsi=5; int *imsip; imsip 0x8047c200 0x8047c2d0 imsip = &imsi; printf( *imsip : %d 입니다.\n, *imsip); return 0;
포인터변수타입 0x08047c24 char * imp_ch; 0x08047c24 4Bytes 0x08047c27 0x08047c28 0x08047c29 0x08047c2a int * imp_int; double * imp_double; 0x08047c27 4Bytes 0x08047c2d 4Bytes 0x08047c2d 0x08047c2e 0x08047c2f 0x08047c30 0x08047c31 0x08047c32 0x08047c33 0x08047c34
포인터 #include <stdio.h> int main() int a; int *p; // 변수 // 포인터 a=6; p = &a; // a 의주소값을 p 에 printf( P s address =%p\n, p); prntf( a s address = %p\n, &a); // %p : 메모리주소값출력 printf( p s value = %d\n\n, *p); // p 가가리키고있는곳 (a) 의값 (?) 출력 return 0;
포인터 #include <stdio.h> int main() int a; int *p; // 변수 // 포인터 a=6; p = &a; printf( address = %p, value = %d\n, p, *p); // p 가가리키고있는곳 (a) 의값 (?) 출력 *p=100; // p 가가리키고있는곳의값을 100 으로 printf( address = %p, value = %d\n, p, *p); // p 가가리키고있는곳 (a) 의값 (?) 출력 return 0;
포인터 p193 9_1.c #include <stdio.h> int main() int a; int score[50]; int *p; // 변수 // 배열 // 포인터 a=6; p = &a; // a의주소값을 p에 printf( Pointer Address =%p\n, p); printf( Memory Address = %p\n\n, &a); // %p : 메모리주소값출력 // 변수a의주소 p=score; // 배열이름으로배열시작주소를 p로 printf( pointer Address = %p\n, p); printf( Memory Address = %p\n, score); printf( score[0] s Address = %p\n, &score[0]); return 0;
포인터 #include <stdio.h> int main() int *p; double q, temp; // 포인터 temp=1234.56; p = &temp; q = *p; // temp 의주소값을 p 에 printf( %f\n, q); return 0;
포인터 ( 메모리할당 ) 포인터메모리 포인터선언 : 포인터변수 ( 주소를담을변수 ) 를위한메모리할당 할당된메모리에는할당된값이없다. 포인터변수에값을할당하는방법 이미존재하는다른변수들이사용하는메모리를공동으로사용 - ex) int a; int *p; p=&a; 메모리할당함수이용 - ex) malloc(), calloc()
포인터 ( 메모리할당 ) 메모리할당함수사용 동적메모리할당 : 실행중에메모리할당 malloc() 함수 / calloc() 함수 void *malloc(size_t size); // size_t = unsigned int void *calloc(size_t nmemb, size_t size); int *p, num; num=50; P = malloc(sizeof(int)*num); P = (int *)malloc(sizeof(int)*num); // (4bytes)*num = 4*50 = 200bytes 할당 int *p, num; num=50; p=(int *)calloc(num, sizeof(int)); // 4bytes 짜리 50 개할당후 => 0 으로초기화
배열과포인터 - 포인터를배열과동일하게사용가능 차이점 : 주소값자체를변경가능 #include <stdio.h> #include <stdlib.h> #include <stdio.h> #include <stdlib.h> int main() int *p; p=(int *)malloc(sizeof(int)*10); int main() int *p; p=(int *)malloc(sizeof(int)*10); p[0]=30; p[3]=10; printf("*p = %d\n", *p); printf("p[0] = %d\n", p[0]); printf("p[3] = %d\n", p[3]); free(p); = *p=30; p=p+3; *p=10; printf("*p = %d\n", *p); printf("p[0] = %d\n", p[0]); printf("p[3] = %d\n", p[3]); free(p); return 0; return 0;
배열포인터 배열포인터 배열을가리키는포인터변수 종류 1차배열포인터 2차배열포인터
배열포인터 (1 차 ) 1 차배열포인터 1 차배열을가리키는포인터변수 imsi ( 배열명 ) - 주소를저장할수없다. - 메모리를할당받지않아허공에떠있는것 imsi[0] imsi[1] 3 5 0x08047c64 0x08047c68 imsip+0 imsip+1 imsi[2] 7 0x08047c6c imsip+2 int imsi[3]= 3, 5, 7; int *imsip; imsip=imsi; imsip 0x08047c64 0x08047c88
배열포인터연산 (1 차 ) 1 차배열포인터의포인터연산 char * imsip; int * imsip; imsip; imsip imsip+0; imsip+1; imsip+2; *imsip+0; *imsip+1; *imsip+2; *(imsip+0); *(imsip+1); *(imsip+2);
배열포인터연산 (1 차 ) #include <stdio.h> int main() int imsi[3]=3,5,7; int *imsip; imsip=imsi; 3 5 7 printf("imsip+0 = %p\n", imsip+0); printf("imsip+1 = %p\n", imsip+1); printf("imsip+2 = %p\n", imsip+2); printf("*imsip+0 = %d\n", *imsip+0); printf("*imsip+1 = %d\n", *imsip+1); printf("*imsip+2 = %d\n", *imsip+2); imsip 0x08047c64 printf("*(imsip+0) = %d\n", *(imsip+0)); printf("*(imsip+1) = %d\n", *(imsip+1)); printf("*(imsip+2) = %d\n", *(imsip+2)); return 0;
배열포인터연산 (1 차 ) - #include <stdio.h> #include <stdlib.h> int main() int i, sum, *score; p199 9_2.c => p176 의 8_1.c 를포인터를이용하여처리 score=(int *)malloc(sizeof(int)*5); for(i=0; i<5; i++) scanf("%d", score++); score-=5; // score 가처음주소를가리키게함 for(i=0,sum=0; i<5; i++, score++) sum+=*score; printf("sum = %d\n", sum); free(score); return 0;
배열포인터 (2 차 ) 2 차원배열포인터 2 차배열을가리키는포인터 imsi[0][0] imsi[0][1] 6 3 0x08047c60 0x08047c64 imsi[1][0] 9 0x08047c68 imsi[1][1] 1 0x08047c6c imsi[2][0] 7 0x08047c70 imsi[2][1] 2 0x08047c74 2 차원배열포인터변수선언 imsip 0x08047c60 int imsi[3][2]=6, 3, 9, 1, 7, 2; // int imsi[3][2]=6, 3, 9, 1, 7, 2; int (*imsip)[2]; // 배열의요소가 2 개인 2 차배열을가리킨다. imsip=imsi; // imsi[0][0] 의주소를포인터에할당
배열포인터 (2 차 ) int imsi[3]=5, 3, 7; int *imsip; imsip=imsi; int imsi[3][2]=6, 3, 9, 1, 7, 2; int (*imsip)[2]; imsip=imsi; 행의주소를나타냄 5 imsi[0] imsi[0] 6 imsi[0][0] 3 imsi[1] 3 imsi[0][1] 7 imsi[2] imsi[1] 9 imsi[1][0] 1 imsi[1][1] imsi[2] 7 imsi[2][0] 2 imsi[2][1] imsip imsip 가가리키는대상 (4bytes) imsip imsip 가가리키는대상 - 행이대상이됨 (8bytes)
배열포인터 (2 차 ) imsi - 배열이름 - imsi[3][2] 을대표함 - imsi[0][0], imsi[0][1], imsi[1][0], imsi[1][1], imsi[2][0], imsi[2][1] 를대표함 #include <stdio.h> int main() int imsi[3][2]=6, 3, 9, 1, 7, 2; int (*imsip)[2]; // 배열의요소가 2 개인 2 차배열을가리킨다. imsip=imsi; // imsi[0][0] 의주소를포인터에할당 imsi[0] - 첫번째행을대표함 (2 차배열이아님 ) - imsi[0][0], imsi[0][1] 를대표 printf( imsi = %p\n, imsi); printf( imsi[0] = %p\n, imsi[0]); printf( &imsi[0][0] = %p\n, &imsi[0][0]); return 0; &imsi[0][0] - imsi[0][0] 의주소
배열포인터 (2 차 ) #include <stdio.h> int main() int imsi[3][2]=6, 3, 9, 1, 7, 2; int (*imsip)[2]; imsip = imsi; imsip = imsi[0]; imsip = &imsi[0][0]; imsip - 2 차원배열포인터변수 - 2 차배열을가리켜야함 - 배열요소가 2 개인 2 차원배열을가리킴 대상체가다름 => 에러 return 0;
배열포인터 (2 차 ) #include <stdio.h> int main() int imsi[3][2]=6, 3, 9, 1, 7, 2; printf( imsi = %d\n, sizeof(imsi)); printf( imsi[0] = %d\n, sizeof(imsi[0])); printf( &imsi[0][0] = %d\n, sizeof(&imsi[0][0])); return 0;
배열포인터 (2 차 ) 2 차배열의값 * 가 2 개필요 * 1 개 [] 1 개 : 행의첫번째배열요소의주소획득 * 2 개 [][] 2 개 : 배열요소획득 행의주소를나타냄 imsip imsip + 1 imsip + 2 *imsip *(imsip+1) // imsi // imsi+1 // imsi+2 // imsi[0] : 1행이주소 // imsi[1] **imsip // imsi[0][0] = 6 *(*imsip+1) // imsi[0][1] = 3 *(*(imsip+1)) // imsi[1][0] = 9 *(*(imsip+1)+1) // imsi[1][1] = 1 imsi[0] 6 imsi[0][0] 3 imsi[0][1] imsip+0 == *(imsip+0) *imsip+0 6 imsi[0][0] imsi[1] 9 imsi[1][0] *imsip+1 3 imsi[0][1] 1 imsi[1][1] imsip+1 == *(imsip+1) *imsip+2 9 imsi[1][0] imsi[2] 7 imsi[2][0] *imsip+3 1 imsi[1][1] 2 imsi[2][1] imsip+2 == *(imsip+2) *imsip+4 7 imsi[2][0] imsip *imsip+5 2 imsi[2][1] imsip 가가리키는대상 - 행이대상이됨 (8bytes)
배열포인터 (2 차 ) #include <stdio.h> #include <stdlib.h> int main() int imsi[3][2]=6,3,9,1,7,2; int (*imsip)[2]; imsip = imsi; printf("&imsi[0][0] = %p\n", &imsi[0][0]); printf("&imsi[0][1] = %p\n", &imsi[0][1]); printf("&imsi[1][0] = %p\n", &imsi[1][0]); printf("&imsi[1][1] = %p\n", &imsi[1][1]); printf("&imsi[2][0] = %p\n", &imsi[2][0]); printf("&imsi[2][1] = %p\n", &imsi[2][1]); printf("\n"); printf("imsip = %p\n", imsip); printf("imsip + 1 = %p\n", imsip + 1); printf("imsip + 2 = %p\n", imsip + 2); printf("\n"); printf("*imsip = %p\n", *imsip); printf("*imsip + 1 = %p\n", *imsip + 1); printf("*imsip + 2 = %p\n", *imsip + 2); printf("*imsip + 3 = %p\n", *imsip + 3); printf("*imsip + 4 = %p\n", *imsip + 4); printf("*imsip + 5 = %p\n", *imsip + 5); printf("\n"); printf("*(imsip+0) = %p\n", *(imsip+0)); printf("*(imsip+1) = %p\n", *(imsip+1)); printf("*(imsip+2) = %p\n", *(imsip+2)); printf("\n"); printf("**imsip = %d\n", **imsip); printf("*(*imsip + 1) = %d\n", *(*imsip +1)); printf("*(*imsip + 2) = %d\n", *(*imsip +2)); printf("*(*imsip + 3) = %d\n", *(*imsip +3)); printf("*(*imsip + 4) = %d\n", *(*imsip +4)); printf("*(*imsip + 5) = %d\n", *(*imsip +5)); printf("\n"); return 0;
문자열포인터변수 ( 문자열선언 ) 문자열과포인터변수 문자열이저장된곳의첫번째문자의위치를가리킴 sungkyul 중에서 s 가저장된곳의주소를 string 에할당 string 0x08047c60 char *string; s 0x08047c60 string = sungkyul ; u 0x08047c64 n 0x08047c68 ( 문자출력 ) g 0x08047c6c k 0x08047c70 printf( %c\n, *(string+1)); ( 출력 : u ) y 0x08047c64 ( 문자열출력 ) u l 0x08047c68 0x08047c6c printf( %s\n, string); ( 출력 : sungkyul ) \0 0x08047c70 %s : \0 가나올때까지화면에출력하는변환문자
문자열선언 #include <stdio.h> int main() char *imsip; char imsi; imsi = p ; imsi = p ; imsip = p ; imsip = p ;? 개념파악문제 - 문자와포인터 - 문자열과포인터 return 0; 문자열 ( a ) 을문자형변수 (imsi) 에저장 ( \0 ) - (X) 문자열 ( a ) 을메모리어딘가에저장되고, 저장된주소를 imsip 에할당
문자열선언 #include <stdio.h> int main() p203 char *string; string = sungkyul ; printf( %c\n, *(string+0)); printf( %c\n, *(string+1)); printf( %c\n, *(string+2)); printf( %s\n, string); printf( %s\n, string+1); printf( %s\n, string+3); return 0;
문자열선언 p204 #include <stdio.h> int main() int i; char *string; string = sungkyul ; for(i=0; *string!= \0 ;i++, string++) printf( 자리수 : %d, 문자 : %c\n, i, *string); return 0;
문자열선언 문자열과배열 char arrstr[]= sungkyul ; 최기화과정에서컴파일러가필요한만큼메모리할당 char name[3][10]; strcpy(name[0], pyo ); strcpy(name[1], wol ); strcpy(name[2], seong ); s u 0x08047c60 0x08047c64 name[0] 0 번째행 메모리낭비 n 0x08047c68 p y o \0 \0 \0 \0 \0 \0 \0 g k 0x08047c6c 0x08047c70 name[1] 1 번째행 메모리낭비 y 0x08047c64 w o l \0 \0 \0 \0 \0 \0 \0 u 0x08047c68 l \0 0x08047c6c 0x08047c70 name[2] 2번째행메모리낭비 s e o n g \0 \0 \0 \0 \0
2 중포인터 2 중포인터 포인터가포인터를가리킴 선언 : * 2 개사용 char **imsipp; int **dp; int temp; int *imsip; int **dp; temp = 5; imsip = &temp; dp = &imsip; dp 1000 imsip 1000 3000 3000 * * temp 5
2 중포인터 #include <stdio.h> int main() int temp; int *imsip; int **dp; temp =10; imsip = &temp; dp = &imsip; **dp = 20; printf( temp = %d\n, temp); printf( **dp = %d\n, **dp); return 0;
2중포인터 ( 메모리할당 ) 포인터변수에값을할당하는방법 이미존재하는다른변수들이사용하는메모리를공동으로사용 메모리할당함수이용 int i; int row=3, col=10; int **dp; // 메모리할당 dp=(int **)malloc(row*sizeof(int)); for(i=0; i<row; i++) dp[i]=(int *)malloc(col*sizeof(int)); dp[0] dp[1] 0 번째행 1 번째행 // 메모리해제 for(i=0; i<row; i++) free(dp[i]); free(dp); dp[2] 2 번째행
포인터배열 포인터배열 포인터를저장할수있는배열 p y 0x08047c04 0x08047c05 char *name[3]; // 포인터배열선언 o 0x08047c06 \0 0x08047c07 name[0] = pyo ; name[1] = wol ; name[2] = seong ; w 0x08047d04 o 0x08047d05 l 0x08047d06 \0 0x08047d07 name[0] name[1] name[2] 0x08047c04 0x08047d04 0x08047e04 s e o 0x08047e04 0x08047e05 0x08047e06 n 0x08047e07 g 0x08047e07 \0
포인터배열과 2 중포인터 포인터배열과 2 중포인터 0x08047c00 char *imsip[3], **imsipp; p y o \0 imsip[0] = pyo ; imsip[1] = wol ; imsip[2] = seong ; imsip[0] 0x08047c00 0x08047d00 w o l \0 imsipp = imsip; imsip[1] imsip[2] 0x08047d00 0x08047e00 0x08047e00 s e o n g \0 imsipp 0x08047000
포인터배열과 2 중포인터 #include <stdio.h> int main() char *name[3]; char **dp; dp = name; // 포인터배열선언 printf( dp = %p\n, dp); printf( *dp = %p\n, *dp); printf( *dp의값 = %s\n, *dp); printf( *(dp+1) = %s\n, *(dp+1)); printf( **dp = %c\n, **dp); printf( **(dp+1) = %c\n, **(dp+1)); name[0] = pyo ; name[1] = wol ; name[2] = seong ; return 0; printf( name[0] = %p\n, name[0]); printf( &name[0] = %p\n, &name[0]); printf( name[0] = %s\n, name[0]);
주소값에의한함수호출 함수의리턴값 1개 예 ) return 0 많은양의데이터를리턴하기원하는경우 포인터이용 배열선언시주의할점 연속된메모리공간차지 프로그램종료때까지메모리차지 항상시작주소로부터이동한후메모리접근하는방식사용
주소값에의한함수호출 오름차순정렬 (bubble sort) 9_4.c (p211) #include <stdio.h> void bubble(int *data, int n); void swap(int *before, int *after); int main() int i, int *data; data=(int *)malloc(sizeof(int)*10); // 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 를 data 에 bubble(data, 10); for(i=0; i<10; i++) printf( %d, data[i]); free(data); return 0; void bubble(int *data, int n) int i, j; for(i=0; i<n-1; i++) for(j=n-1; j>i; j--) swap(&data[j-1], &data[j]); void swap(int *before, int *after) int temp; temp = *before; *before = *after; *after = temp;
주소값에의한함수호출 9_6.c (p219) #include <stdio.h> #include <stdlib.h> int **memory_alloc(int **memory, int row, int col); void data_alloc(int **data, int row, int col); void Average(int **data, float *avg, int row, int col); int main() int i, j, num, class, **score, result=0; float avg[3]=0; score=memory_alloc(score, 3, 35); data_alloc(score, 3, 35); Average(score, avg, 3, 35); int **memory_alloc(int **memory, int row, int col) int i, j; memory = (int **)malloc(sizeof(int)*row); for(i=0; i<row; i++) memory[i] = (int *)malloc(sizeof(int)*col); return memory; void data_alloc(int **data, int row, int col). for(i=0; i<3; i++) printf( average of class %d=%f \n, i+1, avag[i]); return 0; void Average(int **data, float *avg, int row, int col).
함수포인터 #include <stdio.h> int add(int one, int two); int main() int one, two, result; int *imsifp(int, int); imsifp = add; // 정수형매개변수 2 개를갖는함수를가리키기위해함수포인터선언 // 함수포인터에 add 함수의주소저장 scanf( %d, &one); scanf( %d, &two); result = imsifp(one, two); // 함수포인터를통해 add 함수호출 printf( result = %d\n, result); return 0;
연습문제 꼭! 풀어보세요..