[고급 C++]포인터 4편(다중 포인터/함수 포인터/void형 포인터)
- 컴퓨터공학과/Programming
- 2020. 10. 23.
다중포인터
특성
- 포인터 변수의 시작주소를 다른 포인터변수의 데이터로 이용
- 포인터 변수가 변수의 시작주소를 저장하는데 반해 이중 포인터 변수는 포인터 변수의 시작주소를 저장
선언
자료형 **변수명;
#include <stdio.h>
int main()
{
int num, *ip, **mip;
printf("%d %d %d \n", sizeof(num), sizeof(ip), sizeof(mip));
ip = #
mip = &ip;
**mip = 500;
printf("%d %d %d \n", num, *ip, **mip);
return 0;
}
4 4 4 |
※ ** 단항 연산자 우선순위 : 우→좌
※ **mip=500 == *(*(mip))=500
활용 - 다중포인터를 통한 문자열 출력
#include <stdio.h>
int main()
{
int num, *ip, **mip;
char *ptr[] = {"kingdom", "Advanced C program", "C++ prog", "C# program", "one two three", "seoul 서울시 강남구 역삼동 100번지",
"busan 부산시 해운대구 해운대동 200번지", NULL}; // 다중포인트 마지막에 NULL하면 크기 카운트 안해됨
printf("%d %d %d \n", sizeof(num), sizeof(ip), sizeof(mip));
ip = #
mip = &ip;
**mip = 500;
printf("%d %d %d \n", num, *ip, **mip);
funcA(ptr);
return 0;
}
// ptr에 저장된 문자열 출력
funcA(char **tmp)
{
while(*tmp)
{
printf("%s \n", *tmp);
tmp++;
}
}
4 4 4 |
함수포인터
특성
- 포인터 변수가 함수의 시작주소를 저장하여 포인터를 참조하여 함수를 호출할 수 있음
- 콜백함수에서 사용
선언
자료형 (*변수명)(매개변수 리스트);
- int (*funcP)(char*);
1 #include <stdio.h> 28 void myFunc(char* tmp) 29 { 30 printf("myFunc : %p, %s \n", tmp, tmp); 32 } |
funcP size :4 |
활용 - 함수포인터를 이용하여 +-*/ 계산만들기
- add, sub, mul, div 는 코드세그먼트에 저장
- ptrArr는 Stack 영역에 저장
#include <stdio.h>
int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int div(int x, int y);
int main(void)
{
// 함수포인터 배열
int (*ptrArr[4])(int x, int y)={ add, sub, mul, div };
int menu_no, num1, num2, result;
char op[4] = { '+', '-', '*', '/' };
while(1)
{
printf("\n1. add\n");
printf("2. subtract\n");
printf("3. multiply\n");
printf("4. divide\n");
printf("5. end\n");
printf("\nSelect(1-5) --> ");
scanf("%d",&menu_no);
if(menu_no==5)
break;
printf("Input the two numbers --> ");
scanf("%d %d",&num1, &num2);
result = (*ptrArr[menu_no-1])(num1, num2);
printf(" %d %c %d = %d \n", num1, op[menu_no-1], num2, result);
}
return 0;
}
int add(int x, int y)
{
return x+y;
}
int sub(int x, int y)
{
return x-y;
}
int mul(int x, int y)
{
return x*y;
}
int div(int x, int y)
{
if(y==0)
{
printf("can not divide by 0\n");
return -1;
}
return x/y;
}
※ 포인터 형태 참고
- int (*a1)[3]; 배열포인터 변수(4Byte)
- int *a2[3]; 포인터배열 변수(12Byte)
- int (*a3)(int); 함수포인터 변수 (4Byte)
함수 포인터와 typedef
함수포인터 자료형을 자주 사용하면 매번 선언해야하는 번거로우므로 typedef로 함수 포인터의 별칭을 정의
1 #include <stdio.h> 2 3 int add(int x, int y) 4 { 5 return x+y; 6 } 7 8 int sub(int x, int y) 9 { 10 return x-y; 11 } 12 13 // 자료형 재정의 14 // 함수포인터 자료형 정의 15 typedef int (*FP)(int, int); 16 // 함수포인터를 typedef로 선언하면 함수포인터 변수 선언문이아닌, 17 // 함수포인터 자료형(별명)이 된다. 18 19 // void funCalc(int (*f4)(int, int)) 20 void funCalc(FP f4) 21 { 22 printf("funcCalc() : %d \n", (*f4)(300, 30)); 23 } 24 25 int main() 26 { 27 printf("함수포인터와 typedef문 \n"); 28 29 int result; 30 31 // 1. 함수포인터 변수 선언 32 int (*f1)(int, int); 33 f1 = add; 34 result = (*f1)(100, 30); 35 36 printf("f1 add : %d \n", result); 37 38 // 2. FP를 사용하여 함수포인터 변수 선언 39 FP f2; 40 f2 = sub; 41 result = (*f2)(100, 30); 42 43 printf("f2 sub : %d \n", result); 44 45 // 3. FP를 사용하여 함수포인터 배열 사용 46 FP f3[5]; 47 f3[0] = add; 48 f3[1] = sub; 49 50 printf("add() : %d\n", (*f3[0])(200,30)); 51 printf("sub() : %d\n", (*f3[1])(200,30)); 52 53 // 4. 함수 호출 시 함수주소 전달 54 funCalc(sub); 55 return 0; 56 57 } |
함수포인터와 typedef문 |
포인터 형변환
캐스트 연산자를 통해 포인터 자료형의 타입 형 변환 가능
#include <stdio.h>
int main()
{
char ch='A';
int num=10;
double dnum=3.5;
char *ptr=&ch;
printf("&ch: %p, ptr: %p \n", &ch, ptr);
printf("sizeof(ch): %d, sizeof(ptr): %d \n", sizeof(ch), sizeof(ptr));
printf("sizeof(&ch): %d, sizeof(*ptr): %d \n", sizeof(&ch), sizeof(*ptr));
printf("\nsizeof(ptr): %d \n", sizeof(ptr) );
printf("sizeof((int *)ptr): %d \n", sizeof((int *)ptr) );
printf("sizeof((double *)ptr): %d \n", sizeof((double *)ptr));
printf("\nsizeof(*ptr): %d \n", sizeof(*ptr) );
printf("sizeof(*(int *)ptr): %d \n", sizeof(*(int *)ptr) );
printf("sizeof(*(double *)ptr): %d \n", sizeof(*(double *)ptr) );
return 0 ;
}
&ch: 7ffff0f0, ptr: 7ffff0f0 sizeof(ch): 1, sizeof(ptr): 4 (포인터=주소) sizeof(&ch): 4(주소), sizeof(*ptr): 1 (char)
(주소는 4!) sizeof(ptr): 4 sizeof((int *)ptr): 4 sizeof((double *)ptr): 4
sizeof(*ptr): 1 sizeof(*(int *)ptr): 4 // 포인터 형변환 sizeof(*(double *)ptr): 8 // 포인터 형변환 |
void형 포인터
특성
- 어느 것이든 가리킬 수 있는 포인터
- void형 포인터는 참조할 대상체가 정해져있지 않은 포인터
- 실행중에 다양한 타입의 주소를 받을때 사용
선언 형식
void * 변수명;
참조형식
*(형*)변수명;
예시
#include <stdio.h>
int main()
{
char ch = 'A';
int num = 500;
double dnum = 1.3;
void *ptr; // void형 포인터
printf("ptr sizeof : %d \n", sizeof(ptr)); // 주소니까 4
ptr = &ch; // O ch의 주소 저장
// printf("%c \n", *ptr); // compile err
// 주소는 아는데, 몇바이트 참조할지몰라
printf("%c \n", *(char*)ptr); // O 주소 알고, 1바이트인거 알고!
// 다시 void형되었고
ptr = #
printf("%d \n", *(int*)ptr);
ptr = &dnum;
printf("%lf \b", *(double*)ptr);
return 0;
}
ptr sizeof : 4 |
활용 - 오버로딩이 가능한 swap 함수
3 int main() 4 { 5 short int n1 = 100, n2 = 150; 6 long int x = 300, y = 350; 7 double d1 = 1.3, d2 = 5.6; 8 char names[2][20] = {"kim", "lee ??"}; 9 10 swap(&n1, &n2); 11 12 printf("n1 : %hd, n2: %hd \n", n1, n2); 13 14 return 0; 15 } 16 17 swap(short int *sour, short int *dest) 18 { 19 short int tmp; 20 21 tmp = *sour; 22 *sour = *dest; 23 *dest = tmp; 24 } |
- 이렇게 하면 다양한 자료형을 매개변수로 swap함수를 호출할 수 없음, 지정된 타입만 가능하지 이건아니야!
#include <stdio.h>
void swap(void *sour, void* dest, int size);
int main()
{
short int n1 = 100, n2 = 150;
long int x = 300, y = 350;
double d1 = 1.3, d2 = 5.6;
char names[2][20] = {"kim", "lee ??"};
// 타입이 지정되어있음
// swap(&n1, &n2);
// swap(&x, &y);
swap(&n1, &n2, sizeof(n1));
swap(&x, &y, sizeof(x));
swap(&d1, &d2, sizeof(double));
swap(names[0], names[1], sizeof(names[0]));
printf("n1 : %hd, n2: %hd \n", n1, n2);
printf("x : %d, y : %d \n", x, y);
printf("d1 : %lf, d2 : %lf \n", d1, d2);
printf("names[0] : %s, names[1] : %s\n", names[0], names[1]);
return 0;
}
void swap(void *sour, void* dest, int size)
{
// 1Byte씩
char tmp;
int i;
for(i=0;i<size;i++)
{
tmp = *((char*)sour+i);
*((char*)sour+i) = *((char*)dest+i);
*((char*)dest+i) = tmp;
}
}
n1 : 150, n2: 100 names[0] : lee ??, names[1] : kim |
궁금한 사항은 댓글로 남겨주세요💃💨💫
좋아요와 구독(로그인X)은 힘이 됩니다 🙈🙉
'컴퓨터공학과 > Programming' 카테고리의 다른 글
[고급 C++] 구조체와 구조체포인터 (0) | 2020.10.27 |
---|---|
[고급 C++] 가변인자 / CERT C (feat. 안전 코딩하기) (1) | 2020.10.26 |
[고급 C++]포인터 3편(배열 포인터/포인터 배열/문자열 상수 포인터) (2) | 2020.10.22 |
[고급 C++]포인터 2편(배열과 포인터) (0) | 2020.10.21 |
[고급 C++]포인터 1편(프로세스/포인터변수/포인터연산/NULL포인터) (0) | 2020.10.20 |