1.在算数表达式中最好不要使用char或bool,只有在存放字符或布尔值时才使用他们,因为char在有些机器上是有符号的,在一些机器上是无符号的,所以特别容易出问题,如果只表示一个不大的整数,那么明确他的类型是signed char或是unsigned char。

2.关于相互赋值。如果按如下定义bool a = 10; int b = a; 那么b = 1,因为bool变量true类型算术运算时会被当成1,false为0。

当我们把一个浮点数赋给一个整数时,会截尾处理。

当把一个非0的书赋给bool变量是,值为true,否则是false。

当把整数赋给浮点数时,若超过浮点数的精确表示范围,会有精度损失,double能表示的精确范围是2的50+次方以内,若大于这个范围的数赋给一个double数,就会有精度损失。

当赋给无符号类型一个超出他表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如给unsigned char类型的对象赋值的结果是((x % 256) + 256) % 256, 比如输入-1时值为255.

当赋给带符号类型一个超出他表示范围的值时,结果是未定义的,此时,程序可能继续工作,可能崩溃,也可能产生垃圾数据。

其中无符号类型的优先级高于带符号类型,当一个无符号类型和一个带符号类型的变量在一起运算时,带符号类型的数会转成无符号类型再运算,例如unsigned u= 10; int i = 42;cout << u + i << endl;会输出4294967264,因此不要混用无符号类型和带符号类型。

另外,不能在for语句里这样写 : for (unsigned i = 10; i >= 0; --i) 便是死循环,因为i永远不会小于0。

3.若一个字符串过长可以这样输出 : cout << "abcd"

"efgh"

"ijkl"; 而不用加多个 << 运算符。

4.指定字面值的类型 : L'a' 代表wchar_t类型, u8“hi!” 代表utf-8字符串 42ULL代表unsigned类型1E-3F代表float类型的0.001,3.14L代表long double类型。

u或U代表unsigned, f或F代表float类型,l或L代表long类型或long double类型,ll或LL代表long long类型。

5.普通变量初始化有多种形式:int a = 0; int a = {0}; int a(0); int a{0};其中用花括号初始化是C++11新标准,被称为”列表初始化“,无论初始化还是赋值都可以使用,必须在支持C++11的编译器上才能使用。

不过当使用列表初始化时存在丢失信息的风险时,编译器会报错:double a = 3.14; int b{a}, c={a};都会报错,而int d(a), e = a;都会正确执行。

6.extern是声明一个变量而非定义一个变量,可以在程序其他地方定义这个变量,但是不能给extern声明变量时赋初值,若赋了初值,就会抵消extern的作用,变成定义变量,但这会引发错误。

7.变量命名:用户自定义的变量名中不能连续出现两个下划线,也不能以下划线紧连大写字母开头,此外,定义在函数之外的标识符不能以下划线开头。

8.若在一个变量的作用域内层再定义一个变量,并且在自己的作用域里面覆盖(隐藏)了以前的变量,若外层变量是全局变量,也可调用这个全局变量,方法为::a,因为全局作用域没有名字,所以当操作符左侧为空时,向全局作用域发出请求获取符号右侧名字对应的变量名。

9.引用。引用只是一个已存在对象的别名,但引用不是一个对象,所以不能定义引用的数组,也不能定义引用的引用。

除了两种特殊情况(以后再介绍)外,其他所有类型的引用必须要与绑定的对象类型严格匹配(包括const)。

10.指针。与引用不同的是,指针是一个实实在在存在的对象。因为引用不是对象,所以没有自己的地址,因此不能定义引用的指针,但可以定义指针的引用。

除了两种特殊情况(以后再介绍)外,其他所有类型的指针必须要与指向的对象类型严格匹配(包括const)。

得到空指针最直接的方法就是用nullptr来初始化指针,nullptr是C++11的新内容,可以被转换为任何指针类型,还有两种初始化方法:0和NULL,下面三种写法等价:int *p1 = nullptr; int *p2 = 0; int *p3 = NULL; 不过在新标准下,现在的C++程序最好使用nullptr。

