본문 바로가기
Language&Framework&Etc/C

구조체와 사용자 정의 자료형2(23-2) 함수로의 구조체 변수 전달과 반환

by 머리올리자 2020. 12. 13.

구조체 변수를 함수의 인자로 전달하거나 함수 내에서 return문을 통해서 구조체 변수를 반환하는 경우에 발생하는 모든 현상은 int형 변수를 인자로 전달하거나 int형 변수를 반환하는 경우에 발생하는 현상과 완전히 동일하다.

포인터 변수를 구조체의 멤버로 선언하기

다음 코드를 실행하게 되면, 인자로 전달되는 변수의 값은 매개변수에 복수

void simplefunc(int num){....}
int main(void)
{
	int age = 24;
	simplefunc(age); // age에 저장된 값이 매개변수 num에 전달(복사)
}

 

함수의 인자로 구조체 변수가 전달될 수 있으며, 이러한 인자를 전달받을 수 있도록 구조체 변수가 매개변수의 선언으로 올 수 있다.

 

전달되는 구조체 변수의 값은 매개변수에 통째로 복사가 된다.

 

예제.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct point
{
	int xpos;
	int ypos;
}Point;

void showposition(Point pos) // Point pos = curpos
{
	printf("[%d %d] \n", pos.xpos, pos.ypos);
}

/* Point 구조체 변수 cen을 반환하는 함수 */
Point getcurrentposition(void)
{
	Point cen;
	printf("Input current pos: ");
	scanf("%d %d", &cen.xpos, &cen.ypos);

	return cen;
}


int main(void)
{
	Point curpos = getcurrentposition(); // 함수가 반환하는 값으로 구조체 변수 curPos 초기화
	showposition(curpos); // 함수를 호출하면서 변수 curpos를 인자로 전달하고 있다.
	return 0;
}

구조체의 멤버로 배열이 선언되어도 위 예제에서 보인 것과 동일한 형태의 복사가 진행된다.

 

즉 인자의 전달 과정에서, 그리고 값의 반환과정에서 구조체의 멤버로 선언된 배열도 통째로 복사가 된다.

 

예시

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct person
{
	char name[20];
	char phonenum[20];
	int age;
}Person;

void showpersoninfo(Person man) 
{
	printf("name: %s \n", man.name);
	printf("phone: %s \n", man.phonenum);
	printf("age: %d \n", man.age);

}

Person readpersoninfo(void)
{
	Person man;
	printf("name? "); scanf("%s", man.name);
	printf("phonenum? "); scanf("%s", man.phonenum);
	printf("age "); scanf("%d", &man.age);

	return man;
}


int main(void)
{
	Person man = readpersoninfo(); 
	showpersoninfo(man); 
	return 0;
}

구조체 변수를 대상으로 하는 call-by-reference

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct point
{
	int xpos;
	int ypos;

}Point;

void orgsymtrans(Point* ptr)
{
	ptr->xpos = (ptr->xpos) * -1;
	ptr->ypos = (ptr->ypos) * -1;
}

void showposition(Point pos)
{
	printf("[%d %d] \n", pos.xpos, pos.ypos);
}

int main(void)
{
	Point pos = { 7, -5 };
	orgsymtrans(&pos); // pos의 값을 원점 대칭이동
	showposition(pos);
	orgsymtrans(&pos); // pos의 값을 원점 대칭이동
	showposition(pos);
	return 0;
}

구조체 변수를 대상으로 가능한 연산

구조체 변수를 대상으로는 제한된 형태의 연산만 허용

  • 대입 연산
  • sizeof 연산
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct point
{
	int xpos;
	int ypos;

}Point;

int main(void)
{
	Point pos1 = { 1, 2 };
	Point pos2;
	pos2 = pos1; // pos1의 멤버 대 pos2의 멤버간 복사가 진행됨

	printf("크기 : %d \n", sizeof(pos1)); // pos1의 전체 크기 반환
	printf("[%d, %d] \n", pos1.xpos, pos1.ypos);

	printf("크기 : %d \n", sizeof(pos2)); // pos2의 전체 크기 반환
	printf("[%d, %d] \n", pos2.xpos, pos2.ypos);
}

실행결과를 통해서 구조체 변수간 대입연산의 결과로 멤버 대 멤버의 복사가 이뤄짐

 

"덧셈이나 뺄셈도 가능?"

 

Point 구조체만 놓고 보면 구조체 변수를 대상으로도 덧셈이나 뺄셈이 가능할 것 같음

하지만 구조체 안에는 배열도 존재할 수 있고 포인터 변수도 존재할 수 있다.

뿐만 아니라 다른 구조체의 변수도 존재할 수 있다.

 

따라서 구조체 변수 대상의 덧셈과 뺄셈연산의 결과를 정형화 하는데 무리

 

그럼 구조체 변수를 대상으로 덧셈이나 뺄샘을 하려면?

 

아래의 예제로 참고

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct point
{
	int xpos;
	int ypos;

}Point;

Point add(Point pos1, Point pos2)
{
	Point pos = { pos1.xpos + pos2.xpos, pos1.ypos + pos2.ypos };
	return pos;
}

Point min(Point pos1, Point pos2)
{
	Point pos = { pos1.xpos - pos2.xpos, pos1.ypos - pos2.ypos };
	return pos;
}

int main(void)
{
	Point pos1 = { 5, 6 };
	Point pos2 = { 2, 9 };
	Point result;

	result = add(pos1, pos2);
	printf("[%d %d] \n", result.xpos, result.ypos);

	result = min(pos1, pos2);
	printf("[%d %d] \n", result.xpos, result.ypos);
}

 

참고 : [윤성우 열혈 C 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.