문자열과 배열 그리고 포인터의 관계
포인터 변수
- 포인터를 사용하기 위해서 포인터 변수를 먼저 선언 후 주소를 할당한다.
int a[10];
int *pa;
pa = &a[0];
// 이것은 아래와 같다
pa = a;
&a[0]
가 a
와 동치인 이유는 배열의 첫번째 요소의 시작주소와 배열의 주소가 같기 때문이다.
포인터 변수와 함수
- 매개변수의 원본 조작이 필요할때는 포인터 변수로 선언한다.
void swap (int x, int y) // 이렇게 선언하면 지역변수로만 활용된다.
void swap (int *px, int *py) // 이 선언은 원본 변수의 주소를 포인터로 받기 때문에 조작하면 원본이 변한다.
문자열과 포인터
- 흔히 아래 예시에서도 문자열이 인자로 들어간다.
printf("hello world\n");
// 배열의 표현
char amsg[] = "hello world\n";
char amsg[] = {'h','e','l','l','o',' ','w','o','r','l','d','\n'};
// 포인터 변수의 표현
char *pmsg;
pmsg = "hello world\n";
- 둘은 똑같이 문자열을 담는 변수다. 그러나 차이가 있다면.
- 배열은 선언시 배열의 크기를 지정해주거나 선언과 동시에 변수에 할당해야한다.
- 포인터 변수는 원하는 크기의 문자열을 할당할 수 있다.
문자열의 출력
write(1,pmsg, 12);
write(1,&amsg, 12);
printf("%s\n",pmsg);
printf("%s\n",&amsg);
- 포인터 문자열은 주소 그 자체기 때문에 변수명을 넣어주면 된다.
- 배열은 문자열을 참조시 배열의 주소를 넣어준다.
문자열이 요소인 배열
- 문자열이 요소인 배열은 문자열과 마찬가지로
- 배열의 크기를 미리 지정하거나
- 선언과 동시에 변수에 할당해야 한다.
// 미리 배열의 크기를 할당하는 방법
char *pmsgs[6];
pmsgs[0] = "January";
pmsgs[1] = "Feburary";
pmsgs[2] = "March";
pmsgs[3] = "April";
pmsgs[4] = "May";
// 선언과 동시에 변수를 할당하는 방법
char *pmsgs[] = {"January", "Feburary", "March", "April", "May"};
배열 요소의 출력
- 배열의 요소를 출력하는 방법은 크게 두가지 방법이 있다.
- NULL값을 넣어서 배열의 끝을 알리는 방법
- 배열의 크기를 먼저 구해서 사이즈 만큼 순회하는 방법
- NULL값을 넣어서 배열의 끝을 알리는 방법
char *pmsgs[] = {"January", "Feburary", "March", "April", "May", NULL};
- 그리고 포인터 변수를 포인터 변수로 할당받아 순회한다.(이중 포인터)
char **ptr = pmsgs;
while (*ptr) {
printf("--> %s\n", *ptr++);
}
- 문자열이 요소인 배열의 원소를 들여다 볼때는 원형의 2중 포인터를 할당한다.
- 그리고 할당받은 2중 포인터의 포인터로 순회한다. →
*ptr++
- 배열의 크기를 먼저 구해서 사이즈 만큼 순회하는 방법
- 이 방법은 원본 배열을 조작하지 않아도 되는 장점이 있다. 주로 42에서 쓰게 될 듯?
char *pmsgs2[] = {"January", "Feburary", "March", "April", "May"};
char **ptr2 = pmsgs2;
int pmsgs2size = sizeof(pmsgs2) / sizeof(char*);
- 배열의 크기를 계산한다. 분모에 들어가는 사이즈는 포인터로!
int cnt = 0;
while (cnt++ <= pmsgs2size && *ptr2)
{
printf("--> %s\n", *ptr2++);
}
cnt++ <= pmsgs2size
: 배열의 크기만큼 증가하며 순회한다. cnt
를 내부에서 사용해야 한다면 따로 빼서 조작하면 될 일*ptr2
: NULL
값이 오기 전까지 순회한다. → *ptr++