본문 바로가기
프로그래밍 공부(정리)/C, C++

c언어-함수에서 주소를 반환하는 방법. 포인터의 정의

by 프룹 2017. 3. 1.
반응형

다음 설명은 제 개인의 생각을 정리하는 글입니다. 부족한 부분도 많고 틀린 부분도 많으므로 읽으실 때 이점을 고려하셨으면 좋겠습니다.

또한 틀린 부분, 보완할 부분을 댓글로 달아주시면 더욱 감사하겠습니다 ^^

다만, 틀린 내용에 대해서 시비를 거는 행위는 좀 삼가셨으면 합니다^^


다음 예제는 특정 함수에서 주소를 반환하여 특정 함수에서 포인터에 주소를 저장하는 방법이다.


예제 앞서 혹여 다시 한번 포인터의 정의를 짚고 넘어가자.


포인터 : 메모리 주소를 저장하는 변수. 즉, 포인터는 주소를 저장하는 변수를 말한다.

단순히 변수명 뿐만 아니라 상수명, 구조체등 어떤 형식이든 관계없이 해당값에   

접근할 수 있는 주소를 저장한다.


int *ptr;    // *을 선언하는 순간 포인터임을 알려준다.

이때 * (애더리스크)의 의미는 "ptr에 저장되어 있는 주소를 찾아가서 읽고/쓰는 작업을 함"을 의미한다.

int num = 5;

ptr = #    //여기서 *를 붙이지 않는 이유는 *의 의미가 '저장된 주소를 찾아가서 읽고/쓰는 작업/동작 함'을 의미하기때문에

주소를 저장해야 하는 시점에서는 연산자 * 가 동작하지 않아야 하기 때문이다.

*ptr = 7;    // 이제 7을 저장하기 위해서 *를 붙였다. 왜? 연산자 * 가 자신의 기능을 수행해야 7이라는 값을 num에 쓸수있기때문이다.

 현재 ptr에는 num의 주소값이 저장되어 있으므로 ptr앞에 * 를 붙이면 * 가 ptr에 저장되어 있는 주소값을 찾아가서

 7이라는 값을 쓰는 기능을 수행한다.

-----------------------------------------------------------------------------------------------------

#include <stdio.h>

#include <stdlib.h>


int *sum(int a, int b);    /*  함수명앞에 *를 붙이는 이유는 반환값이 값이 아니라 주소이기 때문에 주소를 저장하는 포인터를 사용해야해서 

 함수명앞에 *를 붙이는 것이다. */


int main()

{

    int a, b;

    int *tot;

    a = 10;

    b = 20;

    tot = sum(a, b);     /* tot와 sum이 모두 포인터 이기 때문에 굳이 *를 붙일 필요가 없다.*/

   

    printf("%d\n", *tot);     /*tot라는 변수는 선언된적이 없고 tot라는 포인터가 선언 되었다. 따라서 tot값을 표현하려면 

   포인터 tot를 가르켜야 하기 때문에 *를 붙여야 하는 것이다.*/

    system("pause");

    return 0;

}


int *sum(int a, int b) {

    static int res;    /*  res변수의 메모리가 유지되어야 다른함수에서 불러 쓸수 있기 때문에 정적변수를 사용해야한다. */

    res = a + b;

    return &res;

}


----------------------------------------------------------------------------------------------------------------------------


위 함수를 보면 sum이라는 함수에서 res의 주소를 반환하여 main함수에서 tot가 res의 주소를 받아서 출력하는 단순한 예제이다.


위 예제에서 함수앞에 *를 쓰는 이유를 다시한번 설명하면 일반적으로 포인터를 선언할때 *를 붙인다. 함수역시 마찬가지로 sum함수를 선언하는데 이 함수가 주소를 반환하기 때문에 함수자체가 포인터 함수라고 생각하면 될듯하다. 즉 포인터함수이기 때문에 함수앞에 포인터 함수라는 표현을 하기 위해서 *를 붙이는 것이다. (실제 포인터 함수?? 는 아닐것이다. 아마 내 생각인듯....)


다음은 위 방법을 이용해서 로또 번호 추첨 코드를 작성하였다.

아래 코드는 로또 번호를 입력하면 랜덤번호가 생성되고 입력번호와 랜덤번호를 비교해서 당첨번호만 출력해주는 소스이다.


---------------------------------------------------------------------------------------------------------------------------------


#include <stdio.h>

#include <stdlib.h>


int *input_data (void);

int *random_data (void);    /*  둘다 주소를 반환할것이기 때문에 포인터함수를 선언하였다. */

void compare_data (void);


int main()

{

    int sel;

    printf("로또 뽑기(1) 종료(2)\n선택 :");

    scanf("%d", &sel);

    while (sel == 1) {            /*  while문을 작성한 이유는 껏다 키는것이 귀찮아서..이다. */

    compare_data();       

    printf("\n\n로또 뽑기(1) 종료(2)\n선택 :");

    scanf("%d", &sel);

    }

    return 0;

}


int *input_data (void) {

    static int num[6];

    int i;

    printf("\n선택 번호 : ");

    for(i=0;i<6;i++) {

        scanf("%d", &num[i]);

    }

    return &num;

}


int *random_data (void) {

    int i, j, r;

    static int random[7];

    srand(time(NULL));

    for(i=0;i<=6;i++){

        again:;

        r=(rand()%49)+1;

        for(j=0;j<=i-1;j++)

            if(r==random[j])

                goto again;

        random[i]=r;

    }

    printf("추첨 번호 :");

    for (i=0; i<7; i++){

        printf("%3d", random[i]);

    }

    return &random;

}


void compare_data (void) {

    int i, j;

    int same = 0;

    int *num_com, *random_com;

    int select[6] = {0, 0, 0, 0, 0, 0};

    num_com = input_data();

    random_com = random_data();


    printf("\n당첨 번호 :");

    for(i=0;i<7;i++) {

        for(j=0;j<6;j++){

            if((random_com[i]) == (num_com[j])) {

                select[j] = num_com[j];

            }

        }

    }

    for (i=0;i<6;i++){

        if (select[i] != 0) {

            printf("%3d", select[i]); same++;

        }


    }

    printf("\n같은 번호 개수 :%d", same);

}


--------------------------------------------------------------------------------------------------------------------------------------------------------------

input_data는 번호를 입력하여 저장하는 함수이다.

random_data 함수는 임의의 변수 7개를 생성하는 함수이다. 

compare_data 함수는 input_data와  random_data함수의 번호를 비교하는 함수이다.


주소를 반환해서 포인터로 이용하는 방법을 선택한 이유는 한번 선언된 메모리의 주소값은 변하지 않는다.(내가 배운 시점까지는...)

따라서 해당값이 저장되어 있는 메모리의 첫번째 주소값만 알 수 있다면 그 주소값을 이용해 나머지 값도 이용할 수 있기때문이다.

(즉, 100번지에 첫번때 값이 저장되어 있다면 int형의 경우 104번지는 2번째 값 108번지는 3번쨰값......이 저장되어 있을것이기 때문이다.)


반응형

댓글