응용포인터
이중포인터
- 포인터변수의 주소
int main(){
int a = 1;
int* ap;
int** ap2;
ap = &a;
ap2 = ≈
printf("a\t%d\nap\t%d\nap2\t%d\n", a, ap, ap2);
printf("*ap\t%d\n*ap2\t%d\n**ap2\t%d\n", *ap, *ap2, **ap2);
return 0;
}
결과
이중포인터 배열
int main(){
int a = 1, b = 2, c = 3;
int* ap[] = { &a, &b,&c };
int** ap2 = ap; //배열명이 배열 주소값
printf("ap\t%d\nap2\t%d\n", ap, ap2);
printf("*ap[0]:%d\t*ap[1]:%d\t*ap[2]:%d\n", *ap[0], *ap[1], *ap[2]);
printf("*ap2[0]:%d\t*ap2[1]:%d\t*ap2[2]:%d\n", *ap2[0], *ap2[1], *ap2[2]);
return 0;
}
결과
다중포인터(삼중포인터)
int main(){
int a = 1;
int* ap = &a;
int** ap2 = ≈
int*** ap3 = &ap2;
printf("a\t%d\nap\t%d\nap2\t%d\nap3\t%d\n", a, ap, ap2, ap3);
printf("*ap\t%d\n*ap2\t%d\n*ap3\t%d\n", *ap, *ap2, *ap3);
printf("**ap2\t%d\n**ap3\t%d\n", **ap2, **ap3);
printf("***ap3\t%d\n", ***ap3);
return 0;
}
결과
배열포인터
- 배열 전체를 가리키는 포인터
ex)
int ary[5] => &ary : 배열포인터
- (배열포인터) + (주소값) = (주소) + (정수값*배열전체크기)
ex)
ary + 1 => (주소값) + (1*sizeof(ary[0])) = (주소값) + (1*4)
&ary + 1 => (주소값) + (1*sizeof(ary)) = (주소값) + (1*20)
-2차원배열은 배열명이 배열포인터이다.
- 따라서 ary+1 => (주소값) + (1*sizeof(ary[0])) = (주소값) + (1*16) 이다.
ex)
ary[1][2]의 값을 배열포인터를 이용해 참조하여 찾기
①ary+1 = 100+(1*16)=116
②*(ary+1) = ary[1]
③*(ary+1)+2 = *(ary+1)+(2*4) = 116+8=124
=> 4 : sizeof(ary[1][0])
④*(*(ary+1)+2) = ary[1][2] = 7
-이차원 배열포인터 함수
void func(int(*)[3]); //매개변수는 배열포인터변수
int main(){
int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
func(a); //전달인자는 배열명
return 0;
}
void func(int(* ap)[3]){
int i, j;
for (i = 0; i < 2; i++){
for (j = 0; j < 3; j++){
printf("%d", ap[i][j]);
}
printf("\n");
}
}
결과
함수포인터
- 함수명이 함수의 포인터이다.
-함수포인터는 함수형태만 같으면 기능에 상관 없이 저장이 가능하다.
ex)
int sum(int, int); =>fp = sum;
int max(int, int); =>fp = max;
int sum(int, int);
int main(){
int(* sump)(int, int);
int result;
sump = sum;
result = sump(10, 20);
printf("result : %d\n", result);
return 0;
}
int sum(int a, int b){
return a + b;
}
결과
-함수포인터 프로그램
void func(int(*)(int, int));
int sum(int, int);
int sub(int, int);
int mul(int, int);
int div(int, int);
int main(){
int select;
printf("1.두 정수의 합\n");
printf("2.두 정수의 차\n");
printf("3.두 정수의 곱\n");
printf("4.두 정수의 나누기\n");
printf("선택하세요.");
scanf_s("%d", &select);
switch (select){
case 1: func(sum); break;
case 2: func(sub); break;
case 3: func(mul); break;
case 4: func(div); break;
}
return 0;
}
void func(int(*fp)(int, int)){
int a, b;
int result;
printf("두 정수값을 입력하세요");
scanf_s("%d%d", &a, &b);
result = fp(a, b);
printf("결과는 : %d\n", result);
}
결과
void포인터
- 가리키는 자료형에 대한 정보가 없는 포인터 => 모든포인터 저장 가능
- 사용시 형변환하여 사용
- 다양한 형태의 포인터를 전달인자로 받을 수 있는 함수를 만들 수 있다.
#include <string.h>
void func(char*, void*, void*);
int main(){
int ia = 10, ib = 20;
double da = 1.5, db = 2.5;
func("int", &ia, &ib);
printf("정수 교환 후 : %d, %d\n", ia, ib);
func("double", &da, &db);
printf("실수 교환 후 : %.1lf, %.1lf\n", da, db);
return 0;
}
void func(char* type, void* vp1, void* vp2){
int ip;
int dp;
if (strcmp(type, "int") == 0){ //type에 입력된 값이 int인 경우
ip = *(int*)vp1; //vp1을 int*로 형변환 후ip(=A)에 대입
*(int*)vp1 = *(int*)vp2; //vp2를 int*로 형변환 후 형변환 한vp1에 대입
*(int*)vp2 = ip; //형변환한 vp2에 A대입
}
if (strcmp(type, "double") == 0){ //type에 입력된 값이 double인 경우
dp = *(double*)vp1; //vp1을 double*로 형변환 후ip(=A)에 대입
*(double*)vp1 = *(double*)vp2; //vp2를 double*로 형변환 후 형변환 한vp1에 대입
*(double*)vp2 = dp; //형변환한 vp2에 A대입
}
}
결과