C_C++

(C/C++) 포인터 기초

고니자니 2022. 11. 2. 12:46
반응형

메모리와 주소(memory and address)

컴퓨터 메모리(RAM)는 1 바이트마다 주소가 부여되어 있습니다.

이 주소는 32비트 시스템은 32비트 크기, 64 비트 시스템은 64비트 크기로 부여되며, 보통 16진수를 이용해서 주소를 간단하게 표현합니다.

 

프로그램에서 변수를 선언하면, 메모리의 특정 위치를 할당받아 사용하게 됩니다. 변수를 선언할 때 사용하는 자료형의 크기에 따라서 할당된 메모리 크기가 달라집니다.

int  i1;     // 4 바이트
float f1;    // 4 바이트
double d1;   // 8 바이트
char c1   // 보통 1 바이트 (언어에 따라서 다름. C/C++은 1바이트, C#은 유니코드로 표현하기 때문에 2 바이트 크기)

이 메모리 공간은 변수의 이름을 이용해서 접근할 수 있습니다.

int a=123;              // 변수 이름으로 값을 저장합니다.
printf("%d\n", a);   // 변수 이름으로 값을 가져옵니다.

 

포인터(pointer), 포인터 변수

포인터는 "메모리의 주소를 가리킨다"는 의미입니다.

프로그램에서 포인터를 이용해서 메모리에 접근할 수 있는데, 포인터 변수를 선언해서 접근하게 됩니다.

포인터 변수도 일반 변수처럼 선언해서 사용하며, 변수명 앞에 '*' 문자를 붙여서 선언합니다.

int  a=123;
int *p = &a;    // 변수 a의 주소를 포인터 p에 저장합니다.

 

일반 변수명 앞에 '&' 문자를 붙여서 메모리에 할당된 변수의 주소를 알 수 있습니다. 이 때 이 p를 "포인터 변수" 또는 간단히 "포인터"라고 합니다.

 

포인터 변수를 선언할 때, 포인터를 이용해서 접근할 메모리에 있는 값과 자료형이 서로 일치해야 합니다.

포인터가 메모리의 위치를 가리키게 되면, 이 포인터를 이용해서 해당 메모리를 참조(Read 또는 Write)할 수 있게 됩니다.

 

*p = 200;    // 포인터 p가 가리키는 메모리의 값이 200으로 변경됩니다. 즉, 변수 a값이 200으로 변경됩니다.

#include <stdio.h>
int main()
{
	int a = 123;
	int* p = &a;

	printf("%d %d\n", a, *p);
	*p = 200;
	printf("%d %d\n", a, *p);
	
	return 0;
}

(Output)

 

위 코드에서 *p가 서로 다른 2가지 의미로 사용되고 있으므로 주의하여야 합니다.

int    *p;     // *p: p는 포인터 변수임을 선언 (포인터 선언)
*p = 200;   // *p: 포인터 p가 가리키는 메모리를 참조(참조)

 

 

포인터 연산

포인터에 정수를 더하거나 뺄 수 있으며, ++, -- 연산자를 사용할 수 있습니다.

int *p = &a;

p+1;    // 포인터 p가 int형식이면 p+1은 p번지(주소)에서 4 바이트 만큼 큰 주소입니다.

p-2;     // 포인터 p가 int형식이면 p-2는 p번지(주소)에서 8 바이트 만큼 뺀 값의 주소입니다.

 

double *p = &a;

p+1은 p번지에서 8 바이트 만큼 더한 값의 주소입니다.

#include <stdio.h>
int main() 
{
	int a = 123;
	double d = 3.14;
	
	int* pa = &a;
	double* pd = &d;

	printf("%p %p\n", pa, pa + 1);
	printf("%p %p\n", pd, pd + 1);

	return 0;
}

(Output)

00CFFC80 00CFFC84   -- int 형식 포인터는 4 증가되어 있습니다.
00CFFC70 00CFFC78  -- double 형식 포인터는 8 증가되어 있습니다.

 

다음 예제는 포인터 변수에 ++ 연산자를 사용한 예제입니다.

#include <stdio.h>
int main() 
{
	char* s = "ABCD";
	while (*s)
	{
		printf("%c", *s);
		s++;     // 포인터 s를 1 증가시키면 1 바이트(char 형식) 증가합니다.
	}

	return 0;
}

(Output)

 

 

 

728x90
반응형