有什么区别
char* name
指向一个常量字符串字面量,和
const char* name
有什么区别
char* name
指向一个常量字符串字面量,和
const char* name
当前回答
案例1:
char *str = "Hello";
str[0] = 'M' //Warning may be issued by compiler, and will cause segmentation fault upon running the programme
上面设置str指向“Hello”字面值,该字面值是硬编码在程序的二进制图像中,在内存中被标记为只读,这意味着这个String字面值的任何更改都是非法的,并且会抛出分割错误。
案例2:
const char *str = "Hello";
str[0] = 'M' //Compile time error
案例3:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
其他回答
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 *name
您可以更改名称所指向的字符,也可以更改名称所指向的字符。
const char* 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。
编辑:
从评论来看,你的问题似乎是在问当指针指向一个字符串字面值时,两个声明之间的区别。
在这种情况下,您不应该修改名称所指向的字符,因为这可能导致未定义的行为。 字符串字面值可以分配在只读内存区域(实现定义),用户程序不应该以任何方式修改它。任何这样做的尝试都会导致未定义的行为。
因此,在这种情况下(使用字符串字面值)唯一的区别是,第二个声明给了您一点优势。如果你试图在第二种情况下修改字符串字面量,编译器通常会给你一个警告。
在线示例示例:
#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丢弃指针目标类型的限定符
注意,编译器对第二种情况发出警告,但对第一种情况没有发出警告。
我想在这里补充一点,最新的编译器,例如VS 2022,不允许用字符串文字初始化char*。char* ptr = "Hello";当const char* ptr = "Hello"时抛出错误;是合法的。
案例1:
char *str = "Hello";
str[0] = 'M' //Warning may be issued by compiler, and will cause segmentation fault upon running the programme
上面设置str指向“Hello”字面值,该字面值是硬编码在程序的二进制图像中,在内存中被标记为只读,这意味着这个String字面值的任何更改都是非法的,并且会抛出分割错误。
案例2:
const char *str = "Hello";
str[0] = 'M' //Compile time error
案例3:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
在这两种情况下都不能修改字符串字面值,无论指向该字符串字面值的指针是声明为char *还是const char *。
然而,不同之处在于,如果指针是const char *,那么编译器必须在你试图修改指向值时给出诊断,但如果指针是char *,则不会。