第一章

1.包含来自标准库的头文件用<>,不属于标准库用""。

2.默认情况,读cin会刷新cout;程序非正常终止时也会刷新cout。

3.默认情况,cerr不缓冲,cerr通常用于输出错误信息或其他不属于程序正常逻辑的输出内容。

4.默认情况,clog缓冲,clog通常用于报告程序的执行信息,存入一个日志文件中。

第二章

1.算术表达不要用char,char在一些机器上是有符号的,在一些机器上是无符号的;如要使用一个不大的整数,明确指定是signed char还是unsigned char。

2.当我们赋给无符号类型一个超过它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。

比如8bit的unsigned char表示0到255,则unsigned char c=-1  //实际c=-1+256=255

3.当我们赋给带符号类型一个超过它表示范围的值时,结果是未定义的(undefined)。此时程序可能继续工作,可能崩溃,可能生成垃圾数据。

在某些情况或某些编译器下,含有无法预知行为的程序能正确执行,但我们无法保证同样一个程序在别的编译器下能正常工作,甚至已经编译过的代码再次执行也可能会出错。此外,不能认为这样的程序对一组输入有效,对另一组输入就一定有效。

4.当表达式里既有带符号类型又有无符号类型,带符号数会自动地转换成无符号数。

例如:int a=-1,unsigned b=1,a*b结果是4294967295

5.以0开始的数表示8进制,以0x或0X开头的数表示16进制。以下都表示数值20:

20 /*十进制*/  024/*八进制*/  0x14/*十六进制*/

6.默认情况下,十进制字面值是带符号数,八进制和十六进制字面值既可能是带符号也可能是无符号。

7.如果两个字符串字面值位置紧邻且仅由空格、缩进和换行符分隔,它们实际上是一个整体。

std::cout<<"something is wrong with my head, "
      "and i am try my best to solve it"<<endl;

8.泛化的转义序列,其形式是\x后紧跟1个或多个十六进制数字,或者\后紧跟1个,2个,3个八进制数字。\115和\x4d都表示自负M。

std::cout<<"hi \x4dO\115!";  //输出hi MOM!。

如果\后跟的八进制数超过3个,只有前3个数字与\构成转义序列,\1234表示两个字符。\x要用到后面的所有数字,\x1234表示一个字符。

9.指定字面值的类型,如后缀中有U或u,字面值类型从unsigned int,unsigned long和unsigned long long 中选能匹配的空间最小的一个,如后缀中有L或l,字面值类型至少是long,如有LL或ll,字面值将是long long和unsigned long long中的一种。

L'a'  //wchar_t类型a

u'a'  //char16_t

U'a'  //char32_t

u8'a'  //char

42ULL(ull,Ull,uLL)  //unsigned long long

42l(L)  //long

1e-3f(F)  //float

3.14l(L)  //long double  

10.以下初始化等价:

int a=;
int a={};
int a();
int a{};

如果使用列表初始化且初始值存在丢失信息的风险,编译器将报错:

double b=3.14;
int a{b},c={b};  //wrong
int d(b),e=b; 
 //right

11.默认初始化。内置类型未被显示初始化,它的值由定义的位置决定。定义于任何函数体之外的变量被初始化为0,定义在函数体之内的将不被初始化,访问将引发错误。

每个类各自决定其初始化对象的方式,是否允许不经显示初始化就定义对象也由类自己决定。

12.声明只规定变量的类型和名字,定义除此之外还申请存储空间,也可能为变量赋初值。想声明一个变量而非定义它,就在变量名前缀加关键字extern,而且不要显示地初始化变量:

extern int i;  //声明i而非定义i
int j;  //声明j并定义j

给由extern标记的变量赋初值就抵消了extern的作用:

extern int d=;  //定义

在函数内部,试图初始化一个extern标记的变量将引发错误。

在多个文件中使用同一个变量,只能在一个文件中定义,其他文件中都要且只能声明,不能重复定义。

13.标识符必须以字母或下划线开头,用户自定义的标识符中不能出现两个连续的下划线,也不能以下划线紧邻大写字母开头。定义在函数体外的标识符不能以下划线开头。

变量名一般小写,如index;自定义类名一般以大写字母开头,如Sales_item;多个单词组成中间用下划线,如student_loan,不要写成studentloan。

