> 文档中心 > 100 Days of Code-day23

100 Days of Code-day23

K&R exercise 5-1

#include #define Size 9int main(){int n,array[Size];int getint(int*);for (n = 0; n < Size && getint(&array[n]); n++)//将第n个元素的地址传入getint函数的形参ip//指针变量ip则存储着第n个元素array[n]的地址。通过其所存储的地址,getint函数就可以把输入的数据//放入到相应的数组元素中。//调用完getint函数后,指针形参存储的地址是所得到的整数的地址,然后再将其传回给主调函数。//这就是间接访问。printf("index %d :%d\n",n,array[n]);return 0;}int getch(void);void ungetch(char c);int getint(int *pn){char c;while (isspace(c=getch()))//跳过空格符;if (!isdigit(c) && c != '+' && c != '-' && c != EOF)//输入的不是一个数字{ungetch(c);//压入缓存区中return 0;}if (c == '+' || c == '-')//输入的是'+'后者'-',则继续读取下一个字符c = getch();for (*pn = 0; isdigit(c); c = getch())//不断读取,并放入指针pn所指向的内存空间(初始化空间存储的数字为0)*pn = 10 * *pn + c - '0';//通过计算不断更新该空间内存储的值,直到所读取的字符不为数字为止if (c != EOF)//多读取的内容放入缓存区中ungetch(c);return c;//若之前读取到的是数字,则返回正数;若读取到的是EOF,则直接返回EOF}char buf[MaxSize];int bufp = 0;//缓存区中下一个空闲的位置int getch(void)//getch函数:当缓存区为空时,从输入中读取一个字符{return (bufp > 0) ? buf[--bufp] : getchar();}void ungetch(char c)//ungetch:当程序为了确保读取内容的准确性而多读取一个字符时,就会将多读取的字符放入到缓存区中{if (bufp > MaxSize - 1)printf("too many characters\n");elsebuf[bufp++] = c;}

分析原因:
为什么当符号字符’+’,’-'之后紧跟的不是数字时,getint函数将把符号视为数字0的有效表达式。
因为在读取完符号字符后,接着要读取它后面的字符。不论该字符是否为非数字字符,接下来的程序都会对指针参数pn所指向的内存空间进行写入操作(也就是将数字0放入到该空间中)。为了防止这种情况的发生,不能对pn存储地址的空间进行写入操作。所以在这之前就需要离开getint函数,返回到主调函数中。

if (c == '+' || c == '-')c = getch();for (*pn = 0; isdigit(c); c = getch())//不断读取,并放入指针pn所指向的内存空间(初始化空间存储的数字为0)*pn = 10 * *pn + c - '0';//通过计算不断更新该空间内存储的值,直到所读取的字符不为数字为止
if (c == '+' || c == '-')//输入的是'+'或者'-',则继续读取下一个字符{d = c;//先将符号字符保存在变量d中,并继续读取下一个字符getch();if (!isdigit(c))//如果所读取的字符不是数字,再判断其是否为文件流结束标志(EOF){//如果两者都不是,则将该字符写回输入流中,之后将符号字符也写回输入流中,并返回//该字符以表示这种情况的出现//若为EOF标记,则先将符号字符写入输入流if(c!=EOF)ungetch(c);ungetch(d);return d;}}

戒烟网