Why can't I assign an array variable directly to another array variable with the '=' operator? [duplicate]
Asked Answered
S

5

5

Why does the following assignment not work? I would like a low-level explanation if possible. Also, here's the compiler error I get: incompatible types in assignment of 'char*' to '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 
    }

};
Sox answered 19/6, 2013 at 3:51 Comment(7)
Because C isn't all prettied up like Java (a shame that C++ had to inherit that imo). C++ mostly is if you use C++ features instead of C.Valeric
Because of C and pointers.Ottie
Well guys, I'm not gonna lie, I deduced that much on my own.Sox
The moral of the story being that you can't complain about C++ here, only C. In C++, you have std::string name; and this->name = name;.Valeric
Perhaps this explanation of C++ arrays would suffice?Valeric
@Valeric Thanks! That actually did answer my question. It literally says, "For no particular reason, arrays cannot be assigned to one another." lol.Sox
Well, when you need arrays, there's always std::array. It supports assignment, among other things. std::string is what you should use here, though.Valeric
J
5

Because when you have a function call like this UCSDStudent( char name[] ) only the adress of the array name is copied instead of the whole array. It is a C\C++ feature.

Furthermore the name defined as char name [20] is not a modifiable lvalue.

Regarding strcpy: it will bring undefined behaivour as if your source array doesn't have a NULL character it will copy some trash to this->name too. You may read more about strcpy here

Jannet answered 19/6, 2013 at 4:1 Comment(8)
Even if you passed the array by reference, it still wouldn't work.Valeric
@Valeric I had a typo, it is not a lvalue.Jannet
Are you certain name isn't an lvalue?Berlin
@Valeric my explanation refers to the error he has as it underlines why the thing inside his function is a char* so his logic (the Java one I assume) doesn't work.Jannet
name, in char name[20] is most certainly an lvalue. Otherwise you wouldn't be able to take its address, like this: char (*name_ptr)[20] = &name;Overtly
@BenjaminLindley but you can't modify it.Jannet
I didn't say you could. Modifiability is not a requirement for lvalue-ness.Overtly
@BenjaminLindley yes, my mistake, I disregarded the word "modifiable", thank you for the correction.Jannet
P
1

If you still want to assign array to array, use a loop.

for eg: class UCSDStudent {

char name[20];

public:

UCSDStudent( char name[] ) 
{

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

  }
}
};  
Paulpaula answered 19/6, 2013 at 4:56 Comment(2)
What if the parameter name has less then 20 characters?Caudex
please use proper indentationCoinage
G
1

Because you assingned name as an array so you can not copy just like that and there is 21 count which name has. You must use "=" to copy an with loops and you have to identify array's count.

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

  this -> name[i]=name[i];   
  }
Geek answered 11/2, 2017 at 23:10 Comment(0)
E
1

Let's take this example.

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

In case of C++, the array name arr1 does not get a separate memory location. It's true that arr1 sort of holds the memory location of arr1[0] but that is more of an oversimplification. The way arrays are referenced in C++ is via the symbol table. When an array is created, corresponding to arr1 an entry is created in the symbol table at compile time. This entry contains the information about the data-type of elements in arr1 (which here is an integer-type array) and the address of arr1[0]. Now, here lies the interesting thing. Once an entry is created in the symbol table, C++ does not allow for it be changed.

If you do arr1=arr2, what you are essentially trying to do is reassign arr1 to the entry corresponding to arr2 in the symbol table. But arr1 has already been assigned some value in the symbol table. So C++ will give you an error.

Ehr answered 8/7, 2017 at 11:1 Comment(0)
C
0

c-style arrays are not copyable like that, if you want to copy one, you have to copy the content instead:

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

However, low-level features like c-style arrays, are best avoided.

If what you really wanted was a variable length string, use std::string instead, it supports copying via assignment operator.

If you really wanted a fixed length array, use std::array<T,N> instead, it also supports copying via assignment operator.

Also note, a recommendation is that parameter names and member variable names are distinct, except for constructors where you use the member initialization syntax:

#include <string>

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

Also note, if you planning on having setters and getters for all member variables, may I recommend public data instead, at least if the class does not have an class-invariant.

Coinage answered 11/2, 2017 at 23:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.