IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ primer 复习 第二章 变量和基本类型 2.2 — 2.6 -> 正文阅读

[C++知识库]C++ primer 复习 第二章 变量和基本类型 2.2 — 2.6

C++ primer 复习 第二章 变量和基本类型

2.2 变量

变量

变量提供一个可供程序操作的有名称的空间

变量都有类型,类型决定了变量的内存空间

int sum = 0, val,   // sum,val和units_sold都是int型
units_sold = 0; // sum 和 units_sold 初值为0,val未初始化

Sales_item item; // item 是 Sales_item 类型
std::string book("0-2-1-78345-X"); // book 变量通过字面值初始化

对于 C++ 来说,变量和对象是可以互换的

初始化

C++新标准,使用花括号初始化(列表初始化)

int units_sold = 0;
int units_sold(0);

//列表初始化
int units_sold = { 0 };
int units_sold{ 0 };

使用列表初始化,若存在丢失信息的风险,则编译器报错

long double ld = 3.1415926; //long double 多精度浮点型,不少于double精度,具体和编译器有关
int a{ ld }, b{ ld }; //错误:转换未正确执行
int c(ld),d=ld; //正确:转换执行,且确实丢失了部分值

默认初始化

如果定义变量没有被初始化,则变量被赋予默认值

默认值由变量类型决定,且和变量定义位置有关

内置类型,函数体之外被初始化为 0

每个类决定其初始化对象的方式

std::string empty; // 非显式的初始化一个空串
Sales_item item; // 默认初始化 Sales_item 对象

未初始化的变量含有一个不确定的值,将带来无法预计的后果,应避免

变量定义与声明

C++是静态类型语言,其含义是在编译阶段检查类型。因此在使用某个变量前必须声明

如果声明一个变量而非定义它,就在变量名前加上extern关键字,且不要显式初始化

//若在函数内部则 : 不允许对外部变量的局部声明使用初始值设定项
extern double pi = 3.14;//定义不能放在函数内部

int main(){
	extern int i;//声明 i 而非定义 i
	int j;//声明 j 并定义 j
}

声明和定义的区别在于,变量可以被声明多次,但只能被定义一次

标识符

C++标识符由字母、数字和下划线组成,只能由字母或下划线开头。标识符无长度限制但大小写敏感。C++ 关键字和操作符替代名不可作为标识符

C++ 关键字

在这里插入图片描述

C++ 操作符替代名
在这里插入图片描述

名字作用域

同一个名字出现在程序不同位置,可能指向不同实体

C++作用域大多以花括号分隔

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

#include<iostream>

/*
这里是全局作用域
*/

int main(){
    //这里是块作用域
 
    int sum =0;  //始于sum声明语句
    for(int val=1;val<=10;++val){
        sum += val;
    }
    return 0;
}

2.3 复合类型

复合类型

是指基于其它类型定义的类型

引用

区别:C++11新增了 右值引用,当我们使用术语 引用时,一般指左值引用??

为对象起的另一个名字,定义引用时,程序把引用和它的初始值绑定在一起,而不是把初始值拷贝给引用。引用必须初始化,本身不是对象,所以不能定义引用的引用

int val = 1024;
int &refVal = val;

//int &reVal2; //报错,引用必须初始化

int li = refVal; //等同于li = val
refVal = 2;//把2赋给refVal指向的对象,此处即赋给了val

int& refVal3 = refVal; //正确,refVal3绑定到了与refVal绑定的对象,即绑定了val

指针

对地址的封装,本身就是一个对象

定义指针类型的方法是将声明符写成 *X 的形式

一个语句定义多个指针变量,则每个都需要加 * 符号

和内置类型一样,指针在块作用域内定义未初始化,将拥有一个不确定的值

int *p1, *p2; //p1和p2都是指向int型对象的指针
double dp1, *dp2;

可以通过取地址符 & 获取指针封装的地址

可以通过**解引用符 *** 利用指针访问对象

int val = 42;
int*p = &val;
double *dp = &val; //错误类型不匹配

理解:为什么会报类型不匹配错误

从取地址符的角度,无法把一个 int 类型的地址赋值给 double 类型的指针

从解引用符的角度,需要统一指针类型和数据类型,不然无法取值(更合理)

空指针

不指向任何对象,使用指针前先判空

三种空指针

