문자 배열에 문자열 할당


80

나는 다음과 같이 조금 놀랐다.

예 1 :

예 2 :

두 번째 접근 방식이 작동하지 않는 이유가 궁금합니다. 그것이 (다른 데이터 유형과 함께 작동 함) 당연한 것 같습니까? 누군가가 이것의 논리를 설명해 줄 수 있습니까?

답변:


67

배열을 초기화 할 때 C를 사용하면 배열을 값으로 채울 수 있습니다. 그래서

기본적으로 다음과 같습니다.

그러나 s자유 포인터가 아닌 배열 이기 때문에 할당을 할 수 없습니다. 그 의미

의 포인터 값 할당하는 것입니다 abcd로를 s하지만 당신은 변경할 수 없습니다 s아무 것도 배열을 가리키는되지 않습니다 때문이다.
이것은 할 수 있고 경우에 작업을 수행 sA는 char*- 무엇을 가리킬 수 있습니다 포인터.

문자열을 복사하려면 간단히 strcpy.


7
더 이상 일반 strcpy를 사용해서는 안된다는 점을 제외하면 좋은 대답입니다. strncpy 또는 strlcpy를 사용하십시오.
dwc

4
또한 s는 char *가 아니라 const char *이어야합니다.
aib

1
s[0] = 'x'; s[1] = 'y'; s[2] = 'z'; s[3] = 'm';초기화 후에도 문자열 문자를 하나씩 교체하려는 경우 작동합니다.
RBT

@RBT, 아마도 컴파일 플래그를 사용하여 플랫폼에서 수행 할 수 있지만 종종 이러한 문자열이 읽기 전용 메모리에 정의되어 있습니다. 여기에 쓰는 것은 세그먼트 폴트 또는 액세스 위반 오류가 발생할 것
shoosh

왜? 이렇게이 char s[100]; s = "abcd";의이 효과적으로 CONST 포인터로 취급되기 때문에 오류가 완벽한 의미가 있습니다. 따라서 두 번째 줄에 "abcd"를 할당하려고하면 허용되지 않는 포인터 값을 변경하려고합니다. 그러나 const 포인터가 메모리 위치를 가리키는 경우 메모리 위치의 내용은 물론 수정 가능해야합니다. s메모리 위치 1000을 가리키고 s에 1000이 포함되고 메모리 위치 # 1000에 a가 ​​포함되어 있다고 가정 해 보겠습니다 . 2000과 같은 새 메모리 위치를 저장하도록 s를 변경할 수 없지만 메모리 위치 1000에 z와 같은 새 문자를 저장할 수 있습니다.
RBT

53

C에서 "문자열"과 같은 것은 없습니다. C에서 문자열은 charnull 문자로 끝나는 의 1 차원 배열입니다 \0. C에서는 배열을 할당 할 수 없기 때문에 문자열도 할당 할 수 없습니다. 문자 그대로 "hello"는const char x[] = {'h','e','l','l','o','\0'};

올바른 방법은 다음과 같습니다.

또는 더 나은 방법 :


2
권장되는 접근 방식이 아닙니다. strncpy의 이상한 점에주의하십시오 : stackoverflow.com/a/1258577/2974922
nucleon

이 접근 방식이 쉽게 권장 될 수 있다고 생각합니다
Volt

14

초기화와 할당은 여기서 동일한 연산자 ( "=")를 사용하는 두 가지 별개의 작업입니다.


3

제공 한 예제에서 s는 실제로 2 행이 아닌 1 행에서 초기화됩니다.이 시점에서 명시 적으로 값을 할당하지 않았더라도 컴파일러는 수행했습니다. 2 행에서 할당 작업을 수행하고 있으며 이와 같은 다른 문자 배열에 하나의 문자 배열을 할당 할 수 없습니다. 배열의 각 요소를 할당하려면 strcpy () 또는 일종의 루프를 사용해야합니다.


