'구조체'에 해당되는 글 3건

Programming/C C++
클래스와 비슷하게 멤버변수와 함수를 가질 수 있는 것으로 사용자 정의 자료형을 표현하는데 많이 사용됩니다.

구조체의 형식은 아래와 같습니다.
struct 구조체이름
{
    //멤버
};
적절한 구조체 이름을 부여하고 클래스와 같이 구조체 내부에 필요한 멤버를 정의합니다. 구조체도 클래스와 마찬가지로 마지막에 ;문자를 부여해야 합니다.
struct myStr
{
    int a;
    int b;

    int result()
    {
         return a + b;
    }
};
위와 같은 구조체가 정의되었을때 구조체 내부의 멤버는 다음과 같은 방법으로 접근이 가능합니다. 참고로 구조체의 멤버는 접근제한자가 특별히 설정되지 않으면 모두 public성격을 가집니다.
myStr mystr;
mystr.a = 10;
mystr.b = 20;

cout << "결과 : " << mystr.result() << endl;
구조체를 사용하려면 클래스 처럼 인스턴스를 생성(myStr mystr;)해야 하는데 구조체를 정의할때 바로 인스턴스를 생성하는 방법도 있습니다.
struct myStr
{
    int a;
    int b;

    int result()
    {
        return a + b;
    }
} mystr;

'Programming > C C++' 카테고리의 다른 글

[Visual C++] 포인터와 참조  (2) 2012.07.12
[Visual C++] typedef  (0) 2012.07.06
[Visual C++] 구조체  (0) 2012.07.05
[Visual C++] 함수  (0) 2012.07.04
[Visual C++] 연산자  (0) 2012.07.03
[Visual C++] 흐름제어  (0) 2012.07.02
0 0
Programming/C C++
구조체는 서로 연관된 변수(Data)를 한곳에 묶어놓은 형태를 말합니다. 예를 들어 어떤 학생의 국어, 영어, 수학 성적을 관리하기 위해 다음과 같이 변수를 선언하였을때

int kuk;
int eng;
int mat;

위 변수를 구조체로 묶으려면 다음과 같이 선언될 수 있습니다.

struct score {
 int kuk;
 int eng;
 int mat;
};

이때 구조체는 구조체 내부에서 또 다른 구조체를 포함할 수 있습니다.

struct score {
    int kuk;
    int eng;
    int mat;
};

struct total_score {
   int t_kuk;
   int t_eng;
   int t_mat;
   
   struct score sre;
 };
}


total_score구조체 안에 score구조체를 포함하고 있습니다. (이때 score구조체는 total_score안에서 sre라는 변수로 선언되었으며 이러한 형태의 구조체를 내부구조체라 합니다.)

구조체 이름과 변수명은 개발자 임의로 정할 수 있으며 또한 구조체 안에 변수는 그 Data형을 각각 다르게 지정할 수도 있습니다.

struct score {
 int kuk;
 char eng;
 float mat;
};

이때 구조체안에서 정의된 변수명과 외부에서 선언된 변수명이 같다하더라도 변수명은 충돌하지 않습니다.

struct score {
 int kuk;
 char eng;
 float mat;
};

int kuk;

이렇게 선언된 구조체는 이 구조체 하나만으로 새로운 Data형이 될 수 있습니다. 따라서 선언된 구조체를 실제 사용하려면 새로운 변수명으로 구조체를 선언해야 합니다.

struct score student_sre;

score구조체를 student_sre라는 이름으로 선언하였습니다. 하지만 정의와 선언을 구분하지 않고 정의와 동시에 선언할 수도 있습니다.

struct score {
 int kuk;
 int eng;
 int mat;
} student_sre;

score라는 구조체를 정의하고 student_sre라는 이름으로 선언합니다.

구조체의 정의와 선언을 별도로 처리하는 경우 구조체를 선언하려면

struct score student_sre;

라고 해야하지만 일일이 struct ... 를 사용하기 번거롭다면 typedef를 사용하여 구조체를 선언하는 것도 가능합니다.

