【问题标题】:Why can't I assign an array variable directly to another array variable with the '=' operator?为什么我不能使用 '=' 运算符将数组变量直接分配给另一个数组变量?
【发布时间】:2013-06-15 11:26:47
【问题描述】:

为什么以下作业不起作用?如果可能的话,我想要一个低层次的解释。另外,这是我得到的编译器错误:将 'char*' 分配给 'char [20]' 时的类型不兼容

class UCSDStudent {

  char name[20];

  public:

    UCSDStudent( char name[] ) {
      //this-> name = name; does not work! Please explain why not
      strcopy( this -> copy, copy ); //works 
    }

};

【问题讨论】:

  • 好吧,伙计们,我不会撒谎,我自己推断出这么多。
  • 或许对 C++ arrays 的这种解释就足够了?
  • @chris 谢谢!这确实回答了我的问题。它的字面意思是:“没有特别的原因,数组不能相互分配。”大声笑。
  • 好吧,当您需要数组时,总是有std::array。除其他外,它还支持分配。不过,std::string 是你应该在这里使用的。

标签: c++ arrays char-pointer


【解决方案1】:

因为当您有这样的函数调用UCSDStudent( char name[] ) 时,只会复制数组name 的地址而不是整个数组。这是一个 C\C++ 特性。

此外,定义为char name [20]name 不是可修改的左值。

关于strcpy:它会带来未定义的行为,就好像你的源数组没有NULL字符一样,它也会将一些垃圾复制到this->name。你可以阅读更多关于strcpyhere

【讨论】:

  • 即使你通过引用传递数组,它仍然不起作用。
  • @chris 我打错了,它不是左值。
  • 确定 name不是左值吗?
  • @chris 我的解释是指他的错误,因为它强调了为什么他的函数内部的东西是 char* 所以他的逻辑(我假设的 Java 逻辑)不起作用。
  • 我没说你可以。可修改性不是左值的要求。
【解决方案2】:

如果您仍想将数组分配给数组,请使用循环。

例如: UCSD学生班 {

char name[20];

public:

UCSDStudent( char name[] ) 
{

for(int i = 0; i<20; i++)
  {
  this-> name[i] = name[i];

  }
}
};  

【讨论】:

  • 如果参数name少于20个字符怎么办?
  • 请使用适当的缩进
【解决方案3】:

因为您将名称分配为一个数组,所以您不能像那样复制,并且名称有 21 个计数。您必须使用“=”来复制 with 循环,并且必须确定数组的计数。

 for(int i = 0; i<20; i++){

  this -> name[i]=name[i];   
  }

【讨论】:

    【解决方案4】:

    c 风格的数组不能像那样复制,如果你想 复制一份,你必须复制内容:

    int arr1[10] = {1,2,3,4,5,6,7,8,9,10};
    int arr2[10];
    std::copy(arr1, arr1+10, arr2);
    // std::copy() lives in <algorithm>
    // content of arr2 is a now copy of arr1
    

    但是,最好避免使用 c 样式数组等低级功能。

    如果您真正想要的是可变长度字符串,请使用std::string 相反,它支持通过赋值运算符进行复制。

    如果您真的想要一个固定长度的数组,请改用std::array&lt;T,N&gt;, 它还支持通过赋值运算符进行复制。

    另请注意,建议参数名称和成员变量名称是不同的,但使用成员初始化语法的构造函数除外:

    #include <string>
    
    class UCSDStudent
    {
        std::string name;
    public:
        UCSDStudent( std::string name )
            : name(name)
        {
        }
        void SetName( std::string new_name )
        {
            name = new_name;
        }
    };
    

    另外请注意,如果您计划为所有成员设置 setter 和 getter 变量,我可以推荐公共数据吗,至少如果类 没有class-invariant

    【讨论】:

      【解决方案5】:

      让我们以这个例子为例。

      int arr1[10] = {1,2,3,4,5,6,7,8,9,10};
      

      在 C++ 的情况下,数组名称 arr1 没有获得单独的内存位置。确实,arr1 有点保存arr1[0] 的内存位置,但这更像是过于简单化了。在 C++ 中引用数组的方式是通过符号表。创建数组时,对应于arr1,在编译时会在符号表中创建一个条目。此条目包含有关arr1(此处为整数类型数组)中元素的数据类型和arr1[0] 的地址的信息。 现在,有趣的事情就在这里。一旦在符号表中创建了一个条目,C++ 就不允许对其进行更改。

      如果您使用arr1=arr2,您实际上是在尝试将arr1 重新分配给符号表中与arr2 对应的条目。但是arr1 已经在符号表中分配了一些值。所以 C++ 会给你一个错误。

      【讨论】:

        猜你喜欢
        • 2017-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-27
        • 2014-12-05
        相关资源
        最近更新 更多