C++ Primer Chapter 2 Variables and Basic Types

2024-05-30 15:20

本文主要是介绍C++ Primer Chapter 2 Variables and Basic Types,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C++ Primer Chapter 2 Variables and Basic Types

2024/05/27
2.3 复合类型
引用
定义
通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名。
int ival=1024;
int &refVal=ival;
int &refVal2;
//报错:引用必须被初始化

引用即别名
引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。

定义了一个引用之后,对其进行的所有操作都是在与之绑定的对象上进行的:
refVal=2;
int ii=refVal;

为引用赋值,实际上是把值付给了与引用绑定的对象。
获取引用的值,实际上获取了与引用绑定的对象的值。
以引用作为初始值,实际上是以与引用绑定的对象作为初始值:

int &refVal3=refVal; //正确,refVal3绑定到了那个与refVal绑定的对象上,这里就是绑定在ival上
int i=refVal //正确:i被初始化为ival的值

因为引用不是一个对象,所以不能定义引用的引用。

指针

指针本身就是一个对象,允许对指针进行赋值和拷贝,而且在指针的声明周期内它可以先后指向几个不同的对象。
指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。

定义
int ival=42;
int *p=&ival;
取地址符(&)
指针值

指针的值(即地址)应属于下列4种状态之一:
1.指向一个对象。
2.指向紧邻对象所占空间的下一个位置。
3.空指针,意味着指针没有指向任何对象。
4.无效指针,也就是上述情况之外的其他值。

解引用符(*)
int ival=42;
int *p=&ival; //p存放着变量ival的地址,或者说p是指向变量ival的指针。

cout<<p; //由符号得到指针p所指的对象,输出42

p=0; //由符号得到指针p所指的对象,即可经由p为变量ival赋值

cout<<*p; //输出0

Note 解引用操作仅适用于那些确实指向了某个对象的有效指针。

空指针(null pointer)不指向人很对象,在试图使用一个指针之前可以首先检查它是否为空。

以下列出了几种生成空指针的方法:
int *p1=nullptr;
int *p2=0;
//需要首先#include cstdlib
int *p3=NULL;

把int变量直接赋值给指针是错误的操作,即使int变量的值恰好等于0也不行。
int zero=0;
int *pi=zero; //错误:不能把int变量直接赋给指针
建议:初始化所有指针

赋值和指针
赋值永远改变的是等号左侧的对象

其他指针操作
指针用在条件表达式中
int ival=1024;
int *pi=0; //pi合法,是一个空指针
int *pi2=&ival; //pi2是一个合法的指针,存放着ival的地址

if(pi) //pi的值是0,因此条件的值是false
//
if(pi2) //pi2指向ival,因此它的值不是0,条件的值是true
//

void*指针

void是一种特殊的指针类型,可用于存放任意对象的地址。一个void指针存放着一个地址,这一点和其他指针类似。不同的是,我们对该地址中到底是个什么类型的对象并不了解:

2.3.3理解复合类型的声明
WARNING 很多程序员容易迷惑于基本数据类型和类型修饰符的关系,其实后者不过是声明符的一部分罢了。

指向指针的引用
引用本身不是一个对象,因此不能定义指向引用的指针。但指针是对象,所以存在对指针的引用:
int i=31;
int *p; //p是一个int型指针
int *&r=p; //r是一个对指针p的引用
r=&i; //r引用了一个指针,因此给r赋值&i就是令p指向i
*r=0; //解引用r得到i,也就是p指向的对象,将i的值改为0

要理解r的类型到底是什么,最简单的办法是从右向左阅读r的定义。离变量名最近的符号(此例中的是&r的符号&)对变量的类型有最直接的影响,因此r是一个引用。声明符的其余部分用以确定r引用的类型是什么,此例中的符号*说明r引用的是一个指针,最后,声明的基本数据类型部分指出r引用的是一个int指针。
Tip 面对一条比较复杂的指针或引用的声明语句时,从右向左阅读有助于弄清楚它的真实含义。

2.4 const限定符
因为const对象一旦创建后其值就不能再改变,所以const对象必须初始化。一如既往,初始值可以是任意复杂的表达式:

只能在const类型的对象上执行不改变其内容的操作

在不改变const对象的操作中还有一种是初始化,如果利用一个对象去初始化另外一个对象,则它们是不是const都无关紧要。

默认情况下,const对象仅在文件内有效。
当多个文件中出现了同名的const变量时,七十年等同于在不同文件中分别定义了独立的变量。
Note 如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字。

2.4.1 const的引用

初始化和对const的引用

