鱼C论坛

 找回密码
 立即注册
查看: 8827|回复: 48

[技术交流] 小甲鱼C++快速入门 笔记(3)

[复制链接]
发表于 2013-8-30 12:07:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 新手学习中 于 2014-7-27 15:25 编辑

一、用户一次性输入数据,求和:
#include <stdio.h>#include <stdlib.h>
void main()
{
      int i;
      int sum = 0;
      char ch;

printf("请输入一串整数和任意数目的空格: ");
      while( scanf("%d", &i) == 1 )
      {
            sum += i;

while( (ch=getchar()) == ' ' )


// 屏蔽空格                  ;
            if( ch == '\n' )
            {
                  break;
            }

ungetc( ch, stdin );  // 将变量ch 中存放的字符退回给stdin输入流。
      }
      
      printf("结果是: %d", sum);
      printf("\n");
      system("pause");
}

二、scanf("%d",&i)==1是什么

1、scanf的返回值
scanf函数规定,scanf有返回值,返回的是执行本函数一次所成功读取“数”的个数。(自动忽略缓冲区里的空格)
注意:如果第一个值读入失败,那么直接结束返回0.或者说,遇到读入失败,那么结束
scanf不再读下去,统计前面成功读入的个数,返回值。

2、scanf的缓冲区与用户输入的理解
scanf函数,只是读取输入流里符合要求的数据(自动忽略缓冲区里的空格),并不需要等待用户输入和回车结束。只有当输入流里无数据,或者不符合要求时,才会打开输入流输入开口,让用户往输入流里输入数据,以回车结束对输入流数据的输入。然后scanf函数再运行。执行scanf函数时,执行的并不是“录入用户输入的数”,而是缓冲区中“读取数”当然,缓冲区的数是由用户输入的,不过把scanf理解成“是记录用户输入的数”则会有差错。 scanf并不依赖回车结束。只有在无数据可读的情况下,才依赖回车。scanf函数,是读取输入流里的数据。只有当输入流里没数据时,它才会打开输入流的开口,让用户输入数据,直到回车,输入流开口关闭,函数才从输入流里读数据。准确的说,在无数据可读情况下,scanf打开输入流开口,等待用户输入,当用户输入符合一定要求时,以回车关闭输入流开口,scanf又开始运作,从输入流里读取数据。如果输入流 里本来就有符合要求的数据,那么scanf不会打开输入流开口,它会直接读取数据,运行函数,再执行下一流程,完全的后台操作。一般情况下,第一次执行,都是无数据的,所以就出现等待的情况。但如果一次性输入了两个数据,如: 如果我安排是用户输入2次的数据,也就是说开始运行一次scanf,代码中间又有一个scanf但是由于用户的失误,第一次输入的时候直接给了两个数。比如说1  4
那么运行时,就没有跳出第二次的scanf,而是直接两次的printf。
这种“程序错误”该如何避免呢?
#include <stdio.h>
void main()
{     
int i,j;      


scanf("%d", &i) ;

printf("%d",i);
scanf("%d", &j);
        
  printf("%d",j);
  
   }        

