Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
378 views
in Technique[技术] by (71.8m points)

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

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 '' and 
 */

  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]) != '')
    ++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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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] = '';  /* Zap newline */
        printf("In:  <<%s>>
", buffer);
        reverse(buffer);
        printf("Out: <<%s>>
", 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...