本身就一定基础的读者我想变量常量这些概念应该已经不是问题了。但是本章还是有几个重点,需要特别留意一下的:

  1.初始化和赋值是不同的操作

  2.任何非0值都是true

  3.使用新标准列表初始化,在有丢失精度的可能时,会报错。

  4.引用一旦绑定对象就不可再绑定到其他对象,因此也必须初始化

  5.const引用初始化时可以赋予字面常量值,只要可以转换为相应的类型

  6.顶层const意味着指针本身是个常量,底层const意味着指针所指向的对象是常量

  7.声明成constexpr的变量是一个常量。


到了第二章,其实才算是真正的开始。也就是本书的第一部分C++基础。

第一章可以说就是第一部分的一个简单的梗概。

从第二章开始,对C++的学习步入正轨,从最基础的开始学起,也就是 变量

而说到变量就不得不说类型。

第二章讨论的主要就是如下几点:

  1.什么是基本类型,什么是复合类型?

  2.什么是变量,什么是常量?

  3.什么是类型别名

  4.定义数据结构(struct)

我认为本章讨论常量的部分,对后面的学习影响很大,如果没有理解清楚const的复合类型的一些细节问题,会对后面函数和类的部分的学习造成影响。


基本内置类型

  C++中定义了一套 包括 算术类型 和 空类型 在内的 基础类型。

  而算术类型分为 整型 浮点型

  这些类型的尺寸不同,也就是所占bit数不同。

  根据现在机器的性能,整型中基本用int可以解决大多数需求。

  

无符号和有符号

  这里没什么好说的,值得注意的是字符型被分为三种,char,signed char , unsigned char。

  另外unsigned int 可以缩写为 unsigned

类型转换

  需要记住的是,整型转布尔型。只有0才是false。不管是负数还是正数都是true。只有当值为0的时候才是false。

 

字面值常量

  字面的意思,但是字面值常量的形式和值决定了它的数据类型。

  如,我们可以将字面值写成十进制,八进制或十六进制。

  若字面值是八进制则加前缀:0

  若字面值是十六进制则加前缀:0x

  也可以通过加后缀来表示类型,在书中表2.2可以看到说明。


变量

  当对象创建的时候获得一个特定的值,我们说这个对象被 初始化 了。

  在C++中初始化和赋值是两个不同的操作。

  初始化:创建变量的时候赋予一个初始值。

  赋值:将当前值擦除,并以一个新值代替。

列表初始化

  这个是C++11的新标准。

  对于使用内置类型的变量时,如果使用列表初始化,在有可能损失精度的情况下,编译器会报错。

默认初始化

  如果定义变量的时候没有初始化,那么这个变量会被默认初始化

  但是这个值是什么是不一定的。

  内置类型:由定义的位置而定,全局变量将初始化为0。

  未被初始化的变量的值,是未定义的。拷贝或访问一个未定义的变量会产生可怕的后果。

  每个类各自决定初始化的方式。如果一个类要求每个对象都要初始化,则不初始化会产生错误。

变量声明和定义的关系

  声明:让这个名字被程序所知,如果一个文件想使用别的文件定义的名字就必须包含对那个名字的生命;

  定义:书中说,定义负责创建与名字关联的实体,也就是声明之后还为变量申请了空间和赋值。

  如果是要声明而非定义,则可加关键字 extern 并且不要显式的初始化变量。

  如果初始化了则会变成定义。

作用域

  简单来说

  越外面的影响范围越大,内层作用域可以使用外层作用域的变量,也可覆盖外层变量。


复合类型

   可以说是最重要的内容了,也就是指针和引用。

  复合类型之所以叫做复合的,是因为它是由一个基本类型加一个说明符组成的(说明符可以是多个)

  

  引用

    引用,其实就是一个对象的别名。并且需要注意的是,引用一旦绑定到一个对象身上就不可以再绑定到其他对象上。也由于这个原因, 引用必须初始化

  指针

    类似于引用可以对对象进行间接的访问,但是指针本身是一个对象而引用不是,并且指针的生命周期内可以指向不同的对象不像引用终身绑定。最后指针并不强制要求初始化。

    指针本身存放的是对象的地址,所以在对指针本身赋值的时候需要使用 取地址符&。

    如果想访问指针所指向的对象则应该使用 解引用* 符。

    void*指针  

      这种类型的指针可以存放任意对象的地址。

const限定符

  我认为是个重点,里面的细节如果没有理顺的话对后面的章节会造成很大的影响。

  const限定符实际上就是声明常量用的,代替了预处理。

  被加上const关键字的定义就会变为常量,任何企图修改的行为都会引发错误。

 

  初始化和const

    实际上const也能完成许多非const对象所能完成的操作,限制是只能在const对象上执行不改变其内容的操作。

    比如:const int 也能想 普通 int 一样参与运算。

    使用const对象去初始化也是没问题的,利用一个对象去初始化另一个对象,它们是不是const都无关紧要。

    因为,拷贝一个对象的值并不会改变它。

 默认情况下,const对象只在当前文件内有效。

  如果想在多个文件下共享,则无论是声明还是定义都加上extern就行了。