14.在函数体内使用::a表示全局作用域里的变量a。

15.“引用”指“左值引用”,引用必须被初始化,引用是一个已经存在的对象的另一个名字,与它的初始值绑定在一起。引用不是对象,不能定义引用的引用:

int ival=;  
int &refval=ival;  //refval指向ival,是ival的一个别名
refval=;  //把2赋值给refval指向的对象,即ival
int ii=refval;  //与ii=ival执行结果一样
int &refval2=refval;  //refval2绑定到了与refval绑定的对象上,这里是绑定到ival上
int &refval3=;  //错误,引用类型的初始值必须是一个对象
double dval=3.14;
int &refval=dval;  //错误,类型必须为int

15.指针是对象,允许赋值和拷贝,无须定义时赋初值。因为引用不是对象,没有实际地址,所以不能定义指向引用的指针。

对指针解引会得出所指的对象,因此如果给解引的结果赋值,实际上是给指针指向的对象赋值,解引用操作只适用于那些确实指向了某个对象的有效指针。

16.生成空指针:

int *p1=nullptr;  //nullptr可以被转换成任意其他的指针类型(最好的方法)
int *p2=;
int *p3=NULL;  //NULL是预处理变量,在头文件cstdlib中定义,值为0。预处理变量不属于命名空间std,它由预处理器负责管理(尽量避免)

把int变量直接赋值给指针是错误的操作,即使int变量的值恰好等于0也不行

int zero=;
int *pi=zero;  //错误

17.指向指针的指针:

int ival=;
int *p=&ival;  //p指向一个int型的数
int **pi=&p;  //pi指向一个int型的指针

指向指针的引用:(引用不是对象,不能定义指向引用的指针,但指针是对象,可以定义指向指针的指针和引用)

int i=;
int *p;  //p是一个int型指针
int *&r=p;  //r是一个对指针p的引用
r=&i;  //r引用了一个指针,因此给r赋值&i就是令p指向i
*r=;  // 解引用r得到i,也就是p指向的对象,将i的值改为0了

(理解r从右往左读,&表明r是一个引用,*表明r引用的是一个指针,引用是别名,r表示指针p,所以r=&i后p=&i)

18.默认情况下,const对象仅在文件内有效,当在多个文件出现了同名的const变量时,等同于在不同文件中分别定义了独立的变量。

要想只在一个文件中定义const,而在其他多个文件中声明并使用它,需对const变量不管声明还是定义都使用extern:

extern const int a=;  //在file.cc中,定义并初始化了一个常量,能被其他文件使用
extern const int a;  //在file.h中,与file.cc中定义的a是同一个

19.一般情况下,引用的类型必须与其所引用对象的类型一致。一种例外是初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果可以转换成引用的类型即可:

double d=3.14;
const int &a=d;

编译器会把上述代码转换成如下:

const int temp=d;
const int &a=temp;  //即a绑定到了一个临时量对象,如果a不是常量,就会改变a的值,从而改变临时变量的值,无意义

20.和常量引用一样,指向常量的指针可以指向一个非常量:

const double pi=3.14;
const double p2=3.15
const double *ptr=&pi;
*ptr=;  //错误
ptr=&p2;  //正确,可以改变ptr指向的对象

常量指针表示指针本身不能变,即存放在指针中的地址不能变:

int e=;
int *const c=&e;  //c将一直指向e
*c=;  //正确,因为e非常量,所以可以通过c去修改e的值

要区分变量是指向常量的指针还是常量指针,有效的方法是前面说的从右向左阅读。

21.顶层const表示任意的对象是常量,底层const与复合类型的基本类型部分有关(如表示指针所指的对象是一个常量):

22.常量表达式指在编译过程就能得到计算结果的表达式:

const int sz=get_size();  //sz不是常量表达式,因为它是运行时确定的

允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式,声明为constexpr的变量必须用常量表达式初始化:

constexpr int sz=get_size();  //只有当get_size()是constexpr函数时才是正确的声明

在constexpr声明中定义指针,仅对指针有效,与指针所指对象无关:

const int *p=nullptr;  //p是一个指向常量的指针
constexpr int *q=nullptr;  //q是一个指向整数的常量指针,即constexpr把它所声明的对象置为了顶层const

