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
*var
F000에서 단일 바이트 메모리에 액세스합니다. var
주소는 여기에서 16 비트 너비이기 때문에 자체적으로 주소 0000에 있으며이 시스템에 2 바이트입니다. 새로운 할당 후 var="more neat"
; 메모리 덤프는 다음과 같습니다.
1000: F0 06 // Pointer holds a new address
출처
https://stackoverflow.com/questions/22079953