typedef struct {
 int kuk;
 int eng;
 int mat;
} score;

또는

struct score {
 int kuk;
 int eng;
 int mat;
} typedef struct score student_sre;

이렇게 선언하면 정의는

score student_sre;

로 하여 struct를 생략할 수 있습니다. typedef는 구조체 선언시 해당 구조체의 이름을 score라고 할 수 있도록 해주고 있기 때문입니다.

구조체를 위와 같이 선언하고 해당 변수에 접근하려면 .(점)을 사용하여야 합니다. .(점)은 구조체 Member연산자로서 구조체의 각 Member에 접근할 수 있도록 해줍니다.

#include <stdio.h>

main()
{
  struct score {
    int kuk;
    int eng;
    int mat;
  };
 
  struct score student_sre;
 
  student_sre.kuk = 90;
  student_sre.eng = 100;
  student_sre.mat = 88;
 
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n", student_sre.kuk, student_sre.eng, student_sre.mat);
}


구조체 선언변수명.member' 형식을 통해 각각 90, 100, 88이라는 값을 넣고 printf()를 통해 그 값을 확인하고 있습니다.


참고 :
구조체 안의 int kuk, int eng, int mat등.. 선언된 변수를 구조체 Member라고 합니다.

구조체안에 구조체를 포함한 경우에는 그 만큼 .을 연속해서 사용해 해당 구조체의 Member로 접근하면 됩니다.

#include <stdio.h>

main()
{
  struct tlt_score {
    char t_kuk[4];
    char t_eng[4];
    char t_mat[4];
  };
 
  struct score {
    int kuk;
    int eng;
    int mat;
   
    struct tlt_score sre;
  };
 
  struct score student_sre;
 
  student_sre.kuk = 90;
  student_sre.eng = 100;
  student_sre.mat = 88;
 
  strcpy(student_sre.sre.t_kuk, "kuk");
  strcpy(student_sre.sre.t_eng, "eng");
  strcpy(student_sre.sre.t_mat, "mat");
 
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n", student_sre.kuk, student_sre.eng, student_sre.mat);
  printf("\n");
  printf("국어 : %s\n영어 : %s\n수학 %s\n", student_sre.sre.t_kuk, student_sre.sre.t_eng, student_sre.sre.t_mat);
}


store구조체 안에 tlt_score구조체를 sre라는 변수명으로 포함시키고 student_sre.sre.member형식으로 score안의 tlt_score구조체 Member에 접근하고 있습니다.

참고:
strcpy()는 문자배열에 문자열을 복사하는 표준 Library함수중 하나입니다.

이처럼 '구조체변수명.member명' 형식을 통해 구조체의 각 Member에 값을 초기화 하였는데 이렇게 Member를 일일이 호출하지 않고 구조체를 통틀어 값을 초기화 할 수도 있습니다.

#include <stdio.h>

main()
{
  struct score {
    int kuk;
    int eng;
    int mat;
  };
 
  struct score student_sre = {90, 100, 88};
 
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n", student_sre.kuk, student_sre.eng, student_sre.mat);
}


{와 }를 통해 각각의 구조체 Member값을 초기화 하고 있습니다. {}를 쓴다는 점에서 배열을 초기화 하는것과 비슷하지만 구조체는 'struct 구조체명'이 선행되어야 한다는 점에서 일반배열초기화와는 틀리다고 볼 수 있습니다.

#include <stdio.h>

main()
{
  struct score {
    int kuk;
    int eng;
    int mat;
  }student_sre = {90, 100, 88};
 
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n", student_sre.kuk, student_sre.eng, student_sre.mat);
}


구조체를 선언과 동시에 초기화 하고 있습니다.

만일 구조체를 배열로 활용한다면 다음과 같이 초기화 할 수 있습니다.

#include <stdio.h>

main()
{
  struct score {
    int kuk;
    int eng;
    int mat;
  };
 
  struct score student_sre[2] = {{90, 100, 88}, {80, 90, 70}};
...
}


