C++ 为什么';strlen(..)期望常量字符*常量字符串而不是常量字符*

C++ 为什么';strlen(..)期望常量字符*常量字符串而不是常量字符*,c++,string,C++,String,我在读这篇文章: 在string.h中,定义为: size_t strlen ( const char * str ); 如果我理解正确,strlen需要一个指向常量字符的指针。难道不是: size_t strlen ( const char* const str ); 这将确保strlen无法修改指针以指向其他指针 或者,情况是这样的: 由于str指针将通过值传递给strlen,因此在函数中对该指针的任何更改都不会更改源指针,因此没有问题 ?如果您真的阅读了该讨论,您应该了解第二个常量对函

我在读这篇文章:

string.h
中,定义为:

size_t strlen ( const char * str );
如果我理解正确,strlen需要一个指向常量字符的指针。难道不是:

size_t strlen ( const char* const str );
这将确保strlen无法修改指针以指向其他指针

或者,情况是这样的:

由于str指针将通过值传递给strlen,因此在函数中对该指针的任何更改都不会更改源指针,因此没有问题


如果您真的阅读了该讨论,您应该了解第二个
常量对函数的外部行为没有影响。对于您,
strlen
的用户来说,无论是使用
const char*
还是
const char*const
参数声明,都没有任何区别。正如您正确指出的那样,
strlen
对指针所做的任何修改都只会影响
strlen
中指针的内部本地副本。无论参数是否用second
const
声明,传递给strlen
的参数指针都将保持不变。(您的参数指针甚至不必是左值。)

第二个
const
将只对函数中局部参数变量的内部行为产生影响,从而防止
strlen
的作者修改该局部变量。他们是否想以这种方式限制自己,非正式地说,这是他们自己的事。它与strlen的用户没有任何关系

事实上,由于顶级的
const
限定符对函数类型没有影响,通常可以使用
const char*
参数声明函数,然后使用
const char*const
参数定义它。编译器(链接器)仍将这些声明视为“匹配”。这意味着,如果库作者需要,他们实际上可以使用
const char*const
参数定义
strlen
。他们只是没有告诉你这一点,因为这实际上是一个实现细节或strlen,即你不需要知道的东西

由于str指针将通过值传递给strlen,因此在函数中对该指针的任何更改都不会更改源指针,因此没有问题

对。这只是对内部处理功能的限制

这将确保strlen无法修改指针以指向其他指针

不需要,指针是按值传递的

大小(常量字符*常量字符串)

这将确保strlen无法修改指针以指向其他指针

您自己解释了原因:strlen无法修改指针

它不必要地对参数施加限制,该参数可用于在修改指针本身时计算长度,如下所示:

请参阅
strlen()
的实现,其中修改指针本身:将其指定给可修改的指针类型

另请参见lib实施:

size_t strlen(const char *str)
{
    const char *s;

    for (s = str; *s; ++s)
        ;
    return (s - str);
}

如果
str
const char*const
类型,那么
s=str
将是错误的

+1,该标准是明确的,因为顶级常量volatile限定符(在本例中,第二个
常量
)是从函数签名中删除的。@AndreyT:感谢您这么好地解释了这一点,并为我提供了一个如何将其与
declare
/
define
构造一起使用的实际用例
strlen()
在这两种情况下都无法修改传入的指针;它收到一份副本。这只有在传入指针对指针时才相关。这些函数具有相同的签名。另请参见:以及更多。
size_t strlen(const char *str)
{
    const char *s;

    for (s = str; *s; ++s)
        ;
    return (s - str);
}