차이점은 무엇입니까
char* name
상수 문자열 리터럴을 가리키는
const char* name
차이점은 무엇입니까
char* name
상수 문자열 리터럴을 가리키는
const char* name
답변:
char*
가변 문자 / 문자열에 대한 가변 포인터 입니다.
const char*
불변의 문자 / 문자열에 대한 가변 포인터 입니다. 이 포인터가 가리키는 위치의 내용을 변경할 수 없습니다. 또한 컴파일러는 그렇게 할 때 오류 메시지를 표시해야합니다. 같은 이유에서 변환 에이 되지 않습니다.const char *
char*
char* const
이다 불변 (포인터가 다른 위치를 가리킬 수) 이지만 그 포인트가되는 위치의 내용을 변경할 수는 .
const char* const
불변 문자 / 문자열에 대한 불변 포인터 입니다.
char const *
char *
실행 중 세그먼트 화 오류를 일으키지 않습니까?
const
실수로 데이터를 잊어 버리고 변경하면 컴파일러에서 오류를 표시하려면 사용합니까?
char *name
당신이 name
가리키는 문자와 그것을 가리키는 문자를 변경할 수 있습니다 .
const char* name
문자를 name
가리키는 지점으로 변경할 수 있지만 해당 지점 의 문자를 수정할 수는 없습니다.
수정 : 포인터는 변경할 수 있지만 ( https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx 를 가리키는 문자 는 변경할 수 없습니다 . "예제"참조 ). 이 경우 지정 자는 별표가 아닌에 적용됩니다 .name
const
char
MSDN 페이지 및 http://en.cppreference.com/w/cpp/language/declarations 에 따르면 const
before *
는 decl 지정자 시퀀스의 일부이고 const
after *
는 선언자의 일부입니다.
선언 지정자 시퀀스 뒤에 여러 선언자가 올 수 있으므로 as 및 as을 const char * c1, c2
선언합니다 .c1
const char *
c2
const char
편집하다:
주석에서 포인터가 문자열 리터럴을 가리킬 때 두 선언의 차이점에 대해 질문하는 것 같습니다.
이 경우 정의되지 않은 동작을 초래할 수 있는 지점 을 가리키는 문자를 수정 하면 안됩니다 . 문자열 리터럴은 읽기 전용 메모리 영역 (구현 정의)에 할당 될 수 있으며 사용자 프로그램은이를 수정해서는 안됩니다. 이렇게하면 정의되지 않은 동작이 발생합니다. name
따라서이 경우 (문자열 리터럴 사용)의 유일한 차이점은 두 번째 선언이 약간의 이점을 제공한다는 것입니다. 컴파일러는 두 번째 경우에서 문자열 리터럴을 수정하려고 할 때 일반적으로 경고를 표시합니다.
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
산출:
cc1 : 오류로 취급되는 경고
prog.c : 함수 'main'에서 :
prog.c : 9 : 오류 : 'strcpy'의 인수 1을 전달하면 포인터 대상 유형에서 한정자를 버립니다.
컴파일러는 두 번째 경우에는 경고하지만 첫 번째 경우에는 경고하지 않습니다.
name
UB가 발생할 수 있습니다.
char mystring[101] = "My sample string";
const char * constcharp = mystring; // (1)
char const * charconstp = mystring; // (2) the same as (1)
char * const charpconst = mystring; // (3)
constcharp++; // ok
charconstp++; // ok
charpconst++; // compile error
constcharp[3] = '\0'; // compile error
charconstp[3] = '\0'; // compile error
charpconst[3] = '\0'; // ok
// String literals
char * lcharp = "My string literal";
const char * lconstcharp = "My string literal";
lcharp[0] = 'X'; // Segmentation fault (crash) during run-time
lconstcharp[0] = 'X'; // compile error
// *not* a string literal
const char astr[101] = "My mutable string";
astr[0] = 'X'; // compile error
((char*)astr)[0] = 'X'; // ok
char *
값을 변경하면 문자열 리터럴 (읽기 전용 메모리에 있음)을 수정하려고하기 때문에 분할 오류 가 발생한다는 점에 주목할 가치가 있습니다.
어떤 경우에도 해당 문자열 리터럴에 대한 포인터가 char *
또는 로 선언되는지 여부에 관계없이 문자열 리터럴을 수정할 수 없습니다 const char *
.
그러나 포인터가 포인터이면 const char *
지정된 값을 수정하려고하면 컴파일러에서 진단을 제공해야 하지만 포인터가 그렇지 않으면 컴파일러에서 진단을 제공해야합니다 char *
.
extern ... name
하고 가질 수 있다고 생각합니다 *name = 'X';
. '적절한 운영 체제'에서는 실패 할 수 있지만 임베디드 시스템에서는 플랫폼 / 컴파일러에 특정한 작업을 수행 할 것으로 예상됩니다.
사례 1 :
char *str = "Hello";
str[0] = 'M' //Warning may be issued by compiler, and will cause segmentation fault upon running the programme
위의 설정은 메모리의 읽기 전용으로 플래그가 지정된 프로그램의 이진 이미지에 하드 코딩 된 리터럴 값 "Hello"를 가리 키도록 str을 설정합니다.이 문자열 리터럴의 모든 변경은 불법이며 세그먼트 오류를 발생시킵니다.
사례 2 :
const char *str = "Hello";
str[0] = 'M' //Compile time error
사례 3 :
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
원하는 경우 실제로 변경할 수있는 첫 번째는 변경할 수 없습니다. const
정확성 에 대해 읽으십시오 (차이에 대한 좋은 가이드가 있습니다). 다시 char const * name
지적 할 수없는 곳도 있습니다.
문제는 차이점은 무엇입니까
char *name
상수 문자열 리터럴을 가리키는
const char *cname
즉 주어진
char *name = "foo";
과
const char *cname = "foo";
둘 사이에는 큰 차이가 없으며 둘 다 올바른 것으로 볼 수 있습니다. C 코드의 오랜 유산으로 인해 문자열 리터럴의 유형은 char[]
not const char[]
이며 인수를 수정하지 않은 경우에도 char *
대신 대신 허용 하는 이전 코드가 많이 const char *
있습니다.
일반적으로 (2)의 주요 차이점이다 *cname
또는 cname[n]
유형을 평가한다 lvalues const char
반면, *name
또는 name[n]
타입 lvalues으로 평가하게 char
하고, 수정 lvalues . 할당 대상이 수정 가능한 lvalue가 아닌 경우 진단 메시지를 생성하려면 적합한 컴파일러가 필요합니다 . 유형의 lvalue에 할당 할 때 경고가 발생하지 않아도됩니다 char
.
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message
컴파일러는 두 경우 모두 컴파일을 중지 할 필요 가 없습니다 . 할당에 대한 경고 를 생성하는 것으로 충분합니다 cname[0]
. 결과 프로그램이 올바른 프로그램이 아닙니다 . 구성의 동작은 정의되어 있지 않습니다 . 충돌하거나 더 나빠질 수 있으며 메모리에서 문자열 리터럴을 변경할 수 있습니다.
실제로 char* name
는 상수에 대한 포인터가 아니라 변수에 대한 포인터입니다. 이 다른 질문에 대해 이야기하고있을 것입니다.