【发布时间】:2014-05-31 06:10:42
【问题描述】:
我了解在 strlen 实现中使用指向常量的指针。
size_t strlen ( const char * str );
谁能提出其他原因或提供一些“指向常量值的指针”在实践中有用的场景。
【问题讨论】:
-
您想在任何地方传递不可更改的东西而不复制它? (在 C 中。C++ 有其他可能性)
我了解在 strlen 实现中使用指向常量的指针。
size_t strlen ( const char * str );
谁能提出其他原因或提供一些“指向常量值的指针”在实践中有用的场景。
【问题讨论】:
这样想。您希望我查看变量的值,但您不希望我以任何方式更改该变量,因此您将其作为常量传递给我。当我使用你的函数并看到一个参数是常量时,我知道你和我之间有一个合同,说我不应该更改该变量的值,也不能直接这样做。
当您编写代码时,您并不总是知道谁会使用您的函数。因此,保护您的代码是一种很好的做法。它还可以保护您自己,当您更改该变量的值时,您将得到编译器错误。
附注:确实,在 C 语言中,即使参数为 const,您仍然可以更改值,但它需要另一个指针来更改内存中该变量的内容。
尝试编译此代码并注意编译器如何保护您不犯错误。
const char *cookies(const char *s)
{
return ('\0' == *s)? s: s + 1;
}
它不会让你编译,为什么?因为您正在尝试更改 const 变量。
这里有同样问题的另一个帖子:const usage with pointers in C
【讨论】:
const 变量?
将指针参数标记为const 是一种合同,您可以向用户声明您不会更改指向的值。这也是一个你不会试图写给他们的合同,所以他们给你一个指向只读内存的指针是合法的,你的函数不会崩溃——只要你履行这个合同。
它不仅仅是“有用的”,在某些情况下它是必需的,尤其是当您处理写入受保护内存的量时,例如字符串文字或存储在您的代码部分中的任何值可执行文件。
当您使用可能共享的数据时,这也很有价值:如果两个线程想要调用函数foo(char* x),每个线程都需要自己的字符串副本,否则会发生不好的事情。如果函数是foo(const char* x),那么我们知道两者共享一个指向输入的指针是安全的。
考虑一下,如果你有一个指向写保护内存的指针:
mprotect(ptr, sizeOfData, PROT_READ);
现在无法调用尝试写入 ptr 的函数而不会出现程序异常(这通常在没有人拥有缓存上的写锁时使用缓存之类的东西来完成)。
因此,此时您只能在 ptr 上调用 const 函数。
【讨论】:
指向 char 的 const 的指针是字符串字面量的类型(“”内的字面量)。这是指向 const 值的指针的主要用途。
【讨论】: