什么是两者之间的区别?
char* name
指向一个常量字符串字面值,并且const char* name
什么是两者之间的区别?
char* name
指向一个常量字符串字面值,并且const char* name
char*
指向一个可变的字符/字符串的可变指针。
const char*
指向一个不可变的字符/字符串的可变指针。您无法更改此指针指向位置的内容。此外,当您尝试这样做时,编译器会给出错误消息。由于相同的原因,从const char *
转换为char*
已被弃用。
char* const
是一个不可变的指针(它不能指向任何其他位置),但指向的位置的内容是可变的。
const char* const
是一个不可变的指针,指向一个不可变的字符/字符串。
char const *
。 - Pacerierchar *
会导致段错误吗? - Divyanshu Maithaniconst
,对吗? - Accountant مchar *
的位置。例如:char *s = "A string"
将"A string"放入二进制文件的代码段(只读内存)中。向这个内存写入会导致段错误。但是,char *s = malloc(sizeof(char) * 10)
在堆上分配内存,而这个内存区域是可写的,因此在写入时不会发生段错误。 - d4rwelchar *name
你可以更改name
所指向的字符,也可以更改它所指向的字符。
const char* name
你可以改变指向name
的字符,但你不能修改它所指向的字符。name
指向的字符(参见https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx的"Examples")。
在这种情况下,const
限定符适用于char
,而不是星号。
根据MSDN页面和http://en.cppreference.com/w/cpp/language/declarations,*
前面的const
是decl-specifier序列的一部分,而*
后面的const
是declarator的一部分。
一个声明说明序列可以跟随多个declarator,这就是为什么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
指向的字符。这可能导致未定义行为。 - Alok Savechar 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 *
的值会导致分段错误,因为我们试图修改一个字符串字面量(它存在于只读内存中)。 - Divyanshu Maithani无论将指向字符串字面值的指针声明为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
上述代码将str指向程序二进制映像中硬编码的字面值“Hello”,该映像在内存中标记为只读,这意味着对此字符串字面值的任何更改都是非法的,并会引发分段错误。
情况2:
const char *str = "Hello";
str[0] = 'M' //Compile time error
第三种情况:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
问题是什么是两者之间的区别
char *name
它指向一个常量字符串字面值,并且
const char *cname
char *name = "foo";
并且
const char *cname = "foo";
这两者之间没有太大的区别,都可以看作是正确的。由于C代码的悠久历史,字符串文字一直被视为char[]
类型,而不是const char[]
类型,因此有很多旧代码也接受char *
而不是const char *
,即使它们不修改参数。
总体上,这两者的主要区别在于*cname
或cname[n]
将评估为const char
类型的lvalue,而*name
或name[n]
将评估为char
类型的lvalue,它们是可修改的lvalue。符合标准的编译器需要在赋值的目标不是可修改的lvalue时产生诊断消息;对于char
类型的lvalue赋值,它不必产生任何警告:
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostic message
第一个您可以更改,如果您想的话,但第二个则无法更改。请了解有关const
正确性的信息(有一些很好的区别指南)。还有char const * name
,您不能重定向它。
char*
。 char* ptr = "Hello";
会抛出一个错误,而 const char* ptr = "Hello";
则是合法的。