一、前言

最近在看C++Primer第5版,先前已经看过第4版,但是发现第5版在整个知识布局与个别知识的讲解上跟第4版差别还是挺大的,尤其是新增了C++11的内容,正如孟岩老师在第5版前言中所讲:“现在能够以新的C++11风格开发实践的人是凤毛麟角,如果能够纯熟的运用C++11的新特征、新机制,那么就能够形成一种简洁优雅的C++编程风络,开发会变得更高效,更高质”。

所以正好借助第5版来重新学习巩固C++的知识。《C++的那些事》这个系列,将会以知识碎片的形式记录我在学习过程中一些知识重点。

二、关于C++的学习

个人身为C++菜鸟,自然是没有任何经验之谈,这里摘录C++Primer5ED前言里一些个人以为很有道理的观点。

1,学习语言的一个境界是把自己想象成编译器。

2,使用C++语言的“两面性”观点。C++正在走向完美,所以,C++语言值得学习(甚至研究)。这些知识可以成为一切编程的基础。然而在实践中,不必全面地使用C++语言的各种特性,而应根据工程项目实际情况,适当取舍(譬如动态类型信息、虚拟继承、异常等特性的使用)。通常只鼓励使用C++语言的一个子集。

关于第2点,个人是相当的认同,C++的一些高级特性,确实只有在一些库例程中才有体现,一般工程开发中很少能用得上。所以在学习C++的时候,开始不必对一些语法细节或高级技法过于追求完美,可以先知其大概,在以后工作学习中再逐渐加深认识。

三、数据与类型

1,任何一门编程语言都是由一些基本组件来构成,C++也是一样。

  • 整型、字符型等内置类型
  • 变量,用来为对象命名
  • 表达式和语句,用于操纵上述数据类型的具体值
  • if或while等控制结构,这些结构允许我们有选择地执行一些语句或者重复地执行一些语句
  • 函数,用于定义可供随时调用的计算单元
  • 自定义数据类型:比如:类
  • 标准库

C++的另外一点就是编程思想,通过类引入了面向对象编程的思想,再通过模板等技术引入了通用或泛型编程的思想。

这本篇文章中,主要是关于前2点的内容:对象和对象的类型。

2,类型是程序设计中最基本的概念,一种类型不仅定义了数据元素的内容,还定义了这类数据上可以进行的运算。内置的数据类型如此,用户自定义的类型也是如此,C++的一个很重要的任务就是让用户设计的类型像语言内置类型一样好用。

3,程序所处理的数据都保存在变量中,而每个变量都有自己的类型。

4,执行算术运算时,数据类型的选择

  • short 一般很少使用,容易产生越界。
  • char类型在一些实现中有时作为signed处理,而有时作为unsigned处理,所以只用char来表示字符是明智之举。
  • 在大多数的时候使用int就没有问题,在很多机器上int用4个字节存储,足够满足大部分计算的要求。
  • 浮点型的选择就很简单了,使用double类型基本不会有什么错误,而且有可能会比float计算代价低。

5,在使用无符号数作为循环的索引时,注意unsinged int 与 int类型间的隐式数据转换,如下面的程序,可能实际并不是你想要的结果。

 // error 变量u永远也不会小于0,循环条件一直成立
for (unsigned u = ; u > = ; -- - u)
{
std::cout << u << std::endl;
}

6,C++11定义了一种新的指针字面值nullptr,用于取代C语言中预编译常量NULL

7,注意C++中初始化与赋值的区别,这一点在类的定义中更为明显。初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。

8,引用和指针都是C++定义的复合类型,引用与指针的定义是由一个基本数据类型和紧随其后的一个声明符列表组成。

1)引用是给变量另起了一个名字,当定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始化拷贝给引用。一旦初始化完成,程序把引用和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。

实际上引用的本质是指针,而且是一个常量指针,占用4个字节的空间。

2)与引用不同的是,指针本身是一个对象,允许指针拷贝和赋值,而且在指针的生命周期内,它可以先后指向几个不同的对象。

9,常量表达式是指值不会改变并且在编译过程中就能得到计算结果的表达式。

在一个复杂的系统中,很难分辨一个初始值到底是不是常量表达式。C++11允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明constexpr的变量一定是一个常量,而且必须用常量表达式初始化:

 constexpr int mf = ;
constexpr int limit = mf + ;
constexpr int sz = size(); // 只有当size是一个constexpr函数时才是一条正确的声明语句