int *p1 = nullptr;
int *p2 = 0;  //C语言中定义了 0 地址,不指向任何对象
int *p3 = NULL; //#include<cstdlib>

无法用整型初始化指针

int zero = 0;
int* ptr = zero; //错误,类型不匹配

void* 指针

类型无关指针,可存放任意对象地址

int obj1 = 3;
double obj2 = 3.14, *ptr1 = &obj2;
void* pv = &obj1;
pv = &obj2;

指向指针的指针

通过 * 的个数可以区别指针的级别

int val = 1024;
int* p1 = &val;

int **p2 = &p1; //p2指向 int*

指向指针的引用

指针是对象,可定义引用

int val = 1024;
int* p1;
int* &r = p1; //r是一个对指针的引用

r = &val; //即p1 = &val
*r = 0; //*r = *p1 = val = 0

2.4 const 限定符,constexpr

被 const 限定符 修饰的变量,其值不能被改变(变量—>常量)

const int bufSize = 512; //输入缓冲区的大小
//bufSize = 512; //错误,表达式必须是可被修改的左值

const 对象必须初始化(其它时候不能出现在等号左边,不能被修改)

const int i = get_size(); //正确,运行时初始化
const int j = 42; //正确,编译时初始化
const int k; //错误,未初始化

用 const 对象给指针赋值

编译时,编译器会把 zero ,替换为 0 ,所以可以这么写

const int zero = 0;
void* ptr = zero;

多个文件共享 const 对象

在变量定义前加上 extern 关键字

// file.h 头文件
extern const int bufSize; //声明 bufSize const 对象

//file.cpp 
extern const int bufSize = func(); //定义且初始化 bufSize 对象,该常量可被其它文件访问

const 引用

即对常量的引用

const int ci = 1024;
const int &r = ci; //正确,引用和绑定的对象都是常量

r = 42; //错误,等同于 ci = 42 ,试图修改常量
int &r2 = ci; //错误,ci是常量,存在通过 r2 改变 ci 的风险

存在对常量修改的风险,所以无法将一个非常量引用赋值给常量引用

类型 + 修饰符(描述变量属于哪种内置类型)+ 变量名

指针 和 const

指向常量的指针

const double pi = 3.14;
//double * ptr = &pi;//错误,存在通过指针修改常量的风险
const double *ptr1 = &pi;
*ptr1 = 42;//错误

double val = 3.14;
ptr1 = &val;//正确,但不能通过ptr1修改val的值

const 指针

指针是对象,也可以被限制为常量(必须初始化)

把 * 放到 const 之前,说明指针是一个常量;不变的是指针,而非指向的值

int errNum = 0;
int *const curErr = &errNum;
const double pi = 3.14;
const double *const pip = &pi;//指向常量的常量指针

*pip = 2.71;//错误,试图修改常量
if (*curErr){
	*curErr = 0;//正确,修改变量errNum
}

顶底层const

顶层 const :指针本身是一个常量

底层 const : 表示指针指向的对象是一个 const

是否有常量被修改的风险

int i = 0;
int* const p1 = &i; //顶层
const int ci = 42; //顶层
const int * p2 = &ci; //底层

//是否有常量被修改的风险
const int* const p3 = p2;

i = ci;
p2 = p3;

int *p = p3;//存在通过 *p 修改 *p3(const)风险
p2 = &i;//正确,只是无法用*p2修改i的值
int&r = ci;//错误,存在通过r修改ci的风险
const int &r2 = i;//正确,只是无法通过 r2 修改 i 的值

constexpr 和常量表达式

常量表达式是指 :值不会改变且在编译期间就能得到计算结果的表达式 (例,字面值常量)

自定义类型不能被定义成 constexpr ,例 string

const int max_files = 20;//是
const int limit = max_files + 1;//是
int staff_size = 27;//不是
const int sz = get_size();//不是

constexpr 变量

C++11规定允许将变量声明为 constexpr 类型,验证变量的值是否为一个常量表达式

一个是一个常量,必须用常量表达式初始化

constexpr int mf = 20;
constexpr int limit = mf + 1;
constexpr int sz = size(); //只有size()返回值是一个constexpr时才正确

指针和 constexpr

限定符仅对指针有效和指针所指对象无关

constexpr int *np = nullptr; //指针常量
int j = 0;
constexpr int i = 42;