const的引用

  “对常量的引用”

  在初始化常量引用的时候,允许用任意表达式作为初始值,只要改表达式的结果能够转换成引用的类型即可。并且虽然常量对象只能被对常量的引用所引用,但是非常量对象也可以被对常量的引用所引用。

  虽然对const的引用有可能是一个非const对象,但依然不能通过const引用修改非const对象的值。

指针和const

  与引用类似,对const的指针可以指向常量或非常量。并且无论指向的是常量还是非常量,都不可以通过对const的指针来修改其值。

const指针

  由于指针是个对象,而引用不是对象。

  所以允许把指针本身定位常量。

  常量指针必须初始化,并且初始化后将不能改变(因为指针本身即是常量)

  将*放在const前面即可声明常量指针。

  ***需要注意的是,常量指针仅仅意味着指针本身是常量,但并不意味着指针所指向的对象是个常量。

    所以能不能改变所指向的对象的值,完全依赖于所指对象的类型。

顶层const

  由于指针本身是一个对象,并且可以指向另一个对象。

  所以指针本身是不是常量以及所指的对象是不是常量是两个相互独立的问题。

  顶层const表示 指针本身是个常量

  底层const表示 指针所指的对象是个常量

  顶层const可以表示任意的对象是常量,对任何数据类型都适用。

  而底层const,则与指针和引用等复合类型的基本类型部分有关。

  指针既可以是顶层const也可以是底层const。

  

  int i = 0

  int *const p1 = &i; 顶层

  const int ci = 24 ; 顶层

  const int *p2 = &ci ; 底层

  const int *const p3 = p2 ; 既有底层,又有顶层

  i  = ci   正确,ci是顶层const 对初始化没有影响

  p2 = p3 正确,

  p2 是一个指向const int型的指针,而p3是一个指向const int 型的 常量指针。

  p2 和 P3 所指向的类型相同,而p3的顶层部分对赋值没有影响。

  int *p = p3  错误,P3包含底层const的定义,p没有。意味着P3不可以改变所指向对象的值。P是可以的。因此错误

  p2 = p3 ;  正确, p2 和 P3 都是底层const,这两个变量都不能改变所指对象的值,然而p3本身是个常量指针对赋值没有影响。

  p2 = &i ;   正确, 尽管P2是一个指向const的指针,但仍然可以指向非const对象。只不过不可以通过P2修改i的值罢了。

  int &r = ci; 错误, ci 是一个常量。普通的引用不能绑定到常量上,除非是一个对const的引用。

  const int &r2 = i; 正确,对常量的引用可以绑定到普通对象上。

constexpr 和 常量表达式

  常量表达式指的是,值不会改变,在编译过程就已经得到计算结果的表达式。

  constexpr变量

    由于很难分辨一个初始值到底是不是常量表达式,所以新的C++标准允许将变量声明为constexpr。

    这样做会由编译器来验证变量的值是不是常量表达式。

    声明为constexpr的变量一定是一个常量。

  字面值类型

    算术类型,引用,指针,都属于字面值类型。

    自定义的类,IO库,string类型则不属于自勉之类型。意味着不能被定义为constepxr。

    constexpr指针初始值必须是nullptr或0.或是存储于某个固定地址中的对象(比如全局变量)(一般来说函数体内定义的变量都不是存在固定地址中的,因此constexpr指针不能指向这样的变量)

    指针和constexpr

      constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效,与指针所指的对象无关。

      const int *p = nullptr; p是一个指向整型常量的指针

      constexpr int *q = nullptr; q是一个指向整数的常量指针

      关键在于constexpr把它所定义的对象置于顶层const

    

      与常量指针类似,constexpr既可以指向常量也可以指向非常量


处理类型

  到这里基本没有什么细节问题了,只是介绍一些语法和关键字。

  

  类型别名

    typedef double wages   ;  wages是double的同义词

    using sages = double  ;  同上

   typedef char *pstring;

   char pstring cstr = 0;  cstr是一个指向char的常量指针

   const pstring *ps;  ps是一个指针,对象时指向char的常量指针

   语句中用到pstring时,其基本数据类型是指针。

auto类型说明符

  使用auto类型说明符,让编译器替我们分析表达式所属的类型。

  也因此auto定义的变量必须初始化,

  

  复合类型,常量和auto  

    编译器推断出来的auto类型并不一定和出初始值的类型完全一样。

    比如使用引用其实是使用引用所指的对象,在初始化时,真正参与初始化的是引用对象的值。此时编译器以引用对象的类型作为auto的类型。

    其次,auto一般会忽略顶层const,const则会保留。

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

      const auto f = ci;

decltype类型指示符

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

    与auto不同,如果decltpye使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const和引用)

    引用在哪都是作为所指对象的同义词出现,只有在decltype这里是例外。

  

      

  