另外,把int变量直接赋值给指针变量是错误的行为,即使int值为0也不行:int zero = 0; int *p = zero//严重错误,切记

建议:初始化所有指针。

11.const类型一经定义无法改变,因此const对象必须初始化。

默认情况下,const对象仅在文件内有效。定义并初始化一个常量,编译器会在编译过程中把用到该变量的地方都替换成对应的值,当多个文件中定义了相同的常量时,其实也就是每个文件中都定义了一个单独的常量。

有时候const变量初始值不是一个常量表达式,但想要在文件间共享,这种情况下,如果不希望编译器生成多个const变量,解决的方法是,对于const变量不管声明还是定义都添加extern关键字,这样只需定义一次就可以了

12.const引用。常量必须被常量引用绑定,不能被变量类型引用绑定,而常量类型的引用也能绑定非常量。

另外,允许一个常量引用绑定一个非常量的对象,字面值,甚至是一般表达式。

double a = 3.14; cons int& b = a;此时b引用了一个int类型的数,对b的操作应该是整数运算,因此,编译器把上述代码变成如下形式: const int temp = a; const int& b = a;因此b绑定了一个临时量。 当b不是常量时,如果int& b = a;不出错的话,那b绑定了一个临时对象,有因为b不是const,因此可以改变绑定对象的值,但我们绑定的是临时量,而不是我们想要的量,因此,这是毫无意义的,C++也不允许这样定义。

当一个常量引用绑定一个变量时,不能用该引用修改该值,但该变量还是变量,可以改变他的值,只不过不能通过这个引用修改罢了。

13.const指针。某些地方和const引用一样,要想存放指向常量的地址,只能用指向常量的指针。

除了两中特殊情况,指针类型也必须与指向的对象类型一致。其中一种是允许指向常量的指针指向非常量的对象。

与const引用类似,指向常量的指针指向非常量对象时,仅仅要求此指针不能改变指向对象的值,但该对象还是可以通过其他方式改变。

14.关于const。const分为顶层const和底层const,指针类型既有顶层const又有底层const,比如:const int* const p; 应从右往左读,右边的const为顶层const,左边的为底层const,对于其他情况,const int a; 则为顶层const;特殊的,用于声明引用的const都是底层const。

当对象之星拷贝操作时,顶层const不受什么影响,例如const int a = 1; int b = a;因此拷入和拷出的对象是否是常量都没什么影响。

但是底层const的限制不能忽视,当执行对象的拷贝操作时,拷入和拷出的对象必须是具有相同的底层const资格,或者两个对象的数据类型必须能够转换,例如非常量可以转换为常量,反之则不行。int a; const int* const p1 = &a; int* p2 = p1;//错误

15.constexpr和常量表达式。常量表达式是指值不会改变而且编译过程中就能确得到的计算结果的表达式,显然,用常量表达式初始化的const对象也是常量表达式。例如:int a = 27;不是常量表达式,因为初始化的不是常量;const int b = 1;是常量表达式;const int c = b + 1;是一个常量表达式。int f(){}  int d = f();不是一个常量表达式;

很多时候很难确定一个初始值是不是一个常量表达式,C++11中规定允许将变量生命为constexpr类型以便编译器来检查验证变量的值是否是一个常量表达式。生命为constexpr的变量一定是一个常量,而且必须用常量表达式来初始化。

int a = 1; constexpr int b = a + 1;//编译器会报错

普通函数虽然不能做为constexpr变量的初始值,但是新标准允许定义一种特殊的constexpr函数,这种函数应该足够简单以使得编译时就可以计算其结果,就能使用constexpr函数来初始化constexpr变量了。

对指针而言,constexpr是顶层const,因此定义时必须初始化,且定义后不能修改,constexpr也可以与底层const同时存在,如constexpr const int* p = nullptr;

16.C++11的using声明新类型。与typedef相似,C++11允许允许为一个类型定义别名,用法:using price = double;表明price和double等价;也可using array = int[10];声明array是一个存放10个整数的数组的类型。

