字符串赋值差异

时间:2011-09-17 07:46:39

标签: c++ string

METHOD 1METHOD 2之间的区别是什么?

#include <iostream>
#include <string>

using namespace std;
int main()
{
    // METHOD 1
    std::string name = "testing";
    std::string nameC = name;
    cout << "nameC is : " << nameC << endl;

    // METHOD 2
    char nameC1[8];
    const char* name1 = "testing";
    strlcpy(nameC1,name1,sizeof(nameC1));
    cout << "nameC1 is  : " << nameC1 << endl;
 }

哪个效率更高?快点?什么时候应该跟随另一个呢?

3 个答案:

答案 0 :(得分:7)

C ++方式

std::string name = "testing";
std::string nameC = name;

在C ++中,资源会自动处理。这称为RAII

在这里,字符串可以被视为“值类型”,也就是说,像intdouble一样,可以安全地复制,修改,返回,作为参数等,没有风险。 它正常工作

RAII部分表示字符串具有指向其内容的内部指针(即“测试”)。复制字符串时,将复制内容。退出作用域时,将销毁该字符串,自动清除/取消分配内容。这里没有内存泄漏。

根据实施情况,存在优化。例如,您可以拥有COW,这意味着上面的副本类似于指针副本。在其他情况下,字符串包含一个小缓冲区,这意味着小字符串不需要堆分配/释放。

您的里程可能会有所不同,但重要的一点是:

  • RAII
  • 它只是工作

C方式

//METHOD 2**
char nameC1[8];
const char* name1 = "testing";
strlcpy(nameC1,name1,sizeof(nameC1));

在C中,没有这样的自动行为,所以一切都必须手工完成,一条修改过的代码行可以在没有编译器告诉你的情况下破坏另一行代码。

在上面的当前情况中,由于nameC1是堆栈上的数组,因此无法返回它。这是一个很大的缺点,但另一方面,它意味着堆上没有分配。

C方式的另一个缺点是您必须使用strlcpy,因为您不希望缓冲区溢出(例如,如果name1是"testingtestingtestingtesting"而不是"testing") ,所以你必须提供接收字符串的大小。在这里,使用数组,这几乎很简单,因为sizeof可以解决问题(但将类型从char更改为wchar_t,而sizeof部分则需要修改...)

但是如果字符串类型nameC1更改为char *(因为,例如,您想要从函数返回它),那么您必须(重新)将其内存分配给将“测试”放在里面,意味着你需要知道name1的长度(这可能是昂贵的,和/或繁琐的),然后,不要忘记在不再需要它时解除分配。

所以:

  • 代码很脆弱,因为它取决于使用的类型。改变一件事,代码被打破
  • 代码是有限的,因为你不能返回在堆栈上声明的数组
  • 代码可能已损坏,因为您的接收缓冲区不能容纳超过7 + 1个字符

结论

上面的C代码非常脆弱。

改变一件事,其他人停止正常工作。例如,将数组更改为指针会破坏strlcpy,因为它依赖于sizeof(如果是指针,则会返回错误的值)。

即便如此,最终用户也可能认为代码已被破坏,因为您不会在C数组中放入超过7个字符加\0的内容,这意味着字符串可能会被截断。

C ++版本的代码中不存在这些问题:C ++代码行自然会处理所有情况。

因此,结论是您应该在代码中尽可能std::string,因为它会以零或边际成本自动化事物。

在极少数情况下,当您需要更快的处理时(通常,您希望删除堆分配/释放部分),然后根据需要修改代码(通常通过分配固定大小的缓冲区,在交换中接受其限制)它的优点)。

答案 1 :(得分:3)

使用方法1.


从长远来看,Method 1是:

  • 易于使用 - 您无需手动创建笨重的C - string实施。
  • 更具可读性。
  • C ++ 即可。

Method 2是:

  • 难以使用。
  • 不太可读。
  • <强> C 即可。

对于'更快',Method可能是,取决于您的实施/等。在面对上面列出的其他点时,分钟潜在差异无论如何都不重要。

答案 2 :(得分:1)

Method1是C ++ Metthod2是C

如果您的程序是C ++(如问题的C ++标记所示),请使用方法1:它有助于更​​轻松地编写字符串操作代码,并允许更好的objet生命周期灵活性。它还允许与其他C ++对象(如集合)实现更好的互操作性。