C++ primer 笔记(一)

C++ primer 笔记(一)

第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 面向对象标准库

你可能感兴趣的:(C++ primer 笔记(一))