0

我希望我的函数与我在cstring/string.h库中使用的函数“strchr”一样工作。我知道我不能将“ const char* ”变量/数组转换为“ char* ”。然而,预定义的“strchr”函数如何能够同时传递“const char”和“char”数据类型数组并正常工作?我怎么能改变我的,让它也能工作?

char* my_strchr(char *place_to_find, char what_to_find)
{
for(int i=0;place_to_find[i];i++)
    if(what_to_find==place_to_find[i]) return place_to_find+i;
return NULL;
}
...
int main()
{
const char vocals1[]="AEIOUaeiou";
char vocals2[]="AEIOUaeiou";
cout<<strchr(vocals1,'e');
cout<<strchr(vocals2,'e');
cout<<my_strchr(vocals1,'e');
cout<<my_strchr(vocals2,'e');
return 0;
}

正如您可能已经知道的那样,我的第三个cout<<不起作用。我正在寻找一种方法来改变我的功能(我猜第一个参数应该以某种方式进行类型转换)。

4

3 回答 3

3

如何让我的 strchr 函数将 'const char' 和 'char' 数组作为第一个参数?

您可以将参数更改为const char*. 这将允许将两个指针传递charconst char.

但是,您返回一个指向该数组的非常量指针,如果指针指向一个 const 数组,则不应这样做。所以,当传递 a 时const char*,你的函数也应该返回const char*

然而,预定义的“strchr”函数如何能够同时传递“const char”和“char”数据类型数组并正常工作?

有两个预定义的std::strchr函数。一个接受并返回char*,另一个接受并返回const char*

const char* strchr(const char* str, int ch);
      char* strchr(      char* str, int ch);

如果您希望在有参数char*的情况下返回char*,则需要为每种情况使用不同的函数,就像标准库一样。您可以像标准库一样使用重载,也可以使用函数模板生成两种变体而不重复:

template<class Char>
Char* my_strchr(Char *place_to_find, char what_to_find)

请注意,该函数的 C 版本已声明char *strchr(const char *str, int ch)。这使得单个函数在两种情况下都可用,但不安全,因为即使将 const 数组作为参数传递,类型系统也无法阻止函数的用户修改返回的非 const 指针。

于 2019-05-03T16:24:54.207 回答
1

按照 C++ 标准库中的方式进行两次重载:

char*       my_strchr(      char *place_to_find, char what_to_find)
const char* my_strchr(const char *place_to_find, char what_to_find)

即使在您的情况下,只有第二个重载就足够了(demo),当您需要找到一个字符然后替换它时,您将无法支持一个重要的用例:

// This would not work with only one overload:
char *ptr = my_strchr(vocals2,'e');
if (ptr) {
    *ptr = 'E';
}

这就是为什么非const过载是必要的。

注意:我假设您将其作为学习练习,因为新开发不再需要 C 风格的字符串函数,已被std::string功能取代。

于 2019-05-03T16:38:40.493 回答
1

简短回答:将 place_to_find 的类型设为 const char*

您的错误的原因是您不能将指向 const char 的指针隐式转换为指向非 const char 的指针。如果可以,那么您可以更改指针指向的 char,这将破坏首先将其设置为 const char 类型的目的。

您可以将指向非 const char 的指针隐式转换为指向 const char 的指针,因为它不会删除任何限制。

LE:另外,返回值应该是一个 const char*,因为同样,如果你不这样做,它会删除不允许的 const 限制。唯一的问题是您将无法通过返回的指针修改数组。如果你也想要这个,那么你将不得不在 char 和 const char 上重载该方法。

于 2019-05-03T16:23:48.840 回答