学习C++ Primer 的个人理解(二)的更多相关文章

  1. 学习C++ Primer 的个人理解(十二)

    动态内存与智能指针 在C++中, 动态内存用 new来分配空间并返回一个指向该对象的指针 用delete来销毁. 由于手动的对动态内存进行操作容易出现问题.所以新的标准库提供了两种智能指针. 智能指针 ...

  2. 学习C++ Primer 的个人理解(一)

    <C++ Primer>这本书可以说是公认的学习C++最好的书,但我觉得不是特别适合作为教材,书中内容的顺序让人有些蛋疼.我个人认为初学此书是不能跳着看的.如果急于上手的话,我更推荐< ...

  3. 学习C++ Primer 的个人理解(九)

    这一章介绍顺序容器,在之前的第三章中,了解到的vector就属于顺序容器的一种. 一个容器就是一些特定类型对象的集合. 除了vector,还有哪些顺序容器? vector: 大小可变,随机访问的速度很 ...

  4. 学习C++ Primer 的个人理解(三)

    第三章,主要内容是字符串和数组.感觉作者的意图是希望读者可以早一点可以写出简单的小程序,并且可以早点接触迭代器这种思想. 在我看来,这种内容的难度并不大. 对于编程来说,最重要的应该是思想,类似vec ...

  5. 学习C++ Primer 的个人理解(零)

    由于自己看书之后经常容易忘记细节,所以写在博客上让我自己的思路更加清晰一些. 我的博客仅仅只是将书中的内容概括一下,有一些不好理解的部分我会用我自己理解的方式使用大白话写出来. 仅此而已.

  6. 学习C++ Primer 的个人理解(十一)

    关联容器 就像是个字典, 其元素是 键 - 值 对. 关键字起到索引作用. 有序: map:关联数组:保存 健-值 对 set : 关键字既是值. multimap : 关键字可重复出现的map mu ...

  7. 学习C++ Primer 的个人理解(十)

    标准库没有给每个容器都定义成员函数来实现 查找,替换等操作.而是定义了一组泛型算法,他们可以用于不同类型的元素或多种容器类型. 迭代器令算法不依赖与容器 算法永远不会执行容器的操作 算法本身不会执行容 ...

  8. 学习C++ Primer 的个人理解(八)

    结束了第一部分,在最后的第七章,我只简单的总结了一下,因为后面还会更详细的说明有关类的内容.而且说实在的这一张的内容让我很不舒服,验证了本书实际上有许多内容是作者的学生一起拼凑而成的.第七章结构给我感 ...

  9. 学习C++ Primer 的个人理解(七)

    类,后面还有两章是介绍有关于类的内容的.这一张依然只是个概括.但也已经将大致用法介绍完了. 重点如下: 1.成员函数的声明,必须在类的内部. 2.引用const成员函数 我们知道成员函数中有一个名为t ...

随机推荐

  1. iOS开发-自动布局和自动旋转

    今天学习自动布局中的自动调整尺寸大小. 一.尺寸分类 尺寸分类是对设备宽高的一种大致分类. 有两种具体的尺寸分类用来表示真机:紧凑(Compact)和标准(Regular).还有第三种分类可以在设计工 ...

  2. [Java 7][msvcr100.dll] Error when load Eclipse

    [Problem] After I updated to Java 7, I could not load Eclipse. Here comes the erros: Eclipse: eclips ...

  3. Using breakpad in cocos2d-x 3.2,dump信息收集

    作者:HU 转载请注明,原文链接:http://www.cnblogs.com/xioapingguo/p/4037268.html 一.基本步骤 1.生成转换工具 2.把breakpad加入到项目 ...

  4. Genymotion与本地电脑共享文件夹的方法

    首先打开vbox的界面,左侧列表应该可以看到Genymotion添加的虚拟机,如图:对要设置的虚拟机单击右键,在弹出的菜单中点击“设置...”,弹出设置页面后点击左侧最后一个标签“共享文件夹”,点击右 ...

  5. AVAudioRecorder、AVAudioPlayer录音及播放

    #pragma mark - 设置录制的音频文件的位置 - (NSString *)audioRecordingPath{ NSString *str_date=[TimeTransform Date ...

  6. [018]C++ explicit构造函数

    explicit [英][ɪkˈsplɪsɪt][美][ɪkˈsplɪsɪt] adj.明确的,清楚的; 直言的; 详述的; 不隐瞒的; 看到上面的英文解释,我们应该就知道explicit构造函数是什 ...

  7. debian 系统备份

    tar -zcvpf /home/full-backup.tar.gz / --exclude=/mnt/* --exclude=/proc/* --exclude=/sys/* 这个命令是把根目录下 ...

  8. 去model化开发

    前言 去model化是一种框架设计上的做法,其中的model并不是指架构中的model层,套用Casa大神博客中的原文就是: model化就是使用数据对象,去model化就是不使用数据对象. 常见的去 ...

  9. 路径(keyPath)、键值编码(KVC)和键值观察(KVO)

    键路径 在一个给定的实体中,同一个属性的所有值具有相同的数据类型. 键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制. - 键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接 ...

  10. Java基础知识强化之网络编程笔记16:Android网络通信之 使用Http的Get方式读取网络数据(基于HTTP通信技术)

    使用Http的Get方式读取网络数据,使用Get方式与网络通信是最常见的Http通信,建立链接之后就可以通过输入流读取网络数据. 详见:Android(java)学习笔记209:采用get请求提交数据 ...