구조체의 배열은 배열 수 만큼 {}를 사용해 초기화 하며 각 초기화 단위는 , 으로 구분합니다.


물론 구조체는 '구조체변수명.member' 또는 {}를 사용하거나 구조체 자체를 통해 값을 초기화 할 수 있으나 변수를 복사하듯 구조체 자체를 복사하여 다른 구조체의 변수에 값을 똑같이 초기화 하는 것도 가능합니다.

#include <stdio.h>

main()
{
  struct score {
    int kuk;
    int eng;
    int mat;
  };
 
  struct score student_sre_;
  struct score student_sre = {90, 100, 88};
 
  student_sre_ = student_sre;
 
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n", student_sre.kuk, student_sre.eng, student_sre.mat);
  printf("\n");
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n", student_sre_.kuk, student_sre_.eng, student_sre_.mat);
}


score구조체를 통해 student_sre_ 와 student_sre라는 이름으로 두개의 변수를 선언하였습니다. 이후 student_sre변수 값을 초기화 하고 해당 변수를 student_sre_변수에 대입함으로써 구조체의 복사를 시도하고 있습니다.


만일 선언된 구조체를 다른 함수간에 전달하려면 자연스럽게 구조체 자체를 넘기거나 주소를 통해서 전달하면 됩니다.

#include <stdio.h>

struct score {
    int kuk;
    int eng;
    int mat;
};
memberprnt(struct score v);

main()
{
  struct score student_sre = {90, 100, 88};
 
  memberprnt(student_sre);
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n", student_sre.kuk, student_sre.eng, student_sre.mat);
}

memberprnt(struct score v)
{
  printf("memberprnt : \n");
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n\n", v.kuk, v.eng, v.mat);
 
  v.kuk = 10;
  v.eng = 20;
  v.mat = 30;
 
  printf("memberprnt : \n");
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n\n", v.kuk, v.eng, v.mat);
}


각 함수간 구조체를 값의 형태로 전달하고 있습니다.

함수간 구조체를 전달할때 문제가 되는 것은 함수원형부분입니다. 함수원형을 선언할때 인수 부분을 (struct score v)라고 하고 싶지만 그러기 이전에 구조체 score가 뭔지를 알려야 합니다. 때문에 구조체 선언부분을 함수원형을 정의하는 부분 위에다 작성하여 해당 구조체의 정의부터 먼저 이루어 지도록 해야 합니다.


다음은 주소를 통한 구조체 전달의 예입니다.

#include <stdio.h>

struct score {
    int kuk;
    int eng;
    int mat;
};
memberprnt(struct score *p);

main()
{
  struct score student_sre = {90, 100, 88};
 
  memberprnt(&student_sre);
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n", student_sre.kuk, student_sre.eng, student_sre.mat);
}

memberprnt(struct score *p)
{
  printf("memberprnt : \n");
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n\n", p->kuk, p->eng, p->mat);
 
  p->kuk = 10;
  p->eng = 20;
  p->mat = 30;
 
  printf("memberprnt : \n");
  printf("학생의 국어점수 %d\n학생의 영어점수 %d\n학생의 수학점수 %d\n\n", p->kuk, p->eng, p->mat);
}


각 함수간 구조체를 Pointer(주소)의 형태로 전달하고 있습니다.

함수간 구조체에 대한 Pointer를 전달하려면 &문자를 써서 주소값을 넘겨주어야 합니다. 또한 구조체를 전달받은 함수는 .대신 -> 를 써서 각 구조체의 Member에 접근해야 합니다.

위 Program은 주소를 통한 전달이므로 전달받은 함수측에서 구조체의 값을 바꾸면 본래의 구조체에도 영향을 미치게 됩니다.


구조체는 자신 스스로에 대한 값을 다시 참조하는 '자기참조 구조체'를 구현할 수도 있습니다. 즉, 구조체를 정의할때 자기자신을 Pointer로 하여 구조체를 정의하는 것입니다.

