[C++Primer] 第二章 变量和基本类型
2016-05-16 22:32
519 查看
2.1 基本内置类型
C++定义了一套包括算术类型 (arithmeric type) 和空类型 (void) 在内的基本数据类型。其中算术类型包含了字符、整型数、 布尔值和浮点数。空类型不对应具体的值,仅用于一些特殊的场合,例如最常见的是,当函数不返回任何值时使用空类型作为返回类型
2.1.1 算数类型
算术类型分为两类:整型 (integral type,包括字符和布尔类型在内)和浮点型类型 int、short、long 和 long long 都是带符号的,通过在这些类型名前添加 unsigned 就可以得到无符号类型,例如 unsigned long。类型 unsigned int 可以缩写为 unsigned
类型 char 和类型 signed char 并不一样
2.1.2 类型转换
#include <iostream> int main(){ unsigned u = 10, u2 = 42; std::cout << u2 - u << std::endl; std::cout << u - u2 << std::endl; int i=10, i2= 42; std::cout << i2 -i<< std::endl; std::cout << i - i2<< std::endl; std::cout << i - u<< std::endl; std::cout << u - i<< std::endl; return 0; }
2.1.3 字面值常量
一个形如42的值被称作字面值常量(literal)整型和浮点型字面值
20 /* 十进制 */ 024 /* 八进制 */ 0x14 /* 十六进制 */
浮点数
3.14159 3.14159E0 0. 0e0 .001
字符和字符串字面值
// 分多行书写的字符串字面值 std::cout << "a rea11y, rea11y long string litera1 " "that spans two 1ines" << std::end1;
转义序列
换行符 \n 横向制表符 \t 报警(响铃)符 \a 纵向制表符 \v 退格符 \b 双引号 \" 反斜线 \\ 问号 \? 单引号 \' 回车符 \r 进纸符 \f
2.2 变量
变量提供一个具名的、可供程序操作的存储空间。C++中的每个变量都有其数据类型,数据类型决定着变量所占内存空间的大小和布局方式、该空间能存储的值的范围,以及变量能参与的运算。对C++程序员来说,”变量 (variable)” 和 “对象 (object)” 一般可以互换使用。2.2.1 变量定义
变量定义的基本形式是:首先是类型说明符(type specifier),随后紧跟由一个或多个变量名组成的列表,其中变量名以逗号分隔,最后以分号结束。初始值
2.2.2 变量声明和定义的关系
分离式编译 (separate compilation) 机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译。声明extern和定义
2.2.3 标识符
变量命名规范变量命名有许多约定俗成的规范, 下面的这些规范能有效提高程序的可读性:
标识符要能体现实际含义。
变量名一般用小写字母, 如index, 不要使用Index或INDEX。
用户自定义的类名一般以大写字母开头, 如 Sales_item。
如果标识符由多个单词组成, 则单同间应有明显区分, 如 student_loan 或studentLoan, 不要使用 studentloano
2.2.4 名字的作用域
嵌套的作用域
#include <iostream> int reused = 42; int main(){ int unique = 0; std::cout << reused <<" "<< unique << std::endl; int reused = 0; std::cout<<reused<<" "<<unique <<std::endl; std::cout << ::reused <<" "<<unique <<std::endl; return 0; }
#include <iostream> int main(){ int i = 100, sum = 0; for(int i = 0;i != 10; ++i) sum += i; std::cout << i << " " << sum << std::endl; return 0; }
2.3 复合类型
2.3.1 引用
引用 (reference) 为对象起了另外一个名字,引用类型引用 (refers to)另外一种类型。通过将声明符写成 &d 的形式来定义引用类型,其中 d 是声明的变量名:int ival = 1024; int &refVa1 = iva1; // refVa1指向iva1(是iva1的另一个名字) int &refVa12; // 报错:引用必须被初始化
一般在初始化变量时,初始值会被拷贝到新建的对象中。然而定义引用时,程序把引用和它的初始值绑定 (bind) 在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。
#include <iostream> int main(){ int i = 1, &r1 = i; double d = 0.0, &r2 = d; std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl; // T r2 = 3.14159; std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl; // T r2 = r1; std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl; // F i = r2; std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl; // F r1 = d; std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl; return 0; }
#include <iostream> int main(){ int i = 1, &r1 = i; i = 5; r1 = 10; std::cout << i << " " << r1 << std::endl; return 0; }
2.3.2 指针
指针 (pointer) 是 “指向(point to)” 另外一种类型的复合类型。 与引用类似,指针也实现了对其他对象的间接访问。然而指针与引用相比又有很多不同点。其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。
其二,指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。
指针存放某个对象的地址,要获取该地址,需要使用取地址符 (操作符 &)
int ival = 42; int *p = &iva1; // p存放变量iva1的地址, 或者说p是指向交量ival的指针 double dval; // 正确 : 初始位是 double 型对象的地址 double *pd = &dval; // 正确 : 初始位是指向 double 对象的指针 double *pd2 = pd; int *pi = pd; // 错误: 指针pJ.的类型和pd的类型不匹配 pi = &dval; // 错误: 试图把double型对象的地址赋给int型指针
如果指针指向了一个对象,则允许使用解引用符 (操作符 * 来访问该对象:
int ival = 42; int *p = &ival; // p存放着变量ival的地址。或者说p是指向交量ival的指针 cout << *p; // 由符号*得到指针p指的对象,输出42
对指针解引用会得出所指的对象,因此如果给解引用的结果赋值,实际上也就是给指针所指的对象赋值:
*p = 0; // 由符号*得到指针p所指的对象, 即可经由p为交量ival赋值 cout<<*p; // 出0
int &r = i; int *p; p = &i; *p = i; int &r2 = *p // &是声明的一部分, *是一个解引用符
int i = 42; int &r = i; // r 是引用 int *p; // p 是指针 p = &i; // & 取地址符 *p = i; // * 解引用符 int &r2 = *p; // * 解引用符
空指针
int *p1 = nullptr; // 等价于 int *p1 = 0; int *p2 = 0; // 直接将p2初始化为字面常数0 // 需要首先#include cstdlib int *p3 = NULL; // 等价于int*p3 = 0;
2.4 const 限定符
2.5 处理类型
类型别名 (type alias) 是一个名字,它是某种类型的同义词。使用类型别名有很多好处,它让复杂的类型名字变得简单明了、 易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。typedef double wages; //wages 是 double 的同义词 using SI = Sales_item; // SI是Sales_item的同义词
2.6 自定义数据结构
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性