文章目录
第1章 快速入门
1.2 初窥输入/输出
- 写入到流
输出操作符(<<操作符)接受两个操作数:左操作数必须是ostream对象;右操作数是要输出的值。操作符将其右操作数写到作为其左操作数的ostream对象。
当操作符是输出操作符时,结果是左操作数的值。
故 cout << “Enter two numbers:” << endl;等价于
cout << “Enter two numbers:”;
cout << endl;
- 读入流
从istream操作数读取数据并保存到右操作数中,返回左操作数作为结果。
cin >> v1 >> v2;等价于
cin >> v1;
cin >> v2;
- hello, world
写的第一个c++代码(vs2013)
#include<iostream>
using namespace std;
void main()
{
cout<<"hello, world"<<endl;
system("pause");
}
1.4 控制结构
1.4.4 读入未知数目的输入
#include<iostream>
using namespace std;
int main()
{
int sum = 0, value;
while(cin >> value) //ctrl+z(windows下)/输入null/NULL结束
sum += value;
cout << "sum is: "
<< sum << endl;
return 0;
}
1.5 类的简介
-
使用类时回答三个问题:
(1)类的名字是什么?
(2)它在哪里定义?
(3)它支持什么操作?
-
标准库的头文件用尖括号<>括起来,非标准库的头文件用双引号""括起来。
-
点操作符的右操作数是成员的名字。
第2章 变量和基本类型
2.1 基本内置类型
2.1.1整型
表示整数、字符和布尔值的算术类型合称为整型。
字符类型有两种:char 和 wchar_t。char类型通常是单个机器字节。wchar_t类型用于扩展字符集,比如汉字和日语,这些字符集中的一些字符不能用单个char表示。
1个字节=8位
4个字节=1个字
2.1.2浮点型
2.2 字面值常量
称之为字面值是因为只能用它的值称呼它,称之为常量是因为它的值不能修改。只有内置类型存在字面值,没有类类型的字面值。
- 整型字面值规则
定义字面值整数常量可以使用:十进制、八进制和十六进制。
通过在数值后面加大小写L指定常量为long类型。
通过在数值后面加大小写U定义unsigned类型。
后缀不能有空格:
128u /* unsigned */ 1024UL/* unsigned long */
1L /* long */ 8Lu /* unsigned long */
- 浮点字面值规则
下面每一组字面值表示相同的值:
3.14159F .001f 12.345L 0.
3.14159E0f 1E-3F 1.2345E1L 0e0
- 字符字面值
在字符字面值前加L就能得到wchar_t类型的宽字符字面值。如:L‘a’
-
非打印字符的转义序列
-
字符串字面值
-
字母串字面值的链接
连接不同类型的行为标准没有定义。
- 多行字面值
后继行行首的任何空格和制表符都是字符串字面值的一部分,因此,长字符串字面值的后继行才不会有正常的缩进。
2.3 变量
2.3.3 定义对象
- 初始化
int ival(1024); //直接初始化
int ival = 1024; //复制初始化
c++中初始化不是赋值。直接初始化语法更灵活且效率更高。
- 使用多个初始化式
有多个初始化式时不能使用复制初始化。
- 初始化多个变量
可以用同一个定义中前面已定义变量的值初始化后面的变量。
2.3.4 变量初始化规则
- 内置类型变量的初始化
在函数体外定义的变量都初始化为0,在函数体里定义的内置类型变量不进行自动初始化。
建议每个内置类型的对象都要初始化。
- 类类型变量的初始化
2.3.5 声明和定义
变量可以声明多次,但只能定义一次。
声明包括对象名,对象类型和对象类型前的关键字extern。
已初始化的extern声明被当作是定义。只有当extern声明位于函数外部时,才可以含有初始化式。
2.3.5 名字的作用域
#include<iostream>
using namespace std;
int main()
{
int sum = 0;
for(int val = 1; val <= 10; val++)
sum += val;
cout << "sum of 1 to 10 is "
<< sum;
return 0;
}
sum有局部作用域,val有语句作用域。
2.4 const限定符
非const变量默认为extern。要使const变量能够在其他的文件中访问,必须显示地指定它为extern。
2.5 引用
- 引用是别名
初始化是指明引用指向哪个对象的唯一方法。
-
定义多个引用
-
const引用
const引用是指向const对象的引用:
int ival = 1024;
int &refVal = ival;
可以读取但不能修改refVal,任何对refVal的赋值都是不合法的。
非const引用只能绑定到与该引用同类型的对象。
const引用则可以绑定到不同但相关的类型的对象或绑定到右值。
2.8 类类型
用class和struct关键字定义类的唯一差别在于默认访问级别:默认情况下,struct的成员为public,而class的成员为private。
2.9 编写自己的头文件
2.9.1 设计自己的头文件
头文件一般包括类的定义、extern变量的声明和函数的声明。
- 头文件用于声明而不是用于定义
因为头文件包含在多个源文件中,所以不应该含有变量或函数的定义。
对于头文件不应该含有定义这一规则,有三个例外。头文件可以定义类、值在编译时就已知道的const对象和inline函数。(7.6节介绍inline函数)。这些实体可在多个源文件中定义,只要每个源文件中的定义是相同的。
- 一些const对象定义在头文件中(?)
如果const变量不是用常量表达式初始化,那么它就不应该在头文件汇总定义。
2.9.2 预处理器的简单介绍
#ifndef SALESITEM_H
#define SALESITEM_H
#endif
条件指示 #ifndef SALESITEM_H 测试 SALESITEM_H 预处理器变量是否未定义。
第3章 标准库类型
3.1 命名空间的using声明
3.2 标准库string类型
3.2.1 string对象的定义和初始化
当没有明确指定对象初始化式时,系统将使用默认构造函数。
字符串字面值与标准库string类型不是同一种类型。
3.2.2 string对象的读写
string类型的输入操作符:读取并忽略开头所有的空白字符(如空格,换行符,制表符);读取字符直至再次遇到空白字符,读取终止。
用getline读取整行文本。getline并不忽略行开头的换行符,只要getline遇到换行符,即便它是输入的第一个字符,getline也将停止读入并返回。如果第一个字符就是换行符,则string参数将被置为空string。
3.2.3 string对象的操作
2. string::size_type类型
size操作返回的是string::size_type类型的值,是unsigned型。
任何存储string的size操作结果的变量必须为string::size_type类型。特别重要的是,不要把size的返回值赋给一个int变量。
对于任意一种给定的数据类型,它的unsigned型所能表示的最大正数值比对应的signed型要大一倍。
3. string关系操作符
string对象比较操作时区分大小写的。在多数计算机上,大写的字母位于小写字母之前:任何一个大写字母都小于任意的小写字母。
6. 和字符串字面值的连接
当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的。string标准库定义加操作返回一个string对象。
把两个字符串字面值连接起来是不允许的。
7. 从string对象获取字符
下标操作符需要取一个size_type类型的值。s[s.size()-1]表示s的最后一个字符。
3.2.4 string对象中字符的处理
下表列出各种字符操作函数,适用于string对象的字符。这些函数都在cctype头文件中定义。
3.3 标准库vector类型
vector被称为容器。一个容器中的所有对象都必须是同一种类型的。vector是一个类模板,不是一种数据类型。vector为数据类型。
3.3.1 vector对象的定义和初始化
vector对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效地添加元素。
如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进行值初始化。具体值为何,取决于存储在vector中元素的数据类型。
3.3.2 vector对象的操作
必须是已存在的元素才能用下标操作符进行索引。通过下标操作进行赋值时,不会添加任何元素。
3.4 迭代器简介
1. 容器的iterator类型
2. begin和end操作
由begin返回的迭代器指向第一个元素:
vector<int>::iterator iter = ivec.begin();
由end返回的迭代器指向vector的“末端元素的下一个”,通常称为超出末端迭代器,表明它指向了一个不存在的元素。如果vector为空,begin返回的迭代器与end返回的迭代器相同。
3. vector迭代器的自增和解引用运算
迭代器类型可使用解引用操作符来访问迭代器所指的元素:
*iter = 0;
把iter所指的元素值赋为0。
由于end操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。
6. const_iterator
该类型只能用于读取容器内元素,但不能改变其值。
迭代器的算术操作注意,两个迭代器相加的操作是未被定义的。
3.5 标准库bitset类型
要使用biteset类型就必须包含相关的头文件。
3.5.1 bitset对象的定义和初始化
在定义bitset时,要明确bitset含有多少位,须在尖括号内给出它的长度值。
2. 用string对象初始化bitset对象
string对象直接表示为位模式。从string对象读入位集的顺序是从右向左。可以只用某个子串作为初始值。
string str("11111110000000110");
bitset<32> bitvec5(str,5,4);
bitset<32> bitvec6(str,str.size()-4); //use last 4 characters;
3.5.2 bitset 对象上的操作
4. 获取bitset对象的值
to_ulong操作返回一个unsigned long值,该值与bitset对象的位模式存储值相同。仅当bitset类型的长度小于或等于unsigned long的长度时,才可以使用to_ulong操作。
5. 输出二进制位
可以用输出操作符输出bitset对象中的位模式。
第4章 数组和指针
4.1 数组
没有所有元素都是引用的数组。
数组下标的正确类型是size_t。
4.2 指针的引入
4.2.2 指针的定义和初始化
string* ps1, ps2;
实际上只把ps1定义为指针。
若指针保存0值,表明它不指向任何对象,此时指针是有效的。
把int型变量赋给指针是非法的,但允许把数值0或在编译时可获得0值的const量赋给指针。
void* 指针只支持几种有限的操作:与另一个指针进行比较;向函数传递void* 指针或从函数返回void* 指针;给另一个void* 指针赋值。不允许使用void* 指针操纵它所指向的对象。
4.2.5 指针和const限定符
1. 指向const对象的指针
const double *cptr;
允许把非const对象的地址赋给指向const对象的指针,但任何企图通过指针修改其值的行为都会导致编译时的错误。
2. const指针
int errNumb = 0;
int *const curErr = &errNumb;
const指针必须在定义时初始化。
* 指针本身是const的事实并没有说明是否能使用该指针修改它所指向对象的值。
4. 指针和typedef
typedef string *pstring;
const pstring cstr;
等价于
string *const cstr;
以下三种书写方式相同
string s;
typedef string *pstring;
const pstring cstr1 = &s; //1
pstring const cstr2 = &s; //2
string *const cstr3 = &s; //3
4.3 C风格字符串
尽量避免使用C风格字符串。
4.3.1 创建动态数组
对于动态分配的数组,其元素只能初始化为元素类型的默认值。
int *pia = new int[10];
此new表达式分配了一个含有10个int型元素的数组。
delete [] pia;
以上为动态空间的释放。
4.3.2 新旧代码的兼容
可以把C风格字符串用在任何可以使用字符串字面值的地方。
反之则不成立:在要求C风格字符串的地方不可直接使用标准库string类型对象。