ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (C언어) 10. 포인터_1
    C언어 문서화 2016. 3. 28. 19:28
    반응형

    [포인터]


    0. 동기부여


    흔히 C언어에서 가장 중요하고 가장 어려운 단원이 바로 이 "포인터"라는 단원이라고 한다. 그리고 오래 전에 만들어졌던 C언어가 아직까지 쓰이는 이유 중 하나(어쩌면 유일한 이유)가 바로 이 포인터이다. 

    포인터를 배우기 전 : 정해진 메모리 공간 내에서 비교적 규모가 작은 코딩을 한다면,

    포인터를 배운 후    : 메모리 공간을 다루는 능력이 생겨서 비교적 규모가 큰 코딩을 할 수 있다.



    1. 포인터란?

    <1: 포인터란? : 포인터는 주소 값을 담고 있는 변수(또는 상수)이다.

    <2: 포인터 변수란? : 주소 값의 저장을 위해 선언되는 변수를 가리켜 포인터 변수라 한다.

    <3: 주소체계 : 주소값 하나가 표현하는 메모리 공간은 : 1Byte.


    이 위에 메모리블럭 1개당 1Byte의 값들이 있다.

    <4: 1바이트 안에는 비트단위로 8조각이 나있다. 위의 주소값들은 이 8조각을 모두 포함해서 일컫는 말이라고 보면 된다.


    2. 포인터 변수 선언하기

    <1: 주소값 얻기

    포인터 변수에는 주소값이 들어가기 때문에 주소값을 어떻게 얻는지 알고, 그다음에 포인터 변수 선언하는 법을 알아야한다.

    주소값을 얻기 위해 사용하는 연산자는 바로 & 이다. 어디서 많이 본것같다. 그렇다. AND의 역할을 담당하는 이항 연산자이다.

    &는 이렇게 쓰인다 : 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
     
    int main(){
        int i;
        i=10;
     
        printf("%d\n", i);
        printf("%x\n"&i);
     
        return 0;
    }
    cs

    결과값은 얼마가 나올까?


    이것으로 &i는 i의 주소값을 나타낸다는 것을 알게 됬다.


    여기서 한가지 의문이 들었다. "배열은 값이 나란히 저장되어있는데 주소값도 정말 나란히 있는 걸까? 아니면 혹시 배열의 주소값은 하나일까?"

    역시 직접 해보는게 답이다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #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) 정리

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #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: 포인터를 이용해서 두 값을 바꾸기

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #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

    댓글

Designed by Tistory.