首页 > (《C语言程序设计》)C语言中getchar()函数少了后面的括号能够编译通过但是无法向cmd输入任何字符。

(《C语言程序设计》)C语言中getchar()函数少了后面的括号能够编译通过但是无法向cmd输入任何字符。

《C语言程序设计》中文版第二版27页-28页之间的一段程序,程序的功能是 打印当前最长的输入行

正确程序如下:

程序1:正确程序。

#include <stdio.h>

#define MAXLINE 1000    /* 允许的输入行最大长度 */

int max;                /* 当前最长输入行长度 */
char line[MAXLINE];     /* 当前输入行 */
char longest[MAXLINE];  /* 当前最长输入行 */

int getline(void);
void copy(void);

/* 打印当前最长输入行,特殊版本 */
main()
{
    int len;
    extern int max;
    extern char longest[];

    max = 0;
    while ((len = getline()) > 0)
        if (len > max) {
            max = len;
            copy();
        }
    if (max > 0)    /* there was a line */
        printf("%s", longest);
    return 0;
}

/* getline:特殊版本 */
int getline(void)
{
    int c, i;
    extern char line[];

    for (i = 0; i < MAXLINE - 1
        && (c=getchar()) != EOF && c != '\n'; ++i)
            line[i] = c;
    if (c == '\n') {
        line[i] = c;
        ++i;
    }
    line[i] = '\0';
    return i;
}

/* copy: 特殊版本 */
void copy(void)
{
    int i;
    extern char line[], longest[];

    i = 0;
    while ((longest[i] = line[i]) != '\0')
        ++i;
}

然而中文版因为印刷错误或者别的什么原因,实际上在getline子函数那个for循环里少了一个左括号。

书中原版的程序如下:

程序2:中文版中少了一个括号的程序(该程序无法通过编译)。

#include <stdio.h>

#define MAXLINE 1000    /* 允许的输入行最大长度 */

int max;                /* 当前最长输入行长度 */
char line[MAXLINE];     /* 当前输入行 */
char longest[MAXLINE];  /* 当前最长输入行 */

int getline(void);
void copy(void);

/* 打印当前最长输入行,特殊版本 */
main()
{
    int len;
    extern int max;
    extern char longest[];

    max = 0;
    while ((len = getline()) > 0)
        if (len > max) {
            max = len;
            copy();
        }
    if (max > 0)    /* there was a line */
        printf("%s", longest);
    return 0;
}

/* getline:特殊版本 */
int getline(void)
{
    int c, i;
    extern char line[];

    for (i = 0; i < MAXLINE - 1
        && (c=getchar)) != EOF && c != '\n'; ++i)
            line[i] = c;
    if (c == '\n') {
        line[i] = c;
        ++i;
    }
    line[i] = '\0';
    return i;
}

/* copy: 特殊版本 */
void copy(void)
{
    int i;
    extern char line[], longest[];

    i = 0;
    while ((longest[i] = line[i]) != '\0')
        ++i;
}

我想问的问题是这样的:

原版程序中getline子函数里这句

for (i = 0; i < MAXLINE - 1 
    && (c=getchar)) != EOF && c != '\n'; ++i)

因为左边两个括号,右边三个括号,所以编译无法通过是很正常的。我当时第一反应这么改的:

for (i = 0; i < MAXLINE - 1 
    && ((c=getchar)) != EOF && c != '\n'; ++i)

就是在第一个"&&"后面随手加了个左括号(因为当时光想着匹配括号数了)。这样两边括号数目是匹配了,但结果是能编译通过,却无法在弹出的cmd里输入任何东西

但是这和我预期的不一样。我认为既然getchar那里后面没有那一对括号了(正确用法不应该是getchar()吗?),那么程序不就错了么。应该是无法编译通过才对。可结果跟我想象的不一样。

或者说"getchar没有那对括号就不能输入值了,但是编译器那里依然能通过。"这个说法对吗?

Win 7系统,IDE Code::Blocks 13.12

谢谢回答了~


没有括号的时候就getchar只是简单的函数指针,不会调用函数本身,因此你的cmd没让你输入。原版的错误就成了将函数地址赋值给变量c,当你的编译没做严格的变量类型检查的时候就有可能编译通过(你的IDE貌似刚好没有严格检查)。如果做了严格检查的话就会编译错误或者警告了。


c=getchar这句语法上是正确的,意思是把函数的地址赋给c,但是并不会执行这个函数,自然不会有任何效果了。

PS:因为c并不是指针类型,所以我想编译虽然能够通过但应该会有警告的吧。

【热门文章】
【热门文章】