之间有什么区别
char* name
指向常量字符串文字,并且
const char* name
之间有什么区别
char* name
指向常量字符串文字,并且
const char* name
Answers:
char*
是指向可变的可变指针字符/字符串。
const char*
是指向不可变字符/字符串的可变指针。您不能更改此指针指向的位置的内容。此外,当您尝试这样做时,要求编译器提供错误消息。出于同样的原因,从转换为const char *
char*
已被弃用。
char* const
是一个不变的指针(它不能指向任何其他位置),但是它所指向的位置的内容是可变的。
const char* const
是指向不可变字符/字符串的不可变指针。
char const *
char *
运行时不会突变给细分带来错误吗?
const
如果我忘记并错误地更改了数据,我是否希望编译器给出错误信息,对吧?
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
as const char *
和c2
as的原因const char
。
编辑:
从注释中,您的问题似乎是在询问指针指向字符串文字时两个声明之间的差异。
在这种情况下,您不应将char修改为要name
指向的字符,因为这可能会导致Undefined Behavior。可以在只读存储区(定义的实现)中分配字符串文字,并且用户程序无论如何都不应对其进行修改。尝试这样做会导致未定义的行为。
因此,在这种情况下(与字符串文字一起使用)的唯一区别是第二个声明为您带来了一点优势。如果您试图在第二种情况下修改字符串文字,则编译器通常会向您发出警告。
#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
指向的字符,这可能会导致UB。
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 *
值会导致分段错误,因为我们正在尝试修改字符串文字(只读内存中存在)
无论哪种情况,都不能修改字符串文字,无论指向该字符串文字的指针是声明为char *
还是const char *
。
但是,不同之处在于,如果指针是指针,const char *
则如果您尝试修改指向的值,则编译器必须给出诊断,而如果指针是指针,则编译器必须给出诊断char *
。
extern ... name
并且具有*name = 'X';
。在“适当的操作系统”上,这可能会失败,但是在嵌入式系统上,我希望它能够执行特定于平台/编译器的操作。
情况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 *name
指向常量字符串文字,并且
const char *cname
即给出
char *name = "foo";
和
const char *cname = "foo";
两者之间没有太大差异,两者都可以视为正确。由于C代码的悠久历史,字符串文字的类型为char[]
,而不是,即使不修改参数,const char[]
很多旧代码也可以接受char *
代替const char *
。
一般而言,2的主要区别是*cname
或cname[n]
将求值为类型的左值const char
,而*name
或name[n]
会求值为类型的左值char
,它们是可修改的左值。如果分配的目标不是可修改的左值,则需要合格的编译器产生诊断消息; 它不需要在对类型为lvalue的赋值时产生任何警告char
:
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message
在两种情况下都不需要编译器停止编译。产生一个警告,足以警告分配给cname[0]
。生成的程序不是正确的程序。构造的行为是不确定的。它可能崩溃,甚至更糟,它可能不会崩溃,并且可能会更改内存中的字符串文字。
实际上,char* name
它不是指向常量的指针,而是指向变量的指针。您可能正在谈论另一个问题。