码迷,mamicode.com
首页 > 编程语言 > 详细

C++ Primer(第五版) 第二章 基本内置类型

时间:2018-10-19 00:21:43      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:using   用户   大写   算术   总数   不清楚   别人   字符串类型   span   

容易忘记的部分:

2.1:C++提供的几种字符串类型有哪些及其用途?

基本的字符类型char,一个char的类型和一个机器字节一样

其他字符类型用于拓展字符集,如wchar_t、char16_t、char32_t

wchar_t类型确保可以存放机器最大拓展字符集中的任意一个字符

char16_t和char32_t则为Unicode字符集服务

 

2.2:如何选择所使用的类型

当数值不为负数时,使用无符号类型(unsigned)

一般常用int和long long执行整数的运算

算术表达式中不使用char和bool,只有在特定的时候才使用特定的类型(char:存放字符,bool:存放布尔值)

使用字符时最好明确指出是signed char还是unsigned char

执行浮点数运算时选用double

 

2.3:字符类型转换中需要注意的问题

无符号类型:

1.当赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的取数。例如8bit的unsigned char表示[0,255]内的数,把-1赋值给它得到255

2.如果表达式里既有带符号类型又有无符号类型,那么带符号类型会自动转化为无符号类型,表达式的结果不会有负数的存在

带符号类型:

1.当赋给带符号类型一个超出表示范围的数,结果是未定义的

 

2.4:字面值常量相关内容

1.以0开头的代表8进制,0x/0X开头的代表16进制。整型字面值的具体类型由它的值和符号决定。

2.字符串字面值是由常量字符构成的数组

3.转移字符,具体有哪些转移字符及其表示见书P62

4.我们可以通过添加前缀或者后缀来指定字面值的类型,具体的前缀、后缀见书P63

 

2.5:什么是对象?

对象是指一块能存储数据某种类型的存储空间,一般把命名了的对象叫做变量,而把变量中存的数据叫做值

 

2.6:初始化的相关事项

1.初始化不是赋值,初始化是创建变量时赋予一个初始值,而赋值是把对象当前的值移除,用新的值来替代

2.列表初始化不能用于可能存在初始值丢失的情况(如用浮点数对整型进行列表初始化)

3.默认初始化:对于内置类型来说,当定义的变量在函数外时,默认初始化为0,若定义的变量来函数内时,变量不被初始化。对于类来说,默认值只与类的构造函数有关,与位置无关

 

2.7:声明和定义的区别

声明使得名字被程序知道,一个文件想用别人定义的名字必须包含对那个名字的声明

定义负责创建于名字相关的实体。除了规定变量的类型和名字,还会申请存储空间,也有可能赋予初始值

显示声明:在类型前添加关键词extern。如果存在初始化,则视为定义

如果要在多个文件中使用一个变量,变量只能被定义一次,但是可以被声明多次

 

2.8:标识符的命名规则

标识符(变量名/函数名.....)由字母、数字和下划线组成,其中必须以字母或者下划线开头,长度没有限制,但是对大小写敏感。通常不要使用下划线开头的标识符,因为标准库实现的名字均以下划线开头。

命名规范:

1.能体现实际含义

2.变量名一般用小写字母

3.用户自定义的类名用大写字母开头

4.如果标识符由多个单词组成,则单词间应用下划线分开

注意不要使用C++中的关键词和操作替代名(具体有哪些见书P43)

 

2.9:相同变量名的不同作用域覆盖问题

名字的有效区域始于名字的声明语句,以声明语句所在的作用域末端为结束

当一个变量在它所嵌套的作用域下又被定义了一次,则在新建变量的作用域下,新建的变量值会覆盖老的变量值,如果想要访问老的变量值,则需要使用作用域符::,当作用域符的左侧为空时,获得全局作用域下老的变量值。

建议:当第一次使用变量在定义它,并且局部变量最好不要和全局变量同名

 

2.10:生成空指针的办法

1.用字面值nullptr来初始化指针,nullptr作为一种特殊的字面值可以被转换为任意其他指针类型(推荐使用)

2.用字面值0来初始化

3.用一个名为NULL的预处理变量来给指针赋值,这个变量定义在头文件cstdlib中,值为0(避免使用)

 

2.11:指针值有哪些

1.指向一个对象

2.指向紧邻对象所占空间的下一个位置

3.空指针,没有指向任何对象

4.无效指针,即上述情况之外的其他值

 

 2.12:const限定符

