프로그래밍 언어에서
타입은
타입이 가질 수 있는 값의 집합 + 타입에 수행 가능한 연산
으로 구성됨
예를 들어 C에서
int 타입은
–2,147,483,648 ~ 2,147,483,647 의 정수형의 집합을 가지고(32비트)
+ - * / 등의 연산을 할 수 있음
근데 사용자가 struct로 정의한 타입은
* 곱하기를 못 쓰잖음?
포인터도 곱하기 못쓰고
더하기 빼기 연산도 좀 다르잖음?
이렇게 프로그래밍 언어에서는 타입마다 쓸 수 있는 연산이 다름.
그런 식으로 생각하면
포인터는 64비트의 정수형 집합을 가지고
+ - ++ -- 등의 연산에 더해서
(위 연산들도 일반적인 정수 더하기와는 다르고)
역참조 * 연산(dereference)을 할 수 있다는 거임
그냥 그게 끝임..
int* ptr;
int** ptr;
int****** ptr;
뭘 어떻게 선언하든 하는 짓은 다 똑같음
그냥 64비트 정수를 저장할 수 있고
그 정수에 대한 연산이 독특한 것 뿐임
포인터가 뭐를 가리키네 그딴 거 다 집어치우고...
포인터에는 걍 64비트 정수가 저장되고
*ptr 역참조를 하게되면 64비트 정수를 주소값으로 해석해서 변수처럼 쓰는 거임
한줄요약: 포인터는 독특한 연산(역참조)을 가진 정수형 타입이다
그럼 역참조 연산은 무엇인가?
일단 설명하자면
포인터형 변수에 들어 있는 64비트 정수를 주소로 해석해서 거기 접근하는 거임
말로는 어렵고..
예를 들면서 설명해보겠음
int num = 0;
int* ptr = # //모든 변수는 주소값을 갖는다
void side_effect(int* pnum){
int x = *pnum;
*pnum = 99;
}
이렇게 선언하면 이후
*ptr = 12; 하면 num의 값이 바뀌고
int a = *ptr; 하면 a에 num의 값이 들어갈 수 있음
side_effect 함수 내부에서도 동일한 일이 일어남
int x = *pnum; 이렇게 하면 num의 값을 x에 넣는 거고
*pnum = 99; 이렇게 하면 또 num의 값이 바뀜.
여기서 역참조의 정체를 대강 파악 가능함
역참조를 쓰면 스코프에 상관없이 변수에 접근할 수 있다는 거임
이렇게 생각해보셈. *ptr이랑 *pnum 대신에 int형 변수 num을 갖다 놓는 거야
스코프 그딴 건 다 무시해 버리고.
void side_effect(int* pnum){
int x = *pnum;
*pnum = 99;
}
int main(void){
int num = 0;
int* ptr = #
*ptr = 12;
int a = *ptr;
return 0;
}
이렇게 되어 있으면
역참조를 한 부분은 이렇게 되는 거라고 생각해 보셈
void side_effect(int* pnum){
int x = num;
num = 99;
}
int main(void){
int num = 0;
int* ptr = #
num = 12;
int a = num;
side_effect(&num);
return 0;
}
그럼 쉽져? 이게 역참조라고 생각하면 됨
여기서 중요한 건 지역변수를 함수에서 접근해서 변경할 수 있다는 거임
포인터가 없으면 뭔 짓을 해도 지역변수를 함수에서 변경할 수 없음
절대 불가능함 ㅋ
물론 전역 변수를 쓸 순 있겠지만 그건 존나 쳐맞을 짓임
뇌피셜 요약: 역참조 *ptr는 전에 넣어둔 주소의 변수를 대신 쓰는 것처럼 생각할 수도 있다
뇌피셜임 ㅎㅎ;
그럼 이중포인터의 예를 또 볼까용
void side_effect(int* pnum){
int x = *pnum;
*pnum = 99;
}
int main(void){
int x = 0
int* px = &x;
int** ptr = &px;
*ptr = 12;
int a = *ptr;
return 0;
}
위에서 취소선 그은 애들은 컴파일이 안 될겁니다.
왜 안될까?
아까처럼 생각해 볼까용?
int main(void){
int x = 0
int* px = &x;
int** ptr = &px;
px = 12;
int a = px;
return 0;
}
이렇게 보면 왜 안 되는지 쉽게 알 수 있다
지금 주소값을 ㅈ대로 int형 값 12로 넣으려고 하는데
만약 주소가 12인 곳을 역참조하면 어떻게 될까? 후로그램이 뒤진다
그래서 컴파일러가 int형을 int* px의 변수에 대입하는 걸 금지한다.
이제 두번하면 어떻게 되나..
int main(void){
int x = 0
int* px = &x;
int** ptr = &px;
**ptr = 12;
int a = **ptr;
return 0;
}
그럼 요건 이렇게 되겠지
int main(void){
int x = 0
int* px = &x;
int** ptr = &px;
*px = 12;
int a = *px;
return 0;
}
int main(void){
int x = 0
int* px = &x;
int** ptr = &px;
num = 12;
int a = num;
return 0;
}
이건 말이 된다.
int 변수에 int 값을 넣는다
그리고 int a를 int형 변수의 값으로 초기화한다
말 되네!
사실 제 머가리 속에서는 이렇게까지는 안 하고
C에서는 좌측값은 그냥 주소라고 생각합니다
우측값은 값이구요
끗
http://blog.naver.com/rhdnfka94/221046491976
3줄 요약
프로그래밍 언어에서 타입은 값의 집합 + 타입에 수행 가능한 연산 으로 정의된다.
포인터는 역참조라는 독특한 연산을 가진 정수형 타입이다.
(뇌피셜)역참조 *ptr 는 포인터에 넣어둔 주소의 변수를 대체하는 것으로 이해할 수 있다.
구래요 정수타입이라는게 두번중요 세번중요! - PUSH EBP
추천. 처음에 뽀인타가 해깔리는 이유중 하나는 선언할때와 역참조할때 쓰는 연산자가 같다는게 문제인듯여
왜 그리한지 이해는 가는데 뉴비 배려가 없엉...
쓸데없이 뭐를 가리킨다 뭐가 뭐다 그딴 어설픈 추상화는 아예 안 하는게 낫다고 봐여
타입을 이해하면 배열도 이해할 수 있고 그 다음에 이어지는 포인터 + 배열 + 함수 쓰까 묵는 것도 어렵지 않게 이해할 수 있을 것...
진자 가리킨다는 말 알아 먹을 수가 없음
PL먼저 공부시킨 다음에 C합시닷!
그건 포인터 좀 써본 사람들은 이해하는데 뉴우비들은 처음에는 이해한 줄 알고 자신만만해 하다가 포인터를 함수나 배열이랑 쓰까 묵는 순간 머가리 터짐
선추천 후정독
그냥 머가리 한 두어번 터져보면 이해하게되있음
개소리를 길게도 늘여놨네. 그냥 정수야
그리고 배열쓸때 [] 연산자가 포인터관련 연산자인걸 모르는애들이 많음 ㅜㅜ
다 알 사람들을 위한 글이 아니고 전학기에 막 C 배운 1학년을 위한 글임 훠이훠이
대부분의 C입문서(특히 김치맨이 쓴)에서 이해에 별 도움이 안되는 추상화를 많이들 제시하는 거 같음.. 제가 느끼기에는요
이개념 좋다 그냥 저장
이런 설명 넘나 좋은것. 수학교과서식
야...이거 정말 개쩌는 방식의 설명이다 땡큐!!