17.关于typedef的特殊之处。例如下面的语句typedef char* pstring; const pstring cstr = 0; const pstring* ps; pstring类型实际上是类型char*的别名,cstr是指向char的常量指针,而不是指向char常量的指针,const pstring cstr = 0;也就相当于char* const cstr = 0 。ps是一个指针,他的对象是指向char的常量指针,而不是指向常量的指针的指针,因此const pstring* ps;也就相当于char* const *ps;。

首先明确pstring是指针类型,因此const pstring是指向char的常量指针类型,而非指向常量字符的指针,此const相当于顶层const而非底层const。

18.auto类型。auto类型可以在不知道对象类型的情况下,让编译器去分析表达式所属的类型,例如auto a = 1 + 2;此时auto代表int。

注意auto分析表达式所属的类型,会去计算表达式的值,这一点要特别注意。另外,auto变量在定义时必须有初始值。

auto也能在一条语句中声明多个变量,但该语句中所有变量的初始基本类型必须一样。

编译器推断出来的auto类型有时候和初始值类型并不一样,编译器会适当的改变结果类型使其更符合初始化规则。

如引用,当引用被用作初始值时,真正参与初始化的其实是引用对象的值,该值的类型用作auto的类型。

其次,auto一般会忽略顶层const,保留底层const。例如const int a = 1; auto b = &a;则b为const int* 类型。如果希望保留顶层const,则应该明确指出:const int a = 1; const auto b = a;

但是auto虽然忽略顶层const,但auto引用(auto&)不会,此时顶层const会变成底层const保留在auto类型中,此时auto应为const T&类型。

19.decltype()函数。功能和auto相似,它的返回值是操作数的数据类型,与auto类型不同的是,编译器分析表达式的类型,但并不去计算表达式的值,切记。

decltype(f()) sum = x; //sum的类型就是f()的返回值类型,编译器并不实际调用函数f(),而是直接使用f()的返回值类型。

decltype处理顶层const和引用的方式与auto有些不同,如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const和引用在内),例如:const int a = 0, &b = a; decltype(b) c = a;则c的类型为const int&类型。

需要指出的是,引用从来都作为气所指对象的同义词出现,只有在decltype处是一个例外。

如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型,例如int a = 1, &b = a; decltype(b + 1) c;则c是一个int类型的变量。

int a = 1, *p = &a; decltype(*p) b; 则b是一个int&类型的变量,因为解引用操作得到的是对象的类型引用 (解引用返回左值,因为解引用既能返回指针所指对象,又能给这个对象赋值)。

特殊的,对于decltype来说,如果给变量名加上了一对括号,则得到的类型与不加括号时会有不同。如果给变量加上了一层或多层括号,编译器就会把他当成一个表达式。变量是一种可以作为赋值语句左值的特殊表达式,所以这样的decltype就会得到引用类型,比如:int a = 1; decltype((a)) b = a;此时b是int&类型。

切记:decltype((variable))的结果永远是引用,而decltype(variable)的结果只有当variable本身就是一个引用时才是引用。

其他的,赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型,也就是说,如果i是int,则表达式 i = x 的类型是int&。

20.C++11新标准规定,可以为数据成员提供一个类内初始值,C++课本上说旧标准不能在类型直接提供初始值,但我试过了没问题,不知道是什么原因。。。

其他的没提供初始值的给默认初始化,int 为0,string为“”。

21.预处理变量无视C++语言中关于作用域的规则。

