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
주소: 서울시 용산구 한남동

매개변수로 값이 전달될 때 구조체 멤버가 모두 복사되었으므로 구조체 멤버를 아무리 변경해봐야 바깥에 있는 구조체 변수에는 영향을 미치지 않습니다.