C++ Primer 总结索引 | 第一章:开始

1、一个简单的c++程序

1、C++程序包含一个 或 多个 函数,调用main运行
2、函数定义包含:返回类型(main返回类型必须为int,int是一种内置类型),函数名,形参列表,函数体
3、main的返回值指示状态,0 或 非0
4、类型 定义了数据元素内容,定义这类数据上可以进行的计算,数据都保存在变量中,每个变量都有自己的类型

1.1 编译、运行程序

1、源文件 及 其后缀
2、从命令行运行编译器 P4

2、初识输入输出

1、一个全面的 标准库 提供IO机制
2、iostream库:两个基础类型istream和ostream,输入流输出流:从IO设备读出或写入IO设备;流表明字符是顺序生成 或 消耗
3、标准库的4个IO对象:istream类型的cin对象:标准输入;ostream类型的cout对象:标准输出;ostream类型的cerr对象:标准错误; ostream类型的clog对象:输出程序运行时一般性信息
4、系统 将程序所运行的窗口 和 对象 关联起来,读取cin从程序正在运行的窗口读入,向cout、cerr和clog写入数据时,写入到同一个窗口
5、使用标准库实施的程序必须包含相关的头文件

2.1 向流写入数据

1、一个表达式产生一个计算结果,由运算对象和运算符组成,输出运算符:<<
2、std::cout << "enter two numbers:" << std::endl; <<运算符接受两个运算对象:左侧的运算对象必须是一个ostream对象,右侧的运算对象是要打印的值。运算符将给定的值写入到给定的ostream对象中,输出运算符的计算结果就是其左侧的运算对象,即计算结果就是写入给定值的那个ostream对象,第一个运算符的结果 成为 第二个运算符 左侧运算对象
3、字符串字面值常量
4、操纵符:endl,结束当前行,将与设备关联的缓冲区中的内容刷到设备中;缓冲刷新 保证到目前为止程序所产生的所有输出都真正写入输出流中,不是仅停留在内存中等待写入流
5、调试时添加打印语句,保证一直刷新流;如果程序崩溃,输出可能还留在缓冲区中,导致关于程序崩溃位置的错误判断

2.2 使用标准库中的名字

1、前缀std::指出名字cout和endl是定义在名为std的命名空间中,命名空间可以帮助我们避免不经意的名字定义冲突,以及使用库中相同名字导致的冲突;标准库定义的所有名字都在命名空间std中
2、作用域运算符::指出想使用定义在命名空间std中的名字cout

2.3 从流读取数据

1、初始化变量:创建变量的同时为他赋予一个值
2、std::cin >> v1 >> v2; 输入运算符>>接受一个istream作为其左侧运算对象,接受一个对象作为其右侧运算对象,从给定的istream读入数据,存入给定对象中,输入运算符返回其左侧运算对象作为其运算结果

3、 注释

1、两种注释:(1)单行注释以//开始,换行符结束,这种注释可以包含任何文本,包括额外的双斜线 (2)两个界定符/* */,以/*开始,以*/结束,可以包含除*/外的任意内容,包括换行符

/*
 * 1
 * 2
 */

2、注意第二种注释:界定符 不能嵌套,所以调试期间注释掉一些代码,最好的方式是用单行注释 注释代码的每一行
std::cout << /* "*/" */;报错," */
std::cout << /* "*/" /* "/*" */;结果," /* "

4、 控制流

更为复杂的执行路径

4.1 while语句

1、反复执行一段代码,直到给定条件为假为止

while (condition)
	statement

交替地检测condition条件(一个产生真 或 假 结果的表达式) 和 执行关联语句statement,直至condition为假时停止。当执行完statement,会再次检测condition
2、复合赋值运算符,前缀递增运算符

4.2 for语句

1、使用for语句:循环条件中检测变量,在循环体中递增变量 使用频繁
2、for (int val = 1; val <= 10; val++) 循环头:包含初始化语句int val = 1,循环条件val <= 10,表达式val++

for (int val = 1; val <= 10; val++) {
	循环体
}

初始化语句只在for循环入口处执行一次,循环体每次执行前,先检查循环条件,满足条件执行循环体,表达式在for循环体之后执行,表达式执行完之后,for语句重新检测循环条件,满足条件再次执行循环体,循环持续直至循环条件为假
3、已知迭代次数时,使用for循环比较简洁;不知道迭代次数时使用while

4.3 读取数量不定的输入数据

1、需要不断读取数据直到没有新的输入为止:while (std::cin >> value)
使用一个istream对象为条件时,其效果是检测流的状态,如果流是有效的,条件为真;当遇到文件结束符(Windows下 ctrl + z ,再按回车:从键盘输入的文件结束符),或遇到一个无效的输入时(输入值不是int),istream对象状态变为无效,处于无效状态的istream对象会使条件变为假
2、常见编译器检查出的错误:语法错误,类型错误,声明错误(每个名字先声明后使用)
3、按照报告顺序逐个修正错误,每修正一个错误重新编译代码

5、类简介