《C++ Primer》读书笔记 第二章的更多相关文章

  1. 《ECMAScript标准入门》第二版读书笔记

    title: <ECMAScript标准入门>第二版 date: 2017-04-10 tags: JavaScript categories: Reading-note 2015年6月, ...

  2. 《细说PHP》第二版--读书笔记

    第五章 PHP的基本语法 5.2.4 在程序中使用空白的处理 5.3 变量 5.3.1 变量的声明 在php中变量的声明必须是使用一个$符号,后面跟变量名来表示 unset()函数释放指定变量 iss ...

  3. sed&awk第二版读书笔记

    1. POSIX标准对正则表达式字符和操作符的含义进行了形式化.这种标准定义了两类正则表达式:基本的正则表达式(BRE),grep和sed使用这种正则表达式;扩展的表达式,egrep和awk使用这种正 ...

  4. think in java 第四版读书笔记 第一章对象导论

    很久没有碰过java了,为了项目需要以及以后找工作,还是有必要将think in java通读一遍.欢迎大家一起讨论学习 1.1抽象过程 面向对象语言的5个特性: 1.万物皆对象 任何事物都可以抽象为 ...

  5. 《javascript权威指南》读书笔记——第二篇

    <javascript权威指南>读书笔记——第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字 ...

  6. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  7. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  8. Linux设备驱动程序 第三版 读书笔记(一)

    Linux设备驱动程序 第三版 读书笔记(一) Bob Zhang 2017.08.25 编写基本的Hello World模块 #include <linux/init.h> #inclu ...

  9. Primer C++第五版 读书笔记(一)

    Primer C++第五版 读书笔记(一) (如有侵权请通知本人,将第一时间删文) 1.1-2.2 章节 关于C++变量初始化: 初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义 ...

  10. 单元测试之道Java版——读书笔记

    单元测试知道Java版读书笔记 首先我们必须要知道我们所写的代码,它的功能是什么,如果我们不了解代码的行为,那么也就无从测试. 我们测试的目的,是为了我们整个程序架构的稳定,代码其实就是欧文要实现功能 ...

随机推荐

  1. 【a401】直线的交点数

    Time Limit: 1 second Memory Limit: 32 MB [问题描述] 平面上有n条直线,且无三线共点,问这些直线能有多少种不同的交点数. [输入格式] n(n≤20) [输出 ...

  2. 机器学习: 基于MRF和CNN的图像合成

    前面我们介绍了基于卷积神经网络的图像风格迁移,利用一张content image 和 style image,可以让最终的图像既保留content image的基本结构,又能显示一定的style im ...

  3. Java 中override、overload、overwrite区别,以及与多态的关系【转】

    因为早期的翻译导致了override和overwrite的解释及理解混乱,需要重新梳理这几个词及相关内容. 转自:http://blog.csdn.net/lzhang007/article/deta ...

  4. HDU2665 Kth number 【合并树】

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  5. python3使用多代理访问网站

    #------------------------------------------------------------------------------- # Name: module1 # P ...

  6. 最新用WPF为触摸屏写了一个手写程序,双格输入的

    原文:最新用WPF为触摸屏写了一个手写程序,双格输入的 双格输入可以提高手写速度,当前字写完以后可以自动识别提交,写下一个字.这样比单格手写速度提高一倍.特别适合触摸屏程序使用 界面如下: 程序如下: ...

  7. 编写可移植C/C++程序的要点(12条)

    1.分层设计,隔离平台相关的代码.就像可测试性一样,可移植性也要从设计抓起.一般来说,最上层和最下层都不具有良好的可移植性.最上层是GUI,大多数GUI都不是跨平台的,如Win32 SDK和MFC.最 ...

  8. NetCore使用Jwtbearer给WebAPI添加访问控制

    原文:NetCore使用Jwtbearer给WebAPI添加访问控制 现在JWT代替session来做访问控制已经成为大部分webapi的做法,今天我们也来尝试一下 WebAPI使用NetCore2. ...

  9. Qt SQLite 批量插入优化(SQLite默认将每条语句看成单独的事务)good

    使用SQLite存储数据时发现插入速度太慢,程序跑了将近五分钟才插入了不到三千条.上网查资料才发现,SQLite这种文件数据库与MySql机制不一样,每条事务都有打开和关闭文件的步骤,SQLite默认 ...

  10. OA 框架

    @{    Layout = null;}<!DOCTYPE html><html><head>    <meta name="viewport&q ...