본문 바로가기
TIL (Today I Learned)/C 기초 문법

[C 기초 문법] 포인터 주의사항

by 둥굴프 2022. 12. 25.
이 포스팅은 한국기술교육대학교 김덕수 교수님의 'C언어 Lv2' 강의를 바탕으로 작성됐습니다.

 

#1 원본 값을 보호 - "const"

함수에서 포인터를 매개인자로 받을 때 원본 값을 보호하기 위해서는 'const'를 사용한다.

그렇게 되면 함수 내에서 상수 취급을 한다.

const의 위치에 따라 상수 취급하는 대상이 달라진다.

 

1. const int *ptr : 간접 참조된 위치의 값을 상수 취급한다.

*ptr = 100; // error

prt = &b; // okay

 

2. int* const ptr : 포인터 변수를 상수 취급한다.

*ptr = 100; // okay

ptr = &b; // error

 

 

#2 Local variable 주소 반환 ?

함수 내 지역 변수의 주소를 반환하면, 함수가 종료되는 시점에 stack frame이 사라지기 때문에 그 값이 유지된다는 보장이 없다.

 

 

#3 void 포인터 (void*)

 

1. void

없다 or 모른다

자료형이 정해지지 않음 👉 data type으로 사용 불가

 

2. void pointer (void*)

순수하게 주소만 저장하는 포인터 변수

데이터 형을 특정할 수 없는 (or 지정하지 않은) 데이터의 주소 값

가리키는 메모리 위치의 데이터 길이가 정해지지 않은 자료

void *voidPointer; // okay

모든 data type의 포인터 값을 저장 가능

간접 참조(*) 및 산술 연산 불가능

 

그렇다면.. 우짤까..

 

Pointer Type Conversion

포인터 변수는 다른 데이터형의 포인터 변수로 형 변환 가능하다.

ex) void* 👉 int*, int* 👉 float*,...

void*를 다른 데이터형의 포인터로 변환하여 사용 가능 (간접 참조 및 산술 연산 등 가능해진다.)

int intVar =0;
float floatVar = 0.f;
void *vP = NULL;

vP = &intVar; // okay
vP = &floatVar; // okay

printf("%d\n", *vP); // Error : The type is not defined
printf("&d\n", *((int*)vP)); // okay

 

 

#4 함수 포인터 (Function pointer)

 

함수 이름 = 메모리 주소

함수(명령어)의 시작 주소

함수 호출함수 이름이 가리키는 메모리 위치에 있는 명령어를 수행하는 것.

 

 

함수 이름 = 메모리 주소 👉 포인터 변수에 저장 가능하다.

함수 포인터 (Function Pointer)

- 함수를 가리키는 포인터

- 함수의 메모리 주소를 저장하는 포인터

 

 

함수 포인터 선언/초기화

int(*pFunc)(int, char) = NULL;

함수 포인터는 괄호가 필수적이다. 👉 포인터 변수명과 포인터가 가리키는 함수의 Parameter를 구분한다. 앞에 선언된 자료형은 해당 함수의 반환값을 의미한다.

 

값(함수의 시작주소) 대입

int func(int _a, int _b) { ... }
...
pFunc = func;

 

사용하기

pFunc(a, b);

 

함수 포인터도 포인터기 때문에 함수의 인자로 사용가능하다.

함수 선언

void func( int(*_pf)(int, int) ) { ... }

 

인자로 넣어주기

int (*pFunc)(int, int) = sum;
func(a, b, pFunc);

 

 

 

'TIL (Today I Learned) > C 기초 문법' 카테고리의 다른 글

[C 기초 문법] 이중 포인터  (0) 2022.12.26
[C 기초 문법] 포인터와 배열  (0) 2022.12.26
[C 기초 문법] 포인터?  (1) 2022.12.25

댓글