回 帖 发 新 帖 刷新版面

主题:这是我学习C++ Primer的一些心得(未完),有点菜,但还是想和大家分享一下

引言:
我之所以打算利用寒假的这几天好好学习一下C++ Primer 这本书,是因为很多人都说这本书是C++系列的经典之作,所以我想利用这本书巩固一下自己C++的知识!
    在学习的过程中,我习惯的对书中设计的源代码进行修改,以此来加深对知识的理解!但在此过程中,难免会遇到一些小问题,其实并不是很大的程序错误,可以说是一些小技巧吧,在此我会一一记录,希望当我学完这本书时,这个Word文档可以成为一篇不错的学习笔记,为其他人初识C++提供些帮助!

*******************************************************************************
运行环境为Microsoft Visual Studio 2008(以下简写为:VC2008)
*******************************************************************************

笔记:
1.    (1)日期:2011.1.9
(2)问题:在运行一段只包括“输出”的代码时,窗口停不住,以前未遇到这种情况
(3)原因:通过在网上查询,了解到这个和编译器有关。对于使用Visual C++ 6.0的同学来说不会存在这样的问题,但像我这种使用VC2008 的人来说,就会遇到。
(4)网上查询的解决方法是(我选择较好的一种):
         1.在您想要暂停的地方加上 system("pause"); 就可以使 C/C++ 程序暂停。不过,这个办法奏效的前提是系统中必须存在 pause 这个命令。此外,还需要包含标准头文件 stdlib.h(对于 C)或者 cstdlib(对于 C++)。
2.在您想要暂停的地方加上 getchar();(对于 C 和 C++)或者 cin.get();(仅适用于 C++)就可以使程序暂停,然后按回车程序就会继续执行。不过,您会发现,这种办法却不一定奏效。如果您够细心,会发现只有当 getchar();/cin.get(); 前面有接收输入的语句的时候,该办法才会失效。如果之前没有接收任何输入,该办法是 100% 奏效的!这是因为,如果前面接收了输入,输入流中可能会有残留数据,
getchar();/cin.get(); 就会直接读取输入流中的残留数据,而不会等待我们按回车。解决该问题的办法是,先清空输入流,再用 getchar();/cin.get();。清空输入流的办法如下:
 1). /* 适用于 C 和 C++。需要包含 stdio.h(对于 C)或者 cstdio(对于 C++)*/
        while ( (c = getchar()) != '\n' && c != EOF ) ;  /* 对于 C 和 C++ */
            2). cin.clear();    // 仅适用于 C++,而且还需要包含标准头文件 limits
               cin.ignore( numeric_limits<streamsize>::max(), '\n' ); 
(5)自己实践:
     通过实践,最简单的方法是:首先在头文件部分加入 #include <cstdlib>,然后在你打算停住的地方加上代码:system(“pause”);(注意分号),完成!
(6)实践代码:
     #include "stdafx.h"
#include <iostream>
#include <string>
#include<cstdlib>     //加入的头文件
using namespace std;
int main()
{
string line("dfdsfsfs");
int n=line.size();
    cout<<n<<endl;
       system("pause");   //加入的代码
cout<<n+1<<endl;  //本行是为了验证上面的点是否停住了! 
return 0;  
}
2.(1)日期:2011.1.9
  (2)问题:对string库中size()和empty()两个函数的理解
  (3)实践代码:
       #include "stdafx.h"
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
        string line;
        while(getline(cin,line))
{       //注意用括号将while()循环体括起来,不然while()将进行输出字符串的死循环
        cout<<line<<endl;
         int m=line.empty();
          int n=line.size();
          cout<<m<<endl;  
          cout<<line.size()<<endl;
          system("pause");
          cout<<line.size()+1<<endl; 
         }
         return 0;  
}
3.(1)日期:2011.1.11
  (2)问题:当输入数据是空格(’ ’)、制表符(‘\t’)、换行符(’\n’)时,如何处理输入,还用cin>>.....吗?
