-
(C언어) 10. 포인터_1C언어 문서화 2016. 3. 28. 19:28반응형
[포인터]
0. 동기부여
흔히 C언어에서 가장 중요하고 가장 어려운 단원이 바로 이 "포인터"라는 단원이라고 한다. 그리고 오래 전에 만들어졌던 C언어가 아직까지 쓰이는 이유 중 하나(어쩌면 유일한 이유)가 바로 이 포인터이다.
포인터를 배우기 전 : 정해진 메모리 공간 내에서 비교적 규모가 작은 코딩을 한다면,
포인터를 배운 후 : 메모리 공간을 다루는 능력이 생겨서 비교적 규모가 큰 코딩을 할 수 있다.
1. 포인터란?
<1: 포인터란? : 포인터는 주소 값을 담고 있는 변수(또는 상수)이다.
<2: 포인터 변수란? : 주소 값의 저장을 위해 선언되는 변수를 가리켜 포인터 변수라 한다.
<3: 주소체계 : 주소값 하나가 표현하는 메모리 공간은 : 1Byte.
이 위에 메모리블럭 1개당 1Byte의 값들이 있다.
<4: 1바이트 안에는 비트단위로 8조각이 나있다. 위의 주소값들은 이 8조각을 모두 포함해서 일컫는 말이라고 보면 된다.
2. 포인터 변수 선언하기
<1: 주소값 얻기
포인터 변수에는 주소값이 들어가기 때문에 주소값을 어떻게 얻는지 알고, 그다음에 포인터 변수 선언하는 법을 알아야한다.
주소값을 얻기 위해 사용하는 연산자는 바로 & 이다. 어디서 많이 본것같다. 그렇다. AND의 역할을 담당하는 이항 연산자이다.
&는 이렇게 쓰인다 :
1234567891011#include <stdio.h>int main(){int i;i=10;printf("%d\n", i);printf("%x\n", &i);return 0;}cs 결과값은 얼마가 나올까?
이것으로 &i는 i의 주소값을 나타낸다는 것을 알게 됬다.
여기서 한가지 의문이 들었다. "배열은 값이 나란히 저장되어있는데 주소값도 정말 나란히 있는 걸까? 아니면 혹시 배열의 주소값은 하나일까?"
역시 직접 해보는게 답이다.
12345678910111213141516171819202122#include <stdio.h>int main(){int arr_1[3]={0,1,2};char arr_2[3]="abc";printf("%d\n", arr_1[0]);printf("%d\n", arr_1[1]);printf("%d\n", arr_1[2]);printf("%s\n\n", arr_2);printf("%x\n", &arr_1[0]);printf("%x\n", &arr_1[1]);printf("%x\n", &arr_1[2]);printf("\n%x", &arr_2);printf("\n\n%x\n", &arr_2[0]);printf("%x\n", &arr_2[1]);printf("%x\n", &arr_2[2]);}cs 이걸 돌려보았다. 어떤 결과가 나왔을까?
주소값의 크기는 그 안에 있는 데이터에 상관 없이 4바이트로 표현된다. 따라서 배열에 들어있는 각각의 값들은 나란히 저장되어있다.
하지만 문자열의 경우는 1바이트에 문자 하나씩 들어가기 때문에 문자열의 경우도 각각의 값들이 나란히 저장되어있다는 것을 알 수 있다.
<2: 위에 정의에 따르면 주소 값이 저장되어 있는 변수가 포인터 변수라고 했다. 그러면 그것을 어떻게 선언하는지 알아야 써먹을 수 있다.
포인터 변수는 이렇게 선언한다. :
[데이터형] * [변수명];
(선언하는 건)참 쉽다.
< 여기서 잠깐! *의 명칭은? : Asterisk 와 Asterisk-operator. 전자는 그냥 *(별표)이고, 후자는 포인터 연산자를 일컫는다. >
< 많은 사람들이 포인터연산자를 "에스크리터"라고 읽는다. 영어로는 asteri-tor이라고 읽는다.(필자도 왜 에스크리터라고 읽는지 모른다) >
int A;
int *A;
첫번째는 그냥 변수 A를 선언한 것이고,
두번째는 주소값을 담을 수 있는 포인터 변수 A를 선언한 것이다.
<3: 그럼 초기화는 어떻게 하지?
(1) 선언과 동시에 초기화
int vari=3;
int *A = &vari;
(2) 그냥 초기화
int vari=3;
int *A;
A=&vari;
(3) 정리
1234567891011#include <stdio.h>int main(){int A=3;int *ptr;ptr=&A; //포인터변수 ptr에 A의 주소값 대입. => 현재의 ptr은 A의 주소값이 들어가있다.*ptr=A; //포인터변수 ptr이 가리키는 수=A => 현재의 ptr이 가리키는 값에는 3이 들어가있다.*ptr=&A;//포인터변수 ptr이 가리키는 수에 A의 주소값을 대입한다. =>현재 ptr이 가리키는 값에는 A의 주소값이 들어있다.printf("\n%x\n\n", *ptr);}cs (A의 주소값을 출력한 것이다. 모양을 보아하니 5xxxxbcc이런식으로 되어있는데 왜이런지 아직은 잘 모르겠다.)
3. 포인터를 이용한 간단한 예제
<1: 포인터를 이용해서 두 값을 바꾸기
123456789101112131415#include <stdio.h>int main(){int num1=3, num2=55;int *ptr1, *ptr2, *temp;ptr1=&num1;ptr2=&num2;temp=ptr1;ptr1=ptr2;ptr2=temp;printf("%d %d\n", *ptr1, *ptr2);}cs 결과 : 55 3
4. 널포인터
<1: 다음 두개의 표현은 같은 표현이다.
int *ptr=0;
int *ptr=NULL;
<2: 널포인터란?
널포인터는 포인터 변수를 0으로 초기화 한 것이다.(여기서 0은 0번지, 즉 NULL을 뜻한다.)
이것은 "이 포인터는 어떠한 주소도 가리키고 있지 않습니다." 라는 의미를 지니고 있다.
선언은 다음과 같이 한다 :
[데이터형] *[변수명]=0;
혹은 [데이터형] *[변수명]=NULL;
<3: 쓰임
만약 널포인터가 가리키는 곳에 50을 저장했다고 가정하자.
잠깐, 널포인터는 아무 곳도 가리키지 않는데?
=>에러메세지 출력.(애초에 아무것도 가리키고 있지 않는데 값을 저장한다는 것은 말도 안되는 것이다.)
반응형'C언어 문서화' 카테고리의 다른 글
(C언어) 12. 동적할당 (0) 2016.04.06 (C언어) 11. 문자열(심화) (0) 2016.04.06 (C언어) 9. 다차원 배열 (0) 2016.03.27 (C언어) 8. 정렬 방식 (0) 2016.03.25 (C언어) 7. 함수 (0) 2016.03.25