const只能限定对象,因此没有const引用,但是有引用const对象的引用

对象的类型决定了其上的操作。const类型的对象和非const对象类型相比的不同在于:

1.不能改变对象的内容

2.const对象必须初始化

要想在文件之间共享const变量,解决的办法是不管是声明还是定义都添加extern关键字

 

2.13:constexpr和常量表达式

常量表达式:值不会改变,且在编译过程就能得到计算结果的表达式。一个对象/表达式是否为常量表达式由其对象(const)和初始值(常量表达式)决定

允许将变量声明为constexpr类型以便由编译器来验证变量是否是常量表达式。要求声明constexpr的变量一定是一个常量,同时必须要用常量表达式进行初始化,以及声明要用到的类型必须是字面值类型(内置类型,不包括标准库和自己定义的类类型)

虽然指针和引用都能定义为constexpr,但是因为constexpr的初始值必须是常量,所以对于指针来说,只有当其的初始值为nullptr或者指向某个固定地址(只能是在函数外定义,不能在函数内定义。或者是:允许函数定义一类有效范围超出函数本身的变量)才可以。而对于一个constexpr指针来说,constexpr只修饰指针本身,是一个顶层const,constexpr位于声明最开始的地方

 

2.14:两种处理类型别名的办法

使用关键词typedef和关键词using(别名声明)

typedef double wages;

using SI=Sales_item;

 

2.15:auto类型说明符

auto的原理:通过初始值来推断变量的类型。因此auto定义的变量必须要有初始值

如果使用auto在一条语句声明多个变量,要确保证明语句中变量的数据类型相同

auto会忽略顶层const,保留底层const。因此如果希望推断出顶层const,必须自己明确指出

 

2.16:decltype类型指示符

decltype的作用是选择并返回操作数的数据类型,在这个过程中,它不计算表达式结果,只得到它的类型。

decltype会保留顶层const,此处与auto不同。

引用从来都作为其引用对象的别名出现,而只有在decltype中例外,decltype(引用),会返回一个引用类型,同时注意此处必须初始化

 

 

需要理解的部分:

2.1:内置类型的机器实现是怎么样的?

(详细解释见书P57)一个类型的对象占据一定的字节大小。对于一个地址,我们只有知道了存储在该地址的数据的类型,才能知道该内存空间的明确含义

 

2.2:引用

我们这里的引用指的是左值引用,而右值引用主要用于内置类

因为引用本身不是一个对象,所以不存在引用的引用。

于此同时,引用的类型要和与之绑定的对象严格匹配,不能于某个字面值绑定在一起

 

2.3:指针

指针本身是对象,并且指针也只能指向对象(即不存在指向引用的指针)

指针的类型要和它所指的对象严格匹配

指针的解引用操作只适用于那些确实指向了某个对象的有效指针

不能把int变量直接赋值给指针(但是可以把字面值0赋值给指针)

建议定义了对象之后再定义指向它的指针,同时建议初始化所有指针,如果不清楚指针指向哪里,就初始化为nullptr或0

想要搞清一条赋值语句改变的是指针的值还是指针所指对象的值,记住赋值改变的永远是等号左侧的对象

永远记住指针存的是地址,当拿指针参与运算时(一定要确保指针是有效的指针)。如果是条件判断,则看指针是否指向一个对象。如果是判断指针是否相等,则看指针所保存的地址是否相等即可。

 

2.4:指针和引用的不同

1.指针本身是对象。而引用只是其他对象的别名,和其他对象绑定在一起。

2.指针可以先后指向多个不同的对象,允许指针赋值和拷贝。而引用不能更改绑定对象。

3.指针无需在定义时赋值,其默认初始化和内置类型相同。而引用在定义时一定要确定其引用的对象,所以必须初始化。

 

2.5:某些符号有多重含义

像&和*,既能作为表达式里的运算符,也能作为声明语句中的一部分出现。由符号出现的位置决定了符号的意义。

当&和*紧随类型名出现时,符号是声明的一部分;而当符号出现在表达式中时,它们又转变成了运算符

 

2.6:void*指针

是一种特殊指针,可以存放任意对象的地址。

但因为我们不知道它所指对象的类型,所以不能通过解引用对所指对象进行操作。

但它可以作指针本身的操作:和其他指针比较、作为函数输入/输出,赋值给另一个void*指针

 

2.7:符合类型的声明

1.类型修饰符(*和&)只作用于单个对象。对于int *p,其基本类型是int,不是int*。*仅仅修饰了对象p,不对其他对象产生任何的作用

