为啥字符串函数有一些参数作为 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?
为啥函数 `memchr()` 使用 `int` 作为 `char` 类型的参数?