struct score {
    int kuk;
    int eng;
    int mat;
   
    struct score *n_score;
};

score 구조체 자신을 n_score라는 이름으로 Pointer(*사용에 주의)선언하여 자기참조구조체를 생성합니다.

실제 Program에서 score구조체를 통해 여러개의 변수가 선언되면

struct score stu_fir, stu_sec, stu_thi;

이들 변수들을 선언된 Pointer(*n_score)를 통해 서로 연결할 수 있게 되는 것입니다.

stu_fir.n_score = &stu_sec;

처음 변수(stu_fir)의 n_score pointer에 stu_sec변수의 주소를 대입합니다.

stu_sec.n_score = &stu_thi;

두번째 변수(stu_sec)의 n_score Pointer에 stu_thi변수의 주소(&사용에 주의)를 대입합니다.

이렇게 하면 각 변수의 n_score에 의해 다음과 같은 구조를 이루게 됩니다.


즉, stu_fir의 n_score는 stu_sec의 시작주소를 가지게 되고 다시 stu_sec의 n_score는 stu_thi의 시작주소를 가지게 되서 stu_fir과 stu_sec 그리고 stu_thi가 마치 기차처럼 서로 연결된 형태를 띄게 되는 것입니다.(이러한 형태를 '연결 List'라고 합니다.)

#include <stdio.h>

main()
{
  struct score {
    int kuk;
    int eng;
    int mat;
   
    struct score *n_score;
  };
 
  struct score stu_fir, stu_sec, stu_thi;
 
  stu_fir.kuk = 10;
  stu_fir.eng = 20;
  stu_fir.mat = 30;
 
  stu_sec.kuk = 40;
  stu_sec.eng = 50;
  stu_sec.mat = 60;
 
  stu_thi.kuk = 70;
  stu_thi.eng = 80;
  stu_thi.mat = 90;
 
  stu_fir.n_score = &stu_sec;
  stu_sec.n_score = &stu_thi;
 
  printf("stu_fir의 kuk값 : %d\n", stu_fir.kuk);
  printf("stu_sec의 kuk값(stu_fir.n_score pointer를 통해 확인) : %d\n", *stu_fir.n_score);
  printf("stu_thi의 kuk값(stu_sec.n_score pointer를 통해 확인) : %d\n", *stu_sec.n_score);
}


stu_fir.n_score = &stu_sec; 에 의해서 stu_sec의 시작주소가 stu_fir.n_score에 들어가게 됩니다. str_sec의 시작주소라 함은 str_sec구조체 처음 변수인 kuk주소를 의미하며 이후에 stu_sec.n_score = &stu_thi; 도 같은 맥락에서 동작하게 됩니다.


결국 printf()함수에서 *stu_fir.n_score와 *stu_sec.n_score를 통해 해당 주소가 가리키는 값을 가져오게 되면 stu_fir.n_score는 stu_sec.kuk주소를 가지고 있으므로 40을 그리고 stu_sec.n_score는 stu_thi.kuk주소를 가지고 있으므로 70을 표시하게 되는 것입니다.

또한

stu_fir.n_score = &stu_sec;
stu_sec.n_score = &stu_thi;

위와같이 하게 되면 각 변수의 첫 주소값(kuk)만 들어가게 되므로 결과에서 보듯 kuk에 해당하는 값만을 표시하게 됩니다. 이때 만일 eng나 mat의 값을 가져오고 싶다면 다음과 같이 처리합니다.

#include <stdio.h>

