【问题标题】:How can I make my strchr function take both 'const char' and 'char' arrays as first parameter?如何让我的 strchr 函数将 'const char' 和 'char' 数组作为第一个参数?
【发布时间】:2019-09-22 05:30:37
【问题描述】:

我希望我的函数与我在 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&lt;&lt; 不起作用。 我正在寻找一种方法来改变我的功能(我猜第一个参数应该以某种方式进行类型转换)。

【问题讨论】:

  • 如果您不编辑这些值,您应该接受并返回const char* 类型。然后当提供char* 时,它将隐式转换为const char*
  • doc可以看出,有2个重载。 (并且你有几种方法来分解实现)。
  • 正如 Kyle 所说,如果您的函数不打算修改值,则应始终使用 const char*。他们可以将 char* 传递给它。如果您的函数要修改该值,则不应应用 const 版本。
  • @KyleWillmon -- 你的评论是正确的,除了“隐式转换”应该是“隐式转换”。强制转换是您在源代码中编写的内容,用于告诉编译器进行转换。不存在隐式强制转换。
  • @PeteBecker 谢谢。我无法再编辑它,但我会在以后尝试使用正确的语言。我也意识到两个重载是一个更好的解决方案,因为在可变字符串的情况下,您可能希望使用返回的指针来改变字符串(所以当给定 char* 时的返回应该是 char* 而不是比const char*)

标签: c++ string function parameters strchr


【解决方案1】:

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

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

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

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

【讨论】:

  • 限制来自于返回值。
【解决方案2】:

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

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

但是,您返回一个指向该数组的非 const 指针,如果指针指向一个 const 数组,则不应该这样做。因此,当传递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 指针。

【讨论】:

    【解决方案3】:

    做两个重载,就像在 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 功能取代。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-16
      • 2016-04-22
      • 1970-01-01
      • 2013-12-20
      • 2018-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多