1、定义一个类来定义自己的数据结构,C++能定义 使用上像内置类型一样自然 的类类型
2、需要使用头文件来访问为自己应用程序所定义的类,头文件根据其中定义的类的名字来命名,后缀.h

5.1 自己定义类的例子:Sales_item类

1、Sales_item类表示 一本书的总销售额,售出册数 和 平均售价
2、为了使用一个类,不必关心如何实现,只需要知道类对象可以执行什么操作
3、定义类类型的变量:Sales_item item; 每个类实际上定义了一个新的类型,其类型名就是类名,Sales_item类定义了一个名为Sales_item的类型,item是一个Sales_item类型的对象
4、类Sales_item的作者定义了类对象可以执行的所有动作。Sales_item类定义了创建一个Sales_item对象会发生什么事情,对Sales_item对象进行赋值、加法 或 输入输出运算时会发生什么事情

5.2 VS注释快捷键整理 & VS无法打开源文件 “xxx.h“ 的解决办法

1、VS注释快捷键整理
行注释
行注释有以下两种方式:
方式一:
注释:Ctrl + K, Ctrl + C
取消:Ctrl + K, Ctrl + U
方式二:
注释和取消都是这组快捷键:Ctrl + K, Ctrl + /

块注释
注释和取消都是这个快捷键:Ctrl + Shift + /
2、 visual studio 无法打开源文件 “xxx.h“ 的解决办法

5.3 读写Sales_item,Sales_item对象的加法

以练习1.22为例
1、包含从标准输入读入数据,存入一个Sales_item对象中,将Sales_item的内容写回到标准输出
2、来自标准库的头文件用< >包围头文件名,不属于标准库的头文件,用" "包围
3、定义了两个Sales_item对象来保存销售记录
4、对于Sales_item对象,使用了一个全新“和”的概念——两个Sales_item对象的成员对于相加的结果
5、使用文件的重定向 P19
6、对于sum_item必须初始化(接受一个输入)

#include 
#include "Sales_item.h"

//练习1.22
int main()
{
    Sales_item item, sum_item;
    std::cin >> sum_item;
    while (std::cin >> item) {
        sum_item += item;
    }
    std::cout << sum_item << std::endl;
    return 0;
}

输入输出:
1-01 2 100
1-01 2 100
1-01 3 100
1-01 7 700 100

附头文件Sales_item.h:

/*
 * This file contains code from "C++ Primer, Fifth Edition", by Stanley B.
 * Lippman, Josee Lajoie, and Barbara E. Moo, and is covered under the
 * copyright and warranty notices given in that book:
 * 
 * "Copyright (c) 2013 by Objectwrite, Inc., Josee Lajoie, and Barbara E. Moo."
 * 
 * 
 * "The authors and publisher have taken care in the preparation of this book,
 * but make no expressed or implied warranty of any kind and assume no
 * responsibility for errors or omissions. No liability is assumed for
 * incidental or consequential damages in connection with or arising out of the
 * use of the information or programs contained herein."
 * 
 * Permission is granted for this code to be used for educational purposes in
 * association with the book, given proper citation if and when posted or
 * reproduced.Any commercial use of this code requires the explicit written
 * permission of the publisher, Addison-Wesley Professional, a division of
 * Pearson Education, Inc. Send your request for permission, stating clearly
 * what code you would like to use, and in what specific way, to the following
 * address: 
 * 
 *     Pearson Education, Inc.
 *     Rights and Permissions Department
 *     One Lake Street
 *     Upper Saddle River, NJ  07458
 *     Fax: (201) 236-3290
*/ 

/* This file defines the Sales_item class used in chapter 1.
 * The code used in this file will be explained in 
 * Chapter 7 (Classes) and Chapter 14 (Overloaded Operators)
 * Readers shouldn't try to understand the code in this file
 * until they have read those chapters.
*/

#ifndef SALESITEM_H
// we're here only if SALESITEM_H has not yet been defined 
#define SALESITEM_H

//#include "Version_test.h" 

// Definition of Sales_item class and related functions goes here
#include 
#include 

class Sales_item {
// these declarations are explained section 7.2.1, p. 270 
// and in chapter 14, pages 557, 558, 561
friend std::istream& operator>>(std::istream&, Sales_item&);
friend std::ostream& operator<<(std::ostream&, const Sales_item&);
friend bool operator<(const Sales_item&, const Sales_item&);
friend bool 
operator==(const Sales_item&, const Sales_item&);
public:
    // constructors are explained in section 7.1.4, pages 262 - 265
    // default constructor needed to initialize members of built-in type
#if defined(IN_CLASS_INITS) && defined(DEFAULT_FCNS)
    Sales_item() = default;
#else
    Sales_item(): units_sold(0), revenue(0.0) { }
#endif
    Sales_item(const std::string &book):
              bookNo(book), units_sold(0), revenue(0.0) { }
    Sales_item(std::istream &is) { is >> *this; }
public:
    // operations on Sales_item objects
    // member binary operator: left-hand operand bound to implicit this pointer
    Sales_item& operator+=(const Sales_item&);
    