main()
{
  struct score {
    int kuk;
    int eng;
    int mat;
   
    struct score *n_score;
  };
 
  struct score stu_fir, stu_sec, stu_thi;
 
  stu_fir.kuk = 10;
  stu_fir.eng = 20;
  stu_fir.mat = 30;
 
  stu_sec.kuk = 40;
  stu_sec.eng = 50;
  stu_sec.mat = 60;
 
  stu_thi.kuk = 70;
  stu_thi.eng = 80;
  stu_thi.mat = 90;
 
  stu_fir.n_score = &stu_sec;
  stu_sec.n_score = &stu_thi;
 
  printf("stu_fir의 kuk값 : %d\n", stu_fir.kuk);
  printf("stu_sec의 kuk값(stu_fir.n_score pointer를 통해 확인) : %d\n", stu_fir.n_score->eng);
  printf("stu_thi의 kuk값(stu_sec.n_score pointer를 통해 확인) : %d\n", stu_sec.n_score->mat);
}


printf()에서 *대신 -> 연산자를 통해 해당 eng값과 mat값을 가져오도록 합니다. 여기서 -> 표시는 Member참조연산자로서 구조체나 공용체에서 해당 Pointer를 참조하는 전용 연산자 입니다. 이때 Pointer를 통해서도 . 연산자 사용이 가능합니다. 다만 Pointer를 괄호로 묶어 주어야 합니다.


이전의 구조체는 Pointer를 하나만 갖는 자기참조 구조체였습니다. 이 구조체의 단점은 해당 구조체로부터 Pointer를 따라 앞으로만 진행할 수 있다는 것입니다.

다시 뒤로 돌아올 수 없다는 것인데 이 문제는 다음이 아닌 이전으로 되돌아 갈 수 있는 전용 Pointer를 추가함으로서 간단히 해결이 가능합니다.

#include <stdio.h>

main()
{
  struct score {
    int kuk;
    int eng;
    int mat;
   
    struct score *b_score;
    struct score *n_score;
  };
 
  struct score stu_fir, stu_sec, stu_thi;
 
  stu_fir.kuk = 10;
  stu_fir.eng = 20;
  stu_fir.mat = 30;
 
  stu_sec.kuk = 40;
  stu_sec.eng = 50;
  stu_sec.mat = 60;
 
  stu_thi.kuk = 70;
  stu_thi.eng = 80;
  stu_thi.mat = 90;
 
  stu_fir.n_score = &stu_sec;
  stu_sec.b_score = &stu_fir;
  stu_sec.n_score = &stu_thi;
 
  printf("stu_fir의 kuk값 : %d\n", stu_fir.kuk);
  printf("stu_sec의 kuk값(stu_fir.n_score pointer를 통해 확인) : %d\n", stu_fir.n_score->eng);
  printf("stu_thi의 kuk값(stu_sec.n_score pointer를 통해 확인) : %d\n", stu_sec.n_score->mat);
  printf("stu_thi의 kuk값(stu_sec.n_score pointer를 통해 확인) : %d\n", stu_sec.n_score->mat);
 
  printf("다시 stu_fir의 mat값(stu_sec.b_score pointer를 통해 확인) : %d\n", stu_sec.b_score->mat);
}


구조체 생성시 현재 구조체의 이전과 다음구조체를 기억할 수 있도록 *b_score pointer와 *n_score pointer를 두었습니다.

Program에서는 stu_sec구조체의 b_score에 stu_fir을 n_score에는 stu_thi를 참조하도록 하고(stu_sec.b_score = &stu_fir, stu_sec.n_score = &stu_thi) 해당 구조체의 값을 stu_sec pointer를 통해 확인하고 있습니다.

'Programming > C C++' 카테고리의 다른 글

[C, C++] Class  (0) 2011.05.25
[C, C++] cout 서식지정  (0) 2011.04.14
[C, C++] 구조체  (1) 2011.04.13
[C, C++] 변수선언및 초기화  (0) 2011.04.07
[C, C++] C에서 C++로의 변화  (1) 2011.04.06
[C, C++] 표준 Library 함수 - 각종 변환 함수  (0) 2011.04.05
1 0
Programming/C C++
 1. malloc

C언어에서 동적으로 Memory를 할당하려면 malloc함수를 이용합니다. 이 함수는 인수로 전달된 정수만큼의 byte크기를 Memory에서 할당하고(만일 할당에 실패하면 NULL을 반환합니다.) 할당된 Memory주소를 Pointer로 반환합니다.

