Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't arrays of same type and size be assigned?

Tags:

arrays

c

If I declare two arrays - arr1 and arr2 - of, say, type int of size 10 each, and initialize first array, and I wish to create a copy of arr1 in arr2; why can't I just give the instruction arr2 = arr1 ?

I know two structures of same type can be assigned. Why is that not the case with arrays?

like image 845
KawaiKx Avatar asked Feb 12 '13 06:02

KawaiKx


People also ask

What happen if you assign value more than size in array?

If you try to access the array position (index) greater than its size, the program gets compiled successfully but, at the time of execution it generates an ArrayIndexOutOfBoundsException exception.

What will happen if you try to put so many values into an array when you initialize it that the size of the array is exceeded?

Explanation: If the index of the array size is exceeded, the program will crash.

What happens when array is full?

Approach: When we enter an element in array but array is full then you create a function, this function creates a new array double size or as you wish and copy all element from the previous array to a new array and return this new array.

How do you find the size of an array in C?

We can find the size of an array using the sizeof() operator as shown: // Finds size of arr[] and stores in 'size' int size = sizeof(arr)/sizeof(arr[0]);


2 Answers

The problem with arrays is that in all expressions (except when passed to the sizeof and the unary & operators) they convert to a pointer to their first element.

So, supposing you have:

int arr1[10];
int arr2[10];
...

Then if you write something like

arr1 = arr2;

you are actually attempting to do this:

arr1 = &arr2[0];

or this:

&arr1[0] = &arr2[0];

In both cases you have a problem preventing your code from compiling. In the former case you're attempting to assign between two incompatible types (array vs pointer), while in the latter case you're attempting to modify a constant pointer (&arr1[0]).

like image 104
Alexey Frunze Avatar answered Nov 11 '22 07:11

Alexey Frunze


Actually they can, but in indirect way:

#include <stdio.h>

int main(){
  int arr1[3] = {0};
  int arr2[3] = {1, 2, 3};

  struct tmp{
      int arr[3];
  };

  printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);

  // casting array to address of struct
  // before dereferencing & asigning to it
  *(struct tmp*)arr1 = *(struct tmp*)arr2;

  printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);

  return 0;
}

You can even make it in a little-bit more generic way:

#include <stdio.h>

#define STRUCT_TO(type, size) struct temp##__LINE__{type arr[size];}; *(struct temp##__LINE__*)
#define STRUCT_FROM *(struct temp##__LINE__*)

int main(){
  int arr1[3] = {0};
  int arr2[3] = {1, 2, 3};

  printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);

  STRUCT_TO(int,3) arr1 = STRUCT_FROM arr2;

  printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);

  return 0;
}

Or ... if we can sacrifice some portability, then we can make syntax a little-bit more symmetrical:

#include <stdio.h>

#define ARRAY_LENGTH(arr) (sizeof(arr)/sizeof(arr[0]))
#define TEMP_STRUCT struct temp##__LINE__
#define AS_STRUCT_DESTINATION(arr) TEMP_STRUCT{typeof(arr[0]) arrTmp[ARRAY_LENGTH(arr)];}; *(TEMP_STRUCT*) arr
#define AS_STRUCT_SOURCE(arr) *(TEMP_STRUCT*) arr

int main(){
  int arr1[3] = {0};
  int arr2[3] = {1, 2, 3};

  printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);

  AS_STRUCT_DESTINATION(arr1) = AS_STRUCT_SOURCE(arr2);

  printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);

  return 0;
}
like image 31
Agnius Vasiliauskas Avatar answered Nov 11 '22 07:11

Agnius Vasiliauskas