之间有什么区别
char* name
指向常量字符串文字,
const char* name
答案 0 :(得分:335)
char*
是指向可变字符/字符串的可变指针。
const char*
是指向不可变字符/字符串的可变指针。您无法更改此指针指向的位置的内容。此外,编译器在尝试执行此操作时需要提供错误消息。出于同样的原因,不推荐将const char *
转换为char*
。
char* const
是不可变的指针(它不能指向任何其他位置)但它指向的位置内容 mutable < /强>
const char* const
是指向不可变字符/字符串的不可变指针。
答案 1 :(得分:41)
char *name
您可以更改name
指向的字符,以及它指向的字符。
const char* name
您可以更改 name
指向的字符,但不能修改它指向的字符。
更正: 您可以更改指针,但 不 name
指向的字符( https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx,请参阅“示例”)。在这种情况下,const
说明符适用于char
,而不是星号。
根据MSDN页面和http://en.cppreference.com/w/cpp/language/declarations,const
之前的*
是decl-specifier序列的一部分,const
之后是*
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;
}
指向的字符,因为它可能会导致未定义的行为。
字符串文字可以在只读存储器区域中分配(实现定义),并且用户程序不应该以任何方式修改它。任何这样做的尝试都会导致未定义的行为。
因此,在这种情况下(使用字符串文字)的唯一区别是第二个声明给你一点点优势。如果您尝试在第二种情况下修改字符串文字,编译器通常会给您一个警告。
<强> Online Sample Example: 强>
{{1}}
输出
cc1:警告被视为错误
中的限定符
prog.c:在函数'main'中:
prog.c:9:错误:传递'strcpy'的参数1会丢弃指针目标类型
请注意,编译器会警告第二种情况,但不会警告第一种情况。
答案 2 :(得分:15)
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
答案 3 :(得分:9)
在任何情况下都不能修改字符串文字,无论指向该字符串文字的指针是否声明为char *
或const char *
。
然而,不同之处在于,如果指针是const char *
,那么如果您尝试修改指向的值,则编译器必须提供诊断,但如果指针是char *
,那么它不会
答案 4 :(得分:2)
如果你愿意,第一个你可以实际改变,第二个你不能改变。阅读const
正确性(有关于差异的一些不错的指南)。还有char const * name
你无法重新指责它。
答案 5 :(得分:2)
案例1:
char *str = "Hello";
str[0] = 'M' //No warning or error, just Undefined Behavior
上面的设置指向文本值“Hello”,它在程序的二进制映像中被硬编码,在内存中被标记为只读,意味着此字符串文字中的任何更改都是非法的并且会抛出分段错误。
案例2:
const char *str = "Hello";
str[0] = 'M' //Compiler issues a warning
案例3:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
答案 6 :(得分:1)
实际上,char* name
不是指向常量的指针,而是指向变量的指针。你可能在谈论另一个问题。
What is the difference between char * const and const char *?
答案 7 :(得分:1)
问题是
之间有什么区别char *name
指向常量字符串文字,
const char *cname
即。给出
char *name = "foo";
和
const char *cname = "foo";
两者之间没有太大差异,两者都可以看作是正确的。由于C代码的长期遗留,字符串文字的类型为char[]
,而不是const char[]
,并且有许多旧代码同样接受char *
而不是{{1}即使他们不修改参数。
2的主要区别在于const char *
或*cname
将评估为cname[n]
类型的左值,而const char
或*name
将评估类型name[n]
的左值,modifiable lvalues。如果target of the assignment is not a modifiable lvalue,则需要符合标准的编译器来生成诊断消息。它不需要在分配char
类型的左值时产生任何警告:
char
在任何一种情况下,编译器都不是 required 来停止编译;它足以为name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message
的作业生成警告。生成的程序不是正确的程序。构造的行为是 undefined 。它可能会崩溃,甚至更糟糕的是,它可能不会崩溃,并且可能会更改内存中的字符串文字。
答案 8 :(得分:0)
只是举一个例子:
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"
(我正在使用typeinfo库: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!
你可以自己运行它,看看事情更好。