programing

이 포인터 산술은 왜 C에서는 허용되지 않는 겁니까?

easyjava 2023. 10. 1. 23:04
반응형

이 포인터 산술은 왜 C에서는 허용되지 않는 겁니까?

char arr[] = "Hello";
arr = arr + 1;  // error occurs

배열 타입이 있는 식은 배열의 초기 요소를 가리키는 포인터 타입으로 변환되는 것으로 알고 있습니다.했습니다를 했습니다.arr = arr + 1에 r가 가 됨) 소(arr)다)합니다.이것은 왜 C에서는 작동하지 않습니까?

arr + 1는 실제로 배열의 두 번째 요소(즉, 배열의 두 번째 요소)를 가리키는 포인터입니다.&arr[1]).

을 다시 , 에 쓸 수 것은 .arr 두 때문에 할 수

arr는 의 배열입니다.char포인터가 아닌 요소.여기 유형이 분명히 일치하지 않습니다.

로, ,arr수정할 수 없는 l 값변경할 수 없습니다.arr그 자체로만 요소를 변경할 수 있습니다(이러한 구분은 다소 파악하기 어렵지만, 존재합니다).

마지막으로, 우리가 단지 더 깊은 복잡성을 무시하고 최상위 레벨에서 공식적으로 일어나는 것에 초점을 맞춘다면, 당신의 표현식은 다음과 같습니다.

(char *) arr = (char *) arr + 1;

좌변은 [암시]형 변환의 결과이므로 할당이 불가능합니다.C 유형 변환에서는 항상 r값을 생성합니다.r값은 할당할 수 없습니다.

다시 말해서, 여기서 허용되지 않는 것은 "점자 산술"이 아닙니다.포인터 산술은 괜찮습니다.오류를 발생시키는 것은 포인터 산술의 결과로 수행하는 작업입니다.

배열은 수정할 수 없는 l 값입니다.그들은 할당 연산자의 왼쪽 피연산자가 될 수 없습니다.

C11- §6.3.2.1:

수정 가능한 l 값은 배열 유형이 없고 불완전한 유형이 없는 l 입니다. [...]

§6.5.16/2:

할당 연산자는 왼쪽 피연산자로 수정 가능한 l 값을 가져야 합니다.

명세서에

arr = arr + 1; 

arr 피연산자입니다.=연산자이며 배열 형식입니다.수정할 수 없습니다.
따라서 구문 오류의 원인은 포인터 산술이 아니라 할당 연산자의 언어에 의한 제약 때문입니다.


포인터와 배열은 다른 유형이지만 일부 상황에서는 배열이 첫 번째 요소의 포인터로 붕괴됩니다.배열은 포인터가 아닙니다.포인터 산술 및 배열 색인만 동등합니다.예를들면

char *ptr = &arr[0] + 1 => &(*(arr + 0)) + 1 => &(*arr) + 1 => arr + 1 // * and & nullify each other 

이는 배열이 수정할 수 없다는 점을 제외하고는 포인터와 유사하기 때문입니다.그러나 배열을 가리키는 포인터는 수정할 수 있습니다.위의 예에서는 다음과 같이 수행할 수 있습니다.

char arr[]="Hello";
char *ptr=arr;
ptr=ptr+1;

처음에는 포인터가ptr배열의 첫 번째 문자를 가리킬 것입니다. 즉.'H'그리고 값을 수정한 후 두 번째 문자, 즉 를 가리킵니다.'e'. 다음을 수행할 수도 있습니다.

char arr[]="Hello";
char *ptr=arr;
ptr=arr+1;

둘 다 동일한 효과를 만들어냅니다. 이는 것을 보여줍니다.arr+1정말로 포인터 산술입니다.그러나 다음의 값은 수정할 수 없습니다.arr그 유형이 문자 배열의 유형이고 문자 배열에 대한 포인터가 아니기 때문입니다.

배열 타입이 있는 식은 배열의 초기 요소를 가리키는 포인터 타입으로 변환되는 것으로 알고 있습니다.

대부분의 상황에서 사실입니다.다음과 같은 맥락에서는 그렇지 않습니다.

  1. 연산자의 주소를 사용하는 경우 (&arr). 유형&arrchar (*)[6].그것은 아니다.char**.

  2. 사용시sizeof교환입니다.sizeof(arr)6. 포인터라면 포인터 크기(대부분의 일반 플랫폼에서 4개 또는 8개)가 될 것입니다.

  3. 할당 연산자의 LHS로 사용되는 경우.배열 유형의 변수는 수정할 수 없습니다.

그래서 나는 기대했습니다.arr = arr + 1(pointer에서 배열의 첫 번째 요소(arr)는 배열의 두 번째 요소에 대한 포인터가 됩니다) 작동합니다.이것은 왜 C에서는 작동하지 않습니까?

식의 RHS는 다음의 두 번째 요소를 가리키는 포인터로 평가합니다.arr. 그러나 위 (3) 때문에 해당 선이 작동하지 않습니다.arr수정 가능한 값이 아닙니다.할당 연산자의 LHS로 사용할 수 없습니다.

char[]는 포인터가 아닙니다.char*포인터입니다.이것은 효과가 있지만 잘못된 해결책입니다.

int main()
{
    char *arr = "Hello";
    arr = arr + 1;  // Wrong!
    printf("%s\n", arr); // Output: ello
}

한다면arr다음과 같이 힙 allocated입니다.malloc만약 당신이 메모리 유출을 당한다면.freegarr+1것은 아니다.arr.

하지만 당신은 다음과 같은 것을 할 수 있습니다.

int main()
{
    char arr[] = "Hello";
    char *wordFromSecondLetter = &arr[0] + 1;
    printf("%s\n", wordFromSecondLetter); // Output: ello
}

아니면 이렇게.

int main()
{
    char arr[] = "Hello";
    printf("%s\n", &arr[1]); // Output: ello
}

.arr포인터가 아니라 문자 배열입니다.다를 확인하여 할 수 .sizeof arr .char 에를 char *arr = "Hello";.

포인터와 배열의 가장 큰 차이점은 포인터에 직접 값을 할당할 수는 있지만 배열에는 할당할 수 없다는 것입니다.

을 쓸 때,arr + 1,arr에 대한 즉 괴"을에하면 "됩니다.arr == &arr[0].그렇게arr + 1그 이지만,에 부여합니다.arr

언급URL : https://stackoverflow.com/questions/38842393/why-isnt-this-pointer-arithmetic-allowed-in-c

반응형