본문 바로가기

Programming 언어/C언어

포인터

C언어의 꽃 포인터에 대해 알아보겠습니다!

 

포인터

포인터 변수는 다른 변수의 주소를 저장하는 변수 주소 저장 위해 주소 크기만큼 메모리 사용

포인터 변수는 다른 변수 가리키는 변수

즉 자신이 사용하고 싶은 메모리의 주소를 저장하고 있는 메모리 포인터 *이거로 선언 ex) int *abc; -->이때 int 부분은 포인터가 가리키는 변수의 데이터 형이어야 함 근데 포인터 변수는 자료형 선언하지 않아도 무조건 크기가 4바이트로 정해짐 즉 int는 abc 변수의 주소에 저장될 값의 자료형

변수의 주소는 &사용하여 구할 수 있음(&연산자로 구한 주소를 포인터 변수에 대입할 때 형이 일치하는 경우에만 대입해야 함)

short birthday;
short *ptr;
ptr=&birthday 변수의 포인터 형에 const를 지정한다.

 

‘*’키워드

여러 용도로 쓰이니 헷갈리지 않아야함

  1. short *ptr = &birthday; 에서의 *
  2. *ptr = 1042; 에서의 *는 용도가 다름

1번에서는 포인터 변수의 선언 위한 키워드이고 2번에서는 ptr 포인터가 가리키는 주소의 변수에 값 대입하겠다는 의미

 

ptr = , *ptr = 의 차이점

‘ptr=’ 형태로 사용하면 포인터 변수의 값이 변경(대상이 가리키는 주소)→포인터 변수에 주소 저장

‘*ptr=’ 형태로 사용하면 ‘포인터가 가리키는 대상’의 값이 변경됩니다. →포인터가 가리키는 대상에 값 저장합니다. 즉 포인터 변수가 가리키는 주소에 있는 변수의 값을 변경

포인터 변수 초기화할 때 널 포인터로 초기화

0으로 초기화된 포인터

아무것도 가리키지 않는다는 의미

int *p=NULL;

 

포인터와 +,- 연산

포인터 변수에 정수 n을 더하거나 빼면 포인터가 가리키는 데이터 형 x n 만큼 주소를 더하거나 뺀 값 만들어짐

 

포인터 사용시 주의

void swap(int* pa, int* pb) { int temp; temp = *pa; *pa = *pb; *pb = temp; }

이걸 잘 이해하자

만약에

temp = *pa; pa = pb; *pb = temp;

이렇게라면 포인터 변수 pa가 포인터 변수가 가리키는 pb의 주소와 동일하게 되므로 pb의 포인터 변수가 가리키는 값 temp를 pa도 가지게 됩니다.

 

배열과 포인터

배열을 인덱스 없이 이름만 사용하면 배열의 시작 주소가 된다

배열의 시작 주소와 첫 번째 원소의 주소는 같습니다→ arr == &arr[0]

배열의 이름인 arr는 배열의 시작 주소이므로 포인터인 것처럼 사용할 수 있다.

*arr[i]의 값은 (arr+i)의 값과 같다는 것

 

배열은 포인터가 아니다

배열 이름은 변수처럼 보이지만 내부는 실제로 상수화된 주소이기 때문에 변경할 수 없음

 

즉 배열은 일반 변수들을 묶어 놓은 개념이기에 변수가 자신이 위치한 주소를 변경할 수 없듯

 

배열도 자신이 위치한 메모리 주소를 변경할 수 없음→시작 주소도 변경 불가

 

포인터 변수는 변수이기에 포인터 변수에 보관된 주소를 변경할 수 있음

 

문자열 상수

문자열 리터럴은 다른 상수와 다르게 메모리에 보관해두고 사용한다.

char *p=’abcde’;→포인터 변수 p에는 문자열 리터럴의 주소를 보관(값을 읽어볼 수만 있고 변경할 수 없는 메모리 영역)(이게 문자열 자체를 주소에 넣는 거)

p[0]=’A’ → 문자열 리터럴은 변경할 수 없으므로 실행 에러

strcpy(p,’hello’);→문자열 리터럴은 변경할 수 없으므로 실행 에러

p=’hello’ → 포인터 변수 p에 ‘hello’의 주소를 대입

즉 char 변수가 문자열 리터럴을 가리키고 있을 때 문자열 리터럴의 내용 변경 X 근데 다른 문자열 리터럴 주소를 char * 변수에 대입 가능(가리키고 있을 때)

문자열 리터럴은 상수이다

문자 배열에 문자열을 저장하려면 = 연산자 대신 strcpy 함수를 이용해야 함, 문자열을 비교하려면 == 연산자 대신 strcmp 함수를 이용해야 함

char str[20];

str=’Hello World’; → str은 배열의 시작 주소 ’Hello World’ 문자열 리터럴의 시작 주소이므로 대입 X (단, strcpy(str,’Hello World’)는 가능함)

str==’Hello World’ 주소 비교는 strcmp(str,’Hello World’)==0

 

const 포인터

const int * p → *p로 값을 변경하려면 오류 발생 즉 *p로 대상의 값을 변경하면 오류

int * const p → p 값이 변경되면 오류 발생 즉 주소를 변경하려 하면 오류

const int * const p → 포인터가 가리키는 값 그리고 주소 둘 다 변경 불가

'Programming 언어 > C언어' 카테고리의 다른 글

함수의 활용  (0) 2023.01.20
문자열 입력 함수  (0) 2023.01.19