前言

Stanley B.Lippman 先生所著的《C++ Primer》是学习C++的一本非常优秀的教科书,但《C++ Primer》作为一本大部头书,显然不适合所有的初学者。所以Lippman先生又返璞归真地写了这本短小轻薄的《Essentia C++》。这本书以简短的章节篇幅,帮助初学者快速学习C++的语法,了解C++语言特性,理解C++的设计目的和基本原理。笔者阅读的是《Essential C++》中文版,其译者为侯捷老师,他也是《C++ Primer》中文版第三版的译者。

基础知识

第一个完整的C++程序:

  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8. string user_name;
  9. cout << "Please enter your first name:";
  10. cin >> user_name;
  11. cout << '\n'
  12. << "Hello, "
  13. << user_name
  14. << "...and goodbye!\n";
  15. return 0;
  16. }

关键字(keyword),就是程序语言预先定义的一些具有特殊意义的名称。

函数(function)是一块独立的程序代码序列,能够执行一些运算。它包含四个部分,返回值类型(return type),函数名称,参数列表(parameter list),以及函数体(function body)。main并非是程序语言定义的关键字,但是,C++编译系统会假设程序中定义有main()函数。main()函数是程序执行的起点,如果我们没有定义,程序将无法执行。

类(class),class机制赋予了我们“增加程序内之类型抽象化层次”的能力。class机制让我们得以将数据类型加入我们的程序中,并有能力识别它们。面向对象的类层次体系(class hierarchy)定义了整个家族体系的各个相关类型。class的定义一般来说分为两部分,分别写在不同的文件中。一个就是所谓的“头文件(header file)”,用来声明该class所提供的的各种操作行为(operation)。另一个文件,程序代码文件(program text),则包含了这些行为的实现内容(implementation)。欲使用class,我们必须先在程序中包含其头文件,头文件可以让程序知道class的定义。

命名空间(namespace),是一种将库名称封装起来的方法。通过这种方法,可以避免和应用程序发生命名冲突得到问题(所谓命名冲突是指在应用程序内两个不同的实体(entity)具有相同名称),导致程序无法区分两者。命名冲突发生时,程序必须等到该命名冲突获得解析(resolve)之后,才得以继续执行。命名空间像是在众多名称的可见围内竖起一道围墙。

为了定义对象,我们必须为它命名,并赋予它数据类型。对象名称可以是任何字母、数字、下画线的组合,并大小写敏感。对象名称不能以数字开头。当然任何命名不能和程序语言本身关键字完全一致。例如 delete 是语言关键字,所以 string class 采用 earse() 而非 delete() 来表示“删去一个字符”的原因。

template class 允许我们在“不必指明 data member 类型”的情况下定义class。template class 机制使程序员得以直到使用 template class 时才决定真正的数据类型。程序员可以先插入一个代名,稍后才绑定至实际的数据类型。

由于反斜线字符以用作转义字符的起头字符,因此连续两个反斜线即表示一个真正的反斜线字符。

被定义为 const 的对象,在获得初值之后,无法在有任何变动。如果你企图为 const 对象指定新值,会产生编译错误。

对于 OR 逻辑运算符( || ),左侧表达式会先被求值,如果其值为 true,剩下的表达式就不需要再被求值(此所谓短路求值法)。AND 逻辑运算符( && ),最左侧表达式会先被求值,其结果若为 false ,则 AND 运算符的求值结果即为 false,其余表达式不会再被求值。

一些运算符优先级简列于下,位置在上者的优先级高于位置在下者,同一行的各种运算符具有相同的优先级,其求值次序取决于它在该表达式中的位置(由左至右)。

逻辑运算符 NOT

算术运算符(*,/,%)

算术运算符(+,-)

关系运算符(<,>,<=,>=)

关系运算符(==,!=)

逻辑运算符 AND

逻辑运算符 OR

赋值运算符 (assignment = )

如果要访问一个由指针所指的对象,我们必须对该指针进行提领(dereference,也叫解引用)操作——也就是取得“位于该指针所指内存地址上”的对象。在指针之前使用“*”号,便可以达到这个目的。

