1

采用以下两种形式创建字符串:

const char* pt1 = "Hello";
      char* pt2 = "Goodbye";

上面有什么用const?据我了解,做:

ptr = "Adios";

两者都适用,因为这会更改指针的地址,但尝试更改字符串中的字母对两者都将失败:

const char* pt1 = "Hello";

编译器错误:分配只读位置

char* pt2 = "Goodbye";

运行时错误:段错误,试图更改 .rodata

由于它们产生相同的结果——即错误——const在定义字符串时使用有什么好处吗?

4

5 回答 5

3

将指向字符串常量(又名字符串文字)的指针定义为const char *允许编译器检测不正确的访问,如果您尝试在代码中的其他位置修改pt1指向的内容,*pt1 = 'A';而如果pt1有 type ,则在运行时只会有未定义的行为char *,导致在某些架构上崩溃,对其他架构的影响不太明显但可能更具破坏性。

为了扩展这个主题,有时const对于指针定义的含义会产生混淆:

const char *pt1 = "Hello";定义一个可修改的指针pt1,指向一个char不能通过它修改的数组。由于"Hello"是一个字符串常量,它是正确的类型pt1pt1可以修改为指向另一个字符串或char,可修改或不可修改,或设置为NULL

char *pt2 = "Hello";定义一个可修改的指针pt2,指向一个char可以通过它修改的数组。尽管"Hello"与历史代码兼容,C 标准仍然允许这样做。gccclang-Wwrite-strings可以使用命令行选项禁用此行为。我强烈建议使用此警告和更多警告以避免常见错误。

const char * const pt3 = "Hello";定义一个常量指针pt3,指向一个char不能通过它修改的数组。pt3不能修改为指向另一个字符串,甚至不能设置为NULL.

char * const pt4 = "Hello";定义一个常量指针pt4,指向一个char可以通过它修改的数组。pt4初始化后无法更改。

char并且const可以按任何顺序放置,但是const是在之前还是之后*有很大的不同。

于 2021-02-07T21:36:05.127 回答
1

为什么将const char*表单用于字符串

在不应修改const char *ptr1引用的字符串并允许编译器基于此进行优化时使用。

使用字符串文字进行分配时总是如此。

char *ptr2当引用的字符串可能被修改时使用。

的危险char* pt2 = "Goodbye";在于后面的代码可能会尝试更改 引用的数据pt2,这些数据目前指向 字符串文字

于 2021-02-07T22:08:27.393 回答
1

上面的 const 有什么用?

const char* pt1 = "Hello";

仅仅意味着您不能更改pt1指向的数据。

两个都

const char* ptr1 = "Hello";
char* pt2 = "Goodbye";

为字符串文字创建静态内存。我建议你阅读这个

所以优点是你总是会在第一次出现编译时错误,而第二次它可能取决于编译器。一些编译器会自动执行此操作。请参阅我链接到的页面。

于 2021-02-07T21:41:50.477 回答
0

正如 KamilCuk 指出的那样,修改const char* pt1 = "Hello";已经在编译时给你一个错误,你可以修复代码,重新编译,一切都很好。修改char* pt1 = "Hello";会在运行时引发错误,并且您不希望所有 100 万用户重新下载并重新安装您的程序(您必须首先为此购买更好的互联网连接)。所以,你绝对应该使用const char*.

于 2021-02-07T21:35:47.277 回答
0

为什么对字符串使用 const char* 形式

通知您自己和其他开发人员指针指向的内存无法修改。在这个上下文中const是一个关键字,主要用于程序员通知程序员指针指向的数据是const

基本上,您可以做任何事情来将错误煮沸以被编译器捕获,对吗?

是的。这就是开发人员推动发明更好的静态代码分析工具的原因。静态代码分析的工具有很多,最近GNU编译器gcc 11自带了内部代码静态分析。这也是语言Rust被发明并如此流行的原因。所有工具都试图在编译时推送尽可能多的错误以“静态地”检测到。

Gcc 还有一个警告-Wwrite-strings,警告诸如char *str = "str"将 const 文字分配给非常量指针的代码。

于 2021-02-07T21:40:31.813 回答