공부를 하는 입장이기 때문에, 내용에 오류가 있을 수 있습니다. 오류가 있다면 적극적으로 알려주시면 감사합니다!
Struct
데이터들을 관리하는데 연관성이 있는 데이터들은 그룹으로 묶어서 관리하면 편하지 않을까? 라는 생각에서 나온 개념이 구조체 이다.
구조체의 기본적인 형태는 다음과 같다.
struct point{
...
};
struct point p1;
struct point p2;
========================
typedef struct point {
...
}POINT;
POINT p1;
구조체 변수의 멤버에 접근하기 위해서는 dot(.)연산자 사용한다.
p1.~ 과 같이 접근할수 있고, 선언과 함께 초기화를 할 수 있다.
#include <iostream>
struct __point
{
double xPos;
double yPos;
};
typedef struct __point point;
point IncrePos(point pnt) {
pnt.xPos++;
pnt.yPos++;
return pnt;
}
int main(void) {
point p1, p2, p3;
p1.xPos = 0.5;
p1.yPos = 1.5;
p2 = p1;
p3 = IncrePos(p2);
std::cout <<"p1 "<< p1.xPos << " " << p1.yPos << std::endl;
std::cout << "p2 " << p2.xPos << " " << p2.yPos << std::endl;
std::cout << "p3 " << p3.xPos << " " << p3.yPos << std::endl;
return 0;
}
위 코드는 구조체와 typedef 선언에 대한 간단한 예제이다. __point라는 구조체를 선언하고, 이를 point라는 새로운 사용자 타입을 만들어 준다. 이를 통하여 새로운 타입인 point를 반환하는 함수를 만들어 주었다.
p1을 초기화 하는 변수이고, p2는 p1을 복사한 값이다. 마지막으로 p3는 p2를 함수에 넣은 값이다.
이를 보고 한가지 개념을 더 알 수 있다.
Call-by-value, Call-by-reference
Call by value란 함수 호출 시 넘기는 인자의 값이 매개변수에 복사(Copy)돼서 함수 내에서 매개변수에 직접적인 데이터 조작을 가해도 인자에 전혀 영향을 주지 않는 것이다.
- 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다. (c++의 경우 stack frame) 함수가 종료되면 해당 공간은 사라진다.
- 스택 프레임(Stack Frame) : 함수 호출시 할당되는 메모리 블록(지역변수의 선언으로 인해 할당되는 메모리 블록)
- call-by-value 값에 의한 호출방식은 함수 호출시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.
- 복사된 인자는 함수 안에서 지역적으로 사용되는 local value의 특성을 가진다.
Call by reference란 말 그대로 참조값으로 함수를 호출했단 뜻이다.
- 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다. (예: stack frame) 함수가 종료되면 해당 공간은 사라진다.
- call-by-reference 참조에 의한 호출방식은 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가르킨다.)
- 따라서 함수 안에서 인자의 값이 변경되면, argument로 전달된 객체의 값`도 함께 변경된다.
따라서 이전 코드는 call by value이다. 따라서 p2의 값은 증가하지 않는 것이다. 이를 call by reference로 바꿔보면 다음과 같다.
#include <iostream>
struct __point {
double xPos;
double yPos;
};
typedef struct __point point;
void IncrePos(point* pnt) {
pnt->xPos++;
pnt->yPos++;
}
int main(void) {
point p1, p2, p3;
p1.xPos = 0.5;
p1.yPos = 1.5;
p2 = p1;
IncrePos(&p2); // p2의 주소를 전달하여 값 변경
p3 = p2;
std::cout << "p1 " << p1.xPos << " " << p1.yPos << std::endl;
std::cout << "p2 " << p2.xPos << " " << p2.yPos << std::endl;
std::cout << "p3 " << p3.xPos << " " << p3.yPos << std::endl;
return 0;
}
실행결과를 살펴 보면 이전 코드와 완전하게 대치된다고는 할 수 없지만, p2의 값이 변한 것을 확인 할 수 있다.
Const
마지막으로 const는 우리가 알고 있듯이 상수로 지정해 주는 역할을 한다. const는 포인터에도 사용할 수 있다. 이 부분이 굉장히 헷갈리는데, 외우지 말고 천천히 생각해 보면 알 수 있다.
빨간색 부분이 에러이다. 위에는 포인터의 변수 값(주소의 값)을 상수로 정하는 것이다. 따라서 주소를 바꿀 수 있어도, 주소의 값을 바꿀 수는 없다.
아래는 포인터 값*주소)를 상수로 지정하는 것이다. 따라서 주소의 값을 바구더라도 지정하는 주소를 바꿀 수 없다. 또한 둘 다 상수로 지정하고 싶으면 둘다 const로 놓으면 된다.
'c++' 카테고리의 다른 글
[c++] Range-based for loop (범위 기반 for 문) (1) | 2024.04.25 |
---|---|
04. C++만의 특징 2 (0) | 2024.01.14 |
02. C++만의 특징 1 (0) | 2024.01.03 |
01. C++의 구조 (0) | 2024.01.03 |
00. 첫글! (0) | 2023.12.26 |