我们可以使用 dot 成员选择运算符(member selection opereation),用来选择我们想要的操作。如果要通过指针来选择操作,必须改用 arrow 成员选择运算符。如果要使用下标运算符(subscript operator),我们必须先提领指针,由于下标运算符的优先级较高,因此指针提领操作的两旁必须加上小括号。

练习题答案

练习1.5 编写一个程序,能够询问用户的姓名,并读取用户所输入的内容。请确保用户输入的名称长度大于两个字符。如果用户的确输入了有效的名称,就响应一些信息。请以两种方式实现:第一种使用C-style字符串,第二种使用string对象。

  1. #include <iostream>
  2. #include <string>
  3. #include <iomanip>
  4. #include <cstring>
  5.  
  6. using namespace std;
  7.  
  8. #define MAX 50
  9. #define MIN 2
  10.  
  11. int main()
  12. {
  13. //C-style 字符串
  14. /*
  15. const int nm_size = 128; //分配一个固定大小
  16. char user_name[nm_size];
  17. cout << "Please enter your name:";
  18. cin >> setw(nm_size) >> user_name; //保证读入不超过127个字符,最后一个空间保存null
  19. size_t len = strlen(user_name);
  20. if (len <= 3)
  21. {
  22. cout << "Please enter a longer name!" << endl;
  23. return 0;
  24. }
  25. cout << "Hello," << user_name << endl;
  26. */
  27.  
  28. //string对象
  29. string user_name;
  30. cout << "Please enter your name:";
  31. cin >> user_name;
  32. size_t len = user_name.size(); //获取的即为字符串长度,无null
  33. if (len <= 2)
  34. {
  35. cout << "Please enter a longer name!" << endl;
  36. return 0;
  37. }
  38. cout << "Hello," << user_name << endl;
  39. return 0;
  40. }

练习1.6 编写一个程序,从标准输入设备读取一串整数,并将读入的整数依次放到 array 和 vector,然后遍历这两种容器,求取值总和。将总和及平均值输出至标准输出设备。

  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6. #define MAX 10
  7.  
  8. int main()
  9. {
  10. /*
  11. //存放到vector
  12. vector<double> v;
  13. double temp=0;
  14. double sum = 0;
  15. double ave = 0.0;
  16. while (cin >> temp)
  17. {
  18. v.push_back(temp);
  19. }
  20. for (int i = 0;i < v.size();i++)
  21. {
  22. sum += v[i];
  23. }
  24. ave = sum / v.size();
  25. cout << "Sum=" << sum << endl;
  26. cout << "Average=" << ave << endl;
  27. */
  28. //存放到array
  29. double arr[MAX];
  30. int count = 0;
  31. int count2 = 0;
  32. double temp;
  33. double sum = 0.0;
  34. double ave = 0.0;
  35. while (count<10 && cin >> temp)
  36. {
  37. arr[count] = temp;
  38. count++;
  39. }
  40. count2 = count;
  41. count--;
  42. while (count >= 0)
  43. {
  44. sum += arr[count];
  45. count--;
  46. }
  47. ave = sum / count2;
  48. cout << "Sum=" << sum << endl;
  49. cout << "Average=" << ave << endl;
  50. return 0;
  51. }

