char *和const char *之间的区别?

有什么区别

char* name 

它指向一个常量string,和

 const char* name 
  • const char*
    是一个不可变的字符/string的可变指针。 你不能改变这个指针指向的位置的内容。 另外,当你尝试这样做时,编译器需要给出错误信息。 出于同样的原因,从const char *char*转换已被废弃。

  • char* const
    是一个不可变的指针(它不能指向任何其他的位置), 它指向的位置的内容是可变的

  • const char* const
    是一个不可变的指向不可变字符/string的指针。

  • char*
    是完全宽容的。

 char *name 

您可以更改name指向的字符,以及它指向的字符。

 const char* name 

您可以更改name指向的字符,但不能修改它指向的字符。
更正:您可以更改指针,但不是 name指向的字符( https://msdn.microsoft.com/zh-cn/library/vstudio/whkd4k6a(v=vs.100).aspx ,请参阅“示例“)。 在这种情况下, const说明符适用于char ,而不是星号。

根据MSDN页面和http://en.cppreference.com/w/cpp/language/declarations,*之前的;const是decl-specifier序列的一部分,而const *之后的const是声明的一部分。
声明说明符序列后面可以跟多个声明符,这就是为什么const char * c1, c2声明c1const char *c2const char

编辑:

从注释中,你的问题似乎是在指针指向一个string时,两个声明之间的区别。

在这种情况下,您不应该修改name指向的字符,因为它可能会导致未定义的行为 。 string文字可以分配在只读存储器区域(实现定义)中,用户程序不应该修改它。 任何尝试这样做都会导致“未定义的行为”。

所以在这种情况下(string文字的使用)唯一的区别是第二个声明给你一个轻微的优势。 如果在第二种情况下尝试修改string,编译器通常会给出警告。

在线示例:

 #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丢弃指针目标types的限定符

注意编译器警告第二种情况,但不是第一种情况。

 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 

在任何情况下,您都不能修改string文字,无论指向该string文字的指针是声明为char *还是const char *

然而,不同的是,如果指针是const char *那么编译器必须给出一个诊断,如果你试图修改指向的值,但如果指针是char *那么它不会。

第一个你真的可以改变,如果你想,第二个你不能。 阅读关于const正确性(有一些不错的指导差异)。 还有char const * name ,你不能重新命名它。

实际上, char* name不是指向常量的指针,而是指向variables的指针。 你可能会在谈论这个问题。

char * const和const char *有什么区别?

问题是两者之间有什么区别

 char *name 

它指向一个常量string,和

 const char *cname 

即给出

 char *name = "foo"; 

 const char *cname = "foo"; 

2和2之间没有太大的差别,都可以看作是正确的。 由于C代码的悠久遗产,string文字有一个char[] ,而不是const char[] ,并且有许多旧代码同样接受char *而不是const char * ,即使它们不修改参数。

2的主要区别在于, *cnamecname[n]将被计算为const chartypes的左值,而*namename[n]将被计算为chartypes的左值,这是可修改的左值 。 如果赋值的目标不是可修改的左值 ,则需要符合的编译器生成诊断消息; 它不需要给chartypes的左值赋予任何警告:

 name[0] = 'x'; // no diagnostics *needed* cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message 

无论哪种情况,编译器都不需要停止编译; 它足以产生一个警告 ,分配给cname[0] 。 由此产生的程序不是一个正确的程序。 构造的行为是未定义的 。 它可能会崩溃,甚至更糟糕的是,它可能不会崩溃,并可能改变内存中的string字面值。

情况1:

 char *str = "Hello"; str[0] = 'M' //No warning or error, just Undefined Behavior 

上面设置str指向在程序的二进制图像中硬编码的字面值“Hello”,在内存中标记为只读,意味着此Stringstring中的任何改变都是非法的,并且会引起分段错误。

情况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". 

只是给一个额外的例子:

  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! 

你可以运行它,并为自己看到更好的东西。