구조분석
배열은 포인터와 동일한 방식으로 동작하며 배열의 이름은 배열의 원소의 첫번째 주소가 된다.
유일한 차이점이라고 한다면 포인터는 변수이며 배열의 이름은 상수이다.
#include <stdio.h>
int main(void){
int a = 10;
int b[10];
b = &a;
}
위 예제에서는 배열인 b에 a의 주소값을 넣어주겠다는 것인데 에러가 발생한다.
배열의 이름은 상수이기 때문에 변경할 수 없는데 a의 주소값으로 변경하겠다고 하니 에러가 발생하는 것이다.
하지만 반대로 포인털르 배열처럼 사용하는 것은 문제가 없다.
#include <stdio.h>
int main(void){
int a[5] = {1, 2, 3, 4, 5};
int *b = a;
printf("%d\n", b[2]);
}
이렇게 작성하게 된다면 a배열의 3번째 값인 3이 출력되게 된다.
a라는 배열을 포인터변수 b에 넣어주고 포인터 변수 b에서의 2번 인덱스의 값을 가져오라고 하니 포인터변수의 값인
a 배열의 값 중에서 2번인덱스의 값을 가져오는 것이다.
배열의 이름은 배열의 첫번째 원소의 주소이다.
#include <stdio.h>
int main(void) {
int a[5] = {1, 2, 3, 4, 5};
int *b = &a[0];
printf("%d\n", b[2]);
}
이 코드와 위의 코드의 차이점은 a를 주소값으로 불러왔는지 그냥 배열이름으로 불러왔는지의 차이다.
'배열의 이름은 배열의 첫번째 원소의 주소' 라는 말이 이 말이다.
배열의 이름을 써도 a배열의 0번인덱스의 주소가 되는 것이고 주소값으로 &a[0]으로 사용해도 똑같은 값을 찾는다는
것이다.
포인터는 연산을 통해 자료형의 크기만큼 이동한다는 특징이 있다.
따라서 int 포인터는 4byte씩 이동한다.
#include <stdio.h>
int main(void) {
int a[5] = {1, 2, 3, 4, 5};
int i;
for(i = 0; i < 5; i++){
printf("%d ", a + i);
}
}
위 코드를 출력하면 4만큼씩 증가하는 값을 확인할 수 있다.
출력문에서 *(a + i)로 바꿔준다면 값을 출력할 수 있게 되며 1 2 3 4 5 라는 결과값이 출력되는데 a[i]와 동일하다.
#include <stdio.h>
int main(void) {
int a[5] = {1, 2, 3, 4, 5}
int *p = a;
printf("%d\n", *(p++));
printf("%d\n", *(++p));
printf("%d\n", *(p + 2));
}
위 예제의 경우 1 3 5가 출력이 된다. 포인터 변수 p에 배열 a를 넣어주었다. p는 a[0]이 되는것이기 때문에 출력했을때
1이 나오게 되는데 첫 출력문에서는 p가 후치증가이기 때문에 1을 출력한 뒤에 p가 1증가하여 a[1]이 된다.
그 다음 출력문은 전치증가로 먼저 증가한다음 출력하기 때문에 a[2]의 값을 출력하게 되므로 3이 출력되고
마지막 출력문은 p에 2를 더한 뒤 출력하라고 했기 때문에 a[4]의 값을 출력하게 되고 5가 출력되는 것이다.
#include <stdio.h>
int main(void) {
int a[2][5] = { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10} };
int (*p)[5] = a[1];
int i;
for(i = 0; i < 5; i++){
printf("%d ", p[0][i]);
}
}
위 예제의 결과값은 6 7 8 9 10이다.
포인터 변수 p는 크기는 5이며 a배열의 1번 인덱스의 행 주소를 갖고 있게 된다.
a의 1번 행은 6, 7, 8, 9, 10이기 때문에 출력값 역시 6 7 8 9 10이 되는 것이며 출력시에는 이중포인터이기 때문에
p[0][i]로 처리해야 하는 것이다.
레퍼런스
패스트캠퍼스 올인원 패키지 - 소프트웨어 베이직