    // operations on Sales_item objects
    std::string isbn() const { return bookNo; }
    double avg_price() const;
// private members as before
private:
    std::string bookNo;      // implicitly initialized to the empty string
#ifdef IN_CLASS_INITS
    unsigned units_sold = 0; // explicitly initialized
    double revenue = 0.0;
#else
    unsigned units_sold;  
    double revenue;       
#endif
};

// used in chapter 10
inline
bool compareIsbn(const Sales_item &lhs, const Sales_item &rhs) 
{ return lhs.isbn() == rhs.isbn(); }

// nonmember binary operator: must declare a parameter for each operand
Sales_item operator+(const Sales_item&, const Sales_item&);

inline bool 
operator==(const Sales_item &lhs, const Sales_item &rhs)
{
    // must be made a friend of Sales_item
    return lhs.units_sold == rhs.units_sold &&
           lhs.revenue == rhs.revenue &&
           lhs.isbn() == rhs.isbn();
}

inline bool 
operator!=(const Sales_item &lhs, const Sales_item &rhs)
{
    return !(lhs == rhs); // != defined in terms of operator==
}

// assumes that both objects refer to the same ISBN
Sales_item& Sales_item::operator+=(const Sales_item& rhs) 
{
    units_sold += rhs.units_sold; 
    revenue += rhs.revenue; 
    return *this;
}

// assumes that both objects refer to the same ISBN
Sales_item 
operator+(const Sales_item& lhs, const Sales_item& rhs) 
{
    Sales_item ret(lhs);  // copy (|lhs|) into a local object that we'll return
    ret += rhs;           // add in the contents of (|rhs|) 
    return ret;           // return (|ret|) by value
}

std::istream& 
operator>>(std::istream& in, Sales_item& s)
{
    double price;
    in >> s.bookNo >> s.units_sold >> price;
    // check that the inputs succeeded
    if (in)
        s.revenue = s.units_sold * price;
    else 
        s = Sales_item();  // input failed: reset object to default state
    return in;
}

std::ostream& 
operator<<(std::ostream& out, const Sales_item& s)
{
    out << s.isbn() << " " << s.units_sold << " "
        << s.revenue << " " << s.avg_price();
    return out;
}

double Sales_item::avg_price() const
{
    if (units_sold) 
        return revenue/units_sold; 
    else 
        return 0;
}
#endif

5.4 成员函数 与 输出异常处理信息

以练习1.24为例:
将两个Sales_item对象的相加的程序首先应该检查两个对象是否有相同的ISBN

#include 
#include "Sales_item.h"
//练习1.24
int main() {
	Sales_item book, book_sum;
	if (std::cin >> book_sum) {
		while (std::cin >> book) {
			if (book.isbn() == book_sum.isbn()) {
				book_sum += book;
			}
			else {
				std::cout << book_sum << std::endl;
				book_sum = book;
			}
		}
		std::cout << book_sum << std::endl;
	}
	else {
		//没有输入警告信息
		std::cerr << "No data?" << std::endl;
		return -1;//表示失败
	}
	return 0;
}

输入输出:
1-01 2 100
1-01 3 100
1-01 1 100
1-02 1 150
1-01 6 600 100
1-02 1 150 150

1、其中book.isbn() == book_sum.isbn()调用名为isbn的成员函数,成员函数是定义为类的一部分的函数,也称方法
2、以一个对象的名义来调用成员函数
3、点运算符:book.isbn()名为book的对象的isbn成员,点运算符只能用于类类型的对象,右侧运算对象必须是该类型的一个成员名,运算结果为右侧运算对象指定的成员,此函数返回book中保存的ISBN书号

6、小结

如何定义一个main函数,操作系统执行程序的调用入口;
如何定义变量,如何进行输入输出,如何编写if,for和while语句;
对于其他人定义的一个类,如何创建、使用其对象

术语解释 P23

1、缓冲区:一个存储区域,用于保存数据。IO设施通常将输入(或输出)数据保存在一个缓冲区中,读写缓冲区的动作与程序中的动作时无关的,可以显式的刷新输出缓冲,强制将缓冲区中的数据写入输出设备。读cin会刷新cout,程序非正常终止也会刷新cout
2、cerr:ostream对象,关联到标准错误,写入到与标准输出相同的设备。写到cerr的数据是不缓冲的,cerr通常用于输出错误信息或其他不属于程序正常逻辑的输出内容
3、clog:ostream对象,关联到标准错误,写到clog的数据是被缓冲的。clog通常用于报告程序的执行信息,存入一个日志文件中
4、文件结束符:指出文件中没有更多数据
5、头文件:使类或者其他名字的定义可以被多个程序使用的一种机制
6、未初始化的变量:类类型的变量如果未指定初值,按类定义指定的方式进行初始化。定义在函数内部的内置变量类型变量是默认不初始化的,试图使用一个未初始化变量的值是错误的

你可能感兴趣的:(C++,Primer,c++)