카테고리 없음

[c] char * string = "string"을 수행 할 수있을 때 포인터는 어떻게 "값이 주소 인 변수"입니까?

행복을전해요 2021. 2. 21. 03:04

The unary * operator has two different (but related) purposes. In a declaration, it denotes that the type is a pointer type, but does not imply that the pointer is being dereferenced.

When used in an expression, it denotes deferencing the pointer. That's why your example works where it's a declaration, but when you dereference it you can't assign (because the appropriate type to assign would be a char, if you could modify string literals anyhow).

The equivalent way to do it outside the declaration looks like:

const char *s = "hello"; /* initialize pointer value */
s = "goodbye"; /* assign to pointer value */

The above initialization and assignment are equivalent.

-------------------

"neato" is of the type const char[]. Arrays decay to pointers when appropriate, so the assignment is one pointer to another.

It follows then that your pointer should be to const char. Writing to a memory location occupied by a string literal invokes undefined behavior. This however is valid:

char str[] = "neato";
str[0] = 'p';

Furthermore, if I set it, I would try to do it as *string = "more neat"

글쎄, 당신은 char에 대한 포인터가 있으므로 할당이 의미가 없습니다 (위에서 문자열 리터럴에 쓰는 것에 대해 말한 것).

-------------------

예를 들면

char *ptr = "neato";
char arr[] = "neato"; 

완전히 다릅니다. ptr 은 문자열 리터럴 "neato"에 대한 포인터이며 컴파일러는 일반적으로 문자열 리터럴을 읽기 전용 메모리에 저장합니다. 따라서 ptr이 가리키는 문자열 리터럴 은 변경할 수 없지만 ptr 의 값 , 즉 주소 는 변경할 수 있습니다 .

*ptr = "more neat"; // error, even if *ptr were writable, it should be a character
*ptr = 'b'; // error
ptr = "more neat"; // ok, you just create another string literal and ptr now points to it

두 번째는 약어입니다.

char arr[] = {'n', 'e', 'a', 't', 'o', '\0'};

이 경우 배열의 문자를 변경할 수 있지만 arr의 주소는 변경할 수 없습니다 (예, 배열입니다).

*arr = 'b'; // ok
arr = "more neat" // error, the value of arr, namely the address of the array cannot be changed

초기화와 할당은 서로 다르지만 매우 비슷해 보이지만 작업의 의미는 종종 다릅니다.

-------------------

둘 다의 기본 유형 char *과 문자열 "neato"는 문자입니다. 문자열 리터럴은 읽기 전용 주소에있는 단순한 문자 배열입니다. "n"은 주소에 있어야합니다 (다음 문자 'e'와 마찬가지로). 그 주소는 변수에 저장됩니다 char *ptr.

질문의 두 번째 부분은 왜 *ptr = "more neat";유효하지 않은지입니다.

*var주소를 역 참조합니다.이 경우에는 이미 문자 'n'을 포함하는 1 자 와이드 메모리 주소입니다. 새 문자열 리터럴 (아마 4 또는 8 바이트로 표현 가능)의 주소를 단일 문자에 넣을 수 없습니다. 또한 9 개의 문자와 종료 ASCII를 넣을 수 없습니다.

16 비트 (Big Endian) 머신의 메모리 덤프를 가져 와서이를 연구 할 수 있습니다.

  0FFE: .. ..             // other variables, return addresses etc.
  1000: F0 00             // The pointer "var" is located here
    1002:                   // Top of stack
    
      F000: "n" "e" "a" "t" "o" 00      // Address of constant string is F000
        F006: "m" "o" "r" "e" ...         // Address of next string is F006
        

*varF000에서 단일 바이트 메모리에 액세스합니다. var주소는 여기에서 16 비트 너비이기 때문에 자체적으로 주소 0000에 있으며이 시스템에 2 바이트입니다. 새로운 할당 후 var="more neat"; 메모리 덤프는 다음과 같습니다.

  1000: F0 06             // Pointer holds a new address


출처
https://stackoverflow.com/questions/22079953