Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

나의 IT일지

구조체 포인터 본문

프로그래밍 언어/C언어

구조체 포인터

세레프 2023. 3. 3. 07:00

 구조체여러 개의 자료형을 가진 변수를 모아놓은 자료형으로, 구조체형을 가지고 만든 변수는 일반 변수와 같이 메모리 주소를 가지고 있다. 따라서 포인터를 통해 구조체의 주소를 저장할 수 있다. 포인터주소를 저장하는 변수로, 주소를 통해 저장공간에 접근하기 위해서 사용된다. 

 

구조체 포인터

 구조체 포인터는 구조체와 포인터의 합성어로, 구조체 변수의 주소를 저장하는 변수를 말한다. 하지만 구조체 포인터는 일반 포인터나 배열포인터와 차이점이 존재한다.

 일반 포인터배열 포인터변수, 배열의 주소를 저장하기 때문에 증감연산자로 변수를 호출하는 것이 가능하다. 하지만 구조체 포인터의 경우, 구조체형을 가진 변수의 주소이기에 증감연산자로 내용에 접근하는 것이 불가능하다.

 즉, 구조체 변수에 연산자를 사용하면 구조체형태를 가진 변수에 접근하는 것이지, 그 안에 있는 내용에 접근하는 것이 아니다.

#include<stdio.h>

struct data {

	int num;
	char name[20];

};

void main() {

	struct data data1;
	struct data *pdata1;
	pdata1 = &data1; 
	printf("&data1: %d\n", &data1);
	printf("&data1+1: %d\n", &data1 +1);
}

 위의 코드의 결과를 보면, 구조체 변수의 주소에 산술연산자를 사용하면, 변수에 저장되어 있는 필드의 값만큼 증가하는 것을 알 수 있다. 이는 data1은 하나의 변수로 되어 있으며, 다는 것을 알 수 있다. 그렇다면 변수내의 내용에 접근할려면 어떻게 해야 할까?

구조체 포인터->구조체내 멤버 변수

 위의 구조는 구조체 멤버 변수에 접근하게 해주는 방법으로, "->"연산자(간접 멤버 접근 연산자)를 이용하여 포인터의 주소를 가진 구조체 변수에 접근 후에 변수 내에 있는 멤버변수에 접근해서 해당 레코드에 출력한다.

#include<stdio.h>

struct data {

	int num;
	char name[20];

};

void main() {

	struct data data1;
	struct data *pdata1;
	pdata1 = &data1;
	printf("&data1: %d\n", &data1);
	printf("&data1.num: %d\n", &data1.num);
	printf("&data1.name: %d\n", &data1.name);
	printf("&data1+1: %d\n", &data1 +1);
	printf("&pdata1->num:%d\n", &pdata1->num);	//=&(*pdata1).num
	printf("&pdata1->name:%d\n", &pdata1->name);	//=&(*pdata1).name
}

 위의 결과를 보면 산술연산자를 이용한 주소값과 간접 멤버 접근 연산자을 이용한 주소값이 다르다는 것을 알 수 있다.

 정리하자면, 구조체형을 통해 변수를 생성하여도, 컴퓨터에선 하나의 변수로 인식하며, 구조체 멤버 변수에 접근하기 위해선 간접 멤버 접근 연산자 "->"를 사용하면 접근 할 수 있다. 즉 "pdata1->name"은 "pdata"포인터변수에 저장되어 있는 주소의 "data1"변수의 멤버변수인 "name"변수에 접근한다는 것이다.

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

struct data {

	char name[20];
	int kor;
	int math;
	int sci;
};

int main() {
	struct data* datas;
	int count = 0, i, stud;
	printf("학생 수 입력:");
	scanf("%d",&stud);
	datas = (struct data*)malloc(sizeof(struct data) * stud);

	while (count < stud) {

		
		printf("이름:");
		scanf("%s", datas->name);
		printf("국어점수:");
		scanf("%d", &datas->kor);
		printf("수학점수:");
		scanf("%d", &datas->math);
		printf("과학점수:");
		scanf("%d", &datas->sci);
		datas++;
		count++;
	
	}
	printf("\n\n");
	for (i = count; i > 0; i--) {
		printf("%s의 점수 - 국어: %d,수학:%d, 과학:%d\n", (datas - i)->name, (datas - i)->kor, (datas - i)->math, (datas - i)->sci);
	}

	free(datas);
}

 위의 코드와 결과는 구조체포인터와 동적할당변수를 이용하여 국어,수학,과학점수를 입력하고 저장한 코드이다.  일반적인 동적할당변수를 생성하는 방법처럼 구조체에서도 똑같은 형식으로 생성하는 것을 알 수 있다.

  #include<stdlib.h>

void main(){

    struct data * datas();
    datas = (struct data*)malloc(sizeof(struct data)*3); 
    free(datas) 

}
 

위의 구조를 설명하면 다음과 같다.

  •  <stdlib.h>는 문자열 변환, 동적메모리관리 등의 함수를 포함하는 c언어 라이브러리중 하나로, malloc 함수와 free명령어를 사용하기 위해 불러오는 라이브러리이다.
  •   malloc함수는 메모리를 동적할당할 때 사용하는 함수로, ()안에 적은 숫자나 자료형의 크기를 byte크기 만큼 메모리를 할당하여, 할당 받은 메모리의 시작 주소를 반환하는 함수이다. 그래서 시작주소를 저장할 포인터를 생성하여 포인터에 주소를 저장한다. 이때, 자료형의 자리에 "struct 구조체명"을 사용하는데, 이는 구조체형으로 구조체 선언으로 인해 만들어진 틀이다.
  •   free명령어프로그램이 종료할 때, 동적 할당 받은 메모리 해제하기 위해 사용하는 명령어이다. free명령어를 사용하는 이유는 동적으로 생성된 변수나 배열은 자동적으로 회수가 되지 않기 때문이다.

 이처럼 동적할당변수는 포인터를 이용하여 만들어 지기 때문에, 구조체 또한 동적할당으로 만들 수 있는 것이다.

'프로그래밍 언어 > C언어' 카테고리의 다른 글

구조체와 비트필드  (0) 2023.03.07
구조체 내 구조체  (1) 2023.03.04
구조체 배열  (1) 2023.03.02
구조체 기본  (0) 2023.03.01
동적 메모리 할당 2  (0) 2023.02.28
Comments