Hello에 100 바이트가 필요한 이유는 무엇입니까? 하지가 char s[6]충분?
mLstudent33

1
@ mLstudent33, OP가 제공 한 예입니다.
Matt Davis

2

Sparr의 답변 을 확장하려면

초기화와 할당은 여기서 동일한 연산자 ( "=")를 사용하는 두 가지 별개의 작업입니다.

다음과 같이 생각하십시오.

InitializeObject, 및 이라는 2 개의 함수가 있다고 가정 해보십시오 AssignObject. 컴파일러가 볼 때 thing = value컨텍스트를 보고 InitializeObjectthing. 그렇지 않으면 대신 호출AssignObject .

일반적으로이 같은 괜찮 InitializeObjectAssignObject 일반적으로 동일한 방식으로 작동합니다. 문자 배열 (및 몇 가지 다른 경우)을 다룰 때를 제외하고는 다르게 동작합니다. 왜 이러나요? 글쎄 그것은 스택 대 힙 등과 관련된 완전히 다른 게시물입니다.

추신 : 제쳐두고, 이런 식으로 생각하면 복사 생성자와 다른 것들을 이해하는 데 도움이 될 것입니다.


0

다음을 수행 할 수 있습니다.


strncpy ()가 내부적으로 정확히 이것을 수행한다고 확신하지만 strncpy ()를 사용하는 것이 훨씬 더 좋고 사용하기 쉽습니다.
Chris Lutz

물론이야. 그러나 이것은 's = "hello";'에 가깝습니다. 사실, 이것은 구조체를 할당 할 수있는 방법으로 볼 때 C로 구현되어야합니다.
aib

내 말은, 배열이 아닌 구조체의 할당에 의한 구성원 별 복사는 의미가 없습니다.
aib

0

이미 답변을 받았지만 C / C ++ Facebook 그룹에서 매우 유사한 질문을 한 사람에게 답변을 공유하고 싶었습니다.


배열에는 할당 연산자 기능이 없습니다 *. 이것은 단순히 문자열 리터럴에 char 배열을 할당 할 수 없음을 의미합니다. 왜? 배열 자체에는 할당 연산자가 없기 때문입니다. (* 변경할 수없는 const 포인터입니다.)

배열은 단순히 연속적으로 할당 된 메모리의 영역이며 배열의 이름은 실제로 배열의 첫 번째 요소에 대한 포인터입니다. ( https://www.quora.com/Can-we-copy-an-array-using-an-assignment-operator 에서 인용 )

문자열 리터럴 ( "Hello world"또는 등 "abcd")을 char 배열에 복사하려면 문자열 리터럴의 모든 char 요소를 배열에 수동으로 복사해야합니다.

char s[100]; 이것은 길이가 100 인 빈 배열을 초기화합니다.

이제이 배열에 문자열 리터럴을 복사하려면 strcpy

strcpy(s, "abcd");그러면 문자열 리터럴의 내용이 복사 "abcd"되어s[100] 배열에 됩니다.

이것이 무엇을하는지에 대한 좋은 예가 있습니다.

strcpy이 사용자 지정 문자열 리터럴 복사기 대신 분명히 사용해야 하지만 strcpy기본적으로 작동 하는 방식을 설명하는 좋은 예입니다 .

도움이 되었기를 바랍니다!


-1

이것을 사용할 수 있습니다 :

yylval은 char *입니다. strdup에서 작업을 수행합니다.


에서에서는 StrDup <string.h> 않는 작업 :
Yekatandilburg

strdup은 복제본을 만들고 복제본에 대한 포인터를 반환합니다. 문자 배열이 경우에, 당신은 다시 수행없이 일을 시작 곳이다
JoshKisb

-3

내가 사용하는 것은


2
정의되지 않은 행동의 위험이 있기 때문에 우리 대부분은 그렇지 않습니다. 위의 내용은 const char*.
Toby Speight
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.