(3)原因:不能使用提取操作符(>>),因为对>>而言,空格、制表符和换行符均为数据项分隔符,会被忽略掉,而cin对象的get成员函数则不会这样。
(4)实践代码:
     将需要输入流的地方写为:cin.get(ch); (ch为已经定义的字符型数据:char ch) 即可!
4.(1)日期:2011.1.13
  (2)问题:在C++中,如何理解一个String类型字符串和一个C风格字符串的区别
  (3)原理分析:
      (以下分析中,“前者”是指String字符串,“后者”是指C风格字符串)
1.    首先是两者头文件上的区别:
前者是:#include <iostream>
        #include <string>
       后者是:#include <iostream>
               #include <cstring>
2.    其次是两者所包含库函数的区别
前者是:s.empty()     //如果s为空串,则返回true,否则返回false
        s.size()      //返回s中字符的个数
        s[n]          //返回s中位置为n的字符,位置从0开始计数
         s1+s2         //把s1和s2连接成一个新字符串,返回新生成的字符串
s1=s2         //把s1内容替换为s2的副本
        v1==v2        //比较两者的内容,相等返回true,否则返回false
!=,<,<=,>,>= //保持这些操作惯有的定义(此点很重要)
          后者是:Strlen(s)
                  Strcmp(s1,s2)
                  Stricmp(s1,s2)
                     Strcat(s1,s2)
                     Strcpy(s1,s2)
                     Strncat(s1,s2,n)
                     Strncpy(s1,s2,n)
3.    我个人认为两者的区别主要在于:前者直接定义String类的对象,直接对其进行操作,后者定义的是字符数组,实际上是对数组的操作!
   (4)实践代码:
5.(1).日期:2011.1.18
(2).问题(技巧性的):当我们在程序开发阶段,我们有时需要对所包含的代码进行调试,当我们交付软件时,这些调试代码就不需要了,要进行屏蔽。
(3).原理分析:
      1.我们可以采用“预处理器”进行调试,将用于调试的语句用 #ifndef NDEBUG和 #endif 包含起来,当这些调试代码不再需要时,我们通过定义NDEBUG的方法,即可完成对代码的屏蔽。
      2.(书中P61)#define指示接受一个名字并定义该名字为预处理变量。#ifndef
指示检测指定的预处理变量是否未定义。如果预处理变量未定义,那么跟在其后的
所有指示都被处理,直到出现#endif。
(4).实践代码:
        #include "stdafx.h"
  #include <iostream>
  #include <string>
  #include <cstdlib>  //用于暂停
  #include <cctype>
  #define NDEBUG  //如果未对NDEBUG进行定义,则下面的调试代码将执行
  using namespace std;
  int main()
  {  
          string currword,preword;
         cout<<"Enter some words:"<<endl;
         while(cin>>currword){
          #ifndef NDEBUG
           cout<<currword<<' ';   //调试:将所输入的字符串输出一遍
          #endif
         if(!isupper(currword[0]))
            continue;
         if(currword==preword)
            break;
         else
            preword=currword;
         }
 if(currword==preword&&!currword.empty())
            cout<<"The repeated word:"<<currword<<endl;
         else
            cout<<"There is no repeated word that has initial capital."<<endl;
 system("pause");
          return 0;
 }
6.(1).日期:2011.1.20
  (2).问题:(结合下面的代码进行理解,即习题7.13)在int sum3()函数中,我起初不明白为什么要另外定义一个指针p,对比int sum1(),我不太理解,而且我尝试直接用指针begin,运行结果我发现有错误!
  (3).原理分析:通过实践,我发现其实这是个很简单的问题,直接用begin的话,while 循环体中要执行一步:begin++ 的操作,而while 的判定条件是:begin!=begin+size; 会永远为真,程序将陷入死循环。为了验证这一点,我在while循环体中加入了一个输出语句,验证了我的想法。
