삽질의 현장/- C

곱씹어보자 C!_#018_삽잡이의 두서없이 막말하는 잡다한 것들...

shovelman 2015. 6. 27. 22:51

- 연산자 *와 []


복습하며 까먹지 말아야 할 정리들을 잡다하게 올려봐야겠습니다.


포인터에 대해서 보고 있었는데... *와 []는 같은 기능을 한다고 합니다.

즉, * 주소 = 주소 []  와 같다는 것입니다.

이말은 곧... 

Out Parameter로써 주소값을 인자로 넘길 때에 인자를 받은 함수의 매개변수에 

대체적으로 자료형* 로 인자를 받는다는 것이죠...


1
2
3
4
5
6
7
8
9
10
11
12
void Input(char* sbuf)
{
//중략
}
 
main()
{
char* buf[100];
//중략
Input(buf);
//중략
}
cs


요런식으로 말입니다. 그런데 *와 []의 기능은 같으나,

관례적으로 연속한 메모리의 집합들을 참조할 때에는 []를 사용한다고 합니다.

음... 그러니까 "야... 연속한 메모리들의 집합들이 들어온다!" 이렇게 로봇연기를... 하하..


그렇다고 다른 차이가 있는 것은 아닙니다.

기억하실 것은 char* sbuf 와 char sbuf[] 는 같다는 것.


여기서 하나 더 말씀드리자면... 

위에서는 배열을 인자로 넘겼는데요, 

배열은 통째로 전달 할 수 없으니 시작주소를 전달해줘야합니다.

시작주소만 알려주면 연속되는 메모리로써 배열의 구석구석을 쑤시고 다닐 수 잇죠...


여담으로 매개변수에 이렇게 쓰는 것은 어떨까요?


vodi Input(char sbuf[100])


그렇다면 이것은 배열...?


매개변수에는 배열을 만들 수 없습니다. 즉, 이것은 그냥 위와 같은 포인터입니다.

숫자는 뭐 컴파일러가 알아보지도 못한다는... 



- 데이터 형식


char 변수의 주소를 담고 있는 변수 n의 데이터 형은 뭘까요?

char* 입니다.

int 변수의 주소를 담고 있는 변수 m의 데이터 형은 뭘까요?

int* 이죠...

그렇다면... 일반화 해보겠습니다.

T형식의 값을 담고 있는 주소는 T*의 주소를 가지고 있다고 할 수 있습니다.



-동적 메모리


프로그래밍 언어를 배우며 한번 이상씩은 듣는 데이터 저장...

프로그램 관점에서 데이터는 크게 3가지의 저장소를 가지고 있습니다.


1. Global Data 영역

2. Stack 영역

3. Heap 영역


그 중에서 동적 메모리와 관련된 영역은 바로 Heap 영역이죠...

1, 2 영역은 데이터를 미리 선언해야하지만,

Heap 영역 같은 경우에는 사용자가 필요한 시점에서 메모리를 할당 받고

필요한 시점에서 제거할 수 있다는 장점이 있죠.


예를 들어 생각해볼까요, 

우리가 컴퓨터에 저장해 놓은 사진들을 보려고 클릭 했다고 생각해보죠.

이미지 파일을 더블 클릭 따닥 하는 순간 각 크기에 맞게 출력되죠... 


이와 같이 미리 정해져있지 않고 필요한 시점에 메모리를 할당해주는... 

그런 동적메모리... 매력 있네요... 뭐라는건지 푸하하..


1
2
3
4
5
6
7
8
9
10
//중략
char buf[100];
char* s;
 
printf("문자열 입력:");
gets(buf);
 
= (char*)malloc(strlen(buf) + 1);
strcpy(s, buf);
//중략
cs


malloc은 좀 더 자세하게 말씀드리자면,

사용자가 요청한 사이즈의 메모리를 만들어서 그 시작주소를 건네주는 것입니다.


그렇기에 포인터 변수로 malloc에서 던져준 시작주소를 받는 것이죠.

그리고 포인터 변수의 자료형에 맞게 형변환을 해줘야합니다.

왜냐하면, malloc의 정의에는 반환형이 void* 이기 때문에 사용자에 맞게 형변환을 해줘야하는것이죠...


문자열은 buf 라는 배열에 입력 받고, 

buf사이즈 + 1 만한 크기의 동적 메모리를 할당 받아 

s 라는 int형 포인터 변수에 주소를 대입합니다.


왜 1만큼을 더 받을까요? 

문자열은 맨 뒤에 \0이 붙는 거 아시죠? 그렇기에 1을 추가시켜야 합니다.


그리고 왜 s = buf 가 안될까요?

s는 동적 메모리의 시작주소를 담고 있고, buf는 문자열의 시작주소를 담고 있습니다.

혹여나 s에 buf의 시작주소를 담는다고 쳐도...

그렇다면 동적메모리의 시작 주소는 미아가 되어버리기 때문에 

곤란해집니다...


아무튼... strcpy() 함수를 통해 buf에 있는 문자열을 복사해옵니다.

그리고 위의 코드에는 없지만 동적 메모리 사용이 다 끝나면,

free() 함수를 통해 만들어 놓은 동적 메모리를 삭제해야한다는 사실!


다쓴 메모리는 정리해줘야죠... 안그러면 낭비~


위에서 말씀드린 것과 같이 

동적 메모리를 사용자의 필요에 의해 생성하고 삭제할 수 있는 장점을 확인 할 수 있었습니다.