"文件复制" K& R部分

时间:2013-06-29 16:51:59

标签: c getchar kernighan-and-ritchie

我是编程的新手,我似乎无法理解为什么在我的代码中发生以下情况,这是:

#include <stdio.h>

/*copy input to output; 1st version */

main()
{
    int c;

c = getchar();
while (c != EOF) {
    putchar(c);
    c = getchar();
    }
}

所以在做了一些阅读之后,我收集了以下内容:

  1. 直到我按Enter键才执行任何操作,因为getchar()是一个保留功能。
  2. 在我按Enter键之前,我的所有击键都存储在缓冲区中
  3. 当调用getchar()时,它只是查看缓冲区中的第一个值,变为该值,然后从缓冲区中删除该值。
  4. 我的问题是,当我删除第一个c = getchar()时,生成的代码片段与原始代码具有完全相同的功能,尽管在我输入任何内容之前,屏幕上会立即显示笑脸符号。为什么会这样?是因为putchar(c)没有阻止代码,并试图显示尚未定义的c,因此它输出一些随机符号?如果有帮助,我正在使用Code :: Blocks。

3 个答案:

答案 0 :(得分:1)

您列出的功能只会回显您键入的每个字符。确实I / O是“缓冲的”。正是这种缓冲操作系统的键盘输入驱动程序。当你按下它的缓冲键时,它会向你回复每个键。当您按下换行符时,驱动程序会将缓冲的字符传递给您的程序,getchar然后会看到它们。

如上所述,该功能应该可以正常工作:

c = getchar();   // get (buffer) the first char

while (c != EOF) {  // while the user has not typed ^D (EOF)
    putchar(c);     // put the character retrieved
    c = getchar();  // get the next character
}

由于键盘驱动程序缓冲,每次按下换行符或退出^ D(EOF)时,它只会回显。

笑脸来自@YuHao描述的内容:你可能错过了你所跑的第一个getchar,所以putchar正在回应垃圾。可能是0,在屏幕上看起来像笑脸。

答案 1 :(得分:0)

如果您省略第一个getchar(),代码将如下所示:

int c;
while (c != EOF) {
    putchar(c);
    c = getchar();
}

在这里,c未初始化,因此第一次调用putchar(c)会输出一个垃圾值,这就是你获得笑脸的地方。

答案 2 :(得分:0)

“我是编程新手”

不建议您使用C学习编程(而且您遇到的困难是因为C语言)。例如,我的第一个计算机科学课程是pascal。其他大学可以使用scheme或lisp,甚至是结构化的自然语言来教授编程。麻省理工学院的在线课程以python为基础。

C不是您想要在编程的前几个月使用的语言。您的具体原因是由于该语言允许您使用未初始化值的值。

当你声明整数变量“c”时,它会在程序堆栈上获得一个隐式保留的空间,但没有任何有意义的值:它是“垃圾”,该值是当时内存上已有的值。 C语言要求程序员隐含地知道在使用变量之前他需要分配一些值。在c具有任何有意义的值之前,删除第一个getchar会导致在while条件(c!= EOF)和putchar(c)中赋值之前使用。

考虑在python中重写的相同代码:

import sys

c = sys.stdin.read(1)
while c != '':
    c = sys.stdin.read(1)
    sys.stdout.write(c)

删除初始读取,您会收到以下错误:

hdante@aielwaste:/tmp$ python3 1.py 
Traceback (most recent call last):
  File "1.py", line 3, in <module>
    while c != '':
NameError: name 'c' is not defined

这是一个NameError:您使用未分配给它的值导致语言错误。

有关更多信息,请尝试在线课程,例如:

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/video-lectures/

关于未初始化的值:

http://en.wikipedia.org/wiki/Uninitialized_variable