위의 두 경우 모두 다 동일하다.
포인터를 사용했을 때와는 달리 배열 표기법은 어떤 인덱스의 데이터를 변경하고자 할 때, 전에 정해졌던 데이터 크기 그대로 한 번에 수정이 된다. 위 그림에서 0x78만 0x22로 바꿀 수 없는 것이다.
data[0] = 0x22; // 1
*(data + 1) = 0x22; // 2
2의 경우, 인덱스에 곧바로 접근해 한 번의 연산으로 끝나는 배열 표기법(1의 경우)과는 다르게 주소 지정 연산자 와 + 연산자 2개로 나뉘어져 있다. 2의 코드를 보면 주소 지정에 들어가기 전에 캐스팅 (char )을 걸어서 (data + 1)을 1byte로 바꿔버렸다. 따라서 data[1]의 1byte만 바꿀 수 있다. 포인터 표기법을 사용하면 배열 원소의 크기와는 상관없이 자유롭게 값을 수정할 수 있는 것이다. 이렇게 배열 표기법과 포인터 표기법을 섞어서 사용할 수 있다. 그저 문법적으로 같이 혼용해서 쓸 뿐 배열이 포인터가 되는 것은 아니다.
배열은 순차적으로 메모리에 저장된다. 따라서 배열의 첫 번째 원소가 시작 주소로 된다.
#include <stdio.h>
// 배열을 기준으로 포인터와 합체하기
void main()
{
char *p[5]; // 포인터가 5개 선언된 것이기 때문에 p배열의 크기는 20바이트이다.
// 개별 포인터를 사용하려면 p[0], p[1], p[2]처럼 써야 한다.
// 각 포인터가 가리키는 대상에 값을 읽거나 쓰고 싶다면 *p[0], *p[1], *p[2]
}
#include <stdio.h>
// 0으로 초기화
void main()
{
char data1, data2, data3, data4, data5, i;
char *p[5] = {&data1, &data2, &data3, &data4, &data5};
for (i = 0; i < 5; i++) {
*p[i] = 0;
}
}
위 그림에서 (p[5])처럼 괄호로 묶였기 때문에 p는 배열이고(괄호로 인해 배열이 우선) 각 항목이 포인터라는 뜻이다.
이와 달리 위에서는 *에 괄호가 묶였기 때문에 포인터가 우선이다. p는 포인터인데, char 5만큼의 크기를 가리키는 포인터라는 뜻이다. 이를 사용할 때에는 p가 포인터임을 알려주기 위해 (*p) 처럼 괄호로 먼저 씌워줘야 한다.