(4).实践代码:(sum3的正确函数体见书的配套答案)
#include "stdafx.h"
#include <iostream>
//#include <cstdlib>  //用于暂停
//#define NDEBUG
using namespace std;
int sum1(const int *begin,const int *end)
{
            int sum=0;
            while(begin!=end){
                sum=sum+*begin;
                begin++;
}
             return sum;
}
int sum2(const int ia[],size_t size)
{
          int sum=0;
          for(size_t ix=0;ix!=size;++ix)
          {
             sum+=ia[ix];
          }
               return sum;
}
int sum3(int *begin,size_t size)
{
          int sum=0;
          //int *p=begin;
          while(begin!=begin+size)
          {
              sum=sum+*begin;
           #ifndef  NDEBUG
               cout<<"wsqw"<<endl;
           #endif
               begin++;
          }
                 return sum;
}
int main()
{  
                int ia[]={1,2,3,4};
                cout<<"Summation from sum1():"<< sum1(ia,ia+4)<<endl;
                 cout<<"Summation from sum1():"<< sum2(ia,4)<<endl;
                 cout<<"Summation from sum1():"<< sum3(ia,4)<<endl;
                 system("pause");
return 0;
}
7.(1).日期:2011.2.21
  (2).问题:今天在解决习题11.9时遇到了一些关于文件的问题,由于今天状态不错,于是就尝试解决了一下~~
  (3).解决方案:首先我根据书中题干编译了代码,生成了exe文件;然后我在桌面定义了一个文本文件,并在文件中输入了为测试而准备的一段英文;之后利用刚才的exe文件将其打开,得到的运行结果与预想一致,程序成功!!!
   (4).实践代码:
        // 123.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cstdlib>  //用于暂停
#include <vector>   
#include<fstream>
#include<algorithm>
using namespace std;
//用于将单词排序的比较函数
bool isShorter(const string &s1,const string &s2)
{
            return s1.size()<s2.size();
}
//确定给定单词的长度是否不小于
bool GT6(const string &s)
{
            return s.size()>=6;
}
//如果ctr不为,返回word的复数版本
string make_plural(size_t ctr,const string &word,const string &ending)
{
             return (ctr==1) ? word:word+ending;
}     
int main(int argc,char **argv)
{   
         //检查命令行参数
         if(argc<2)
         {
            cerr<<"No input file!"<<endl;
            return EXIT_FAILURE;
         }
//打开文件
        ifstream inFile;
        inFile.open(argv[1]);
        if(!inFile)
        {
           cerr<<"Can not open input file!"<<endl;
           return EXIT_FAILURE;
        }
vector<string> words;
        string word;
        //读入要分析的输入序列,并存放在vector容器中
         while(inFile>>word)
        words.push_back(word);
        //对输入排序以便去除重复的单词
        sort(words.begin(),words.end());
        //使用算法unique对元素重新排序并返回一个迭代器,
        //表示无重复的单词范围的结束,
        //erase操作使用该迭代器删除输入序列中重复的单词
        words.erase(unique(words.begin(),words.end()),words.end());
//将单词按长度排序,等长的单词按字典顺序排列
        stable_sort(words.begin(),words.end(),isShorter);
//计算并输出长度不小于的单词的数目
        vector<string>::size_type wc=count_if(words.begin(),words.end(),GT6);
        cout<<wc<<" "<<make_plural(wc,"word","s")<<" 6 characters or longer"<<endl;
        //输出输入序列中不重复的单词
        cout<<"unique words:"<<endl;
        for(vector<string>::iterator iter=words.begin();iter!=words.end();++iter)
            cout<<*iter<<" ";
        cout<<endl;
system("pause");  //程序在此处停住,以便检查运行结果!
return 0;
}
(5).测试文件内容:
      the quick red fox jumps over the slow red turtle













回复列表 (共2个回复)

沙发


支持你^^^^^^^^^^^^^

板凳

谢谢了~~

我来回复

您尚未登录,请登录后再回复。点此登录或注册