为啥字符串函数有一些参数作为 const char *(指向常量字符的指针)?

Posted

技术标签:

【中文标题】为啥字符串函数有一些参数作为 const char *(指向常量字符的指针)?【英文标题】:Why do string functions have some parameters as const char *( pointers to constant characters)?为什么字符串函数有一些参数作为 const char *(指向常量字符的指针)? 【发布时间】:2017-02-19 10:41:11 【问题描述】:

可以在 C 中修改字符串(字符数组),但不能修改字符串文字。但是为什么像 strlen(const char *str) 这样的字符串函数有一个指向常量字符的指针呢?

【问题讨论】:

请注意,const 和 "constant" 在 C 中实际上是两个不同的东西。const 表示只读。 “常量”表达式是可以在编译时评估的表达式。例如:const int r = rand();r 的值显然不是常量,但初始化后不能合法更改。 【参考方案1】:

因为他们不修改(也不需要修改)他们的参数字符串。这就是const 的意思。

如果strlen 的参数被声明为char *(不是const),您将无法使用strlen 来确定常量字符串的长度。例如

size_t my_own_strlen(char *str)  /* whatever */ 

const char hello[] = "Hello";

size_t l1 = my_own_strlen(hello); // Error: cannot convert `const char *` to `char *`
size_t l2 = strlen(hello);        // OK

将该参数声明为const char * 使strlen 适用于常量和非常量字符串。

【讨论】:

【参考方案2】:

const T* p表示p指向的内存不能通过变量p修改。它代表了一个承诺,p 不会用于修改指向的内存。这并不意味着p 指向永远无法修改的内存。

T* 转换为const T* 总是安全的:

T value;
T* q = &value; // Not const.
const T* p = q; // No cast necessary.
p = &value; // No cast necessary here either.

因此,如果字符串函数不改变其参数,则将其参数声明为const char* 并没有什么坏处:

const char* s = "string literal";
strlen(s); // This is legal.

char buf[] =  'h', 'e', 'l', 'l', 'o', '\0' ;
strlen(buf); // This is legal too.

但是,如果参数被声明为 char*,那么您将无法const char* 传递给它。

 void foo(char* s);

 const char* s = "string literal";
 foo(s); // This will fail to compile.

因此,如果可能的话,最好记住用const 限定指针参数,这样做可以证明函数承诺不会改变指针。

【讨论】:

【参考方案3】:

这只是意味着函数不会修改指针指向的数据。为您提供一些类型安全性和优化编译器的机会。

【讨论】:

它没有提供任何优化机会,只是为了通过类型安全避免意外写入 嗯,它可以帮助编译器推断该函数是纯函数。有很多优化机会。例如,编译器可以使用它来将函数调用更改为常量或执行某种 CSE 该函数仍然可以丢弃 const 并修改指向的对象(如果该对象实际上不是 const,则这不是未定义的行为),因此调用代码不能假定该函数没有更改对象。【参考方案4】:

strlen(const char *str) 有一个指向常量字符的指针,因为它将输入 *str 作为 只读 字符串,然后执行计算并返回值而不修改原始字符串,因为它为了计算字符串的长度,不需要修改内存中的字符串。

【讨论】:

以上是关于为啥字符串函数有一些参数作为 const char *(指向常量字符的指针)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们使用 const 和 reference 作为参数来复制构造函数?

为啥 atoi 函数不能将 const char * 转换为 int?

C++ 函数形参里的const char作为返回值问题

为啥函数 `memchr()` 使用 `int` 作为 `char` 类型的参数?

为啥 const QString& 参数返回错误的 const char* 指向数据的指针

为啥 const char* 不能与 boost 的 stringstream 和 read_json 一起使用?