1. 포인터
- 포인터란 특정한 데이터가 저장된 주소값을 보관하는 변수
- 즉, 포인터도 변수다!
- 메모리 상에 위치한 특정한 데이터의 (시작)주소값을 보관하는 변수
- 포인터 역시 변수이기에 다른 변수와 마찬가지로 형(type)을 가짐
- 즉, int형 데이터 주소값을 저장하는 포인터와 char형 데이터 주소값을 저장하는 포인터가 서로 다른다.
예를 들어, p라는 포인터가 int 데이터를 가리키고 싶다고 하면 다음과 같이 사용하면 된다.
// (포인터에 주소값이 저장되는 데이터의 형)* (포인터의 이름);
int* p; // 라고 하거나
// (포인터에 주소값이 저장되는 데이터의 형) *(포인터의 이름);
int *p; // 로 하면 된다.
이러면 위의 포인터 p는 int형 데이터의 주소값을 저장하는 변수가 된다.
2. & 연산자
- 단항 & 연산자는 피연산자의 주소값을 불러오는 연산자
- 단항 & 연산자라고 하는 이유 ! => &는 AND 연산자와 기호가 같아서 AND 연산자에서는 & 기호를 두 개 연속으로 붙여 쓴다. A&&B와 같이 AND 연산자에서는 피연산자가 두 개 있어야 둘을 비교하는 반면, 포인터에서의 & 연산자는 피연산자 하나만을 필요로 한다.
#include <stdio.h>
int main(){
int a;
a = 2;
// 주소 연산자(&)를 붙여, 변수 a의 주소를 구함
printf("%p \n", &a);
// 출력 결과: 0x7fffffffd984
return 0;
}
p = &a 로 포인터 p에 a의 주소값을 줬을 경우 결과값이 같은 것을 볼 수 있다.
포인터 p에 들어있는 값: 0x7fffffffd96c
int 변수 a가 저장된 주소: 0x7fffffffd96c
#include <stdio.h>
int main(){
int *p;
int a;
p = &a;
printf("포인터 p에 들어있는 값: %p\n", p);
printf("int 변수 a가 저장된 주소: %p\n", &a);
// 출력결과
// 포인터 p에 들어있는 값: 0x7fffffffd96c
// int 변수 a가 저장된 주소: 0x7fffffffd96c
return 0;
}
여기까지 요약 👻✨
1. 포인터는 특정 데이터의 주소값을 보관.
2. 포인터는 주소값을 보관하는 데이터의 형 or 포인터 이름에 *를 붙임으로써 정의
3. & 연산자로 특정한 데이터의 메모리 상의 주소값을 알아올 수 있다.
3. * 연산자
- * 연산자는 주소값에서 해당 주소값에 대응되는 데이터를 가져오는 연산자
- * 역시 곱셈 연산자로 사용하는 친구이지만, 피연산자가 2개일 때만 곱셈 연산자로 작동한다. 만약 피연산자가 하나만 있다면 * 연산자는 해당 포인터가 가리키는 데이터 값을 가져온다.
#include <stdio.h>
int main(){
int *p; // p는 정수형 변수를 가리키는 포인터
int a; // a는 정수형 변수
p = &a; // p는 이제 정수형 변수 a의 주소값을 가리킨다.
a =2;
printf("a의 값: %d\n", a);
printf("*p의 값: %d\n", *p); // 포인터 변수 앞에 *가 붙었으니 해당 주소값에 들어있는 데이터를 출력한다.
// 출력결과
// a의 값: 2
// *p의 값: 2
return 0;
}
💡이해해. 외워.
&a : a의 주소를 가져옴
*a : a를 주소로 하는 곳의 값
3. 상수 포인터
- C에서는 변수 앞에 const를 붙이면 그 변수와 변수에 대응하는 값은 상수로 처리된다.
- 즉, 어떤 짓을 해도 해당 변수의 값은 그 값을 상수로 선언한 순간부터 상수가 된다.
Q. 상수 const를 쓰는 이유는 무엇인가?
A. 절대 바뀌지 않은 것 같은 값에 const 설정을 해주면 혹여나 실수로 해당 값을 바꾸는 상황이 발생해도 에러가 뜨기 때문에 실수할 일이 없어진다.
// 상수 포인터
#include <stdio.h>
int main(){
int a;
int b;
const int* pa = &a;
*pa = 3; // 올바르지 않은 문장
pa = &b; // 올바른 문장
return 0;
}
const int* pa = &a;
이 코드의 의미는 무엇인가?
const int형을 가리키는 포인터? => Nope
pa는 int형 포인터 변수인데, 이 포인터가 가리키는 값이 절대 바뀌면 안 된다는 것을 선언하는 것이다.
따라서, const int*의 의미는 const int형 변수를 가리키는 것이 아니라 int형 변수를 가리키는데 그 값을 절대로 바꾸지 말라는 말이다. 헷갈리는 부분 .....
a 자체는 변수이니깐 자유롭게 값을 변경할 수 있다.
그런데 위에서는 상수 포인터 pa를 통해서 a를 간접적으로 가리키고 있다. 이는 컴퓨터에게 const인 변수를 가리키고 있다고 말해주는 것이기 때문에 *pa로 a의 값을 호출할 때는 a의 값을 바꿀 수 없다.
즉, a=3; 이라고 선언하면 이는 오류가 아니다. a 자체를 다이렉트로 바꾸는건 a가 변수이기에 상관 없다.
하지만 *pa=3; 의 경우 *pa로 a의 값을 호출할 때는 a의 값을 바꿀 수가 없다.
또또.. 아래의 pa = &b는 옳은 문장이다.
pa가 가리키는 주소에 해당하는 데이터를 바꿀 수 없는 것이지, pa 자체를 바꿀 수 없다고는 하지 않았다.
공부 참고 블로그)
'SW사관학교 정글 > C언어와 친구들' 카테고리의 다른 글
[C언어와 친구들] 이진 탐색 트리 (BST) (0) | 2022.10.24 |
---|---|
[C언어와 친구들] 구조체(Struct)의 멤버가 포인터일 때, 구조체 포인터 변수 선언(동적메모리할당) (1) | 2022.10.24 |
[C언어와 친구들] 구조체(Struct)와 연결리스트(Linked List) wow (4) | 2022.10.24 |
[C언어와 친구들] 배열 .. 너 .. 포인터랑 뭐 있어? (0) | 2022.10.22 |
[C언어와 친구들] C언어를 알아볼까 ? 하잇 ~! (0) | 2022.10.21 |