본문 바로가기

CS/자료구조

[인프런|10강] C로 배우는 자료구조 | 전화번호부 v5.0 (1)

전화번호부 v5.0 (1)

구조체에 대한 포인터, 동적 메모리 할당

구조체 배열

v4.0에서 구조체를 배열로 사용하였다. 배열 각 칸에 name, number 등 등 여러 변수가 저장된다.

 

 

함수 호출 과정에서 매개변수의 복사
return되는 변수

 

함수를 호출할 때 넘겨주는 매개변수를 실질매개변수라고한다.

호출되는 함수에서 넘겨받는(복사되는) 매개변수를 형식매개변수라고 한다.

'함수 호출 과정에서 매개변수의 복사' 그림에서
void status()에서 print_person(directory[i])를 부를 때 directory[i]실질매개변수가 되며
void print_person(Person pp형식매개변수가 여기서 실질매개변수가 형식매개변수로 복사가 되어서 사용된다.

그러므로 구조체 배열로 선언하여 넘겨주고 받게되면 매번 함수를 호출할때마다 구조체의 항목(멤버)들을 일일이 복사해주어야한다. 구조체의 항목들이 많다면 복사해야하는 데이터가 많아지게되고 그런 일은 컴퓨터 자원을 많이 쓰게 만들어 성능이 떨어질 수 밖에 없다.

 

이런 일은 매개변수에서만 발생하는게 아니라 'return되는 변수' 그림처럼 return 될때에도 마찬가지로
Person thePerson = get_person("John")

Person get_person(char * name) 에서 return 되는 directory[i] 값이 임시 객체)(치환문 속 getperson("John"))에 복사가되고 
임시 객체(치환문 속 getperson("John"))에서 최종적으로 thePerson변수 에게로 복사된다. 

복사가 총 2번 발생한다. 이런 일이 구조체 모든 멤버에 적용되므로 역시나 프로그램 성능이 떨어지게된다.

 

전화번호 프로그램 속 add(), remove() 함수에서도 마찬가지로 전화번호 구조체(이름, 번호, 메일, 그룹) 이 추가 삭제 될때마다 배열 공백이 없게 정렬을 함에 있어서 매번 구조체 멤버들의 복사가 일어난다. 마찬가지로 프로그램 성능을 떨어트린다.

 

 

v4.0의 Person dicrectory[] 에서 v5.0은 Person *directory[] 로 구조체 포인터로 쓰인다.

 

 

void status()에서 print_person(directory[i]) 를 호출할 때 

 print_person(Person p)의 형식매개변수 p포인터변수인 실질매개변수 directory[i](i는 특정 값) 가 가르키는 변수를 p도 가르키게 된다.  구조체배열일떄는 실질매개변수의 모든 멤버들을 복사하여 형식매개변수로 넘겨주었지만

포인터를 사용하게되는 경우 실질매개변수가 가르키는 변수의 주소값만 복사해서 형식매개변수로 넘겨주게 되어서 프로그램에 부하가 덜 가게된다.

 

 

void print_person(Person *p) 함수에서 (*p).name 과 같은 식으로 포인터를 사용하였다. *포인터 연산자보다 . 연산자 우선순위가 더 높기 떄문에 ()를 써서 (*)로 표현해주어야한다.

이렇게 쓰면 프로그래밍 중 헷갈릴 수 있다.

C언어에서는 포인터변수로 "->" 화살표 연산자를 제공해 준다.

그래서  (*p).name 를 p->name로 표현 할 수 있다.

 

구조체 자체를 쓰는 것이 아니라 구조체에 포인터를 사용하여 복사되는 데이터의 양을 줄인다.

V4.0 구조체 배열 사용
V5.0 구조체 포인터 사용