用户第一次输入了8个数,回车。那么scanf设定是一次读取一个数,那么执行时它先从缓冲区里读取第一个数,第二次执行时,就读取缓冲区里第二个数。如果按照scanf是“记录用户输入的数”,那么每次循环用户都要输入数!这道题就难以理解为何能实现了!以下是百度网友回答:用户输入的数据被控制台放在键盘缓冲区中,敲入回车scanf(流输入,会把数据放在自已的缓冲区中,然后才开始真正的输入数据,够用则输入到变量中,多余数据放到流缓冲中结束输入,不够等待用户输入新数据并回车再从流缓冲中读数据直到够用为止!当流缓冲中有上次用户输入的没用完的数据时,直接从流缓冲中读取数据,再不需要回车了,除非流缓冲中的数据消耗完了,否则不用重新从键盘录入数据了!scanf本身的实现会有一个循环,流输入有一个结构记录键盘录入数据,只有回车才会更新数据,否则数据会一直存贮键盘缓冲区中

3、scanf运行原理导致的错误

如果我安排是用户输入2次的数据,也就是说开始运行一次scanf,代码中间又有一个scanf
但是由于用户的失误,第一次输入的时候直接给了两个数。比如说1  4
那么运行时,就没有跳出第二次的scanf,而是直接两次的printf。
这种“程序错误”该如何避免呢?
#include <stdio.h>
void main()
{     
int i,j;      

scanf("%d", &i) ;
printf("%d",i);
scanf("%d", &j);
        
  printf("%d",j);
  
   }        


4、为何scanf有时回车没反应
比如scanf设定读取5个数。那么如果用户只输入4个数就回车,scanf不会结束运行,它在
等待,等待用户输入第5个数。用户输入了,然后回车,就OK了。

三、using namespace std是什么
这句话不用深究什么意思,解释也需要深入其汇编原理,只需要知道,程序开始就写这
一句。这是为了变量名不重复。
具体以下解释也不太准确,反正这个问题深入研究为什么比较复杂,目前的知识是理解不
了的。
1,C++中如果不写这句话,后面按照C去声明变量,那么会报错
2,因为一个程序可能有很多人去写,从而有大量的变量名,为了不重复,所以
C++中引入空间名。把std放在一个命名空间中,所有的函数,类都在这空间中。
3,如果不写,那么以后代码的变量名都需要std::cout  这样来写,就很麻烦。

四、为何要用getchar()

1、为何要用getchar()
前面的scanf自己就带有从缓冲区顺序录入的功能,那么加上后面的sum = sum + i
不是就完成程序了么?
实际执行时,回车,无反应。
因为scanf循环最后一次后,发现没数据,就要求用户再次输入数据,用户输入,回车,
那么scanf再循环,再要求输入.......
所以,这里要使得scanf前面的while不循环,读到最后的时候就终止。这就需要在
scanf函数后面加上一点其他东西,来终止循环。而终止的标准是用户的回车,这里
就选择用getchar()函数。

2、getchar()函数潜规则
getchar()简易解释是:从缓冲区(输入流)中读入字符。
潜规则:
(1)、scanf在getchar前面,scanf提取一个数后,缓冲区中这个数就没有了,getchar只能从
这个数的后面提取。
(2)、scanf是提取数,自动排除空格,分隔符,以回车结束。getchar是读入字符,包含数字,空格,分隔符,还有最后的回车。如果对象是33,它会先提取3而不是33.
(3)、getchar提取了,缓冲区里被提取的字符也就没有了。

五、ungetc的作用
1、此程序的实现分析



(1),scanf第一次先运行,先读入第一个数。这个数就在缓冲区中没了。

(2),进行小循环的条件判断,因为第一个数没了,getchar只能读取第一个数后面的“字符”,也就是空格

(3),如果ch等于空格,那么不执行任何内容,再次进入小循环,调用getchar读入空格后面的字符。

(4),当读到不是空格的时候,跳出小循环,进入大循环中的下一步。但是!!!此时
ch已经被赋值了一个非空字符。而且缓冲区中的这个字符已经不在了!!!!

(5),利用ungetc把不在的非空字符给返回缓冲区中

(6),大循环一次结束。scanf再次读入。


(7),到了最后一个数,getchar把回车赋值给ch,这个时候直接break终止大循环,输出
sum的值。


2、ungetc功能
ungetc(ch,stdin);
表示将ch中的值返回给缓冲区(输入流stdin)

3、while的隐藏指令与空代码指令
while的隐藏指令
while (ch = getchar()==" ")
    ;

这里,用了空指令。
等于空格,啥都不执行。不等于呢?也不执行。那为何还要while循环呢?
也就是说,等于不等于,都不执行,不就等于没有这代码??
这是错误的。因为while的括号里面,还有一条指令: ch = getchar()
这是很容易被人遗忘的。不等于不执行。等于,则执行ch = getchar()
类似于for循环,特别容易让人忽略最后一步ch值的变化,以至于后面代码的出错

六、system("pause");是什么

命令行上输出一行类似于“Press   any   key   to   exit”的字,等待用户按一个键,然后返回。

七、我的错误


以下求和代码为何是这种结果??
: 输入:1 2 3 4 5 回车(无反应)再回车 结果:9

#include <stdio.h>#include <stdlib.h>
void main()
{
      int i;
      int sum = 0;
      char ch;

printf("请输入一串整数和任意数目的空格: ");
      while( scanf("%d", &i) == 1 )
      {
            sum += i;

while( getchar()  == ' ' )  

;// 屏蔽空格                  ;
            if( getchar() == '\n' )
            {
                  break;
            }

ungetc( getchar(), stdin );  // 将变量ch 中存放的字符退回给stdin输入流。
      }
      
      printf("结果是: %d", sum);
      printf("\n");
      system("pause");
}



解析:这样将原程序ch替换成getchar(),因为我觉得ch是多此一举。可惜结果错了,我却找不出原因。
这样要注意,特别是条件句,循环句里,句子里面还有函数,虽然函数当做一个变量来处理,虽然可能条件句不成立不执行,循环不执行,但是函数却是执行了,函数一执行函数里面的变量可能就变了!
所以,一个条件句不执行,循环不执行,不代表什么都没有变!
我似乎已经第二次犯这个错误了。
还有一个问题,为何我要按两次回车才有结果??
这又是我对流程函数的不理解,因为scanf是包涵在while循环里面的。



八、VC++的调试功能如何用

在菜单 build 那里、具体难以文字描述

九、此求和程序C++实现代码


#include <iostream>
using namespace std;
int main()
{
      int sum = 0;
      int i;

      cout << "请输入一串整数和任意数目的空格:";
      
      while( cin >> i )
      {
            sum += i;
            while( cin.peek() == ' ' )
            {
                  cin.get();
            }
            if( cin.peek() == '\n' )
            {
                  break;
            }
      }

      cout << "结果是: " << sum << endl;
      return 0;
}




十、与C不同点:cout与cin

cout 相当于 printf
cin  相当于 scanf
scanf返回的是个数,或者0
而cin返回的是数的具体数值???或者0
cin.get()与cin.peek()
cin.get()相当于getchar()
cin.peek()从输入流中读取一个字符 但该字符并未从输入流中删除

要使用cin 需要#include <iostream>

十一、cin.get()与cin.peek的不同

cin.get()与cin.peek的不同:
一个是读取并删除 一个是读取不删除

举例:
#include <iostream>
using namespace std;
int main()
{
      char p;
      cout << "请输入一段文本: \n";

      while( cin.peek() != '\n' )
      {
            p = cin.get();
            cout << p;
      }
      cout << endl;

      return 0;
}


这个程序中,如果cin.peek() 是读取删除,那么结果就会是残缺的。但是结果不残缺,说明cin.peek() 是读取不删除
读取不删除,这个功能大大简化了此程序。

十二、cin特性与再次发现scanf新特性

cin与scanf读取规律:
要求是输入整形,但是我们输入的是小数,那么结果是怎样呢?
比如输入3.15
cin 与scanf都是3
当定义输入2个整形变量,而实际是 3.15   5
结果是: 3  垃圾值
也就是说,读第一个数,后面不符合,就停止,5也没有读出来  3却是畸形的读出来。

十三、C与C++变量名位置的不同


C语言中,变量声明必须在前面。
而C++中,可以用到变量的时候再声明。
这样的好处是,可以让人看的明白,不然一大堆变量名放在前面,让人头晕



十四、const在这里效果等同于#define

#include <iostream>
using namespace std;
int main()
{
      const int SIZE = 50;
      char buf[SIZE];
      
      cout << "请输入一段文本: ";
      cin.read( buf, 20 );

      cout << "字符串收集到的字符数为: "
           << cin.gcount() << endl;

      cout << "输入的文本信息是: ";
      cout.write( buf, 20 );
      cout << endl;

      return 0;
}

#define SIZE 50  (必须放在最前面)相当于 const int  SIZE = 50(可以放在函数里面)     但是#define 与const 定义常量还有区别 。


十五、字符与字符串的难点区别

如果我们分配了10个字符串,那么实际只能用9个,还有一个是自动添加的/0

如:
#include <iostream>
using namespace std;
int main()
{
      char buf[20];

      cin.ignore(7);
      cin.getline( buf, 10 );

      cout << buf << endl;
      return 0;
}


cin.ignore(7);表示忽略输入数据的前7个字符串(就是准7个)
cin.getline( buf, 10 );表示读取输入字符串的10个(按顺序,其实是9个)
这里只能读取9个因为字符串必须要以/0结尾,这是自动添加的。

十六、cin的其他5函数:

1、cin.read(  );    cout.write(  );    cin.gcount()

#include <iostream>
using namespace std;
int main()
{
      const int SIZE = 50;
      char buf[SIZE];
      
      cout << "请输入一段文本: ";
      cin.read( buf, 20 );

      cout << "字符串收集到的字符数为: "
           << cin.gcount() << endl;

      cout << "输入的文本信息是: ";
      cout.write( buf, 20 );
      cout << endl;

      return 0;
}





2、cout.precision() ;


#include <iostream>
#include <math.h>

using namespace std;
int main()
{
      double result = sqrt(3.0);

      cout << "对 3 开方保留小数点后0 ~ 9 位,结果如下: \n" << endl;
      for( int i=0; i <= 9; i++ )
      {
            cout.precision(i);
            cout << result << endl;
      }

      cout << "当前的输出精度为: " << cout.precision() << endl;
      return 0;
}


3、cin.width();




#include <iostream>
using namespace std;
int main()
{
      int width = 4;
      char str[20];

      cout << "请输入一段文本: \n";
      cin.width(5);

      while( cin >> str )
      {
            cout.width(width++);
            cout << str << endl;
            cin.width(5);
      }

      return 0;
}


游客,如果您要查看本帖隐藏内容请回复


评分

参与人数 2荣誉 +12 鱼币 +11 贡献 +6 收起 理由
抹语 + 2 + 1 + 1 感谢楼主无私奉献!
怡静 + 10 + 10 + 5 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-8-30 12:22:43 | 显示全部楼层
不错,谢谢楼主!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-8-30 12:47:24 | 显示全部楼层
O(∩_∩)O~真心不错啊O(∩_∩)O~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-30 18:51:57 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-30 18:52:46 | 显示全部楼层
牡丹花下死做鬼 发表于 2013-8-30 12:47
O(∩_∩)O~真心不错啊O(∩_∩)O~

小甲鱼C++信息量太大~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-8-30 18:53:43 | 显示全部楼层
新手学习中 发表于 2013-8-30 18:52
小甲鱼C++信息量太大~~

其实我也自己在写 但看到你的我自愧不如啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-30 19:51:02 | 显示全部楼层
牡丹花下死做鬼 发表于 2013-8-30 18:53
其实我也自己在写 但看到你的我自愧不如啊

汗 别紧张 这是我以前写的,断断续续用了很久很久,效率是很低的。以至于后面小甲鱼C++教程我都没看了。话说你不是在写C语言吗?也在写C++?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-8-30 19:52:04 | 显示全部楼层
新手学习中 发表于 2013-8-30 19:51
汗 别紧张 这是我以前写的,断断续续用了很久很久,效率是很低的。以至于后面小甲鱼C++教程我都没看了。话 ...

学杂了 很多都一起的 O(∩_∩)O~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-8-30 20:24:42 | 显示全部楼层
{:1_1:}看完再说
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-2 18:42:28 | 显示全部楼层
支持楼主~~哈哈哈哈哈哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-2 19:28:38 | 显示全部楼层
{:1_1:}不错,很好
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-4 12:37:38 | 显示全部楼层
去去去去去全球去去去去去去去去去去去去
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-4 13:46:26 | 显示全部楼层

不错,谢谢楼主!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-5 01:24:19 | 显示全部楼层

不错,谢谢楼主!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-9 22:10:29 | 显示全部楼层
先看看再说吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-9 23:33:37 | 显示全部楼层
好好看看 哈哈在!!!!!!!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-10 00:42:53 | 显示全部楼层
。。。。。。。。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-10 09:35:38 | 显示全部楼层
谢谢楼主分享。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-25 22:00:17 | 显示全部楼层
看那一看{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-7-1 21:11:20 | 显示全部楼层
感谢楼主分享,很喜欢这个教程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 07:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表