代码之家  ›  专栏  ›  技术社区  ›  John

简易C最长行复制程序

c
  •  0
  • John  · 技术社区  · 16 年前

    这是克尼根C书中一个练习的变体。基本上打印标准输入中最长的行。

    我的问题是,如果查看“copy方法”,如果copy方法返回void,它实际上是如何工作的。我是从Java来的,第一次学C。 在copy方法中,to和from char数组是本地的。如果不能返回到main,那么如何将它们实际存储在main方法中的longest和line变量中?

    我很困惑。。。

    非常感谢你的时间!

    编辑:谢谢你的回复。

    再来一个便条。。。

    哦。因此,作者是用指针传递值的。这是非常令人困惑的,因为在a页之前它会读到-“……在C中,被调用函数不能直接改变调用函数中的变量;它只能改变其私有的临时副本。”是这样吗?

    第二个问题是,如何使这些函数像在Java、PHP等中一样传递数据,或者这是C程序员认为的一个好处?

    来自K&R的代码

    #include <stdio.h>
    #define MAXLINE 1000
    
    int getline(char line[], int maxline);
    void copy(char to[], char from[]);
    
    main () {
    
     int len;
     int max;
     char line[MAXLINE];
     char longest[MAXLINE];
    
     max = 0;
    
     while ((len = getline(line, MAXLINE)) > 0) {
    
       if(len > max) {
    
         max = len;
         copy(longest, line);
    
       }
    
     }
    
     if(max > 0) printf("%s", longest);
    
     return 0;
    }
    
    int getline (char line[], int limit) {
    
     int i, c;
    
     for (i = 0;  i < limit - 1 && (c = getchar()) != EOF && c != '\n';  i++) line[i] = c;
    
     if (c == '\n') {
    
      line[i] = c;
      i++;
    
     }
    
     line[i] = '\0';
    
     return i;
    }
    
    void copy(char to[], char from[]) {
    
      int i;
    
      i = 0;
      while((to[i] = from[i]) != '\0')
        i++;
    }
    
    4 回复  |  直到 11 年前
        1
  •  3
  •   DevSolar    16 年前

    在C语言中, 一切都是按价值传递的 . 你必须注意 什么 不过,是按值传递的。

    C型数组 char from[] 不是容器对象,正如您可能从其他语言中期望的那样。在大多数实际应用中,C数组相当于指向第一个元素的指针,即。 char * from .

    所以,参数 to from 确实是按价值传递的,但它们是什么 指针 到数据,以便您可以修改通过它们指向的数据。

        2
  •  1
  •   Tal Pressman    16 年前

    Java字符串是不可变的,而C语言中的“字符串”只是字符数组。通过更改数组中的字符,这些更改在copy()外部“可见”。

        3
  •  0
  •   Jonathan Leffler    11 年前

    在问题的更新中,您会问:

    “在C语言中,被调用函数不能直接改变调用函数中的变量;它只能改变其私有的临时副本。”对吗?

    是的,这是正确的,即使是数组。不过,理由很微妙。

    对于整型参数:

    int somefunc(int i) { return ++i; }
    

    更改为 i 在函数中只影响 ,而不是对应于 在调用函数中:

    int i0 = 26;
    int i1 = somefunc(i0);
    

    类似地,对于“array”参数:

    int anotherfunc(int a[]) { return *++a; }
    

    打电话给:

    int array[3] = { 13, 23, 37 }; 
    int n = anotherfunc(array);
    

    函数接收指针的副本 array (又名 &array[0] ),以及函数对 a 在函数中对 阵列 在呼叫代码中。但是,如果函数是:

    int modifyfunc(int a[]) { return *(++a) = 37; }
    

    使用调用序列:

    int array[3] = { 13, 23, 37 };
    int n = modifyfunc(array);
    int *ip = &array[1];
    int m = modifyfunc(ip);
    

    则函数不修改 阵列 调用函数中的指针,但它确实修改数组指向的数据(确切地说,它设置了 array[1] 第一次打给37,然后 array[2] 对于第二个调用为37),以及修改 阵列 (被称为 在函数内部)。

    因此,如前所述,C只有传递值,但是当传递的值是指针时,被调用代码可以修改指针指向的内容,而不是调用代码中的实际指针。

    是的,所示功能中的副作用总是不必要的。它们说明了这一点,而不是实际的代码。

        4
  •  0
  •   Jonathan Leffler    11 年前

    首先,这是你正在学习的可怕代码。它很难阅读,很难理解,并且不会处理超过给定限制的行。依克。

    但是要回答您的问题,当调用copy()时,这两个参数是指向存储字符数组的内存区域的指针。因此,当调用copy时,变量“to”等于调用帧中的“longest”,变量“from”等于调用帧中的“line”。