第1章
>> << 输入输出操作符返回 输出流std::cin, std::cout本身
endl输出换行,刷新与设备关联的buffer
augument 实参 paremeter 形参
buit-in type 内置类型
manipulator 操纵符
第2章
C++是静态类型语言,编译时执行类型检查
wchar_t =L'a' 16位
float 6位有效数字
double 至少10位有效数字
long double 至少10位有效数字
赋值:对于unsigned越界赋值,结果等于该值对unsigned可能取值个数求模
例如:unsigned char c=336; //实际c=336%256=80
unsigned char c=-1; //实际c=-1%256=255
对于signed越界赋值,由编译器决定实际值
初始化不是赋值,初始化指创建变量并赋值,赋值是擦出当前值赋新值
内置类型初始化:在函数体外定义的变量初始化为0,函数体内定义的不自动初始化。
定义:分配存储空间,还可以指定初值
声明:向程序表明变量的类型,名字
extern声明:当有初始化式时则为定义
非const变量默认为extern,要使const变量能在其他文件中访问,则需显式指定为extern。const默认为定义它的文件的局部变量。
引用必须在定义时初始化,引用一经初始化,就始终指向同一个特定对象。
const必须在定义时初始化。
非const引用 只能绑定与该引用同类型的对象
const引用:int a=1;
const int &p=a //等价于int temp=a; const int &p==temp;
头文件不应该有定义的例外:1)可定义类 2)值在编译时已知的const对象 3)inline函数
头文件中const应被常量表达式初始化,并extern被多个文件共享
预处理器preprocessor 头文件保护符header guard
#ifndefine
#define
#endif
第3章
#include <string>
using std:string:
string s1;
string s2(s1);
string s3("value");
string s4(n,'c');
s.empty()
s.size() 字符个数 返回string::size_type类型// 配套类型(companion type),使库类型的使用与机器无关machine-independent, unsigned类型,不要赋值给int
s[]的索引变量最好也是string::size_type类型
getline(istream,string);
#include <cctype>
isalnum(c)字母或数字 isalpha(c) isdigit(c) islower(c) isupper(c)
tolower(c) toupper(c)
类模板vector #include <vector> using std::vector
vector<T> v1;
vector<T> v2(v1);
vector<T> v3(n,i);
vector<T> v4(n); //值初始化的n个副本
vector<T> v5(p,p+n); //用数组初始化,数组的第一个元素p和最后一个元素的下一元素p+n
v.empty(); v.size();//返回vector<T>::size_type
v.push_back(i);
迭代器iterator
vector<int>::iterator iter=ivec.begin();
end()返回指向末端元素的下一个
const_iterator 自身可变,指向的元素只能读不能写
const类型的iterator 自身不能变,指向固定元素
迭代器距离difference_type, signed类型
vector<int>::iterator mid=v.begin()+v.size()/2;
#include<bitset> using std::bitset;
bitset<位数> bitvec; 0为低阶位
bitset<n> b;
bitset<n> b(u); //unsigned自动转化为二进制,n大于u的位数,则高阶位补0,若小于则超过n的高阶位被丢弃。
bitset<n> b(s); //反向转化,从右往左
bitset<n> b(s,pos,n);
b.any(); 是否存在为1的二进制位 b.none(); 不存在1
b.count(); 1的个数 b.size();二进制位个数
//都返回cstddef头文件中的size_t类型,与机器相关的unsigned类型
b.test(pos); b[pos]是否为1
b.set();所有都置1 b.set(pos);
b.reset();都置0 b.reset(pos);
b.filp();所有都取反 b.flip(pos); //b[0].flip()等价于b.flip(0);
b.to_ulong(); 返回一个unsigned long值
os <<b;
bitset无iterator
第4章
非const变量及要到运行阶段才知道其值的const变量不能用于定义数组维数。
函数体外定义的内置数组,均初始化为0.
不管在哪里定义,类类型数组,自动调用默认构造函数进行初始化,如果没有默认构造函数需显式初始化。
如果数组维数大于显式初始化列表中的初始值数,则剩下的元素,如是内置类型则初始化为0,类类型则调用默认构造函数。 如int a[5]={1,2}; //对于多维数组同样适用
数组下标类型 size_t
不允许使用void*指针操纵它所指向的对象
指针相减,在cstddef中的ptrdiff_t类型,是signed类型
int *p = &ia[2];
int j = p[1]; //j=ia[3];
int k = p[-2]; // k=ia[0];
C++允许指针计算末端的一个地址,但不允许对此地址进行解引用。
指向const对象的指针: const int *cptr; 定义时不需初始化
const指针: int *const cp; 定义时必须初始化
typedef string *pstring;
const pstring cstr; // 解释为const指针,string *const cstr;
C风格字符串:以null结尾的字符数组
#include <cstring>
strlen(s); strcmp(s1,s2); strcat(s1,s2);strcpy(s1,s2);strncat(s1,s2,n);strncpy(s1,s2,n); //如果非null结尾则结果不可预料。
new 类类型数组时,使用默认构造函数初始化,
内置类型则无初始化
也可加上()做值初始化,如 int *p=new int[10]();
char a[0]; //error
char *p=new char[0] //ok,返回有效的非0指针,但不能解引用操作,允许比较运算,在指针上加减0或减去本身得0
string str; string加法两个操作数可以有一个C风格字符串
const char *p=str.c_str(); // c_str返回const指针
int a[3][4];
typdef int int_array[4];
for (int_array *p=a; p!=a+3; ++p)
for(int *q=*p; q!=*p+4; ++q)
cout<<*q<<endl;
dimension 维数 free store 自用存储区==heap 堆
precedence 优先级
第5章
int_quizl |=1UL<<27; //第27位置1
int_quizl &=~(1UL<<27); // 第27位置0
++,--后置,需要先保存操作数原理的值,对于int和指针编译器可优化这额外的工作,但对于复杂迭代器类型需花费更大代价,因此尽量用前置
*iter++ ; //*(iter++)
求3个变量最大值
int max = i > j
? i > k ? i : k
: j >k ? j : k;
sizeof 返回编译时常量,size_t类型
数组元素个数:
int sz=sizeof(ia)/sizeof(*ia);
逗号操作符,最右端的操作数是左值,则逗号表达式的值也是左值。
delete 值为0的指针合法
delete指针后要将指针置0,悬垂指针指向曾经存放对象的内存,但该对象已不存在。
内存泄露memory leak: 删除动态分配的指针失败。
const int *pci=new const int(1024);
delete pci; // ok.
类型转换istream-》bool
while(cin>>s)
显式转换(强制类型转换): cast_name<type>(expression) 关闭或挂起正常的类型检查
static_cast
dynamic_cast 支持运行时识别指针或引用所指向的对象
const_cast 添加或删除const特性
reinterpret_cast:将操作数内容解释为另一种类型
dangling pointer 悬垂指针
implicit conversion 隐式类型转换
integral promotion 整型提升
操作符的优先级
操作符及其结合性 功能 用法
L :: global scope(全局作用域) :: name
L :: class scope(类作用域) class :: name
L :: namespace scope(名字空间作用域) namespace :: name
L . member selectors(成员选择) object . member
L -> member selectors(成员选择) pointer -> member
L [] subscript(下标) variable [ expr ]
L () function call(函数调用) name (expr_list)
L () type construction(类型构造) type (expr_list)
R ++ postfix increment(后自增操作) lvalue++
R -- postfix decrement(后自减操作) lvalue--
R typeid type ID(类型 ID) typeid (type)
R typeid run-time type ID(运行时类型 ID) typeid (expr)
R explicit cast(显式强制类型转换)type conversion(类型转换) cast_name <type>(expr)
R sizeof size of object(对象的大小) sizeof expr
R sizeof size of type(类型的大小) sizeof(type)
R ++ prefix increment(前自增操作) ++ lvalue
R -- prefix decrement(前自减操作) -- lvalue
R ~ bitwise NOT(位求反) ~expr
R ! logical NOT(逻辑非) !expr
R - unary minus(一元负号) -expr
R + unary plus(一元正号) +expr
R * dereference(解引用) *expr
R & address-of(取地址) &expr
R () type conversion(类型转换) (type) expr
R new allocate object(创建对象) new type
R delete deallocate object(释放对象) delete expr
R delete[] deallocate array(释放数组) delete[] expr
L ->* ptr to member select(指向成员操作的指针) ptr ->* ptr_to_member
L .* ptr to member select(指向成员操作的指针) obj .*ptr_to_member
L * multiply(乘法) expr * expr
L / divide(除法) expr / expr
L % modulo (remainder)(求模(求余)) expr % expr
L + add(加法) expr + expr
L - subtract(减法) expr - expr
L << bitwise shift left(位左移) expr << expr
L >> bitwise shift right(位右移) expr >> expr
L < less than(小于) expr < expr
L <= less than or equal(小于或等于) expr <= expr
L > greater than(大于) expr > expr
L >= greater than or equal(大于或等于) expr >= expr
L == equality(相等) expr == expr
L != inequality(不等) expr != expr
L & bitwise AND(位与) expr & expr
L ^ bitwise XOR() expr ^ expr
L | bitwise OR(位异或) expr | expr
L && logical AND(逻辑与) expr && expr
L || logical OR(逻辑或) expr || expr
R ?: conditional(条件操作) expr ? expr : expr
R = assignment(赋值操作) lvalue = expr
R *=, /=, %=, compound assign(复合赋值操作) lvalue += expr, etc.
R +=, -=,
R <<=, >>=,
R &=,|=, ^=
R throw throw exception(抛出异常) throw expr
L , comma(逗号) expr , expr
第6章
switch-case 必须是整型,只能在最后一个case标号或default后面定义变量,或者引入块语句{},以保证该变量在使用前被定义和初始化。
在while循环条件中定义的变量,每次循环里都要经历创建和销毁的过程。
stdexpcept头文件中定义几种标准异常类:
运行时错误:exception 最常见问题 runtime_error仅在运行时才能检测到的问题 range_error overflow_error underflow_error
逻辑错误:logic_error 可在运行前检测到的问题 domain_error 参数的结果值不存在 invalid_argument 不合适的参数 length_error 试图生成一个超出该类型最大长度的对象 out_of_range 使用一个超出有效范围的值
第7章
void func(string &s){..} //实参为字符串字面值出错,func("abc"); 编译失败
void fuc(const string &s){...} //func("abc"); ok.
编译器不会检查形参数组关联的实参数组的长度。
形参是数组的引用int (&a)[10], 编译器不会将数组实参转化为指针,这时编译器会检查形参数组和实参数组的长度是否匹配。
不要返回指向函数局部变量的引用或指针!
//ff.h
int ff(int = 0);
//ff.cc
#include "ff.h"
int ff(int i=0){...} // error. 默认实参只能出现一次,通常放头文件里,如果在定义中提供默认实参,则只有在包含该函数定义的源文件中调用该函数,默认实参才有效。
static局部对象:当定义static局部对象的函数结束时,该对象不会撤销,在之后该函数的多次调用中,该对象会持续存在并保持它的值。
编译器隐式地将在类内定义的成员函数作为内联函数。
每个成员函数(除static成员函数外),都有隐含形参this,在调用成员函数时,形参this初始化为调用函数的对象的地址。
const成员函数则是则是使this指针有const特性,因此该函数不能修改调用对象的数据成员。
const对象,指向const对象的指针或引用,只能调用其const成员函数。
如果类没有显式定义任何构造函数,编译器自动生成默认构造函数。
默认构造函数自动调用类类型的成员的默认构造函数,无需显式初始化。
void func(int);
void func(const int); //重载ok
void func(int *);
void func(const int *);重载ok
void func(int *);
void func(int *const); //redeclaration,不能基于指针是否为const实现重载。
function prototype 函数原型==函数声明
synthesized default constructor合成默认构造函数
第8章
ostream istream
ofsream ostringstream iostream istringstream ifstream
stringstream fstream
IO对象不可复制和赋值! 只有支持复制的元素类型可以存在vector等容器中。形参或返回类型也不能为流类型,只能用指针或引用。
strm::iostate 机器相关的整形名,定义条件状态
strm::badbit 指出被破坏的流 ,不可恢复
strm::failbit 指出失败的IO操作,可恢复
strm::eofbit 指出流已到达文件结束符,同时设置failbit
s.eof(); 如设置了s的eofbit值,则返回true
s.fail();如设置了failbit值则返回true
s.bad();入设置badbit置则返回true
s.good();上面3个都不为true
s.clear();将所有状态重置为有效
s.clear(flag); 重置为flag,strm::iostate类型
s.setstate(flag);添加指定条件 //is.setstate(ifstream::badbit | ifstream::failbit);同时置1.
s.rdstate();返回当前条件
每个IO对象管理一个缓冲区,刷新后写入到真实的输出设备或文件。
导致刷新:1)程序正常结束。
2)缓冲区满
3)endl,ends,flush
4)每次输出操纵符执行完后,用unitbuf设置流的内部状态,从而清空buffer
cout<<unitbuf<<"output sth"<<nounitbuf;
等价于cout<<"output sth"<<flush;
5)将输出流于输入流tie起来,则在读输入流时将刷新关联的输出缓冲区。
cin.tie(&cout);
ostream *old_tie=cin.tie();
cin.tie(0);
cin.tie(old_tie);
string ifile="..";
ifstream infile(ifile.c_str()); //文件名使用C风格字符串
ofstream outfile;
outfile.open("..");
outfile.close(); //重新绑定其他文件前须先关闭
outfile.clear(); //重用已存在的流对象记得clear恢复流状态
文件模式
in out打开后清空
app 在每次写之前找到文件尾 ate打开文件后立即定位到文件尾
trunc打开文件时清空已存在的文件流 binary
fstream inOut("copyOut",fstream::in | fstream::out); //同时in和out不清空
stringstream strm;
stringstream strm(str);
strm.str();
strm.str(s); //返回void
while (getline(cin, line))
{
istringstream stream(line);
while(stream >> word)
{}
}
stringstream 在不同数据类型之间实现自动转换/格式化。
derived class 派生类
object-oriented library 面向对象标准库