Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I copy an array by using `=`?

Tags:

arrays

c

I'm starting to learn C by reading K&R and going through some of the exercises. After some struggling, I was finally able to complete exercise 1-19 with the code below:

/* reverse: reverse the character string s */
void reverse(char s[], int slen)
{
  char tmp[slen];
  int i, j;

  i = 0;
  j = slen - 2;    /* skip '\0' and \n */

  tmp[i] = s[j];
  while (i <= slen) {
    ++i;
    --j;
    tmp[i] = s[j];
  }

  /* code from copy function p 29 */
  i = 0;
  while ((s[i] = tmp[i]) != '\0')
    ++i;

}

My question is regarding that last bit of code where the tmp char array is copied to s. Why doesn't a simple s = tmp; work instead? Why does one have to iterate through the array copying index by index?

like image 318
felideon Avatar asked Jun 20 '09 19:06

felideon


People also ask

Can an array be copied?

Answer: There are different methods to copy an array. You can use a for loop and copy elements of one to another one by one. Use the clone method to clone an array. Use arraycopy() method of System class.

How do you copy an array using the spread operator?

The “=” operator, this operator will create a new variable and that just points to the existing array instead of copying the elements from existing elements to newly created variable. The (...) operator, spread syntax operator will create a cloned array with different references to the original array but same values.

Can we copy an array using assignment operator?

Copy Array Using Assignment Operator The assignment operator is used to assign a value to an array. By using the assignment operator, we can assign the contents of an existing array to a new variable, which will create a copy of our existing array.


1 Answers

Maybe I'm just old and grumpy, but the other answers I've seen seem to miss the point completely.

C does not do array assignments, period. You cannot assign one array to another array by a simple assignment, unlike some other languages (PL/1, for instance; Pascal and many of its descendants too - Ada, Modula, Oberon, etc.). Nor does C really have a string type. It only has arrays of characters, and you can't copy arrays of characters (any more than you can copy arrays of any other type) without using a loop or a function call. [String literals don't really count as a string type.]

The only time arrays are copied is when the array is embedded in a structure and you do a structure assignment.

In my copy of K&R 2nd Edition, exercise 1-19 asks for a function reverse(s); in my copy of K&R 1st Edition, it was exercise 1-17 instead of 1-19, but the same question was asked.

Since pointers have not been covered at this stage, the solution should use indexes instead of pointers. I believe that leads to:

#include <string.h>
void reverse(char s[])
{
    int i = 0;
    int j = strlen(s) - 1;
    while (i < j)
    {
        char c = s[i];
        s[i++] = s[j];
        s[j--] = c;
    }
}

#ifdef TEST
#include <stdio.h>
int main(void)
{
    char buffer[256];
    while (fgets(buffer, sizeof(buffer), stdin) != 0)
    {
        int len = strlen(buffer);
        if (len == 0)
            break;
        buffer[len-1] = '\0';  /* Zap newline */
        printf("In:  <<%s>>\n", buffer);
        reverse(buffer);
        printf("Out: <<%s>>\n", buffer);
    }
    return(0);
}
#endif /* TEST */

Compile this with -DTEST to include the test program and without to have just the function reverse() defined.

With the function signature given in the question, you avoid calling strlen() twice per line of input. Note the use of fgets() — even in test programs, it is a bad idea to use gets(). The downside of fgets() compared to gets() is that fgets() does not remove the trailing newline where gets() does. The upsides of fgets() are that you don't get array overflows and you can tell whether the program found a newline or whether it ran out of space (or data) before encountering a newline.

like image 135
Jonathan Leffler Avatar answered Sep 23 '22 00:09

Jonathan Leffler