用constexpr修饰的指针说明是常量指针,它本身在定义初始化后不可以再更改指向,但是所指的对象可以是个变量。

10,注意指针、常量和类型别名在一块的时候:

 typedef char* pstring; // pstring是一指向字符的指针
const pstring cstr=; // cstr是一个指向字符的常量指针
const pstring *ps; // ps是一个指针,它的对象是指向char的常量指针。

11,auto类型

C++11引入auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型。编译器是通过初始值来推算变量的类型,显然,auto定义的变量必须有初始值。

如果我们用一个引用类型去初始化一个auto类型时,得到的类型将是引用对象的类型:

 int i = , &r = i;
auto a = r; // a是一个整数

其次auto一般会忽略掉顶层的const,同时底层的const则会保留下来。

 const int ci = i, &cr =  ci;
auto b = ci; // b是一个整数
auto c = cr; // cr是一个整数(ci的顶层const特征被忽略了)
auto d = &i; // d是一个指针(指针是指向整数的指针)
auto e = &ci; // e是一个指向整数常量的指针

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

 const auto f = ci; 

12,decltype类型指示符

有的时候想从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量,为些C++11引入了第二种类型说明符decltype,它的作用是选择并返回操作数的数据类型。

decltype(f()) sum = x; // sum的类型就是f的返回值类型,编译器并不调用f

decltype在处理顶层const和引用的方式与auto不同。

 const int ci = , &cj =  ci;
decltype(ci) x = ; // x的类型是const int
decltype(cj) y = x; // y的类型是const int&, y绑定到变量x
decltype(cj) z; //error, z是一个引用,必须初始化

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

delctype((variable))(注意是双层括号)的结果永远是引用,而decltype(variable)结果只有当variable本身就是一个引用时才是引用。

13,标准库定义了2种非常重要的抽象类型,一种是string用来支持可变长的字符串;另一种是vector表示可变长的集合。

14,对于string和vector对象都可以有多种方式初始化,这取决于类的定义,但一般直接初始化和拷贝初始化都是存在的。如果使用等号“=”初始化一个变量,实际上执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新创建的对象中去。与之相反,如果不使用等号,则执行的是直接初始化。

 string s1 = "hiya";  // 拷贝初始化
string s2("hiya"); // 直接初始化
string s3(, 'c'); // 直接初始化

15,string类型和标准库容器类型都提供了一种size_type类型,它是一个无符号的值,而且足够存放下任何容器或string对象的大小。而在C++11中,我们可以用auto或decltype来让编译器自动推断出这种类型,而不用写很长的代码,比如:

 vector<vector<double>>::size_type i; // 原来的方法
decltype(dvv.size()) i; // C++11用decltype
auto i = dvv.size(); // C++11用auto

16,C++11中另外为vector对象提供了一种列表初始化的方法,此时,用花括号括起来的0个或多个初始化元素值被赋予vector对象。但是值得注意的是:如果用的是花括号,可以表述成我们想列表初始化该vector对象。也是就是,初始化过程会尽可能地把花括号内的值当成是元素初始化的列表来处理,只有在无法执行列表初始化时才会考虑其他初始化方式。

 vector<string> v1{"hi"};  //v1有一个元素
vector<string> v2("hi"); //error
vector<string> v3{}; //v3本来想用10来初始化vector,但是发现10不是strring对象,所以把v3初始化为10个元素。
vector<string> v4{,"hi"}; //v4本来想用10和“hi”初始化vector,但发现10不是string对象,所以就把v4定义为10个元素的vector

17,数组,与vector类似,数组也是存放类型相同的对象的容器,这些对象本身没有名字,需要通过其所在的位置访问。而且数组是在定义的时候就分配了大小,中间不能变化,这就给使用时带来很大的不便。

18,指针其实与迭代器具有相同的功能,在遍历数组的情况下,用指针操作就像在容器上使用迭代器一样。类似于容器类型的begin和end迭代器,C++11定义了两个函数begin和end用来获取序列的首指针和尾指针,这两个函数定义在iterator头文件中。

 int ia[]={,,,,,,,,,};
int *beg = begin(ia); // 指向ia首元素的指针
int *end = end(ia); // 指向ia尾元素的下一位置的指针

