[자료구조] 구조체 & 포인터 개념

pkkheesun·2023년 10월 20일
0

자료구조

목록 보기
2/20

💡분명 다 이해하고 넘어간 것 같은데 다시 마주하면 헷갈리는 포인터&구조체 개념들 ^^,, 각각 이해하고 있어도 구조체 매개변수로 포인터가 들어가거나 하면 멈칫하게 되는 것 같다. 확실하게 정리하고 넘어가자.


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) 구조체 변수로 포인터를 사용하는 경우

포인터를 구조체의 멤버 변수로 쓰는 것이 아니라, 구조체를 가리키는 포인터를 사용하는 경우다.

(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); // 구조체 변수의 주소를 넘긴다
}

callByValue 함수에서 x와 y의 값을 변경해도 이는 복사한 값을 변경힌 것이기 때문에 실제 구조체 struct pos p의 x와 y의 값은 바뀌지 않는다. 마찬가지로 구조체의 복사본이 계속 늘어나서 스택 영역을 많이 잡아먹을 수 있다.

0개의 댓글