본문 바로가기

awesome-c Beginner 번역/A tutorial on pointers

<비공식 번역>awesome-c Beginner 번역 : CHAPTER 5 : Pointers and Structures

현재위치


<주의!!>

'A TUTORIAL ON POINTERS AND ARRAYS IN C'의 공식적인 번역이 아니며 수를 받은 것 역시 아닙니다!!




CHAPTER 5 : Pointers and Structures(챕터 5: 포인터와 구조체)


여러분이 아시다시피, 구조체 선언에 의해 다른 데이터 타입을 포함하는 데이터 블록의 형태를 선언할 수 있습니다. 예를 들어, 인사 파일은 다음과 같은 구조를 포함할 수 있습니다.


struct tag {
char lname[20];    /* last name */
char fname[20];    /* first name */
int age;            /* age */
float rate;         /* e. g. 12.75 per hour */
};

가정해봅시다. 이러한 구조체가 디스크 파일에 있고 우리는 이것을 읽어서 각각의 성과 이름을 출력하길 원합니다. 그래서 우리가 파일안에 있는 사람들의 리스트를 가질 수 있습니다. 남은 정보들(나이, rate)는 인쇄 되지 않습니다. 우리는 이것을 출력할 때 함수롤 호출하고 함수에 구조체 포인터를 전달하길 원할 것입니다. 데모 목적으로 지금 구조체 하나를 사용할 것입니다. 그리고 실제 목표는 파일을 읽는 것이 아닌 함수를 사용하는 것입니다. 아마도 저희는 어떻게하는지 압니다.

검토를 위해, 우리는 구조체의 멤버들을 .(dot) 연산자를 통해 접근할 수 있임을 상기합시다.
--------------- program 5.1 ------------------

/* Program 5.1 from PTRTUT10.HTM     6/13/97 */


#include <stdio.h>
#include <string.h>

struct tag {
    char lname[20];      /* last name */
    char fname[20];      /* first name */
    int age;             /* age */
    float rate;          /* e.g. 12.75 per hour */
};

struct tag my_struct;       /* declare the structure my_struct */

int main(void)
{
    strcpy(my_struct.lname,"Jensen");
    strcpy(my_struct.fname,"Ted");
    printf("\n%s ",my_struct.fname);
    printf("%s\n",my_struct.lname);
    return 0;
}

-------------- end of program 5.1 --------------


이제, 이 특정 구조체는 C프로그램에서 자주 사용하는 것에 비교하면 작습니다. 위에 우리는 추가할 수 있습니다:


date_of_hire;                  (data types not shown)

date_of_last_raise;

last_percent_increase;

emergency_phone;

medical_plan;

Social_S_Nbr;

etc.....


만약 다수의 직원들이 있다면, 우리는 함수적 방법에 의해서 이 구조체의 데이터를 다루길 원 할 것입니다. 예를 들어, 어떤 구조체로 전달되는 직원리스트의 이름을 출력하는 함수를 원한다고 가정합시다. 그러나 오리지널 C에선(Kernighan & Ritchie, 1st Edition) 구조체를 전달하는 것은 불가능 했습니다. 오직 구조체 포인터를 전달할 수 있을 뿐입니다. ANSI C에서는 구조체를 완전히 전달하는 것이 가능합니다. 그러나 우리의 목표는 포인터에 대해서 더 배우는 것이므로 그것은 목적에 부합하지 않습니다.


어쨋든, 만약 우리가 구조체 전체를 전달할 수 있다면 그것은 호출 함수에서 호출된 함수의 구조체 내용의 복사를 의미합니다. 시스템이 stack을 사용한다면, stack의 push를 이용하여 stack에 구조체의 내용을 넣음으로써 가능합니다. 거대한 크기의 구조체로 이 문제를 증명할 수 있습니다. 그러나 포인터를 전달하는 것은 stack 공간의 최소한 양을 사용합니다. 


어떤 경우에는, 포인터의 토론 이후로, 우리는 어떻게 구조체 포인터가 전달되는지, 어떻게 그 함수들을 사용하는지 토의할 것입니다.


설명된 경우를 고려하면 즉, 우리는 구조체 포인터를 인자로 수용하고 함수내에서 구조체의 멤버에 접근할 수 있는 함수를 원합니다. 예를 들면 우리는 예시의 구조체에서 직원의 이름을 출력하길 원하는 것입니다.


좋습니다. 그래서 우리는 구조체 포인터가 구조체 태그를 사용하여 선언됨을 압니다. 우리는 그러한 포인터를 다음 설명을 통해 선언합니다:


struct tag *st_ptr;


그리고 우리는 예제 구조체를 가리키게 합니다.


st_ptr = &my_struct;


이제 우리는 포인터를 역참조하여 지정된 멤버들에 접근할 수 있습니다. 그러나 어떻게 구조체 포인터를 역참조 할까요? 음.. 우리는 직원의 나이를 설정할 수 있다는 사실을 고려하면 이렇게 쓸 수 있을 것입니다 :


(*st_ptr).age = 63;


주의깊게 보셔야합니다. 이것은 괄호안에 st_ptr이 가리키는 것은 my_struct 구조체를 가리킵니다. 따라서 이것은 세분화하면 my_struct.age와 같습니다.


그러나, C의 디자이너들이 만들었던 같은 의미지만 다른 형태의 문구는 꽤 자주 사용된다. :


str_ptr->age = 63;


이를 염두해두고 다음 프로그램을 봅시다.


------------ program 5.2 ---------------------


/* Program 5.2 from PTRTUT10.HTM   6/13/97 */


#include <stdio.h>

#include <string.h>


struct tag{                     /* the structure type */

    char lname[20];             /* last name */

    char fname[20];             /* first name */

    int age;                    /* age */

    float rate;                 /* e.g. 12.75 per hour */

};


struct tag my_struct;           /* define the structure */

void show_name(struct tag *p);  /* function prototype */


int main(void)

{

    struct tag *st_ptr;         /* a pointer to a structure */

    st_ptr = &my_struct;        /* point the pointer to my_struct */

    strcpy(my_struct.lname,"Jensen");

    strcpy(my_struct.fname,"Ted");

    printf("\n%s ",my_struct.fname);

    printf("%s\n",my_struct.lname);

    my_struct.age = 63;

    show_name(st_ptr);          /* pass the pointer */

    return 0;

}


void show_name(struct tag *p)

{

    printf("\n%s ", p->fname);  /* p points to a structure */

    printf("%s ", p->lname);

    printf("%d\n", p->age);

}


-------------------- end of program 5.2 ----------------


다시 한번에 흡수하는 많은 정보입니다. 독자분들은 컴파일하고 다양한 코드 부분을 실행해보셔야합니다. 그리고 디버거 모니터를 사용하여 my_structp의 값에 main을 실행하는 동안 한 단계씩 아래로 내려가면서 어떤 일이 일어나는지 관찰합니다.

 

출처1 : https://github.com/aleksandar-todorovic/awesome-c

출처2 : http://home.netcom.com/~tjensen/ptr/pointers.htm