65 함수에서 구조체 매개변수 사용하기
함수에 전달해야 할 매개변수가 이름, 나이, 전화번호, 우편번호, 주소처럼 많을 때는 어떻게 해야 할까요?
void printPerson(char *name, int age, long long phoneNumber, int postalCode, char *address)
이렇게 작성하면 코드도 길어지고 너무 복잡해집니다. 이럴 때는 관련 정보를 구조체로 묶어서 매개변수로 전달하면 일이 간단해집니다.
void printPerson(struct Person p)
참고로 함수의 구조체 매개변수는 문법이 복잡하고 내용이 다소 어려울 수 있습니다.
65.1 구조체 매개변수 사용하기
함수에서 구조체를 매개변수로 사용하려면 ( ) (괄호) 안에서 struct 키워드와 구조체 이름으로 매개변수를 지정해줍니다.
반환값자료형 함수이름(struct 구조체이름 매개변수) { }
다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.
parameter_struct.c
#define _CRT_SECURE_NO_WARNINGS // strcpy 보안 경고로 인한 컴파일 에러 방지 #include <stdio.h> #include <string.h> // strcpy 함수가 선언된 헤더 파일 struct Person { char name[20]; int age; char address[100]; }; void printPerson(struct Person p) // 반환값 없음, 구조체 매개변수 한 개 지정 { // 구조체 매개변수 멤버의 값 출력 printf("이름: %s\n", p.name); // 이름: 홍길동 printf("나이: %d\n", p.age); // 나이: 30 printf("주소: %s\n", p.address); // 주소: 서울시 용산구 한남동 } int main() { struct Person p1; strcpy(p1.name, "홍길동"); p1.age = 30; strcpy(p1.address, "서울시 용산구 한남동"); printPerson(p1); // 함수를 호출할 때 구조체 변수 전달, 멤버가 복사됨 return 0; }
실행 결과
이름: 홍길동 나이: 30 주소: 서울시 용산구 한남동
함수를 작성할 때 void printPerson(struct Person p)와 같이 구조체를 매개변수로 지정했습니다. 그리고 함수 안에서는 구조체 매개변수 멤버의 값을 출력합니다.
void printPerson(struct Person p) // 반환값 없음, 구조체 매개변수 한 개 지정 { // 구조체 매개변수 멤버의 값 출력 printf("이름: %s\n", p.name); // 이름: 홍길동 printf("나이: %d\n", p.age); // 나이: 30 printf("주소: %s\n", p.address); // 주소: 서울시 용산구 한남동 }
함수를 호출할 때 구조체 변수를 넣어주면 구조체 변수의 모든 멤버가 매개변수로 복사됩니다. 단, 구조체 크기가 커지면 복사할 공간이 그만큼 더 필요하게 되므로 공간이 낭비되어 비효율적입니다. 보통 매개변수로 구조체를 전달할 때는 포인터를 활용하는 것이 좋습니다.
int main() { struct Person p1; strcpy(p1.name, "홍길동"); p1.age = 30; strcpy(p1.address, "서울시 용산구 한남동"); printPerson(p1); // 함수를 호출할 때 구조체 변수 전달, 멤버가 복사됨 return 0; }
함수에 구조체를 넘겨줄 때 복합 리터럴을 사용하면 구조체 변수를 따로 선언하지 않아도 됩니다.
- (struct 구조체이름) { .멤버이름 = 값1, .멤버이름2 = 값2 }
- (struct 구조체이름) { 값1, 값2 }
compound_literal_struct.c
#include <stdio.h> struct Person { char name[20]; int age; char address[100]; }; void printPerson(struct Person p) { printf("이름: %s\n", p.name); printf("나이: %d\n", p.age); printf("주소: %s\n", p.address); } int main() { // 복합 리터럴 방식으로 구조체를 넘겨줌 printPerson((struct Person) { .name = "홍길동", .age = 30, .address = "서울시 용산구 한남동" }); // 복합 리터럴 방식으로 구조체를 넘겨줌. 멤버 이름 생략 printPerson((struct Person) { "고길동", 40, "서울시 서초구 반포동" }); return 0; }
다음과 같이 함수 안에서 매개변수로 받은 구조체 멤버의 값을 변경해도 함수 바깥에는 영향을 미치지 않습니다.
parameter_struct_set_value.c
#define _CRT_SECURE_NO_WARNINGS // strcpy 보안 경고로 인한 컴파일 에러 방지 #include <stdio.h> #include <string.h> // strcpy 함수가 선언된 헤더 파일 struct Person { char name[20]; int age; char address[100]; }; void setPerson(struct Person p) // 반환값 없음, 구조체 매개변수 한 개 지정 { // 매개변수로 받은 구조체 멤버의 값 변경 strcpy(p.name, "고길동"); p.age = 40; strcpy(p.address, "서울시 서초구 반포동"); } int main() { struct Person p1; strcpy(p1.name, "홍길동"); p1.age = 30; strcpy(p1.address, "서울시 용산구 한남동"); setPerson(p1); // 함수를 호출할 때 구조체 변수 전달, 멤버가 복사됨 // setPerson에서 변경한 값은 영향을 미치지 않음 printf("이름: %s\n", p1.name); // 이름: 홍길동 printf("나이: %d\n", p1.age); // 나이: 30 printf("주소: %s\n", p1.address); // 주소: 서울시 용산구 한남동 return 0; }
실행 결과
이름: 홍길동 나이: 30 주소: 서울시 용산구 한남동
매개변수로 값이 전달될 때 구조체 멤버가 모두 복사되었으므로 구조체 멤버를 아무리 변경해봐야 바깥에 있는 구조체 변수에는 영향을 미치지 않습니다.