当得到 我的代码在这里审查 使用的问题 const 关键词出现了。据我所知,它用于实现变量的只读行为。

我很困惑它在什么情况下有用。

  • 是否应该为了函数原型的清晰性而使用它?
  • 是否应该在代码开发过程中将其用作安全措施?
  • 是否应该在各种函数范围内使用它来声明运行时常量?
  • 到底应该使用它吗?

这些问题只是我面临的困惑的例子。普遍的困惑是

  • 应该是什么时候 const C语言编程中使用的关键字?
  • 在 C 中使用此关键字可以获得哪些不同类型的好处?
  • 使用有什么缺点吗 const 关键词?


有人指出,由于我的问题细节中存在所有这些问题,这个问题可能太宽泛。我只是想澄清一下,这些问题只是为了澄清对主要问题的困惑。

在 C 语言中何时应使用 const 关键字来表示变量?出于什么目的?

它也可以改写为

正确使用 const 与C`中的关键字的优点和缺点相同。

有帮助吗?

解决方案

在审查代码时,我应用以下规则:

  • 总是使用 const 为了通过引用传递的函数参数,该函数不会修改(或免费)指向的数据。

    int find(const int *data, size_t size, int value);
    
  • 总是使用 const 对于可能使用 #define 或枚举定义的常量。结果,编译器可以在只读存储器 (ROM) 中定位数据(尽管在嵌入式系统中链接器通常是实现此目的的更好工具)。

    const double PI = 3.14;
    
  • 切勿在函数中使用 const 原型 对于传递的参数价值. 。它没有任何意义,因此只是“噪音”。

    // don't add const to 'value' or 'size'
    int find(const int *data, size_t size, int value); 
    
  • 在适当的情况下,使用 const volatile 位于程序无法更改但仍可能更改的位置。硬件寄存器是这里的典型用例,例如反映设备状态的状态寄存器:

    const volatile int32_t *DEVICE_STATUS =  (int32_t*) 0x100;
    

其他用途是可选的。例如,函数内的函数参数 执行 可以标记为 const。

// 'value' and 'size can be marked as const here
int find(const int *data, const size_t size, const int value)  
{
     ... etc

或函数返回获得的值或计算结果,然后永远不会改变:

char *repeat_str(const char *str, size_t n) 
{
    const size_t len = strlen(str);
    const size_t buf_size = 1 + (len * n);
    char *buf = malloc(buf_size);
    ...

这些用途 const 只是表明您不会更改该变量;它们不会改变变量的存储方式或位置。编译器当然可以计算出变量没有改变,但是通过添加 const 你允许它强制执行。这可以帮助读者并增加一些安全性(当然,如果您的功能很大或 复杂到这一点会造成很大的不同,可以说你还有其他的 问题)。 编辑 - 例如。具有嵌套环和许多长或类似变量名称的200条密集编码功能,知道某些变量永远不会改变可能会大大减轻理解。这些功能设计不当或 维护。


问题与 const. 。您可能会听到“const 中毒”这个词。添加时会出现这种情况 const 函数参数的 "constness "会导致 传播。

编辑-常量中毒:例如在函数中:

int function_a(char * str, int n)
{
    ...
    function_b(str);
    ...
}

如果我们改变 strconst, ,然后我们必须确保 fuction_b 还需要 a const. 。依此类推如果 function_b 通过 strfunction_c, 等等可以想象,如果这种情况蔓延到许多地方,那将是非常痛苦的。 单独的文件/模块。如果它传播到一个无法 如系统库),则有必要进行转换。如此洒const 现有代码中的周围可能是自找麻烦。在新代码中 不过,最好 const 在适当的情况下始终符合资格。

更隐蔽的问题是 const 因为它不在原 语言作为一个附加组件,它不太适合。首先,它有两个含义 (如上述规则,意思是 "我不会修改这个 "和 "这个不能修改")。但更重要的是,它可能很危险。例如,编译和 运行这段代码时(取决于编译器/选项),很可能会崩溃。 运行:

const char str[] = "hello world\n";
char *s = strchr(str, '\n');
*s = '\0';

strchr 返回一个 char* 不是一个 const char*. 。因为它的调用参数是const 它必须 投掷 调用参数为 char*. 。在这种情况下 会丢失真正的只读存储属性。 编辑:- 这通常适用于只读存储器中的变量。我所说的“ROM”不仅指物理 ROM,还指任何受写保护的内存,就像在典型操作系统上运行的程序的代码部分一样。

许多标准库函数的行为方式相同,因此请注意:当你 有 真实的 常数(即存储在 ROM 中),您必须非常小心,以免 失去恒定性。

其他提示

Generally in any programming language its recommended to use const or the equivalent modifier since

  • It can clarify to the caller that what they passed in is not going to change
  • Potential speed improvements since the compiler knows for certain it can omit certain things that are only relevant if the parameter can change
  • Protection from yourself accidentally changing the value

In agreement with TheLQ's statements:

When working with a team of programmers declaring const is a good way of indicating that said variable shouldn't be modified, or just for reminding yourself in large projects. It's useful in that sense, and can save many headaches.

Yes, it's basically the TheLQ's answer.

Is a security measure for the programmer so you don't modify a variable, and to not call functions that may modify them. In an array or structure the const specifier indicates that the values of their contents won't be modified, and even the compiler will not allow you to do so. You still can easily change the value of the variable with just a cast however.

In what I have usually see, it's mostly used to add constant values in code, and to indicate that the array or structure won't be modified if you call a particular function. This last part is important, because when you call a function that WILL modify your array or structure, you may want to keep the original version, so you create a copy of the variable and then pass it to function. If that is not the case, you don't require the copy, obviously, so for example you can change,

int foo(Structure s);

to

int foo(const Structure * s);

and not getting the copy overhead.

Just to add, note that C has particular rules with the const specifier. For example,

int b = 1;
const int * a = &b;

is not the same as

int b = 1;
int * const a = &b;

The first code won't allow you to modify a. In the second case, the pointer is constant but its contents is not, so the compiler will allow you to say * a = 3; without a compiler error, but you can't make a to be a reference to another thing.

许可以下: CC-BY-SA归因
scroll top