💡분명 다 이해하고 넘어간 것 같은데 다시 마주하면 헷갈리는 포인터&구조체 개념들 ^^,, 각각 이해하고 있어도 구조체 매개변수로 포인터가 들어가거나 하면 멈칫하게 되는 것 같다. 확실하게 정리하고 넘어가자.
c언어의 함수 매개변수 전달 방식: 값 전달 방식, 주소 전달 방식
구조체를 함수 매개변수로 전달했을 경우, 구조체의 원본이 아니라 복사본이 전달되기 때문에 함수 안에서 수정이 이루어져도 원본은 그대로다.
즉 원본에 대한 포인터를 전달하면 원본 수정이 가능하다.
call by reference의 장점 => 배열과 포인터의 연결
int array[] = int* array
✨함수 매개변수들이 늘어날수록 스택/메모리 공간을 필요로 하는데 이때 포인터는 주소를 넘겨주니까 낭비되는 공간을 줄일 수 있다.
📕구조체 배열
(1) 멤버 변수로 배열을 사용하는 구조체
typedef struct student
{
char name[100];
int class;
int score;
}Student;
int main()
{
Student stu = {"김철수, 2 ,100};
}
만약, 저장할 학생의 정보가 너무 많아진다면?
Student stu[x]={ {"김철수, 2, 100}, {"홍길동, 2, 50}, ,,, };
stu.name="홍길동";
-> 오류 발생!
구조체 student에서 선언된 name은 배열의 시작주소, 즉 &name[0]과 같다. 따라서 선언과 동시에 초기화하지 않으면 대입연산자로 문자열을 저장할 수 없기 떄문에 string.h에 있는 strcpy()를 사용해야 한다.
📕구조체와 포인터
(1) 구조체에서 멤버변수로 포인터를 사용하는 경우
<struct example
{
int* a;
int* b;
};
int main()
{
int x=1, y=2;
struct example ex;
ex.a=&x;
ex.b=&y;
}
참고로 구조체 변수의 시작주소는, 첫번째 멤버 변수의 주소로
&ex=&ex.a 이다.
포인터를 구조체의 멤버 변수로 쓰는 것이 아니라, 구조체를 가리키는 포인터를 사용하는 경우다.
(2 - 1) 구조체 변수를 포인터로 사용할때, 값에 의한 호출을 하는 경우
struct pos
{
int x;
int y;
};
void callByValue(struct pos call)
{
call.x-2;
call.y=3;
}
int main()
{
struct pos p = {1, 2};
callByValue(p);
}
struct pos
{
int x;
int y;
};
void callByValue(struct pos* p)
{
p->x=2; //(*p).x=2;와 같은 말이다.
p->y=3;
}
int main()
{
struct pos p = {1, 2};
callByValue(&p); // 구조체 변수의 주소를 넘긴다
}