2.类型修饰符的个数没有限制。如:可以通过*的个数区分指针的级别,**代表指向指针的指针,要想访问到最原始的对象,需要通过两次解引用,在内存中的表示就是一个新的地址空间存了上一个指针所在的地址。

3.存在指向指针的引用。如int *p; int *&r=p;

要想理解r的含义,最简单的办法就是从右向左阅读。在C++中里变量名越近的符号对变量的影响越大。

 

2.8:const的引用

引用所能进行的操作,受其绑定对象的限制。当其绑定的对象为常量时,则引用不能改变其对象的值,同时要求引用本身也必须是const的

引用的类型于其引用对象的类型必须保持一致的例外情况:

在初始化 常量引用 时,可以用任意表达式作为初始值,只要该表达式的结果能转化成引用的类型即可。尤其,允许绑定非常量的对象,字面值,甚至是一般表达式。(后两种情况会创建临时地址用于转化后的值/字面值/表达式的结果)

而对于 常量引用 引用非常量对象的行为虽然不算错误,但在在C++中被归为非法

 

2.9:指针和const(指向的对象是const的)

和常量引用一样,指向常量的指针不能用于改变其对象的值,同时想要存放常量对象的地址,只能用常量指针。

指针的类型和其指向对象的类型必须保持一致的例外情况(和常量引用类似):

允许常量指针指向非常量的对象,该情况下不能通过指针去改变对象的值(因为指针认为自己指向了常量),但是可以通过其他途径去该改变对象的值(因为对象不是常量)

 

2.10:const指针(指针本身是const的)

同其他基本的const对象一样,const指针也必须初始化,一旦初始化后便不能再改变

书写格式: 【对象类型 *const 变量名】把*放到const前说明指针是一个常量,同时不变的是指针而不是指针所指的对象

指针本身是常量只是指针的值不变(存放对象的地址),但是这不意味着不能通过解引用指针去改变所指向的对象的值

 

2.11:顶层const

哪些对象含有顶层const或/和底层const:

对于指针来说,指针本身和指针所指的对象是不是常量是两个独立的问题,进而引出顶层const(指针本身是const)和底层const(指针所指的对象是const)这两个概念。

拓展到一般情况,对于一般的数据类型,只含有顶层const,表示自己对象本身是否为const

而底层const则与指针和引用这样的复合类型有关。当引用所指对象是const,那么该引用含有底层const,但是引用不含顶层const,因为引用本身不是对象

因此只有指针对象可能同时拥有顶层和底层const,而对于引用最多只能拥有底层const,对于一般类型最多只能拥有顶层const

 

有关含底层/顶层const对象的拷贝操作:

在执行对象的拷贝操作时,顶层const可以忽略。

而底层const的限制不能被忽视,拷入和拷出对象必须具有相同的底层const;或者拷出对象无底层const,但是拷入对象有底层const。对此,我们可以先去掉顶层是否有const(底层const对底层的赋值不起任何的影响),只关注底层const,问题又回到了含const的对象的赋值问题上来。

 

2.12:使用别名时需要注意的问题

当别名声明一个复合类型(如指针)/常量时,对于一条声明语句不能直接直接将别名替换回原来的形式。一定要明确整个声明语句其基本类型到底是什么,若别名代表一个指针,则基本类型为指针。

如:typedef char* pstring; //别名代表一个指针

const pstring cstr=0;  //const修饰这个别名(即指针),如果替换回char*就会发生错误

 

2.13:decltype和引用

如果decltype使用的是表达式,则其返回表达式结果对应的类型

若有int i=42,*p=&i,&r=i;   则decltype(r)得到引用类型,但decltype(r+0)得到一个int类型,而解引用操作得到引用类型(因为解引用指针可以得到指针所指的对象,而且还能给这个对象赋值,即解引用常出现在等号左侧)

同时decltype和auto另一个区别(还有一个是decltype保留顶层const)在于,decltype的结果类型与表达式形式密切相关。如果decltype使用的是一个不加括号的变量,则得到变量的类型。如果变量加上括号,就会被当作一个表达式(因为变量是一种可以作为赋值语句左值的特殊表达式),从而得到一个引用类型

C++ Primer(第五版) 第二章 基本内置类型

标签:using   用户   大写   算术   总数   不清楚   别人   字符串类型   span   

原文地址:https://www.cnblogs.com/HDUjackyan/p/9811662.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!