zoukankan      html  css  js  c++  java
  • C语言实例解析精粹学习笔记——28

    实例28:从键盘读入实数

    题目要求:

           编制一个从键盘读入实数的函数readreal(double *rp)。函数将读入的实数字符列转换成实数后,利用指针参数rp,将实数存于指针所指向的变量*rp。

     思路:

           其实一开始我是懵逼的(╯︵╰),输入实数的话用scanf不就可以了吗?为啥还要转换呢?在经过一些思考后,发现要理解这道题需要了解以下一些知识点:

                  1.标准输入\输出流

                  2.getchar()等相关函数的使用

    知识点:(内容摘自于《C语言大学教程》中文第六版)

           此题需要从标准输入流(standard input stream)输入数据(虽然输入\输出流是在一起的,但本题更关注的是输入),并将数据输出到标准输出流。

        流:

           所有的输入/输出都是基于流(stream)实现的,所谓流就是字节的序列。在输入操作中,字节从一个外部设备流向主存;在输出操作中,字节从流主存流向一个外部设备。

    当程序开始执行时,有三个流被自动地连接到程序上:

           标准输入流:连接到键盘上(操作系统可以将其重定向到其他设备上)

           标准输出流:连接到显示器上(操作系统可以将其重定向到其他设备上)

           标准错误流:

    对于我这种初学者来说,在C语言中说的输入数据首先想到的是scanf函数:

    scanf函数具有如下格式化输入功能:

           1. 输入任意一种类型的数据,也就是说可以用scanf函数直接读取输入的实数,但是需要指定格式(即,明确的高速编译器你输入的是实数)

           2. 从一个输入流中指定的字符

           3. 忽略一个输入流中指定的字符

    调用scanf函数的格式:

           scanf(格式控制字符串,其余实参);

           格式控制字符串:描述了输入数据的格式

           其余实参:指向存储输入数据的目标变量的指针

     getchar函数:

    可以参考链接:https://blog.csdn.net/nopoppy/article/details/51906337

           在此程序中就是把输入当做字符进行处理将其转换成实数。

    原书实例代码如下所示:

     1 #define ERR 5
     2 #define OK 6
     3 #include <stdio.h>
     4 
     5 int status;
     6 double result,sig,scale;
     7 
     8 int sign(int c)/*处理数的符号函数*/
     9 {
    10     if(c=='-')/*若为负号,置负数标记*/
    11         sig=-sig;
    12 }
    13 
    14 int integer(int c)/*转换整数部分,转换一位整数位*/
    15 {
    16     result=result*10.0+c-'0';
    17 }
    18 
    19 int decimal(int c)/*转换小数部分,转换一位小数位*/
    20 {
    21     result+=(c-'0')*scale;
    22     scale/=10.0;
    23 }
    24 /*状态表*/
    25 int statbl[ ][4]={{   1,2,3,ERR},/*0*/
    26             {ERR,2,3,ERR},/*1*/
    27             {OK,2,4,OK},/*2*/
    28             {ERR,4,ERR,ERR},/*3*/
    29             {OK,4,OK,OK}};/*4*/
    30 //状态变量为1表示已遇数的符号字符
    31 //状态变量为2表示正在转换实数的整数部分
    32 //状态变量为3表示在未遇到数字字符之前先遇到小数点,必须要有小数部分
    33 //状态变量为4表示在转换整数部分之后遇到小数点,这种情况可以没有小数部分。
    34 
    35 /*转换函数表*/
    36 int(*funtbl[ ][4])( )={{sign,integer,NULL,NULL},
    37                     {NULL,integer,NULL,NULL},
    38                     {NULL,integer,NULL,NULL},
    39                     {NULL,decimal,NULL,NULL},
    40                                     {NULL,decimal,NULL,NULL}};
    41 
    42 int readreal(double *dp)
    43 {
    44     int c,ckind;
    45     sig=1.0;
    46     result=0.0;
    47     scale=0.1;
    48 
    49     while((c=getchar( ))==' '||c=='\n'||c=='\t');/*跳过前导空白符*/
    50     status=0;/*置初始状态*/
    51     for(;;)
    52     {
    53         /*分类当前字符*/
    54         if(c=='+'||c=='-') ckind=0;/*数的符号字符*/
    55         else if(c>='0'&&c<='9') ckind=1;/*数字符*/
    56         else if(c=='.') ckind=2;/*小数点*/
    57         else ckind=3;/* 其它字符 */
    58 
    59         if(funtbl[status][ckind])/* 如有转换函数 */
    60             (*funtbl[status][ckind])(c);/* 执行相应的函数 */
    61         status=statbl[status][ckind];/*设置新的状态*/
    62         if(status==ERR||status==OK)break;/* 结束:出错或成功 */
    63         c=getchar();
    64     }
    65     ungetc(c,stdin); /* 归还数德结束符 */
    66     if(status==OK)
    67     {
    68         *dp=result *sig;/* 读入数按指针参数赋给相应变量 */
    69         return 1;
    70     }
    71     return -1; /* 出错返回 */
    72 }
    73 main()
    74 {
    75     double x;
    76     //clrscr();
    77     printf("\nPlease input real numbers (use nonreal char to end input):\n");
    78     while(readreal(&x)==1)
    79         printf("The real number you input is: %f\n",x);
    80     printf("\nYou have inputted nonreal char.\n Press any key to quit...\n");
    81     getch();
    82 }

    一些测试结果如下所示:

    结论:

            虽然程序还是可以基本看懂的,但是自己独立写的话,根本写不出这种程度的代码。..(。•ˇ‸ˇ•。)…

  • 相关阅读:
    USACO Section 2.2 Subset Sums
    九度 1399 名侦探柯南
    九度 1416 猴子吃坚果
    pch文件的使用(原作者太逗了)
    线程同步
    extern "c"
    进程与线程
    排序算法代码汇总
    Linux Shell 常用命令与目录分区的学习总结 (开始学习linux)
    堆和栈
  • 原文地址:https://www.cnblogs.com/llccbb1/p/9689552.html
Copyright © 2011-2022 走看看