[1] 배열의 이름
- 배열의 이름은 포인터이다. 단, 그 값을 바꿀 수 없는 '상수 형태의 포인터'이다.
- 배열의 이름은 배열의 시작 주소 값을 의미하며, 그 형태는 값의 저장이 불가능한 상수이다.
- 배열의 이름도 포인터이므로 배열의 이름을 피연산자로 하는 * 연산이 가능하다.
위의 말들이 무슨 뜻인지 부연설명하면,
배열의 이름이 "상수 형태의 포인터"라는 개념은 C 언어에서의 배열과 포인터 사이의 관계를 설명하기 위한 개념이다. 이것은 배열과 포인터 간의 유사성을 강조하는 방식으로 설명할 수 있다.
1. 배열의 이름은 포인터 상수(constant pointer)이다.
- 배열을 선언하면 배열의 이름은 해당 배열의 첫 번째 요소를 가리키는 포인터 상수로 간주된다.
- 이 포인터는 상수이기 때문에 다른 메모리 주소로 변경할 수 없다. 즉, 배열의 이름을 다른 변수에 할당하거나 다른 주소로 초기화할 수 없다.
2. 배열의 이름은 주소를 나타낸다.
- 배열의 이름은 실제로 배열의 첫 번째 요소의 메모리 주소를 나타낸다. 따라서 배열의 이름을 사용하면 해당 배열의 첫 번째 요소에 대한 포인터로 작동한다.
예를 들어, 다음과 같이 정의된 배열이 있다고 가정
[2] 포인터를 배열의 이름처럼 사용 가능하다는 말의 의미
포인터를 배열의 이름처럼 사용할 수 있다는 것은 포인터 변수를 사용하여 배열과 유사한 방식으로 데이터에 접근할 수 있음을 의미한다. C 언어에서 배열의 이름은 배열의 첫 번째 요소를 가리키는 포인터 상수로 간주되며, 이로 인해 배열의 이름과 포인터 변수 간에 몇 가지 유사성이 있습니다.
아래는 포인터를 배열의 이름처럼 사용하는 예시를 보여줍니다:
위의 코드에서 ptr은 배열 arr의 첫 번째 요소를 가리키는 포인터로 설정되었다. 그러면 *ptr을 사용하여 포인터를 통해 배열 요소에 접근할 수 있습니다. 이렇게 포인터를 배열의 이름처럼 사용하면 배열 요소에 접근할 수 있으며, 포인터 산술을 사용하여 다른 요소에도 접근할 수 있다.
그러나 배열의 이름과 포인터 간에 중요한 차이점은 배열의 이름은 상수 포인터로 간주되어서 배열의 주소를 변경할 수 없다는 것이다. 반면 포인터 변수는 다른 주소로 변경할 수 있으므로 주의해야 한다.
배열의 이름과 포인터 변수는 변수냐 상수냐의 특성적 차이가 있을 뿐 둘 다 포인터이다.
따라서, 포인터 변수로 할 수 있는 연산은 배열의 이름으로도 할 수 있고, 배열의 이름으로 할 수 있는 연산은 포인터 변수로도 할 수 있다.
#include <stdio.h>
int main(void)
{
int arr[3]={15, 25, 35};
int* ptr=&arr[0]; // int* ptr=arr;과 동일한 문장
printf("%d %d\n", ptr[0], arr[0]); // 15 15
printf("%d %d\n", ptr[1], arr[1]); // 25 25
printf("%d %d\n", ptr[2], arr[2]); // 35 35
printf("%d %d\n", *ptr, *arr); // 15 15
return 0;
}
[3] *(++ptr)=20과 *(ptr+1)=20 연산의 차이점
int arr[3]={11, 22, 33};
int* ptr=arr;
*(++ptr) = 20와 *(ptr + 1) = 20는 포인터를 사용하여 메모리에서 데이터에 접근하는 두 가지 다른 방법을 나타낸다. 이 두 연산의 차이점은 다음과 같다.
- *(++ptr) = 20:
- ++ptr는 포인터 ptr를 증가시키는 연산이다. 따라서 ptr이 현재 가리키고 있는 요소(첫 번째 요소)에서 다음 요소(두 번째 요소)로 이동합니다.
- 그런 다음 * 연산자를 사용하여 해당 메모리 위치에 20을 할당한다.
- 결과적으로 두 번째 요소인 arr[1]의 값이 20으로 변경된다.
- *(ptr + 1) = 20:
- ptr + 1은 현재 ptr이 가리키고 있는 메모리 위치에서 한 요소 뒤의 메모리 위치를 계산한다. 즉, ptr이 첫 번째 요소를 가리키고 있으면, ptr + 1은 두 번째 요소를 가리킨다.
- 그런 다음 * 연산자를 사용하여 해당 메모리 위치에 20을 할당한다.
- 결과적으로 두 번째 요소인 arr[1]의 값이 20으로 변경된다.
요약하면, 두 연산은 모두 배열의 두 번째 요소(arr[1])를 변경한다. 다만 첫 번째 연산 *(++ptr) = 20은 포인터 ptr을 증가시켜 다음 요소로 이동한 후 값을 할당하고, 두 번째 연산 *(ptr + 1) = 20은 포인터 연산을 사용하여 다음 요소의 메모리 위치에 직접 값을 할당한다. 결과적으로 두 연산 모두 동일한 결과를 얻지만 표현 방식이 다르다.
*(++ptr)=20; // ptr에 저장된 값 자체를 변경
*(ptr+1)=20; // ptr에 저장된 값은 변경되지 않음.
위의 두 문장 모두 현재 ptr이 가리키는 위치에서 4바이트 떨어진 메모리 공간에 20을 저장하는 문장이다.
하지만 연산 이후 포인터 변수 ptr의 상태에는 차이가 있다.
첫 번째 문장의 경우 ++연산의 결과로 인해서 포인터 변수 ptr에 저장된 값이 4만큼 증가한다.
하지만 두 번째 문장의 +연산으로 인해서는 ptr에 저장된 값이 증가하지 않는다. 다만, 증가된 값을 연산의 결과로 얻어서 * 연산을 진행할 뿐이다.
'2023 > C' 카테고리의 다른 글
포인터 대상의 const 선언 (0) | 2023.10.09 |
---|---|
배열 기반의 문자열 표현 (0) | 2023.10.08 |