简体   繁体   English

为什么C中的字符串用'const'声明?

[英]Why are strings in C declared with 'const'?

For example, why not: 例如,为什么不:

char *s= "example";

instead of: 代替:

const char *s= "example";

I understand that const makes it unchangeable, but why do I receive an error when compiling the first? 我知道const使它不可更改,但为什么在编译第一个时会收到错误?

Additionally, how does the concept apply to 此外,该概念如何适用

int * x;

vs VS

const int *x;

I see the second used a lot more, is it good practice to use "cons int *"? 我看到第二个使用了更多,使用“cons int *”是好的做法吗?

There's no requirement to use const , but it's a good idea. 没有要求使用const ,但这是一个好主意。

In C, a string literal is an expression of type char[N] , where N is the length of the string plus 1 (for the terminating '\\0' null character). 在C中,字符串文字是char[N]类型的表达式,其中N是字符串的长度加1(对于终止'\\0'空字符)。 But attempting to modify the array that corresponds to the string literal has undefined behavior. 但是,尝试修改与字符串文字对应的数组具有未定义的行为。 Many compilers arrange for that array to be stored in read-only memory (not physical ROM, but memory that's marked read-only by the operating system). 许多编译器安排将该数组存储在只读存储器中(不是物理ROM,而是由操作系统标记为只读的存储器)。 (An array expression is, in most contexts converted to a pointer expression referring to the initial element of the array object.) (在大多数上下文中,数组表达式转换为指向数组对象的初始元素的指针表达式。)

It would have made more sense to make string literals const , but the const keyword did not exist in old versions of C, and it would have broken existing code. 将字符串文字设为const会更有意义,但旧版本的C中不存在const关键字,它会破坏现有代码。 (C++ did make string literals const ). (C ++确实使字符串文字为const )。

This: 这个:

char *s= "example"; /* not recommended */

is actually perfectly valid in C, but it's potentially dangerous. 实际上在C中完全有效,但它有潜在危险。 If, after this declaration, you do: 如果在此声明之后,您执行以下操作:

s[0] = 'E';

then you're attempting to modify the string literal, and the behavior is undefined. 然后你试图修改字符串文字,并且行为是未定义的。

This: 这个:

const char *s= "example"; /* recommended */

is also valid; 也有效; the char* value that results from evaluating the string literal is safely and quietly converted to const char* . 通过评估字符串文字得到的char*值安全且安静地转换为const char* And it's generally better than the first version because it lets the compiler warn you if you attempt to modify the string literal (it's better to catch errors at compile time than at run time). 它通常比第一个版本更好,因为它允许编译器在您尝试修改字符串文字时警告您(在编译时捕获错误比在运行时捕获错误更好)。

If you get an error on your first example, then it's likely that you're inadvertently compiling your code as C++ rather than as C -- or that you're using gcc's -Wwrite-strings option or something similar. 如果你的第一个例子出现错误,那么很可能你无意中将你的代码编译为C ++而不是C - 或者你正在使用gcc的-Wwrite-strings选项或类似的东西。 ( -Wwrite-strings makes string literals const ; it can improve safety, but it can also cause gcc to reject, or at least warn about, valid C code.) -Wwrite-strings使字符串文字为const ;它可以提高安全性,但它也可能导致gcc拒绝或至少警告有效的C代码。)

With Visual Studio 2015 at warning level 4, this compiles and runs whether compiled as C or C++: 使用警告级别4的Visual Studio 2015,无论是编译为C还是C ++,都会编译并运行:

#include <stdio.h>

char *s1= "example\n";
const char *s2= "example\n";

int main(int argc, char **argv)
{
    printf(s1);  // prints "example"
    s1[2] = 'x';
    printf(s1);  // prints "exxmple"

    printf(s2);

    return 0;
}

If I add this line, it will fail to compile as C or C++ with every compiler I know of: 如果我添加这一行,它将无法用我知道的每个编译器编译为C或C ++:

    s2[2] = 'x'; // produces compile error

This is the error the const keyword is designed to avoid. 这是const关键字旨在避免的错误。 It simply tells the compiler not to allow assignments to the object pointed to. 它只是告诉编译器不允许对指向的对象进行赋值。

It doesn't matter if your pointer points to char or int or anything else. 如果您的指针指向charint或其他任何内容都无关紧要。 The const keyword has the same effect on all pointers, and that's to make it impossible (well, very hard) to assign to the thing declared const . const关键字对所有指针都有相同的效果,这就是为了分配给声明为const的东西是不可能的(好的,非常困难的)。

A string literal used as a value compiles to an array of char that should not be modified. 用作值的字符串文字将编译为不应修改的char数组。 Attempting to modify it invokes undefined behavior. 尝试修改它会调用未定义的行为。 For historical reasons of backward compatibility, its type is char [] although is really should be const char [] . 由于向后兼容的历史原因,其类型为char []但实际上应该是const char [] You can enable extra compiler warnings to change this and instruct the compiler to consider such strings to be const . 您可以启用额外的编译器警告来更改此值,并指示编译器将此类字符串视为const

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM