제 8 장. 포인터
목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2
포인터의개요 포인터란? 주소를변수로다루기위한주소변수 메모리의기억공간을변수로써사용하는것 포인터변수란데이터변수가저장되는주소의값을 변수로취급하기위한변수 C 3
포인터의개요 포인터변수및초기화 * 변수데이터의데이터형과같은데이터형을포인터 변수의데이터형으로선언 일반변수와포인터변수를구별하기위해 * 기호를사용 포인터변수명은일반변수명을지정할때와같은규칙을 따름 C 4
포인터의개요 포인터변수선언및의미 포인터변수 ptr 에일반변수 a 의주소가대입 C 5
포인터의개요 포인터구조 char ch[4]={ a, b, c, d ); char *ptr; ptr = ch; 포인터변수 ptr 에문자변수 a a, b, c, d 의주소가 순차적으로대입 C 6
포인터변수와일반변수의관계 #include<stdio.h> void main(void) { char ch a int i 10 float f 0.55 char *ptr_c int *ptr_i float *ptr_f ptr_c &ch ptr_i &i ptr_f &f printf( ch %c, i %d, f %f n, ch, i, f) printf( ch %d, i %d, f %d n, &ch, &i, &f) printf( n ptr_c %d, ptr_i %d, ptr_f %d n, ptr_c, ptr_i, ptr_f) C 7
포인터변수와일반변수의관계 [ ] ch a, i 10, f 0.550000 ch 1245052, i 1245048, f 1245044 : ptr_c 1245052, ptr_i 1245048, ptr_f 1245044 C 8
포인터의개요 포인터연산 포인터변수는주소에관한연산만가능 주소는정수에대한연산만가능 덧셈, 뺄셈의연산은가능하나, 곱셈, 나눗셈의연산은불가능 포인터변수에정수덧셈, 뺄셈연산은주소값에대한연산 * 연산자는포인터변수가가리키는주소의실제값 C 9
포인터의개요 포인터연산 int *p ( 1000 ) p+1 1000 1000 + 1 * 4Byte( ) 1004( ) p+5 1000 + 5 * 4Byte( ) 1020( ) p 2 1000 2 * 4Byte( ) 992( ) 포인터의연산은정수만큼의주소를전 후로이동한주소의연산 포인터변수의연산 실제주소 = 포인터가가리키는주소 + 정수 포인터변수 데이터형크기 C 10
포인터의개요 포인터연산 (* 연산자및증가 감소연산수식이존재 ) int a, b[2] {10, 20 int *p p b // p &b[0] b p C 11
문자배열과포인터변수 #include<stdio.h> void main(void) { char ch[4] { a, b, c, d char *ptr ptr ch printf( ch[0] %c, ch[1] %c, ch[2] %c, ch[3] %c n, ch[0], ch[1], ch[2], ch[3]) printf( ch[0] %d n ch[1] %d n ch[2] %d n ch[3] %d n, &ch[0], &ch[1], &ch[2], &ch[3]) printf( n % %d n % %d n %d n %d n, ptr, ptr+1, ptr+2, ptr+3) [ ] ch[0] a, ch[1] b, ch[2] c, ch[3] d ch[0] 1245052 ch[1] 1245053 ch[2] 1245054 ch[3] 1245055 : 1245052 1245053 1245054 1245055 C 12
Call for Value( 호출함수에값을전달 ) #include<stdio.h> void change(int x, int y) void main(void) { int a 3, b 5 printf( a %d, b %d n, a, b) change(a, b) printf( a %d, b %d n, a, b) void change(int x, int y) { int temp temp x x y y temp printf( change a %d, b %d n, x, y) [ ] a 3, b 5 change a 5, b 3 a 3, 3 b 5 C 13
Call for Reference( 호출함수에주소전달 ) #include<stdio.h> void change(int *x, *int y) void main(void) { int a 3, b 5 printf( a %d, b %d n, a, b) change(&a, &b) printf( a %d, b %d n, a, b) void change(int *x, int *y) { int temp temp *x *x *y *y temp printf( change a %d, b %d n, *x, *y) [ ] a 3, b 5 change a 5, b 3 a 5, 5 b 3 C 14
배열과포인터 1 차원배열과포인터 int a {1, 2, 3, 4, 5 int *p p a // p &a[0] 포인터변수에 1 차원배열을대입 1 차원배열의데이터가저장되기시작하는곳의주소가전달 메모리공간을한정하지않고, 필요한만큼사용가능 배열명이나타내는주소값은상수주소값 (&) C 15
배열과포인터 1 차원배열명주소상수 int point[] {1, 2, 3, 4, 5 배열명의주소상수를이용하여주소를표현 (point == &point[0]) 배열명을이용한실제데이터값의표현 (*point == point[0]) 배열명은주소상수, 포인터변수는주소를변수로취급 C 16
1 차원배열과포인터의관계 #include<stdio.h> void main(void) { int a[4] {1, 2, 3, 4 int *pi, index pi a for(index 0 index < 4 ++index) { printf( a[%d] : %u, a[%d] :%d n, index, &a[index], index, a[index]) printf( pi pi + %d : %u, *(pi+%d) : %d n, index, pi + index, index, *(pi+index)) printf( a[%d] : %u, a[%d] :%d n n, index, a+index, index, *(a+index)) [ ] a[0] : 1245040, a[0] :1 pi + 0 : 1245040, *(pi+0) : 1 a[0] 1245040 : 1245040, a[0] 1 :1 a[1] : 1245044, a[1] :2 pi + 1 : 1245044, *(pi+1) : 2 a[1] : 1245044, a[1] :2 (3, 4 ) C 17
배열과포인터 다차원배열과포인터 배열의첨자가 2 개이상인배열과포인터의관계 2 차원배열요소의데이터표현 int a[2][3] {{1, 2, 3, {4, 5, 6 (a) 2 (b) C 18
배열과포인터 2 C 19
배열과포인터 2 차원배열명주소상수및포인터의표현 int a[2][3], *ptr ptr a C 20
포인터의구조 배열포인터 배열을가리키는포인터 배열이시작되는곳의주소를가리키는포인터변수를선언하는 의미 (* ) [ ] int *pa int (*pb)[2] int (*pc)[2][3] *pa 가 1 차원배열포인터 (*pb)[2] 가 2 차원배열포인터 (*pc)[2][3] 은 3 차원배열포인터 C 21
배열포인터의표현 #include<stdio.h> void main(void) { int a[2][3] {{1, 2, 3, {40, 50, 60 int *pa, index, i, j int (*ppa)[3] pa a ppa a for(i 0 i <2 ++i) for(j 0 j < 3 ++j) printf( 2 a[%d][%d] %d n, i, j, a[i][j]) for(index 0 index < 6 ++index) printf( 1 2 a %d n, *(pa+index)) for(i 0 i < 2 ++i) for(j 0 j < 3 ++j) printf( 2 2 a %d n, *(*(ppa+i)+j)) (ppa+i)+j)) C 22
배열포인터의표현 [ ] 2 [0][0] a[0][0] 1 2 a[0][1] 2 2 a[0][2] 3 2 a[1][0] [ ] 50 2 a[1][2] 60 1 2 a 1 1 2 a 2 1 2 a 3 1 2 a 40 1 2 a 50 1 2 a 60 2 2 a 1 2 2 a 2 2 2 a 3 2 2 a 40 2 2 a 50 2 2 a 60 C 23
포인터의구조 포인터배열 포인터변수를배열의요소로선언 배열의개수만큼의포인터변수가존재 각배열의시작메모리의주소값을포인터변수로선언 * [ ] int *pa[2] 주의사항 배열포인터와달리포인터변수명에괄호 () 사용안함 C 24
포인터의구조 2 차원배열및포인터배열 char a[4][6] { ONE, TWO, THREE, FOUR char *pa[4] { ONE, TWO, THREE, FOUR C 25
포인터의구조 중첩포인터 포인터를여러개겹쳐쓰는것 주소의주소값을표현 (* 를겹쳐사용하여선언 ) ** int i 10 int *pi, **ppi pi &i ppi &pi i C 26
중첩포인터의사용 #include<stdio.h> void main(void) { int i 100 int *pi, **ppi pi &i ppi &pi printf( i %u, t i %d n, &i, i) printf( i %u, i : %d n, pi, *pi) printf( i %u, i : %d n, &ppi, **ppi) [ ] i 1245052, i 100 i 1245052, i : 100 i 1245044, i : 100 C 27
실무응용예제 ( 초급 ) 1., 1 #include <stdio.h> 2 #include <math.h> 3 #define N 10 4 int mid_ find(double, double *); 5 6 void main(void) 7 { 8 9 10 11 12 13 14 15 16 17 18 19 int i; double mid=0.0, num[n]; printf( 숫자 10개를입력하시오...\n ); for( i=0; i<n; i++ ){ printf( 숫자 %2d:, i+1); scanf( %lf, &num[i]); mid += num[i]; mid /= N; i=mid_find(mid, num); printf( 중간값 %.2lf 과제일가까운값은 %.2lf 입니다., mid, num[i]); C 28
실무응용예제 ( 초급 ) 1., ( ) 21 22 23 24 25 26 27 28 29 30 31 32 33 34 int mid_find(double mid, double *num) { int i, nval=0; double value, min; min=fabs(*num-mid); for( i=1; i<n; i++ ) { value=fabs(*(num+i)-mid); id) if ( min > value ) { min=value; nval=i; return nval; C 29
실무응용예제 ( 초급 ) 2. 1 #include <stdio.h> 2 3 void main(void) 4 { 5 int i=0; 6 char ch[100]; 7 8 printf( 문자열또는한문장을입력하시오...\n ); 9 gets(ch); 10 while( *(ch+i) ) 11 i++; 12 printf( 입력된문장을거꾸로출력합니다...\n ); 13 while( i-- > 0 ) 14 putch( *(ch+i) ); 15 C 30
실무응용예제 ( 중급 ) 3. 1 #include <stdio.h> 2 3 void main(void) 4 { 5 int in1[2][3]={{1, 2, 3, {4, 5, 6, out[2][2]={0,0,0,0; 6 int in2[3][2]={{1, 2, {3, 4, {5, 6; 7 int i, j, k; 8 for(i=0; i<2;i++) 9 { 10 for(j=0; j<2; j++) 11 { 12 13 14 15 16 17 18 19 20 for(k=0; k<3; k++) { *(*(out+i)+j) += *(*(in1+i)+k) * *(*(in2+k)+j); printf( %d, *(*(out+i)+j)); ( printf( \n ); C 31
실무응용예제 ( 중급 ) 4. 1 #include <stdio.h> 2 #include<math.h> 3 4 void main(void) 5 { 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int i, x[]={1, 3, 1, y[]={1, 3, 3; int *px=x, *py=y; float length[3], *plength=length; printf( 삼각형의꼭지점의좌표 :\n ); printf( A(x, y)=a(%d, %d)\n, *px, *py); printf( B(x, ( y)=b(%d, %d)\n, *(px+1), *(py+1)); printf( C(x, y)=c(%d, %d), *(px+2), *(py+2)); printf( \n\n삼각형의각변의길이 :\n ); for( i=0; ; i<3; ; i++) ){ *(plength+i)=sqrt( pow(*(px+(i+1)%3)-*(px+i), 2) + pow(*(py+(i+1)%3)-*(py+i), 2)); printf( %.2f, *(plength+i)); C 32
실무응용예제 ( 고급 ) 5. 3 10 2 1 #include <stdio.h> 2 3 void main(void) 4 { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int i, in; int out[16]={0, *pout=out; printf( 양의 3자리 10진수를입력하시오 : ); scanf( %d, &in); for(i=0; in;i++) { *(pout+i)=in % 2; in /= 2; printf( 2 진수 : ); while( i-- > 0) printf( %1d, *(pout+i)); C 33