练习1.7 使用你最称手的编辑工具,输入两行(或更多)文字存盘。然后编写一个程序,打开该文本文件,将其中的每个字都读取到一个 vector<string> 对象中。遍历该 vector,将内容显示到 cout。然后利用泛型算法 sort(),对所有文字排序。

  1. #include <iostream>
  2. #include <fstream>
  3. #include <algorithm>
  4. #include <string>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. int main()
  10. {
  11. ifstream in_file("1.txt");
  12. if (!in_file)
  13. {
  14. cerr << "opps! unable to open input file\n";
  15. return -1;
  16. }
  17. ofstream out_file("2.txt");
  18. if (!out_file)
  19. {
  20. cerr << "opps! unable to open output file\n";
  21. return -1;
  22. }
  23. string word;
  24. vector<string> text;
  25. while (in_file >> word)
  26. text.push_back(word);
  27. size_t ix;
  28. cout << "unsorted text:\n";
  29. for (ix = 0;ix < text.size();++ix)
  30. {
  31. cout << text[ix] << ' ';
  32. }
  33. cout << endl;
  34. sort(text.begin(), text.end());
  35. cout << "sorted text:\n";
  36. for (ix = 0;ix < text.size();++ix)
  37. {
  38. cout << text[ix] << ' ';
  39. out_file << text[ix] << ' ';
  40. }
  41. cout << endl;
  42. out_file << endl;
  43. return 0;
  44. }

练习1.8 1.4节的 switch 语句让我们得以根据用户答错的次数提供不同的安慰语句。请以 array 储存四种不同的字符串信息,并以用户答错的次数作为 array 的索引值,以此方式来显示安慰语句。

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <ctime>
  4.  
  5. using namespace std;
  6.  
  7. const char* msg_to_usr(int num_tries);
  8.  
  9. int main()
  10. {
  11. int count=0;
  12. srand(time(0));
  13. int answer = rand() % 3;
  14. int myAnswer;
  15. char isContinue = 'y';
  16. while (isContinue=='y')
  17. {
  18. cout << "Please input your answer(0-2): ";
  19. cin >> myAnswer;
  20. if (myAnswer == answer)
  21. {
  22. cout << "Congratulations!" << endl;
  23. break;
  24. }
  25. else
  26. {
  27. count++;
  28. cout << msg_to_usr(count) << endl;
  29. cout << "Continue? input y or n: ";
  30. cin >> isContinue;
  31. }
  32. }
  33. return 0;
  34. }
  35.  
  36. const char* msg_to_usr(int num_tries)
  37. {
  38. const int rsp_cnt = 5;
  39. static const char* usr_msgs[rsp_cnt] =
  40. {
  41. "Go on, make a guess. ",
  42. "Oops! Nice guess but not quite it. ",
  43. "Hmm. Sorry. Wrong a second time. ",
  44. "Ah, this is harder than it looks, no? ",
  45. "It must be getting pretty frustrating by now! "
  46. };
  47. if (num_tries < 0)
  48. {
  49. num_tries = 0;
  50. }
  51. else if (num_tries >= rsp_cnt)
  52. num_tries = rsp_cnt - 1;
  53. return usr_msgs[num_tries];
  54. }

end。

“取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,则无所得矣。”