初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。
int i = 31;
const int& r1 = i;
const int& r2 = 31; //r2也绑定对象i,但是不允许通过r2修改i的值
const int& r3 = r1 * 2;
//非常量引用的初始值必须为左值
//int& r4 = r2*2;

对const的引用可能引用一个并非const的对象

2.4.2 指针和const
指向常量的指针不能用于改变其所指对象的值。
要想存放常量对象的地址,只能使用指向常量的指针;

和常量引用一样,指向常量的指针也没有规定其所指的对象必须是一个常量。所谓指向常量的指针仅仅要求不能通过该指针改变对象的值,而没有规定那个对象的值不能通过其他途径改变。

Tip 试试这样想把:所谓指向常量的指针或引用,不过是指针或引用的“自以为是”罢了,他们觉得自己指向了常量,所以自觉地不去改变所指对象的值。

const指针
允许把指针本身定位常量。常量指针(const pointer)必须初始化,而且一旦初始化完成,则它的值(也就是存放在指针中的那个地址)就不能再改变了。
把*放在const关键字之前用以说明指针是一个常量,这样的书写形式隐含了一层意味,即不变的是指针本身的值而非指向的那个值:

指针本身是一个常量并不意味着不能通过指针修改其所指对象的值,能否这样做完全依赖于所指对象的类型。

2.4.3 顶层const
指针本身是一个对象,它又可以指向另外一个对象。因此,指针本身是不水常量一级指针所指的是不是一个常量就是两个相互独立的问题。用名词顶层const(top-level const)表示指针本身是个常量,而用名词底层const(low-level const)表示指针所指的对象是一个常量。
更一般的,顶层const可以表示任意的对象是常量,这一点对任何数据类型都适用,如算法类型、类、指针等。底层const则与指针和引用等复合类型的基本类型部分有关。
比较特殊的是,指针即可以是顶层const也可以是底层const,这一点与其他类型相比区别明显。

当执行对象的拷贝操作时,常量是顶层const还是底层const区别明显。
其中,顶层const不受什么影响:
执行拷贝操作并不会改变被拷贝对象的值,因此,拷入和拷出的对象是否是常量都没什么影响。
另一方面,底层const的限制却不能忽视。
当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。
一般来说,非常量可以转换为常量,反之则不行。

2.4.4 constexpr和常量表达式

常量表达式(const expression)是指值不会改变并且在编译过程就能得到计算结果的表达式。
一个对象(或表达式)是不是常量表达式由它的数据类型和初始值共同决定。
2.4.4 constexpr和常量表达式

常量表达式(const expression)是指值不会改变并且在编译过程中就能得到计算结果的表达式。
一个对象(或表达式)是不是常量表达式由它的数据类型和初始值共同决定的。

const int max_files=20;				//max_files是常量表达式
const int limit=max_files+1;		//limit是常量表达式
int staff_size=27;					//staff_size不是常量表达式
const int sz=get_size();			//sz不是常量表达式,尽管sz本身是一个常量,但它的具体值知道运行时才能获取到,所以不是常量表达式。

constexpr变量
C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化:

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

尽管不能使用普通函数作为constexpr变量的初始值,但是,新标准允许定义一种特殊的constexpr函数。这种函数应该足够简单以使得编译时就可以计算其结果,这样就能用constexpr函数去初始化constexpr变量了。
字面值类型
算数类型、引用和指针都属于字面值类型。
自定义类、IO库、string类型则不属于字面值类型,也就不能被定义成constexpr。

指针与constexpr

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

constexpr把它所定义的对象置为了顶层const。

这篇关于C++ Primer Chapter 2 Variables and Basic Types的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1016441

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

使用C/C++调用libcurl调试消息的方式

《使用C/C++调用libcurl调试消息的方式》在使用C/C++调用libcurl进行HTTP请求时,有时我们需要查看请求的/应答消息的内容(包括请求头和请求体)以方便调试,libcurl提供了多种... 目录1. libcurl 调试工具简介2. 输出请求消息使用 CURLOPT_VERBOSE使用 C

C++实现获取本机MAC地址与IP地址

《C++实现获取本机MAC地址与IP地址》这篇文章主要为大家详细介绍了C++实现获取本机MAC地址与IP地址的两种方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实际工作中,项目上常常需要获取本机的IP地址和MAC地址,在此使用两种方案获取1.MFC中获取IP和MAC地址获取

C/C++通过IP获取局域网网卡MAC地址

《C/C++通过IP获取局域网网卡MAC地址》这篇文章主要为大家详细介绍了C++如何通过Win32API函数SendARP从IP地址获取局域网内网卡的MAC地址,感兴趣的小伙伴可以跟随小编一起学习一下... C/C++通过IP获取局域网网卡MAC地址通过win32 SendARP获取MAC地址代码#i

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(