constexpr const int *p = &i; //p是指针常量,指向常量
constexpr int *p1 = &j; //p1是指针常量,指向变量

2.5 处理类型

类型别名:提高代码可读性

解决程序复杂,变量复杂,拼写困难问题

typedef double wages;
//注意这里并不是声明变量, typedef 声明别名
typedef wages base, *p;//base是double的同义词,p是double*的同义词

using p = double*; //C++11,声明别名
wages hourly, weekly;

p p1;//等价于double* p1

指针(复合类型)使用类型别名

typedef char* pstring;
const pstring p1 = 0; //const 和 pstring都是用来修饰 p1的
//指向char*的 指针常量

const pstring *ps; //const是修饰pstring的,修饰符的匹配原则,从右往左
//ps是指针变量,它的对象是指向char的指针常量

auto 类型说明符:C++11让编译器通过初始值推断变量类型

auto i = 0,*p = &i; //正确
auto a = 0, b = 3.14;//错误,auto已经被推断为int型
int i = 0, &r = i;
auto a = r; //a是int型

const int c1 = i, &r1 = c1;

//auto在推断类型时,顶层const会忽略(对于等号左边而言)
auto b = c1; //b是int型,c1的顶层const被忽略
auto c = r1; //c是int型,c1顶层const被忽略
auto d = &i; //d是int*,整型的地址就是指向整型的指针
auto e = &c1;//e是const int* 常量指针,底层const没被忽略

const auto f = c1;//auto推演类型为int,f类型为const int
auto &g = c1; // const int 整型常量引用,即引用的对象是一个常量

auto &h = 42; //错误,规定:不能对非常量引用绑定字面值
const auto &h = 42;//正确,可以为常量引用绑定字面值

decltype类型说明符: 选择并返回操作数的数据类型

引用都是其对象的同义词,但decltype是一个例外

const int c1 = 0,&c2 = c1;
decltype(c1) x = 0; //const int 
decltype(c2) y = 0; //const int&
decltype(c2) z;//错误,必须初始化

如果表达式内容是解引用操作,则decltype会得到引用类型

decltype(val)的结果永远为引用,val本身也可以是引用

int i = 42, *p = &i, &r = i;
decltype(r + 0) b; //正确,int

//注意,*不是出现在声明中,而是在表达式中的解引用符
decltype(*p) c;//错误,解引用表达式,c的类型为引用必须初始化

//变量如果是加上括号,decltype的结果为引用
decltype((i)) d;//错误,int&类型必须初始化
decltype(((i))) d1 = i; //正确
decltype(i) e;//正确,e是一个未初始化的int

解引用操作符 :*,得到指针所指对象的引用

int ival;
int *ip = &ival;
int &iref = *ip; //*ip就是ival的引用,等价于 int &iref = ival

2.6 自定义数据结构,类和文件

自定义数据结构 :一组数据以及相关操作的集合

类定义:类定义可以是关键字 class 或 struct

默认继承访问权限不同,struct 是 public ,class 是 private

//数据成员定义了类对象的具体内容,每个对象有自己的一份拷贝
struct Sales_data{
	std::string bookNo;
	unsigned units_sold = 0;
	double pi = 3.14;
}; //类定义的最后需要加上分号

类使用

类通常定义在头文件中

#ifndef SALES_DATA_H
#ifndef SALES_DATA_H

#include<string>
struct Sales_data{
	std::string bookNo;
	unsigned units_sold = 0;
	double pi = 3.14;
};

#endif

//*ip就是ival的引用,等价于 int &iref = ival




## 2.6 自定义数据结构,类和文件

**自定义数据结构** :一组数据以及相关操作的集合



**类定义**:类定义可以是关键字 class 或 struct

默认继承访问权限不同,struct 是 public ,class 是 private

```c++
//数据成员定义了类对象的具体内容,每个对象有自己的一份拷贝
struct Sales_data{
	std::string bookNo;
	unsigned units_sold = 0;
	double pi = 3.14;
}; //类定义的最后需要加上分号

类使用

类通常定义在头文件中

#ifndef SALES_DATA_H
#ifndef SALES_DATA_H

#include<string>
struct Sales_data{
	std::string bookNo;
	unsigned units_sold = 0;
	double pi = 3.14;
};

#endif

附 思维导图
第二章完整思维导图,便于记忆

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:17:43  更:2021-11-09 19:19:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:47:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码