constexpr指针的初始值必须是nullptr或者0,或者是存储于某个固定地址中的对象:

int j=;
constexpr int i=;
//i和j都必须定义在函数体外
constexpr const int *p=&i;
constexpr int *q=&j;

23.类型别名:

typedef double wage;  //wage是double的同义词
typedef wage base,*p;  //base是double的同义词,p是double*的同义词
using s=sale_item;  //s是sale_item的同义词

在使用了类型别名的声明语句中,不能把类型别名替换成它本来的样子理解该语句:

typedef char *ps;
const ps p=;  //p是常量指针,const修饰ps,而ps是指针
const char * p=;  //p是指向const char的指针,const修饰*p,而*p是指针的解引用,即p所指对象的值

24.auto定义的变量必须有初始值,由编译器去分析表达式所属的类型:

auto item=v1+v2;  //item初始化为v1和v2相加的结果
auto i=,*p=&i;  //正确,类型相同
auto sz=,pi=3.14;  //错误,类型不同
int i=,&r=i;
auto a=r;  //a是一个整数(r是i的别名,而i是一个整数)

auto会忽略顶层const,保留底层const:

const int ci=i, &cr=ci;
auto b=ci; //b是一个整数(ci的顶层const被忽略)
auto c=cr; //c是一个整数(cr是ci的别名,ci本身是一个顶层const)
auto d=&i; //d是一个整型指针(整数的地址就是指向整数的指针)
auto e=&ci; //e是一个指向整数常量的指针(对常量对象取地址是一种底层const)

如果希望推断出的auto类型是一个顶层const,需要明确指出:

const auto f=ci;    //ci的推断类型是int,f是const int

还可以将引用的类型设为auto,设定一个类型为auto的引用时,初始值中的顶层常量属性仍然保留:

auto &g=ci;    //g是一个整型常量引用,绑定到ci
auto &h=; //错误,不能为非常量引用绑定字面值
const auto &j=; //正确,可以为常量引用绑定字面值

一条语句定义多个变量时,*和&只从属于某个声明符,而非基本数据类型的一部分:

auto k=ci; &l=i;    //
auto &m=ci,*p=&ci; //m是对整型常量的引用,p是指向整型常量的指针
auto &n=i,*p2=&ci; //错误,i的类型为int而&ci的类型时const int

25.decltype用于希望从表达式的类型推断出要定义的变量的类型,但是又不希望用该表达式的值初始化变量:

decltype(f()) sum=x;    //sum的类型就是函数f的返回类型

如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const和引用在内):

const int ci=,&cj=ci;
decltype(ci) x=; //x的类型是const int
decltype(cj) y=x; //y的类型是const int&,y绑定到变量x
decltype(cj) z; //错误,z是一个引用,必须初始化
int i=,*p=&i,&r=i;  
decltype(r+) b; //正确,加法的结果是int
decltype(*p) c; //错误,c是int&,必须初始化

r是引用,decltype(r)的结果是引用类型,想让结果是r所指的类型,可以把r作为表达式的一部分,如r+0。

如果表达式的内容是解引用操作,decltype将得到引用类型,解引用指针将得到指针所指的对象。

另外,如果decltype的表达式是加上了括号的变量,结果将是引用:

decltype((i)) d;    //错误,d是int&
decltype(i) e; //正确,e是int

