《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
并不是指针类型,所以我想编译虽然能够通过但应该会有警告的吧。