文章目录
- 第2章 变量和基本类型
- 2.1 基本内置类型
- 2.1.1 算术类型
- 2.1.2 类型转换
- 2.1.3 字面值常量
- 2.2 变量
- 2.2.1 变量定义
- 2.2.2 变量声明与定义的关系
- 2.2.3 标识符
- 2.2.4 名字的作用域
- 2.3 复合类型
- 2.3.1 引用(左值引用)
- 2.3.2 指针
- 2.3.3 理解复合类型的声明
- 2.4 const限定符
- 2.4.1 const的引用
- 2.4.2 指针和const
- 2.4.3 顶层const
- 2.4.4 constexpr和常量表达式
- 2.5 处理类型
- 2.5.1 类型别名
- 2.5.2 auto类型说明符
- 2.5.3 decltype
- 2.6 自定义数据类型
- 2.6.1 定义Sales_data类型
- 2.6.2 使用Sales_data类
- 2.6.3 编写自己的头文件
- 小结
- 术语表
为铁西等地区用户提供了全套网页设计制作服务,及铁西网站建设行业解决方案。主营业务为网站建设、
成都做网站、铁西网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
第Ⅰ部分 c++基础
语法特征
- 类型 变量 语句 控制结构 函数
- 补充:自定义数据类型(语言扩展);功能封装成库函数
c++ 静态数据类型语言 类型检查发生在编译时
c++类 包含 数据成员 函数成员
第2章 变量和基本类型
数据类型:数据意义 操作
内置类型: 字符 整型 浮点型
2.1 基本内置类型
2.1.1 算术类型
类型 | 含义 | 最小尺寸 |
---|
bool | 布尔类型 | / |
char | 字符 | 8 |
wchar_t | 宽字符 | 16 |
char16_t | Unicode字符 | 16 |
char32_t | Unicode字符 | 32 |
short | 短整型 | 16 |
int | 整型 | 16 |
long | 长整型 | 32 |
long long | 长整型 | 64 |
float | 单精度浮点型 | 6位有效数字 |
double | 双精度浮点型 | 10位有效数字 |
long double | 扩展精度浮点型 | 10位有效数字 |
char 空间确保可存放机器基本字符集任意字符对应数字值
wchar_t char16_t char32_t 确保可存放机器大扩展字符集任意字符
赋予内存中某地址明确含义需知道存储在地址的数据类型,类型决定数据所占比特数/解释比特内容
浮点型 :单/双/扩展精度浮点型 float 1个字32bit;double 2个字64bit;long double 3/4个字96/128bit
- 带符号类型 无符号类型
- (除去 布尔型 扩展字符型)整型可分 带/无符号类型
- 带符号:正、负、0;无符号:大于0
- int short long ,long long 均为带符号,加unsigned为无符号;unsigned int 可简写为unsigned
- 字符型:char(实际上会为后两种的其中一种由编译器决定)、signed char、unsigned char
- unsigned char可表示0-255区间内的值,signed char表示范围-128-127
- 如何选择类型
- 明确值不可能为负时选无符号类型
- 整数运算用int,超出int范围用long long
- 算数表达式不使用char/bool
- 浮点数运算用double(float精度不够/计算代价相差不大)
2.1.2 类型转换
- 类型所能表示的值得范围决定了转换的过程
- 非bool->bool: 0->false; other->ture
- bool->非bool:false->0; ture->1
- 浮点->整型:仅保留小数点前部分
- 整型->浮点:小数部分记为0,若超出浮点类型容量则精度可能有损失
- 给无符号赋超出范围的值->初始值对无符号类型表示数值总数取模后的余数
- 给带符号类型赋超出表示范围的值,结果为未定义
- 避免无法预知(编译器无需/不能检测的错误)和依赖于现实环境的行为
- 含有无符号类型的表达式
- 负数和无符号数相加,先将负数转换为无符号数类似直接给无符号数赋一个负值,结果等于这个负数加上无符号数的模
- 从无符号数减去一个值(无论是不是无符号数),须确保结果不能是一个负值
- 循环中的条件,for不要写无符号数>=0;因为其永远也不会小于0,会导致死循环;改用while(u>0){–u;}
2.1.3 字面值常量
- 整型和浮点型字面值
- 字符和字符串字面值
- 单引号字符字面值’a’
- 双引号字符串字面值"a"(常量字符构成的数组array,编译器在字符串结尾添加’\0’,故长度比内容多一;可以分行书写"hello"“world”)
- 转义序列
- 不能直接使用:1. 不可打印;2. 特殊含义字符:单引号 双引号 问号 反斜线
- 换行 \n 横向制表\t 纵向制表\v 退格\b 双引号
\"
反斜杠\\
回车\r … - 泛化的转义序列 \x后跟一个或多个16进制数字,\后跟1/2/3个八进制数字
- 指定字面值的类型(前缀(字符和字符串字面值)u,U,L,u8;后缀(整型/浮点型字面值)U,L,LL, F,L)
- 布尔字面值和指针字面值
- 布尔:true false ;指针:nullptr
2.2 变量
- 具名的 可供操作的储存空间;数据类型决定变量所占内存空间大小和布局方式,存储值的范围,能够参与的运算;变量和对象可以互换使用
2.2.1 变量定义
- 类型说明符 变量名(变量名以逗号分隔 以分号结束)
- 对象:一块能存储数据并具有某种类型的内存空间
- 初始值:创建变量时获得的特定值(初始化);初始化不是赋值,赋值:把对象的当前值擦除而以一个新值替代
- 列表初始化int a=0;int a={0};int a{0};//花括号列表初始化 int a(0);
- 默认初始化:定义时没指定初值变量被默认初始化;内置类型定义于函数体外初始化为0,定义于函数体内则不被初始化。(建议初始化每一个内置类型变量)
2.2.2 变量声明与定义的关系
- 分离式编译:将程序分割为若干个文件,每个文件可被独立编译
- 声明:使名字为程序所知(规定变量的类型和名字)(extern);定义:负责创建与名字关联的实体(规定变量的类型和名字外还申请储存空间/可能为变量赋初始值);任何包含显式初始化的声明即成为定义;函数体内部试图初始化extern关键字标记的变量将引发错误;变量只能被定义一次但可被多次声明
- c++静态类型语言,编译阶段检查类型
2.2.3 标识符
- 字母 数字 下划线组成,必须以字母或者下划线开头;长度无限制,大小写敏感
- 不能被用作标识符:保留字,标准库保留名字(连续两个下划线/下划线紧连大写字母开头),定义在函数体外标识符不能以下划线开头
- 变量命名规范:
- 标识符要体现实际含义
- 变量名一般用小写字母
- 自定义类名以大写字母开头
- 标识符由多单词组成,单词间应明显区分(下划线或驼峰)
2.2.4 名字的作用域
- c++作用域以花括号分割
- 名字有效区域:始于名字声明语句,终于声明语句所在作用域末端
- 全局作用域:定义在函数体外(花括号外);块作用域
- 嵌套的作用域
- 内层作用域:被包含(被嵌套)的作用域 (允许内层作用域中重新定义外层作用域已有的名字)
- 外层作用域:包含着别的作用域的作用域
- 局部变量正在作用域内(in scope)会覆盖全局变量;域操作符左侧为空如 ::g_cat即为全局作用域对应变量
2.3 复合类型
- 基于其他类型定义的类型:引用 指针
- 声明语句: 数据类型 变量名;基本数据类型 声明符列表
2.3.1 引用(左值引用)
- 为对象另起一个名字,定义引用&(必须初始化)时,程序将引用和初始值绑定而不是拷贝;引用本身不是对象不能定义引用的引用;引用只能绑定在对象上,不能与字面值或表达式计算结果绑定在一起
2.3.2 指针
- 指向另外一种类型的符合类型(存放某个对象的地址);
- 和引用的不同
- 指针本身是一个对象,允许指针赋值和拷贝,可以先后指向不同的对象;
- 指针无须在定义时赋初值
- 获取对象地址
- 使用取地址符&
- 除两例外情况外,指针类型都要与指向对象严格匹配
- 指针值(地址)
- 指向一个对象
- 指向紧邻对象所占空间的下一个位置
- 空指针
- 无效指针
- 利用指针访问对象
- 使用解引用符(*)(仅适用于指向某个对象的有效指针)访问对象,给解引用的结果赋值,实际上就是给指针所指的对象赋值
- 在声明语句中,
&
和*
用于组成复合类型(引用 指针);在表达式中他们转变成运算符(取地址 解引用)
- 空指针
- 不指向任何对象,使用指针前先检查其是否为空
- 初始化(nullptr(最好使用nullptr),0,NULL(尽量避免))
- 不能把int型变量直接赋值给指针 变量值恰好为0也不行
- 赋值和指针
- 定义引用后无法令其再绑定到另外的对象
- 给指针赋值令它存放一个新的地址,指向新的对象
- 赋值永远改变的是等号左侧的对象
- 其他指针操作
- 任何非0指针的条件值都是true
- == 指针存放的地址值相同:都为空;都指向同一个对象;都指向同一对象的下一地址
- void*指针
- 可用于存放任意(类型)对象的地址
- 与别的指针比较;作为函数输入输出;赋给另外一void指针;不能直接操作void指针所指对象
2.3.3 理解复合类型的声明
- 一条定义语句可能定义出不同的数据类型,如
int 1=1024,*p=&i,&=i;
- 定义多个变量
- 类型修饰符
&
和*
,对声明语句中的其他变量不产生任何作用。建议将&
或*
与变量名连在一起
- 指向指针的指针
- 指针本身也有自己的地址,
**
表示指向指针的指针,***
表示指向指针的指针的指针
- 指向指针的引用
- 引用本身不是对象,不能定义指向引用的指针,但存在对指针(是对象)的引用
int *p;int *&r=p;
- 面对比较复杂的指针或者引用的声明语句使,从右向左阅读有助于弄清楚其真实含义
2.4 const限定符
- const对象一旦创建后值就不能再改变,必须初始化
- 初始化和const 只能在const类型的对象上执行不改变其内容的操作
- 默认状态下 const对象尽在文件内有效,多文件共享方法:const变量不管是声明还是定义都添加extern关键字
2.4.1 const的引用
- 对常量的引用:引用及其对应的对象都是常量const
- 引用的对象是常量还是非常量都不会影响引用和对象的绑定关系
- 初始化和对const的引用 引用类型和引用对象类型应一致的两个例外:初始化常量引用时允许用任意表达式作为初始值,只要表达式结果能转换为引用类型即可(绑定临时量对象);
- 对const的引用可能引用一个并非const对象
int i=42;const int &r2=i;
i可以改变,但不允许通过r2修改i的值
2.4.2 指针和const
2.4.3 顶层const
- 顶层const 指针/任意对象本身是个常量
- 底层const 指针所指向的/引用对象是个常量(用于声明引用的const都是底层const)
- 对象的拷贝操作,顶层const(被拷贝对象)不受什么影响,底层const拷入和拷出的对象必须具有相同的底层const资格/两对象的数据类型必须能够转换;非常量可以转换为常量反之不行
2.4.4 constexpr和常量表达式
- 常量表达式:值不会改变并且在编译过程中就能得到计算结果的表达式(如 字面值 用常量表达式初始化的const对象)
- constexpr变量:将变量声明为constexpr以便由编译器来验证变量的值是否是一个常量表达式;若认定变量是一个常量表达式就将其声明成constexpr类型
- 字面值类型:算术类型 引用 指针; 不属于字面值类型: 自定义类 IO库 string
- constexpr指针的初始值必须是nullptr/0/存储于某个固定地址中的对象
- 指针和constexpr:constexpr限定符仅对指针有效,与指针所指的对象无关,constexpr将其所定义的对象置为顶层const
2.5 处理类型
2.5.1 类型别名
2.5.2 auto类型说明符
- 让编译器通过初始值来推算变量的类型
- 一条声明语句中只能有一个基本数据类型,同一条auto语句中所有变量的初始基本数据类型都必须一致
- 复合类型 常量 和 auto
- auto一般会忽略顶层const,保留底层const;如果希望推断出的auto是顶层const须明确指出 即在auto前加const
- 设置一个类型为auto的引用时,初始值中的顶层常量属性仍然保留
- &和*只从属于某个声明符而非数据类型的一部分 因此初始值必须是同一种类型
2.5.3 decltype
- 选择返回操作数的数据类型,编译器分析表达式并得到它的类型,却不实际计算表达式的值
- decltype处理顶层const和引用的方式与auto不同,若decltype使用的表达式是一个变量则decltype返回该变量的类型(包括顶层const 和引用在内)
- decltype和引用
- 引用类型作为表达式的一部分结果将是一个具体值而非引用
- 若表达式内容是解引用操作,decltype将得到引用类型
- decltype((variable))的结果永远是引用
2.6 自定义数据类型
- 数据结构:把一组相关的数据元素组织起来然后使用它们的策略和方法,c++允许用户以类的形式自定义数据类型
2.6.1 定义Sales_data类型
- struct 类名 类体(花括号{}包围形成一个新的作用域) 分号;
- 类数据成员 类内初始值 没有初始化的成员将被默认初始化
2.6.2 使用Sales_data类
- 添加类对象
- 对象读入数据(使用点操作符.读入对象成员)
- 输出两个对象的和
2.6.3 编写自己的头文件
- 头文件通常只包含那些只能被定义一次的实体 如类/const/constexpr
- 预处理器概述(确保头文件多次包含仍能安全工作)
- 编译之前执行的一段程序 可部分的改变我们写的程序
- 头文件保护符 依赖于预处理变量
- #define 将一个名字设定为预处理变量
- #ifdef 变量已定义为真
- #ifndef 变量未定义时为真
- 一旦检查结果为真,执行后续操作直到遇到#endif指令为止
- 预处理变量无视c++中关于作用域的规则
- 预处理变量包括头文件保护符必须唯一 一般预处理变量名字全部大写
- 一般习惯性加上头文件保护符
小结
- 类型 分为非常量和常量 常量对象必须初始化,一旦初始化就不能再改变
- 复合类型(以其他类型为基础) 指针 引用
- 以类的形式自定义类型,c++库提供高级抽象类型如string
术语表
| | | | | |
---|
address | alias declaration | arithmetic type | array | auto | base type |
bind | byte | class member | compound type | const | const pointer |
const reference | const experession | constexpr | conversion | data member | declaration |
declarator | decltype | default initiatialization | defintion | escape sequence | global scope |
header guard | identifier | in-class initializer | in scope | initialized | inner scope |
integral type | list initialization | literal | literal | local scope | low-level const |
member | nonprintable character | null pointer | nullptr | object | outer scope |
pointer | pointer to const | preprecessor | reference | reference | reference to const |
scope | class | namespace | block | separate compilation | signed |
string | struct | temporary | top-level const | type alias | type checking |
type specifiler | typedef | undefined | uninitialized | unsigned | variable |
void* | void | word | & operator | * operator | #define |
#endif | #ifdef | #ifndef | | | |
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站标题:c++primer第2章变量和基本类型-创新互联
本文网址:
http://6mz.cn/article/pjjoh.html