为什么不能使用`=`复制数组? [英] Why can't I copy an array by using `=`?

查看:147
本文介绍了为什么不能使用`=`复制数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始通过阅读K& R并进行一些练习来学习C.经过一些努力,我终于可以使用以下代码完成练习1-19:

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;

}

我的问题是关于代码的最后一部分,其中将tmp char数组复制到了s.为什么简单的s = tmp;不能正常工作?为什么必须逐索引遍历数组复制索引?

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?

推荐答案

也许我只是老而脾气暴躁,但我看到的其他答案似乎完全没有抓住重点.

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

C不执行数组分配,即句点.与某些其他语言(例如,PL/1;例如,Pascal及其许多后代-Ada,Modula,Oberon等)不同,您不能通过简单的分配将一个数组分配给另一个数组. C也不真正具有字符串类型.它仅包含字符数组,并且在不使用循环或函数调用的情况下,您不能复制字符数组(比复制任何其他类型的数组要多得多). [字符串文字并不真正算作字符串类型.]

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.

在我的K& R 2nd Edition中,练习1-19要求提供功能reverse(s);在我的K& R 1st Edition中,它是练习1-17,而不是1-19,但是提出了相同的问题.

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

使用-DTEST进行编译,以包含测试程序,而不必仅定义函数reverse().

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

使用问题中给出的功能签名,可以避免每行输入两次调用strlen().注意fgets()的使用-即使在测试程序中,使用gets()也是一个坏主意.与gets()相比,fgets()的缺点是fgets()不会删除gets()所在的尾随换行符. fgets()的好处是您不会遇到数组溢出的情况,并且可以在遇到换行符之前告诉程序是否找到了换行符,或者它是否耗尽了空间(或数据).

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.

这篇关于为什么不能使用`=`复制数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