【问题标题】:C++ Can't edit a string in functionC ++无法在函数中编辑字符串
【发布时间】:2015-03-10 19:58:18
【问题描述】:

我被难住了。这个实在想不通。

int main(){
    string blah = "text";
    example(&blah);
}

void example(string *h){
    *h[3]='l';
}

我在上面的函数中试图做的是在不使用全局变量的情况下编辑原始字符串的第 4 个字符。我原以为这会起作用,因为我知道我可以用整数做类似的事情。猜测这与字符串/字符转换有关,但我在网上找不到太多信息。

【问题讨论】:

  • 运算符优先级:(*h)[3]。但是,如果您想让它变得简单,请通过引用传递:void example(string& h) { h[3] = '1'; }
  • std::string*eeewwww...

标签: c++ string function


【解决方案1】:

那不是 C,是 C++,通过引用传递让你的生活更轻松:

void example(string & h){
    h[3]='l';
}

在 C++ 中将其作为指针传递(在该特定用例中)几乎是零意义,这是“C 风格”通过引用传递,由于在 C++ 中引入引用而过时。

通常,如果您打算使用指针算术,则通常需要作为指针传递,C++ 标准库容器大多已经过时,或者为了符合某些已建立的库 API - 有大量使用指针,但意图与您的用例略有不同。

顺便说一句,std::string 有一个 at() 方法,使用指针可能会更优雅一些:

h->at(3) = 'l';

当然,您也可以将[] 运算符作为函数从指针中调用:

h->operator [](3) = 'l';

但这有点违背了目的。

【讨论】:

  • 通过指针而不是引用传递有一个参数:接口的清晰性。如果对象作为 const 引用或非常量引用传递,则在调用站点不可见。通过指针传递对象所需的额外& 使潜在更改在调用站点可见(例如,谷歌风格指南强制执行此操作)
  • @stefan - 确实如此,但在大多数当代 IDE 中,您只需将鼠标悬停在调用上即可查看函数签名。当您键入呼叫的左括号时,您通常也会得到它。
【解决方案2】:

执行:(*h)[3]='l';

这是因为运算符的优先级,[]* 之前。

【讨论】:

  • 甜蜜而简单。图例。
【解决方案3】:

问题很简单:*h[3] 等效于 *(h[3]),而不是 (*h)[3],因为运算符优先级。

有三种方法可以规避这个问题:

  1. 改变界面:

在 C++ 中,您可以通过引用传递对象

void example(std::string& h)
//                      ^
{
    h[3] = '1';
}

在函数 example 内对 h 所做的所有更改在“函数外”都是可见的。

  1. 保持界面不变:

如果改变界面不是一种选择,你仍然可以让你的生活更轻松

void example(std::string* h_ptr)
{
    assert( h_ptr != nullptr ); // make sure you didn't pass a NULL pointer
    std::string& h = *h_ptr;    // create a reference from a non-NULL pointer
    h[3] = '1';
}
  1. 绝对精确,生活在一个危险的世界中:

您必须非常小心运算符的优先级。最好避免使用这种解决方案。

void example(std::string* h)
{
   (*h)[3] = '1'; // be explicit on the order you want (you will often make mistakes!)
}

【讨论】:

  • assert(h_ptr) 有什么问题?可读性?
  • @ddriver 没有错,但这是个人喜好。我认为assert(h_ptr != nullptr) 更具可读性。
  • “非常多” - 听起来很多 ;) 在旁注中,我发现它不是最佳的,不仅打字时间更长,而且它增加了另一个层次的推理,不知何故听起来问“如果这是真的”比“如果这不是不真实的”更清楚:)
  • @ddriver 我更喜欢“这个指针不是 nullptr”的说法,而不是“这个指针是真的”。指针不是“真”,它要么有效,要么无效。
  • 您使用if 的事实使它解析为布尔值,它是真或假,除了指针可以通过这样的检查并且如果它指向错误的地址仍然无效.我同意有时隐式转换是不好的,它们在 C++ 中太常见了,并且在许多情况下使代码的可读性降低,但在那种特定情况下并非如此,至少这对我来说是这样的。仍然“水是湿的是真的吗”听起来比“水不湿是不是真的”好一点。
猜你喜欢
  • 1970-01-01
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多