본문 바로가기

자린고비 독학하기/자린고비 코딩하기

C 언어 코딩 도장 빨리 끝내기 - 2 : 포인터

반응형

 

c 언어 기초 그만 좀 보고 싶어서 빨리 끝내 보려고 합니다 

2 : 포인터

 

 

핵심 정리 1: https://dojang.io/mod/page/view.php?id=605

 

C 언어 코딩 도장: 핵심 정리

포인터와 메모리 포인터는 메모리의 특정 위치를 가리킬 때 사용하며, 정수형으로 된 메모리 주소가 저장되어 있습니다. 포인터는 *를 사용하여 선언하며, 이미 선언된 포인터에 *를 사용하면 포인터에 저장된 메모리 주소에 접근(역참조)하여 값을 가져오거나 저장할 수 있습니다. 자료형 *포인터이름; // 포인터 선언 *포인터; // 포인터를 역참조하여 값을 가져옴 *포인터 = 값; // 포인터를 역참조하여 값을 저장 변수의 메모리 주소를 구할 때는 주소 연산자

dojang.io

 

핵심 정리

포인터와 메모리

포인터는 메모리의 특정 위치를 가리킬 때 사용하며, 정수형으로 된 메모리 주소가 저장되어 있습니다. 포인터는 *를 사용하여 선언하며, 이미 선언된 포인터에 *를 사용하면 포인터에 저장된 메모리 주소에 접근(역참조)하여 값을 가져오거나 저장할 수 있습니다.

자료형 *포인터이름; // 포인터 선언

*포인터; // 포인터를 역참조하여 값을 가져옴

*포인터 = ; // 포인터를 역참조하여 값을 저장

 

변수의 메모리 주소를 구할 때는 주소 연산자 &를 사용합니다. &로 구한 주소는 포인터에 할당할 수 있습니다. 즉, 포인터와 변수의 메모리 주소는 자료형이 같습니다.

포인터 = &변수; // 변수의 메모리 주소를 포인터에 저장

 

포인터와 역참조 연산자 *, 주소 연산자 &의 관계를 그림으로 표현하면 다음과 같은 모양이 됩니다.

 그림 포인터와 *, & 연산자의 관계

다음은 포인터에 변수의 메모리 주소를 저장하고, 포인터를 역참조하여 값을 출력하는 예제입니다.

int age = 20;

int *pointer = &age; // 포인터를 선언하고 변수의 메모리 주소를 저장

printf("%d\n", *pointer); // 20

포인터와 포인터 역참조를 그림으로 표현하면 다음과 같은 모양이 됩니다.

 그림 포인터와 포인터 역참조

포인터와 주소의 자료형

int *a;는 pointer to int라고 읽으며, *a와 같이 변수를 역참조하면 pointer to를 제거하여 int로 만듭니다.

int b;에서 &b와 같이 변수의 주소를 구한 것을 address of int라고 읽습니다. 특히 address of int는 pointer to int와 자료형이 같으므로 포인터에 주소를 할당할 수 있습니다. 즉, 포인터와 주소는 표기법만 차이가 있을 뿐 본질은 같습니다.

포인터의 자료형과 역참조

포인터는 포인터를 선언한 자료형의 크기만큼 역참조하는 크기가 결정됩니다.

char *cPtr1; // char형 포인터 선언 
*cPtr1 = 'a'; // char의 크기 1바이트만큼 역참조하여 값을 저장 

short *numPtr1; // short형 포인터 선언 
*numPtr1 = 100; // short의 크기 2바이트만큼 역참조하여 값을 저장 

int *numPtr2; // int형 포인터 선언 
*numPtr2 = 100; // int의 크기 4바이트만큼 역참조하여 값을 저장 

long long *numPtr3; // long long형 포인터 선언 
*numPtr3 = 100; // long long의 크기 8바이트만큼 역참조하여 값을 저장

 

void 포인터

void 포인터는 어떤 자료형으로 된 포인터든 모두 저장할 수 있습니다. 반대로 다양한 자료형으로 된 포인터에도 void 포인터를 저장할 수 있습니다. 이런 특성 때문에 void 포인터는 범용 포인터라고 합니다. 단, 자료형의 크기가 정해지지 않았으므로 역참조는 할 수 없습니다.

이중 포인터

포인터도 일반 변수이므로 다른 포인터의 메모리 주소를 저장할 수 있습니다. 이때 포인터의 메모리 주소를 담고 있는 포인터를 이중 포인터라고 합니다. 이중 포인터를 선언할 때는 *를 두 개 사용하며, 역참조할 때도 *를 두 개 사용합니다.

 

자료형 **포인터이름; // 이중 포인터 선언

**포인터; // 이중 포인터를 역참조하여 값을 가져옴

**포인터 = ; // 이중 포인터를 역참조하여 값을 저장

 

예를 들어 int **a;는 pointer to pointer to int 입니다.

 

 그림 34‑25 이중 포인터의 역참조

포인터를 선언할 때 *의 개수에 따라서 삼중 포인터, 사중 포인터 그 이상도 만들 수 있습니다. 마찬가지로 역참조를 할 때도 *를 세 번, 네 번 또는 그 이상 사용할 수 있습니다.

 

메모리 할당하기

malloc 함수를 사용하면 메모리를 바이트 단위로 할당할 수 있습니다. 단, 메모리를 할당했으면 반드시 free 함수로 메모리를 해제해야 합니다.

자료형 *포인터이름 = malloc(크기); // 일정 크기만큼 동적 메모리 할당 

free(포인터); // 동적 메모리 해제

메모리를 특정 값으로 설정하기

memset 함수를 사용하면 메모리의 내용을 한꺼번에 특정 값으로 설정할 수 있습니다. 값을 설정하는 단위는 바이트 단위입니다.

memset(포인터, 설정할값, 크기);

널 포인터

포인터가 아무것도 가리키고 있지 않는 상태를 널 포인터(null pointer)라고 하며 포인터에 NULL을 할당하면 됩니다.

자료형 *포인터이름 = NULL; // 포인터에 NULL 할당

잘못된 포인터 사용

포인터에는 임의의 값을 할당하면 안 됩니다. 반드시 이미 있는 변수의 메모리 주소를 구해서 할당하거나, malloc 함수로 메모리를 할당해야 합니다.

int *numPtr = 0x100; // 잘못된 포인터 사용, 임의의 값을 할당하면 안 됨 

int num1; int *numPtr = &num1; // 변수 num1의 메모리 주소를 포인터 변수에 저장 

int *numPtr = malloc(sizeof(int)); // int의 크기만큼 동적 메모리 할당

 

 

반응형