#include <stdio.h>
#include <stdlib.h>

main()
{
  char *p;
 
  p = (char *)malloc(10);
}


10 byte의 Memory확보 후 해당 Memory위치를 Pointer p에 되돌립니다.

참고 :
malloc()함수사용시 반환부분에 (char *)형으로 변환시켜 주는 이유는 malloc()함수가 Memory를 확보한 후 해당 Pointer를 반환할때 형이 없는 void(*)를 반환하기 때문입니다. 이는 반환되는 Memory영역을 범용적으로 활용하기 위해서 입니다.

malloc()함수를 이용하면 구조체와 결합하여 해당 구조체를 동적으로 할당하고 할당된 구조체를 연결시킴으로서 연결 List를 생성할 수 있습니다.(연결 list라는 것은 같은 데이터형이 기차처럼 연결된 형태를 지닌다고 하여 붙여진 이름입니다.)

다음 Program은 구조체와 malloc()함수를 사용해 동적으로 구조체에 대한 Memory를 할당하고 연결 List를 생성한 예제입니다.

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

main()
{
  struct student{
    char name[5];
    int kuk;
    int eng;
   
    struct student *np;
  };
  struct student *p;
 
  p = (struct student *)malloc(sizeof(struct student));
 
  strcpy(p->name, "kim");
  p->kuk = 80;
  p->eng = 90;
 
  p->np = (struct student *)malloc(sizeof(struct student));
 
  strcpy(p->np->name, "choi");
  p->np->kuk = 90;
  p->np->eng = 100;
 
  printf("%s : kuk - %d, eng - %d\n", p->name, p->kuk, p->eng);
  printf("%s : kuk - %d, eng - %d\n", p->np->name, p->np->kuk, p->np->eng);
  free(p);
  free(p->np);
}


일단 Header File에서 stdlib.h는 malloc()함수 사용을 위해 선언되었으며 string.h는 strcpy()함수 사용을 위해 선언되었습니다.

다음은 구조체 선언부분입니다.

struct student{
    char name[5];
    int kuk;
    int eng;
   
    struct student *np;
};

struct로 구조체가 student라는 이름으로 선언되었습니다. 이 구조체는 학생의 점수관리를 위한 구조체로 학생의 이름과 국어점수 그리고 영어점수를 저장할 수 있도록 name과 kuk, eng Member로 구성되어 있습니다.

그리고 마지막 member에는 struct student *np;가 있는데 이는 자기 자신을 가리키는 Pointer를 Memeber(자기참조 구조체)로 가지기 위해서 존재합니다.

이 자기참조 구조체는 동적으로 같은 구조체가 Memory에서 생성될때 그 구조체의 시작주소를 갖게 됨으로서 자연스럽게 구조체간 연결 List를 이루도록 하는 것입니다.

구조체 선언 다음에는 구조체에 접근하기 위해 해당 구조체 Data형의 Pointer변수를 선언하였습니다.

struct student *p;

구조체와 Pointer를 선언하고 malloc()함수를 호출하여 구조체크기 만큼의 Memory를 동적으로 생성하도록 합니다.

p = (struct student *)malloc(sizeof(struct student));

보시는 바와 같이 malloc함수안에 sizeof함수가 사용되었습니다. 이 sizeof함수는 인수로 student구조체를 전달하고 그 크기만큼의 Byte값을 정수형태로 반환합니다. 그러면 malloc함수는 반환되는 값 만큼 Memory를 확보하고 그 수행 결과로 Memory의 시작주소를 Pointer p에 반환합니다.(이때 반환되는 Data형은 void형이므로 해당 Data형을 student 구조체로 변환해야 합니다.)

이렇게 Pointer p는 student구조체 형식으로 확보된 Memory시작 주소값을 가지게 됩니다.


이제 Pointer p를 이용해 학생의 이름과 점수를 Memory영역에 담아봅시다.

