2013년 1월 19일 토요일

포인터 연산

안녕하세요.

이번포스트는 포인터의 증가감소연산을 알아 볼텐데요.

우선 포인터에 대한 증가감소가 가능한 코드들을 알아 볼게요.

int main(void)
{
int t=10;
int *ptt=t;
int *ptt1=....;
ptt++;
ptt += 3;
ptt -= 3;
ptt1 += ptt;
ptt1= ptt+10;
등등
}
보시다시피 증가감소는 다 사용할 수 있다고 할 수 있습니다.

그런데 이 때, 연산의 결과는 어떨까요.

실험으로 알아보겠습니다.

포인터ptt선언 밑 초기화 %p로 주소값 출력.

%d 였다면 9 11 이라는 값이 출력했겠지만 %p(주소는 자료형의 사이즈간격으로 되있다.)라서 자료형사이즈 x n이 되는 겁니다.


다 이해하셨으리라 믿고 이 포스트를 마치겠습니다.

2013년 1월 13일 일요일

포인터로 이뤄진 배열을 알아보자!

1.포인터

포인터라는 것은 주소 값을 저장하려는 목적으로 쓰입니다.

여기서 주소란 메모리 주소인데요. 즉, 1바이트 메모리의 단위를 하나의 주소 값이 할당되고 그 할당된 주소를 저장하려는 목적으로 만들어진 함수가 바로 포인터라는 것입니다.

포인터란 것을 처음 아신 분은 주소는 어떻게 표현할까 라는 의문점이 생길수도 있습니다.

우선 작은 예를 들자면 int형 변수 Num의 주소는 0x12ff76~Ox12ff79(16진수)가 int형 변수입니다.

왜 주소가 4개이냐면 int는 4바이트이기 때문입니다. 주소 변경은 16진수이고 맨 뒤에 숫자가 하나씩늘어나는 것입니다.

자 이제 포인터를 쓰는 예를 보여드리겠습니다.






딱히 걸고 넘어갈 것은 없구요.
결과창을 보면 첫 줄, 둘 째줄에 1번 결과들은 첫 번째 짤에서 설명 가능합니다.
두 번째 칸들도 글로 설명했죠. int함수의 주소(제가 스샷 찍었을 때는 몰랐는데 %d를 %p로 하면 16진수 주소들이 정확히 나오더라구요. 참고하세요~)라고.

참! 까먹었었는데 프린트함수에서 포인터함수를 *을붙여서 출력하게 되면 그 문에서 그 포인터함수가 저장하고 있던 값을 그대로 내뱉습니다. *를 붙이지 않으면 

그리고 별로 도움은 안되지만 포인트함수의 선언 방법을 알려드릴게요.


int* pt
int *pt
int*  pt

int * pt


int  *pt
int*   pt
int *  pt
int  * pt
int   *pt
.
.
.
.
.
.
보시다시피 *만 포인터함수 앞에 붙여두면 됩니다.

더 나가서, 리턴문에서의 포인터함수 사용법과 널 포인터를 언급하겠습니다.

리턴문에서의 사용법
리턴문(return *ptender;)에서는 이 문장(return *ptender;)을 통해 값을 반환하려면 pt가 가리키는 메모리 공간에 접근을 해서 값을 읽혀져야 합니다.

그 때, pt는 크기 값으로 읽혀져야 하나 아니면 데이터에 저장되있는 수로 읽혀져야 하느냐에서 의견이 갈릴 수 있습니다.

그런데 위에 두 갈등은 return문만 가지고는 풀리지 않습니다.

그리고 pt의 정보가 필요합니다. 그니까 위에 실험에서와 같이
int t=10;
int *pt=&t;
이렇게 pt가 가리키면 리턴문(return *pt;)에서의 pt는 저장되있던 int자료형의 크기,주소 순서로 읽혀져 마지막엔 10이라는 저장되있던 정수로 해석이 된다.

이를 좀 고쳐서 double t=10으로 했다면 리턴문은 실수로 해석이 된다.

널 포인터
널 포인터라는 것은 int *pt=NULL;이라는 문장에서 *pt인데 사실 NULL은 0을 표현하는 함수입니다.

그럼 저 문장은 주소가 0인곳을 가리키는 것일까요? 절대 아닙니다.

아무주소도 가리키지 않는 것입니다.

포인터로 이뤄진 배열

드디어 포인터와 배열인데요. 시간 정말 많이 까먹었습니다. 워낙 이해하는데 오래걸려서 ..

arr(배열함수)과 pt(point tender 즉, 포인트함수)의 차이부터 알아봅시다.


비교조건\
\비교대상
포인터 변수
배열의 이름
이름 존재
나타내는 것과
저장 가능
메모리의 주소 값
메모리의 주소 값
주소 값의
변경이 가능
가능
불가능
이 표가 사실인지 확인해보겠습니다.




여기서 보여드리지 못한것이 9번줄의 arr=&arr인데요.
그 문장을 주석해제하면 에러가 뜹니다.
즉, arr함수는 주소값을 변경 가능하지 않는다는거죠.
(오랜만에 코드 만들어보니까 아주 엉망이네요. 8번 째 줄에 arr[0]입니다.)

이번에는 배열을 대상으로 하는 포인터 연산 (*연산)을 알아봅시다.

위 파란글씨문장 을 짧게 1차원 배열이름의 포인터라고 하는데, 그래도 기네요.

아무튼 1차원 배열이름의 포인터 사용법을 작은 예로 보여드리자면,.



*tender[n]으로 n번의 요소를 표현할 수 있습니다.
저는 그냥 귀찮아서 배열함수만 쓰고 1번 요소만 보여드린겁니다.

위의 코드들을 해석하자면

5,6 줄에서 보시면 텐더 배열함수를 각각 선언했는데, 배열함수는 배열함수 자체가 포인터이기 때문에, 배열함수를 따로 포인터함수로 가리키지 않고 배열함수 이름만으로 포인터함수를 가리킬 수 있습니다.

그래서 8,9번 줄에 따로 포인트 함수를 선언 가리킴 없이도 포인터함수가 가능했던 것이구요.



대충해서 죄송하구요.
시간이 오래걸려서인지 의욕도 떨어지고, 정신적으로도 약간 멘붕이 오네요.
사실 뭐 보러오는 사람도 없는데 열심히 해봤자 시간만 더 까먹으니깐 상관은 없겠죠.
여기서 포스팅 마칠게요~