C++的那些事:数据与类型的更多相关文章

  1. 如何正确选择MySQL数据列类型

    MySQL数据列类型选择是在我们设计表的时候经常会遇到的问题,下面就教您如何正确选择MySQL数据列类型,供您参考学习. 选择正确的数据列类型能大大提高数据库的性能和使数据库具有高扩展性.在选择MyS ...

  2. MySQL学习笔记之数据存储类型

    说明:本文是作者对MySQL数据库数据存储类型的小小总结. Numeric Type (数字类型) 1.TINYINT.SMALLINT.MEDIUMINT.INT.BIGINT主要根据存储字节长度不 ...

  3. sql 数据字段类型

    bit    整型 bit数据类型是整型,其值只能是0.1或空值.这种数据类型用于存储只有两种可能值的数据,如Yes 或No.True 或False .On 或Off. 注意:很省空间的一种数据类型, ...

  4. JSTL实现int数据的类型的长度

    JSTL否int类型转换string该功能.为了解决增益int数据的类型的长度,闹失踪. 得到String的数据的长度是jstl的fn能够${fn:length(string)},但int做数据? 经 ...

  5. CG中的数据变量类型

    CG 中的数据变量类型有三: float:高精度浮点值,通常是32位. half:中精度浮点值.通常是16位,范围是-60000至+60000,它适合存储UV坐标,颜色值等. fixed:低精度浮点值 ...

  6. python小白——进阶之路——day3天-———容器类型数据+Number类型强制类型转换

    -->Number 部分 int :     整型   浮点型 布尔类型  纯数字字符串 float:    整型   浮点型 布尔类型  纯数字字符串 complex:  整型   浮点型 布 ...

  7. 详解MySQL数据表类型

    学习Mysql数据库,Mysql表类型都有哪些是一定需要知道的,下面就为您介绍七种Mysql表类型,希望能对您学习Mysql表类型有所帮助. MySQL作为当前最为流行的免费数据库服务引擎,已经风靡了 ...

  8. iOS数据存储类型 及 堆(heap)和栈(stack)

    iOS数据存储类型 及 堆(heap)和栈(stack) 一般认为在c中分为这几个存储区: 1栈 --  由编译器自动分配释放. 2堆 --  一般由程序员分配释放,若程序员不释放,程序结束时可能由O ...

  9. MySQL数据库修改数据表类型(引擎)的方法

    MySQL数据库使用事务,相关数据表必须为InnoDB引擎 查看数据表状态: SHOW TABLE STATUS FROM wawa WHERE NAME='ww_invite_code_temp'; ...

随机推荐

  1. 同步文本框内容的JS代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. [Angularjs]ng-switch用法

    用法描述 ng-switch根据表达式的值显示或这隐藏对应部分.类似c#或者其他预览里面的switch用法.可以慢慢体会. 说道ng-switch就要说到子元素该怎么根据当前值进行变化.子元素可以通过 ...

  3. 手机wifi密码的保存位置

    subjects:  adj. 受制于...的, 被统治的; n. 主题,学科, 国民 the subjects had to kneel down before the king. kneel -& ...

  4. C/C++内存分配区

    一.起源 C++内存分成5个区,分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 但这个自由存储区这么一听还是模模糊糊的,和堆好像是一样的,还有同学说起这个问题.   二.个人理解 关于自由存 ...

  5. Ubuntu 14.04.2 x64 安装tomcat服务器傻瓜教程

    序:安装tomcat服务器之前有一堆的准备工作,比如JDK安装. 一.JDK 7 下载及安装 1.下载JDK文件 X86 代表i386,i486系列, 是为32位操作系统所使用的包.X64是64位操作 ...

  6. jquery 调用数据

    <body> <div id="aa" style="">hello</div> <div class="b ...

  7. Who Gets the Most Candies?(线段树 + 反素数 )

    Who Gets the Most Candies? Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d &am ...

  8. cocos基础教程(6)坐标与锚点讲解

    坐标系详解 Cocos2d-x坐标系和OpenGL坐标系相同,都是起源于笛卡尔坐标系.原点为屏幕左下角,x向右,y向上. 世界坐标系(World Coordinate) VS 本地坐标系(Node L ...

  9. Linux文件权限管理(持续更新)

    文章是从我的个人博客上粘贴过来的, 大家也可以访问我的主页 www.iwangzheng.com 以root身份登录linux以后, ls -al 可以看到 -rw-rw-r--  1 wangzhe ...

  10. BZOJ 1452 [JSOI2009] Count

    这道题好像有点简单的样子... absi找题目好厉害啊...确实是一道比较裸的2dBIT啊. 水掉吧. 附:2dBIT怎么做: 2dBIT就是BIT套BIT啦. 所以修改loop(x+=lowbit( ...