关于K&R《C程序设计语言》中getint()函数的技术疑问
关于K&R《C程序设计语言》getint()函数的疑问解答
嘿,作为同样啃过K&R的过来人,你的这个疑问特别典型——你观察到的“非数字字符导致无限循环”的现象完全没错,但咱们得从这个函数的设计定位说起,帮你理清思路:
你的理解偏差在哪里?
你没看错这个循环问题,但你可能忽略了getint()的设计本质是教学示例,而非工业级健壮函数。它的核心是演示「预读字符判断类型+ungetch回推缓冲」的用法,而不是要处理所有输入场景。
这个函数真的会无限循环吗?
是的,在你贴的main函数逻辑下确实会!你的main循环条件是getint(...) != EOF,但当遇到非数字、非正负号的字符时:
- getint()会把这个字符用
ungetch()塞回输入流 - 然后返回0(不是EOF)
- 下次调用getint()时,又会读到这个被塞回去的字符,重复上述操作,永远返回0,永远到不了EOF,自然陷入无限循环。
为什么要这么设计?
K&R写这个函数的目的,是教你如何处理「需要先读一个字符判断类型,不符合就塞回去给后续逻辑处理」的场景,它有个隐含假设:
- 调用者会处理getint()的返回值:当getint()返回0时,调用者应该去处理那个被回推的非数字字符(比如读取并丢弃、或者终止循环),而不是无脑继续调用getint()。
- 这个函数的职责只是「提取整数」,如果当前位置不是整数开头,就把字符塞回去,告诉调用者「这里不是整数,你自己处理」,而不是替调用者做决定。
比如,把你的main函数改成这样,就不会循环了:
#include <stdio.h> #include <ctype.h> #define BUFSIZE 100 int getint(int *); int getch(void); void ungetch(int); int main() { int n, array[BUFSIZE], res; for (n = 0; n < BUFSIZE; ) { res = getint(&array[n]); if (res == EOF) break; if (res != 0) { // 只有成功读取整数才移动数组下标 n++; } else { // 处理非数字字符,比如读取并丢弃 printf("跳过非数字字符: %c\n", getchar()); } } return 0; } // 以下是原getint、getch、ungetch实现 int getint(int *pn) { int c, sign; while (isspace(c = getch())) ; if (!isdigit(c) && c != EOF && c != '+' && c != '-') { ungetch(c); return 0; } sign = (c == '-') ? -1 : 1; if (c == '-' || c == '+') c = getch(); for (*pn = 0; isdigit(c); c = getch()) *pn = 10 * *pn + (c - '0'); *pn *= sign; if (c != EOF) ungetch(c); return c; } int buf[BUFSIZE]; int bufp = 0; int getch(void) { return (bufp > 0) ? buf[--bufp] : getchar(); } void ungetch(int c) { if (bufp >= BUFSIZE) printf("ungetch: can't push character\n"); else buf[bufp++] = c; }
关于你提到的习题修正
你说习题要求修正「'-'或'+'后接非数字时被视为有效0」的问题,这个是原函数的逻辑漏洞,和无限循环是两个层面的问题。原函数遇到+a或-b时,会把*pn设为0再乘以符号,最后返回a或b,相当于把这种无效格式当成了值为0的整数。
修正的思路是:读完符号后,检查下一个字符是不是数字,如果不是,把符号和非数字字符都塞回输入流,返回0,比如修改这部分代码:
sign = (c == '-') ? -1 : 1; if (c == '-' || c == '+') { int sign_char = c; // 保存符号字符 c = getch(); if (!isdigit(c)) { ungetch(sign_char); // 把符号塞回去 ungetch(c); // 把非数字字符塞回去 return 0; } }
这样就能正确识别+a或-b是无效输入,不会当成值为0的整数了。
内容的提问来源于stack exchange,提问作者ThornyHatcher
相关产品推荐
相关产品推荐