#《Essential C++》读书笔记# 第一章 C++ 编程基础的更多相关文章

  1. 第一章 C++编程基础

    第一章 C++编程基础 1.1 如何撰写C++程序 赋值 assignment复合赋值 (compound assignment) += 函数(function)是一块独立的程序代码序列(code s ...

  2. 《css3实战》读书笔记 第一章 基于CSS需求而编写的HTML.

    笔记说明 <CSS3实战手册第3版(影印版)>可以消除Web设计工作的痛苦,并且带给你:HTML--重新入门.如果你是HTML新手,你会学到如何以CSS友好的方式进行基本页面构造.若你是H ...

  3. .net架构设计读书笔记--第一章 基础

    第一章 基础 第一节 软件架构与软件架构师  简单的说软件架构即是为客户构建一个软件系统.架构师随便软件架构应运而生,架构师是一个角色. 2000年9月ANSI和IEEE发布了<密集性软件架构建 ...

  4. 《疯狂Java:突破程序员基本功的16课》读书笔记-第一章 数组与内存控制

    很早以前就听过李刚老师的疯狂java系列很不错,所以最近找一本拿来拜读,再此做下读书笔记,促进更好的消化. 使用Java数组之前必须先对数组对象进行初始化.当数组的所有元素都被分配了合适的内存空间,并 ...

  5. Getting Started With Hazelcast 读书笔记(第一章)

    第一章:数据集群的演化与 早期的服务器架构 显然,应用是可扩展的,但是由于是集中式服务器,随着数据库性能达到极限,再想扩展就变得极端困难,于是出现了缓存.    缓存显然再次提升了可扩展性,减轻了数据 ...

  6. C缺陷与陷阱----读书笔记---第一章

    第一章:词法陷阱 编译器中负责将程序分解为一个一个符号的部分,一般称为“词法分析器”.例如,对于语句: if ( x == big ) big = x ; 它的第一个符号是C语言关键字if,紧接着下一 ...

  7. 《C++ Primer》读书笔记 第一章

    读<C++ Primer>才知道,自己对C++知之甚少... 写个博客记录下自己C++的成长,只是读书笔记,不是对<C++ Primer>知识点的总结,而是对自己在书上看到的以 ...

  8. 《深入理解计算机系统》(CSAPP)读书笔记 —— 第一章 计算机系统漫游

    本章通过跟踪hello程序的生命周期来开始对计算机系统进行学习.一个源程序从它被程序员创建开始,到在系统上运行,输出简单的消息,然后终止.我们将沿着这个程序的生命周期,简要地介绍一些逐步出现的关键概念 ...

  9. javascript 数据结构和算法读书笔记 > 第一章 javascript的编程环境和模型

    1.变量的声明和初始化 必须使用关键字 var,后跟变量名,后面还可以跟一个赋值表达式. var name; var age = 5; var str = 'hello'; var flg = fal ...

随机推荐

  1. Spring-Cloud之Eureka注册中心环境搭建(单节点)

    一 Eureka概述 服务启动时会生成服务的基本信息对象InstanceInfo,然后在启动时会register到服务治理中心. 注册完成后会从服务治理中心拉取所有的服务信息,缓存在本地. 之后服务会 ...

  2. Linux Centos7 在桌面添加快捷方式

    当时,刚刚安装好centos7,又下载好了jb家的软件,但是每一次都要用命令行才能运 我想要的是下面的效果,那是我后来才研究出来的 我看到了自动生成的为什么可以用,我的打开了源文件研究了一下 第一,先 ...

  3. redis端口6379的由来

    有一个技巧,Redis端口号6379,是手机键盘上的MERZ.

  4. (转)KL散度的理解

    KL散度(KL divergence) 全称:Kullback-Leibler Divergence. 用途:比较两个概率分布的接近程度.在统计应用中,我们经常需要用一个简单的,近似的概率分布 f * ...

  5. DWZ框架--页面样式丢失

    案例 今天我导入DWZ框架demo时,发现主页面样式丢失,出现了如下图那鬼样: 正常情况应该是有表格显示,并且用chrome开发者模式调试,可以看到有对应的样式,如下图所示: 先简单介绍下dwz框架的 ...

  6. Arduino系列之按键模块(一)

    今天我将简单介绍按键模块计数的原理: 我们常用的按键及按键模块有2脚和4脚的,其内部结构如图所示,当按下按键时就会接通按键两端,当放开时,两端自然断开.                         ...

  7. 删除我的电脑wps、百度网盘图标

    删除我的电脑wps.百度网盘图标 删除下面子项 输入"计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Expl ...

  8. 11、ACL

    IP访问控制列表 标准ACL 1)检查源地址 2)不能对协议簇作限定 扩展ACL 1)检查源和目标地址 2)能容许或拒绝特定的协议和应用(端口号) 区别列表类型: 1)ACL号 : 1-99,1300 ...

  9. Spanner的TrueTime与事务

    Spanner的TrueTime与事务 Spanner是谷歌的分布式数据库,发表于著名论文Spanner: Google's Globally-Distributed Database,它创造性的采用 ...

  10. Zabbix监控实现跨区域跨网络监控数据

    Zabbix监控实现跨区域跨网络监控数据 环境: 公司现有服务器10台,其中5台服务器有一台安装了zabbix,并且这5台服务器处于一个网络,只有一台服务器有公网ip, 另外的5台处于另一个网络,仅有 ...