strcpy(p->name, "kim");
p->kuk = 80;
p->eng = 90;

Pointer에서 -> 를 사용하여 각 Member에 접근합니다. 그리고 kim이라는 이름과 국어점수 80점, 영어점수 90점을 저장합니다.

이때 학생은 단 한명이 아니라 2명 세명.. 그 이상도 될지 모르기 때문에 미리 일정한 구조체를 선언해 두는 것은 그리 좋은 선택이 아닐 것입니다. 따라서 이런경우 동적으로 할당한다는 개념이 필요하게 됩니다.

학생수가 늘어나면 그 만큼 더 많은 구조체가 할당되어야 하기 때문에 처음 구조체의 자기참조 구조체에 동적으로 할당한 다른 구조체의 Memory주소를 갖게 함으로서 연결 list형의 구조를 이루도록 하려 합니다.

p->np = (struct student *)malloc(sizeof(struct student));

p->np를 통해 구조체의 np Pointer에 student 구조체 만큼의 Memory영역을 할당하고 해당 Memory의 주소값을 전달하고 있습니다.

이렇게 되면 이전에 할당된 구조체의 np Pointer는 이후에 할당된 구조체의 시작주소를 가지게 됨으로서 연결 List를 이루게 됩니다.


이제 이전 구조체의 Pointer에서 다음 구조체의 Pointer를 통하여 해당 구조체의 Member에 접근해서 이름과 주소를 할당합니다.

strcpy(p->np->name, "choi");
p->np->kuk = 90;
p->np->eng = 100;

그리고 마지막으로 할당된 Memory영역이 더이상 필요가 없어지면 그 Memory영역을 해제하여 그 만큼의 영역을 다시 회수해야 합니다.

free(p);
free(p->np);

free함수를 호출하여 해당 Pointer에 위치한 Memory영역을 해제합니다.

이 작업이 이루어 지지 않으면 쓸데없는 Memory공간을 낭비하게 됩니다.


2. calloc()

calloc() 함수를 이용하면 같은 Data형의 Memory공간을 여러개 배열 형태로 할당할 수 있습니다.

#include <stdio.h>
#include <stdlib.h>

main()
{
  char *p;
  int i;
 
  p = (char *)calloc(5, 1);
 
  for (i = 0; i < 5; i++)
    printf("%d\n", p[i]);
}


calloc(5, 1)을 통해 1Byte의 Memory를 5개(0~4)의 배열로 확보하고 해당 Memory시작 주소를 Pointer p에 반환하도록 합니다.

그리고 p[배열인자]형식을 통해 각 배열의 값을 for문으로 돌면서 확인하고 있는데 그 결과는 다음과 같습니다.


참고:
calloc()함수는 Memory를 배열로 확보한고 각 배열의 초기값으로 0을 부여합니다.

이제 확보된 배열의 초기값을 직접 부여하여 그 결과를 확인해 보도록 하겠습니다.

#include <stdio.h>
#include <stdlib.h>

main()
{
  char *p;
  int i;
  char cal;
 
  p = (char *)calloc(5, 1);
 
  cal = 'a';
 
  for (i = 0; i < 5; i++)
    p[i] = cal + i;
   
  for (i = 0; i < 5; i++)
    printf("%c\n", p[i]);
  free(p);
}


확보된 각 배열 cal변수에 문자 'a'를 설정하고 for문을 통해 0부터 4까지 문자 'a'에 값을 1씩 더하여(그럼 'b'.. 'c'형태로 변할 것입니다.) 저장한 후 다시 for문을 통해 값을 확인하고 있습니다.


3. free

calloc()함수사용시에도 예외없이 free()함수를 호출하여 사용된 Memory영역을 해제해야 합니다.

사실 malloc()함수나 calloc()함수 사용시에만 free()함수를 쓸 수 있는건 아니고 필요하다면 다른 상황에도 호출하여 사용할 수 있습니다.
0 0
1
블로그 이미지

클리엘