[C++] 함수, 구조체

happyyeom·2025년 7월 7일

void

void는 그냥 아무것도 없는것이 아니라 형식이 없음을 나타낸다. 그래서 void value와 같이 변수를 선언할 수 없는것이다.
void는 3가지 상황에서 사용하는데 첫 번째는 함수가 값을 반환하지 않을 때,

void print_func(){
	std::cout << "func" << std::endl;
    }

두 번째는 매개 변수가 없음을 표시할 때이다. 물론 함수의 매개변수가 없으면 ()빈괄호로 두어도 되지만 void print_func(void)처럼 명시적으로 나타낼수도 있다.
3번째는 제네릭 포인터를 만들 때 사용한다. 제네릭 포인터에서 void는 단순히 형태가 없음을 의미하기보다 형태가 자유로움을 의미한다.

int int_value;
float float_value;
void *ptr_value;
ptr_value = &int_value;
ptr_value = &float_value;

포인터를 매개변수로 사용하기

매개변수의 값을 음수로 만드는 코드

#include <iostream>

void change_negative(int value) {
	if (value > 0) {
		value = -value;
	}
}

int main() {
	int a = 3, b = -3;

	std::cout << "a : " << a << std::endl;
	std::cout << "b : " << b << std::endl;

	change_negative(a);
	change_negative(b);

	std::cout << "change_negative(a) : " << a << std::endl;
	std::cout << "change_negative(b) : " << b << std::endl;

	return 0;
}

출력결과
a : 3
b : -3
change_negative(a) : 3
change_negative(b) : -3

위의 코드를 보면 우리가 기대한 값은 a의 값을 음수로 바꾸어 -3이 출력되는 것을 기대했지만 출력값은 3이 그대로 출력되었다. 이유는 매개변수인 value가 함수 내부에서만 효력이 있는 지역변수이기 때문이다. 물론 return값을 만들고 그 값을 다시 a에게 집어넣으면 해결되지만 이러한 문제를 해결하기 위해 포인터를 매개변수로 활용할 수 있다.

#include <iostream>

void change_negative(int *value) {
	if (*value > 0) {
		*value = -(*value);
	}
}

int main() {
	int a = 3, b = -3;

	std::cout << "a : " << a << std::endl;
	std::cout << "b : " << b << std::endl;

	change_negative(&a); //주소연산자를 이용해 a의 주소값을 전달
	change_negative(&b); //주소연산자를 이용해 b의 주소값을 전달

	std::cout << "change_negative(a) : " << a << std::endl;
	std::cout << "change_negative(b) : " << b << std::endl;

	return 0;
}

main하무에서는 인자로 넘기는 a,b를 값을 넘기는 대신 &주소 연산자를 이용해 주소를 전달했고 change_negative함수에서는 포인터 변수 value앞에 *역참조 연산자를 사용해 포인터 변수가 가리키는 데이터에 직접 접근할 수 있도록 만들었다. 결과를 보면 저장된 값이 모두 음수로 바뀐 것을 확인할 수 있다.

비슷한 방식으로 배열도 함수의 매개변수로 사용하여 여러 개를 한 번에 전달할 수 있다. 배열은 그 변수이름이 자체로 포인터와 유사한 역할을 하므로 배열에 저장된 데이터에 직접 접근한다.

구조체

struct 키워드를 이용해 여러가지 형식의 데이터를 하나로 묶어서 관리할 수 있다. 아래는 Person이라는 구조체를 선언한 예이다.

struct Person{
	std::string name;
    int age;
    float height;
    float weight;
    }

변수는 Person adult라는 방식으로 변수를 생성하는데 그 안의 세부 데이터에 접근하려면 adult.age처럼 .연산자를 사용하여야 한다.
위에서도 말했듯 주소를 전달하는 이유는 구조체를 함수에 전달했을 때, 복사본이 전달되므로 구조체가 매우 크다면 성능 문제가 발생할 수 있다.
그래서 복사본 대신 구조체에 대한 포인터(주소)를 전달하면 해결할 수 있다.

void check_age(Person *adult){~}

int main(){
	check_age(adult) //구조체 배열의 시작 주소
}

구조체 초기화는

Person adult = {"Brain", 24, 180, 70};
//단일 구조체일 경우

Person adult[3] = {
	{"Brain", 24, 180, 70},
    {"Brain", 24, 180, 70},
    {"Brain", 24, 180, 70},
    {"Brain", 24, 180, 70},
}
//구조체 배열일 경우

이렇게 하면 된다.

profile
🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳

0개의 댓글