c++ primer (5)1的更多相关文章

  1. C Primer Plus 学习体会

    本月刚刚开始学习<C primer plus>,之前课上草草学过一遍,讲到指针就结束了.现在重新开始看感觉难度不大只是刚开始接触有些语言细节比较琐碎.学习这一周的体会如下: 诸多前辈推荐的 ...

  2. C++ Primer Plus 第六版笔记

    C++ Primer Plus 第六版笔记 关于对象声明的思考 转自:http://www.cnblogs.com/weiqubo/archive/2009/11/02/1930042.html C+ ...

  3. 《3D Math Primer for Graphics and Game Development》读书笔记2

    <3D Math Primer for Graphics and Game Development>读书笔记2 上一篇得到了"矩阵等价于变换后的基向量"这一结论. 本篇 ...

  4. 《3D Math Primer for Graphics and Game Development》读书笔记1

    <3D Math Primer for Graphics and Game Development>读书笔记1 本文是<3D Math Primer for Graphics and ...

  5. 再读《C++ Primer》——变量和基本类型

    刚上大学那时,几个室友一块买了本<C++ Primer>第4版,看了一遍后就没怎么碰了,偶尔拿出来翻翻,当作工具书使用.后来知道有第5版了,一直觉得内容差不多吧.直到最近,再读其中的一些内 ...

  6. C Primer Plus_第6章_循环_编程练习

    1.题略 #include int main(void) { int i; char ch[26]; for (i = 97; i <= (97+25); i++) { ch[i-97] = i ...

  7. C Primer Plus_第5章_运算符、表达式和语句_编程练习

    Practice 1. 输入分钟输出对应的小时和分钟. #include #define MIN_PER_H 60 int main(void) { int mins, hours, minutes; ...

  8. C++Primer 5th 练习 12.19

    这阵子真是太忙了, 连续做了四个课设. 当然这并不能作为好久没写博客的借口, 没写博客的主要原因只有一个: 懒. 最近又开始回顾C++的语法与特性(据说C++就是一门需要反复回顾的语言),以及学习C+ ...

  9. [翻译]Primer on Cognitive Computing(认知计算入门)

    Source Kelly J., Primer on Cognitive Computing 20150216. 侵删,联系方式:zhoujiagen\@gmail.com. 按A candidate ...

  10. c++ Primer 第四版 第一阶段 const总结

    由于期末值考一门软件安全,所以果断看起c++Primer ,因为之前看谭浩强的c++感觉没什么用啊.所以这本书每阶段做个总结!!! 1.Const限定符作用: 在for循环中上限应该用一个固定变量来设 ...

随机推荐

  1. [置顶] SNMP协议详解<二>

    上一篇文章讲解了SNMP的基本架构,本篇文章将重点分析SNMP报文,并对不同版本(SNMPv1.v2c.v3)进行区别! 四.SNMP协议数据单元 在SNMP管理中,管理站(NMS)和代理(Agent ...

  2. [Effective C++ --030]透彻了解inlining的里里外外

    引言  inline函数 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数.与非inline函 ...

  3. linux下xargs命令用法详解

    原文:http://blog.chinaunix.net/uid-128922-id-289992.html xargs在linux中是个很有用的命令,它经常和其他命令组合起来使用,非常的灵活. xa ...

  4. Java SE ---算术运算符

    算术运算符:(加)+,(减)-,(乘)*,(除)/,(求余)%,自增自减 一,算数运算符:当有若干个变量参与运算时,结果类型取决于这些变量中表示范围最大的那个变量类型.如果参加运算的变量中有整型int ...

  5. How to solve Original Tango programmer”Hardware not Found”?

    Original Tango programmer is a new generation of transponder programmer which is developed to cover, ...

  6. mybatisGenerator 代码自动生成报错 Result Maps collection already contains value for BaseResultMap【转】

    由于mybatis简单易学,比起Hibername来,更容易上手,代码也能自动生成.这几天研究了下代码自动生成的,参考: http://0609xiaohua.iteye.com/blog/14535 ...

  7. MYSQL基础笔记(二)-SQL基本操作

    SQL基本操作 基本操作:CRUD,增删改查 将SQL的基本操作根据操作对象进行分类: 1.库操作 2.表操作 3.数据操作 库操作: 对数据库的增删改查 新增数据库: 基本语法: Create da ...

  8. Objective-C基础笔记一

    这里开始了我OC旅程 花了8天的时间粗略的学习了新知识Objective-C(简称OC),虽然只是学习了其中的基础部分,但经过这一周的学习也算是入门了.对面向对象的封装.继承.多态以及其中所包含的方法 ...

  9. Oracle启动的整个过程

    1.启动选项 在发出startup命令启动数据库时,oracle将在默认位置$ORACLE_HOME/dbs(UNIX/Linux)中查找初始化参数文件.Oracle将以下面的顺序在其中寻找合适的初始 ...

  10. [改善Java代码]频繁插入和删除时使用LinkedList

    一.分析 前面有文章分析了列表的表里方式,也就是“读”的操作.本文将介绍表的“写”操作:即插入.删除.修改动作. 二.场景 1.插入元素 列表中我们使用最多的是ArrayList,下面看看他的插入(a ...