【问题标题】:Why don't you have to dereference a pointer using strcpy and strlen?为什么不必使用 strcpy 和 strlen 取消引用指针?
【发布时间】:2020-10-05 00:24:11
【问题描述】:

我一直在尝试创建自己的字符串类,但在下面的代码中遇到了问题:

String::String(const char *s) : str {nullptr}
{
    if(s == nullptr)
    {
        str = new char[1];
        *str = '\0';
    }else{
        str = new char[std::strlen(*s)+1];
        strcpy(*str,*s);
    }
}

我传入构造函数的是一个 const char 指针;要获得指针内的值,我必须取消引用它,对吗?但是为什么在将参数放入 strcpy 和 strlen 时不必取消引用指针呢?

如下所示。

String::String(const char *s) : str {nullptr}
{
    if(s == nullptr)
    {
        str = new char[1];
        *str = '\0';
    }else{
        str = new char[std::strlen(s)+1];
        strcpy(str,s);
    }
}

【问题讨论】:

  • std::strlen 不采用“指针内的值”。它需要一个指针。出于同样的原因,您的 String 构造函数需要一个指针。
  • 查看strlen 的签名。它需要一个const char*en.cppreference.com/w/cpp/string/byte/strlen 它需要 const char*,因为它就是这样设计的。
  • 取消引用 const char * 将产生 char,如果您想对整个字符串而不是单个字符进行操作,这将没有用。
  • 你能通过看第一个字符来判断一个字符串有多长吗?或者我在想哪本小说以'G'开头?
  • 既然您有兴趣重新创建标准库的一部分(一个有用的练习),您会考虑编写自己的strlenstrcpy 版本吗?这可能会导致理解。

标签: c++ pointers function-pointers


【解决方案1】:

strcpystrlen 都有 char * 作为参数,因此您不需要遵守。

更多信息: https://www.cplusplus.com/reference/cstring/strcpy/

https://www.cplusplus.com/reference/cstring/strlen/

【讨论】:

    【解决方案2】:
    str = new char[std::strlen(*s)+1];
    

    我传入函数的是一个常量指针

    不,这不是你通过的。您传递给函数的是charchar 不是指针。

    要获取指针内的值,我必须取消引用它,对吗?

    当您有一个指向char 的指针时,要获得指向的char,您必须通过指针间接访问。但是std::strlen 不期望char 作为参数,因此char 不是您所需要的,因此您不需要通过指针间接获得char

    std::strlen 的参数是指向char 的指针。所以,如果你有一个指向char 的指针,并且你需要将一个指向char 的指针传递给函数,那么你需要对指向char 的指针做什么才能获得指向@987654335 的指针@ 可以传递给函数吗?您无需执行任何操作,因为您已经有一个指向 char 的指针,您可以将它传递给函数(假设值满足函数的先决条件)。

    【讨论】:

      【解决方案3】:

      你必须传递字符串的开始地址,而字符串本质上是一个非零字节序列。一个最简单的strlen 看起来像:

      size_t strlen(const char* s)
      {
          const char* p = s;
          
          while(*p) p++;
          return p - s;
      }
      

      实际实现通常通过检查长字和/或使用直接汇编代码进行一些优化,这比逐字节扫描内存有更好的性能。不知道字符的地址是做不到的,尤其是在不存在引用的C语言中。

      【讨论】:

        猜你喜欢
        • 2017-06-08
        • 2011-02-24
        • 1970-01-01
        • 2013-04-01
        • 2014-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        相关资源
        最近更新 更多