마지막 6주차
포인터!
지금까지 변수를 선언해 메모리 공간에 정보를 저장하고 변수를 통해 접근하였다.
하지만 변수는 변수가 선언된 블록이나 함수를 벗어나면 사용이 불가능
-> 이젠 변수가 위치한 메모리의 주소를 사용해 데이터에 접근할 수 있는 포인터에 대해 배운다.
메모리의 주소
메모리에 저장된 데이터에 접근하려면 해당 데이터의 메모리 주소를 알아야 한다.
메모리의 주소는 바이트 단위로 구분되며 예를 들어 int 형 변수 a가 메모리 주소 0번지 부터 할당되었다면 0 ~ 3까지 4 바이트의 메모리 공간이 변수 a이다.
& 연산자를 사용하면 변수의 메모리 주소 (시작 주소)를 알 수 있다.
--> 위의 예에서 &a 는 0이다.
포인터와 간접 참조 연산자
포인터는 아래와 같이 선언한다
int *p;
// 자료형 * 변수명;
자료형은 포인터가 주소를 저장하는 변수의 자료형을 사용한다.
포인터 또한 변수 이므로 메모리에 공간을 확보하고, 포인터가 가리키는 변수의 시작 주소를 저장할 수 있다.
pa = &a;
-> pa 라는 포인터 변수에 변수 a의 시작 주소를 저장한다. 이러한 경우 "포인터 pa가 변수 a를 가리킨다"고 표현하고 pa -> a로 간단히 적을 수 있다.
이젠 a를 가리키는 포인터 pa를 통해 변수 a를 직접 사용할 수 있다. 이때 포인터에 간접 참조 연산자 * 를 사용한다.
다시말해,
*pa == a; // true
*pa = 10; // 변수 a에 10 대입
포인터는 주소를 저장하는 메모리의 공간
--> 포인터 = 변수, 주소 = 상수
따라서, 포인터가 가리키는 변수가 달라질 수 있다.
즉, 아래와 같은 코드를 작성할 수 있다.
double a, b;
double *p;
*p = &a;
*p = &b; // a를 가리키던 p가 이젠 b를 가리킴
주소와 포인터의 크기
포인터의 크기는 가리키는 변수의 자료형과 상관이 없다.
저장할 주소의 크기와 같기 때문! (시작 주소)
흠 그러면 도대체 왜 포인터에 가리키는 변수의 자료형을 명시하는가 하는 의문이 듦과 동시에 간접 참조 연산자로 데이터를 읽어올 때 메모리 주소 몇간을 읽어 와야 하는가를 컴파일러에게 알려주기 위해서인가 하는 생각이 들어서 조사를 해보았다.
-> 그러니까 명시된 자료형의 크기만큼 메모리를 읽어 와야 하기 때문이 아닌가?
맞는듯하다
출처: https://ko.wikipedia.org/wiki/C_(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4)
이렇게 생각하니 아래의 포인터의 대입 규칙 또한 자연히 이해가 되었다.
규칙 1. 포인터는 가리키는 변수의 형태가 같을 때에만 대입해야 한다.
규칙 2. 형 변환을 사용한 포인터의 대입은 가능하다.
[선택 미션]
출력:
+ 회고
지금까지 혼자서 c언어를 복습하려고 여러번 시도했지만 매번 실패하였다。
항상 어설프게 이해하고 책 한권 완독하지 못했다。
물론 혼공단 활동으로 c언어 교재를 전부 공부하지는 않았지만 이제는 혼자 할 수 있지 않을까 하는 자신감도 든다。
족장님께서 격려해주시고 매번 댓글도 달아주시니 매주 게시글을 작성할 힘이 났다。글을 써야 하니 더 꼼꼼히 공부하게 될 뿐만 아니라 누군가와 함께 공부하는 기분¡ (왜 느낌표가 거꾸로 달리는지¿)¿¿¿¿ <- 얘는 왜 이러는지
아무튼 다들 고생하셨고、 족장님도 고생 하셨습니다。
남은 교재 진도는 스스로 헤쳐 나가겠습니다。
다들 화이팅¡¡¡¡¡¡¡¡