char *와 const char *의 차이점은 무엇입니까?
차이점은 무엇입니까
char* name
상수 문자열 리터럴을 가리키는
const char* name
char*
가변 문자 / 문자열에 대한 가변 포인터 입니다.
const char*
불변의 문자 / 문자열에 대한 가변 포인터 입니다. 이 포인터가 가리키는 위치의 내용을 변경할 수 없습니다. 또한 컴파일러는 그렇게 할 때 오류 메시지를 표시해야합니다. 같은 이유에서 변환 에이 되지 않습니다.const char *
char*
char* const
이다 불변 (포인터가 다른 위치를 가리킬 수) 이지만 그 포인트가되는 위치의 내용을 변경할 수는 .
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을 전달하면 포인터 대상 유형에서 한정자를 버립니다.
컴파일러는 두 번째 경우에는 경고하지만 첫 번째 경우에는 경고하지 않습니다.
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 *
또는 로 선언되는지 여부에 관계없이 문자열 리터럴을 수정할 수 없습니다 const char *
.
그러나 포인터가 포인터이면 const char *
지정된 값을 수정하려고하면 컴파일러에서 진단을 제공해야 하지만 포인터가 그렇지 않으면 컴파일러에서 진단을 제공해야합니다 char *
.
사례 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".
The first you can actually change if you want to, the second you can't. Read up about const
correctness (there's some nice guides about the difference). There is also char const * name
where you can't repoint it.
Actually, char* name
is not a pointer to a constant, but a pointer to a variable. You might be talking about this other question.
What is the difference between char * const and const char *?
The question is what's the difference between
char *name
which points to a constant string literal, and
const char *cname
I.e. given
char *name = "foo";
and
const char *cname = "foo";
There is not much difference between the 2 and both can be seen as correct. Due to the long legacy of C code, the string literals have had a type of char[]
, not const char[]
, and there are lots of older code that likewise accept char *
instead of const char *
, even when they do not modify the arguments.
The principal difference of the 2 in general is that *cname
or cname[n]
will evaluate to lvalues of type const char
, whereas *name
or name[n]
will evaluate to lvalues of type char
, which are modifiable lvalues. A conforming compiler is required to produce a diagnostics message if target of the assignment is not a modifiable lvalue; it need not produce any warning on assignment to lvalues of type char
:
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message
The compiler is not required to stop the compilation in either case; it is enough that it produces a warning for the assignment to cname[0]
. The resulting program is not a correct program. The behaviour of the construct is undefined. It may crash, or even worse, it might not crash, and might change the string literal in memory.
Just to give an extra example:
std::cout << typeid(2.3).name() << '\n'; // -----> prints "double" simply because
//2.3 is a double
//But the "double" returned by typeid(2.3).name() is indeed a
//const char * which consists of 'd','o','u','b','l','e'and'\0'.
//Here's a simple proof to this:
std::cout << typeid(typeid(2.3).name()).name() << '\n'; //prints: "const char *"
const char* charptr
charptr = typeid(2.3).name();
std::cout << charptr[3]; // ---------> prints: "b"
(I'm using the typeinfo library: http://www.cplusplus.com/reference/typeinfo/type_info/name)
//Now let's do something more interesting:
char* charptr2="hubble";
strcpy(charptr, charptr2); // --------> Oops! Sorry, this is not valid!
You can run it and see things better for yourself.
참고URL : https://stackoverflow.com/questions/9834067/difference-between-char-and-const-char
'IT' 카테고리의 다른 글
Entity Framework에서 데이터베이스 시간 초과 설정 (0) | 2020.06.08 |
---|---|
PHP / XAMPP에서 cURL을 활성화하는 방법 (0) | 2020.06.08 |
모든 쿼리를 기록하는 MongoDB (0) | 2020.06.08 |
Ruby에서 배열의 교차, 합집합 및 부분 집합을 얻으려면 어떻게해야합니까? (0) | 2020.06.08 |
기존 Rails 열에서 부울에 : default => true 추가 (0) | 2020.06.08 |