C++之复合资料型态 第一部(参考 列举 指标)

复合资料型态(compound type) 是由其他资料型态(data type) 定义出来的型态, C++ 中的复合资料型态包括参考(reference) 、列举(enumeration) 、阵列(array) 、指标(pointer ) 、结构(structure) 及联合(union) 。

参考

参考是变数(variable) 的别名(alias) ,例如

#include <iostream>int main() {int a = 22;int& a_ref = a;std::cout << "a: " << a << std::endl;std::cout << "a_ref: "<< a_ref << std::endl;a_ref = 11;std::cout << "a: " << a << std::endl;std::cout << "a_ref: " << a_ref << std::endl;return 0;
}

​ 第5 行,宣告参考的型态(type) 必须与参考所指向的变数型态相同,然后在型态名称后后使用& 运算子(operator) 标明这是个参考变数,因此这个例子的参考变数为a_ref,等号右边为所要指向的变数,此例为a ​

int& a_ref = a;

由于C++ 是自由格式的程式语言,因此写成int & a_ref或int &a_ref都可以。

接下来我们印出aa_ref的值,然后把a_ref改成11

a_ref = 11;

这样a也会变成11,编译后执行结果如下

$ g++ u0701_1.cpp
$./a.out 复制代码
答:22
参考编号:22
答:11
参考编号: 11
$

由上可看出参考等同于原来的变数,这被称为左值参考(lvalue reference) 。 C++11 增加了一个右值参考(rvalue reference) ,用以增进运算的效率,这是用&&来宣告,例如

int&& ref = a + b + c;

右值参考是对运算式的参考,举例如下

#include <iostream>int main() {int a = 22;int b = 33;int c = 11;int&& ref = a + b + c;std::cout << "a: " << a << std::endl;std::cout << "b: " << b << std::endl;std::cout << "c: " << c<< std::endl;std::cout << "ref: " << ref << std::endl;ref += 66;std::cout << "a: " << a << std::endl;std::cout << "b: "<< b << std::endl;std::cout << "c: " << c << std::endl;std::cout << "ref: " << ref << std::endl;return 0;
}

编译后执行,结果如下

$ g++ u0701_2.cpp -std=c++0x
$./a.out 复制代码
答:22
乙:33
額: 11
参考:66
答:22
乙:33
額: 11
参考:132
$

列举

列举是一组整数常数,例如

#include <iostream>int main() {enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};std::cout << "Sunday: " << Sunday << std::endl;std::cout << "Monday: " << Monday << std::endl;std::cout << "Tuesday: " << Tuesday << std::endl;std::cout << "Wednesday: " << Wednesday << std::endl;std::cout << "Thursday: " << Thursday << std::endl;std::cout << "Friday: " << Friday << std::endl;std::cout << "Saturday: " << Saturday << std::endl;Day today = Wednesday;std::cout << today << std::endl;return 0;
}

第4 行,定义一个列举型态Day,使用关键字(keyword) enum,后面接着型态名称Day,然后大括弧中是列举的识别字(identifier) ,这被称为非作用域列举(unscoped enumeration )

enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

列举常数为从0开始递增的整数常数数列,因此第30 行宣告的today亦为整数常数,Wednesday是第4 个值,所以是整数3

Day today = Wednesday;

编译执行,结果如下

$ g++ u0702_1.cpp
$./a.out 复制代码
周日:0
星期一:1
星期二:2
星期三:3
星期四:4
周五:5
星期六:6
今天:3
$

列举也可以匿名(anonymous) 与指定起始整数,例如

#include <iostream>int main() {enum {apple, banana = 11, orange, peach = 5};std::cout << "apple: " << apple << std::endl;std::cout << "banana: " << banana << std::endl;std::cout << "orange: " << orange << std::endl;std::cout << "peach: " << peach << std::endl;return 0;
}

此例的列举没有识别字,另外将banana设定为11,因此orange就由11递增为12,最后的peach则设定为5

enum {apple, banana = 11, orange, peach = 5};

编译后执行,结果如下

$ g++ u0702_2.cpp
$./a.out 复制代码
苹果:0
香蕉:11
橙色:12
桃子:5
$

列举也可以跟struct或class一起宣告,形成作用域列举(scoped enumeration) ,例如

enum class Color {RED, GREEN, BLUE};

C++11 中,列举常数可以改用其他型态,此时要在列举识别字后面加上冒号及型态名称,举例如下

#include <iostream>enum class Color: char {RED = 'r',GREEN = 'g',BLUE = 'b',
};int main() {Color r;r = Color::RED;Color g;g = Color::GREEN;Color b;b = Color::BLUE;std::cout << "RED: " << static_cast<char>(r) << std::endl;std::cout << "GREEN: " << static_cast<char>(g) << std::endl;std::cout << "BLUE: " << static_cast<char>(b) << std::endl;return 0;
}

这里定义一个作用域列举,并且将列举常数的型态指定为char

enum class Color: char {RED = 'r',GREEN = 'g',BLUE = 'b',
};

编译后执行,结果如下

$ g++ u0702_3.cpp -std=c++0x
$./a.out 复制代码
红色:r
绿色:g
蓝色:b
$

指标

指标是储存记忆体位址(address) 的资料型态,例如

#include <iostream>int main() {int a = 22;int* a_ptr = &a;std::cout << "a_ptr: " << a_ptr << std::endl;std::cout << "*a_ptr: " << *a_ptr << std::endl;return 0;
}

第5 行,宣告指标的型态,必须与指标所指向的变数型态相同,然后在型态名称后使用* 运算子标明这是个指标变数,因此这个例子的参考变数为a_ptr,等号右边为所要指向的变数,此例为a,a之前的&则是取址运算子(address-of operator)

int* a_ptr = &a;

由于C++ 是自由格式的程式语言,因此写成int * a_ptrint *a_ptr都可以。

接下来先印出a_ptr的值,然后利用反参考运算子(dereference operator) *取得a_ptr所指向变数的值

std::cout << "a_ptr: " << a_ptr << std::endl;
std::cout << "*a_ptr: " << *a_ptr << std::endl;

编译后执行,结果如下

$ g++ u0704_1.cpp
$./a.out 复制代码
a_ptr:0x7fff50b81b08
*a_ptr: 22
$

注意,编译器(compiler) 会依据运算子出现的位置判断运算子的用途,例如

int* a_ptr; // 定义a_ptr为指标变数
int& a_ref; // 宣告 a_ref 为参考变数
a_ptr = &a; // & 为取地址侵犯子,取得一个的记忆体位址
*a_pr = 36; // * 为反参考进攻子,将设定为36

阵列识别字其实就是个指标,另外指标也可以作算术运算,例如

#include <iostream>int main() {int a[] = {1, 2, 3, 4, 5};std::cout << "a[2]: " << *(a + 2) << std::endl;std::cout << "a[4]: " << *(a + 4) << std::endl;return 0;
}

这里用阵列名称与反参考运算子取得元素,指标的算术运算如同阵列的索引值,由于阵列名称为第1 个元素索引值为0的记忆体位址,所以加2就是索引值为2的元素记忆体位址,也就是第3 个元素,加4就是索引值为4的元素记忆体位址,也就是第5 个元素

std::cout << "a[2]: " << *(a + 2) << std::endl;
std::cout << "a[4]: " << *(a + 4) << std::endl;

编译后执行,结果如下

$ g++ u0704_2.cpp
$./a.out 复制代码
a[2]: 3
a[4]: 5
$

事实上,所有指标都预设能隐性转换指向void,举例如下

#include <iostream>int main() {int n = 1;int* p = &n;void* p2 = p;int* p3 = static_cast<int*>(p2);std::cout << "n: " << n << std::endl;std::cout << "p: " << p << std::endl;std::cout << "*p3: " << *p3 << std::endl;return 0;
}

这里将指向int的指标重新指派给指向void的指标,转换回来要利用关键字 static_cast

int* p = &n;
void* p2 = p;
int* p3 = static_cast<int*>(p2);

编译后执行,结果如下

$ g++ u0704_3.cpp
$./a.out 复制代码
数量:1
p: 0x7fff55f89b18
*p3:1
$

C++11 新增一个关键字nullptr表示空的指标,等同于巨集NULL,举例如下

#include <iostream>int main() {int n = 22;std::cout << "n: " << n << std::endl;int* p = &n;std::cout << "p: " << p << std::endl;p = nullptr; // NULLstd::cout << "p: " << p << std::endl;return 0;
}

编译后执行,结果如下

$ g++ u0704_4.cpp
$./a.out 复制代码
人数:22
p: 0x7fff503acae8
p: 0x0
$

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/44688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GuLi商城-商品服务-API-品牌管理-OSS获取服务端签名(续)

如何进行服务端签名直传_对象存储(OSS)-阿里云帮助中心 gulimall-third-party服务的代码: package com.nanjing.gulimall.thirdparty.controller;import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.utils.BinaryUtil; impor…

Linux开发:Fuse介绍

Fuse(filesystem in userspace),是一个用户空间的文件系统。通过fuse内核模块的支持&#xff0c;开发者只需要根据fuse提供的接口实现具体的文件操作时所对应的回调函数&#xff0c;就可以实现一个文件系统。由于其主要实现代码位于用户空间中&#xff0c;因此不需要重新编译内…

实时数仓项目需求及架构设计

第2章实时数仓项目需求及架构设计 2.1 项目需求分析 1&#xff09;采集平台 ​ &#xff08;1&#xff09;用户行为数据采集平台搭建 ​ &#xff08;2&#xff09;业务数据采集平台搭建 2&#xff09;离线需求 … 2.2 项目框架 2.2.1 技术选型 ​ 技术选型主要因素&a…

15 - matlab m_map地学绘图工具基础函数 - 一些数据转换函数(二)

15 - matlab m_map地学绘图工具基础函数 - 一些数据转换函数&#xff08;二&#xff09; 0. 引言1. 关于m_geodesic2. 关于mygrid_sand23. 结语 0. 引言 通过前面篇节已经将m_map绘图工具中大多绘图有关的函数进行过介绍&#xff0c;已经能够满足基本的绘图需求&#xff0c;本节…

探索 `DatagramSocket` 类

DatagramSocket 类是 Java 网络编程中的一个关键组件&#xff0c;专门用于处理 UDP&#xff08;用户数据报协议&#xff09;通信。与基于连接的 TCP 不同&#xff0c;UDP 是一种无连接协议&#xff0c;适用于对速度和效率要求较高&#xff0c;但对可靠性要求相对较低的场景。 …

【JavaScript】包装类

包装类 JS 提供了三个主要的包装类&#xff1a;String、Number、Boolean。如果尝试把原始类型&#xff08;string、number、boolean&#xff09;数据当成对象使用&#xff0c;JS 会自动将其转换为对应包装类的实例。 我们先来看一下 “基本类型数据” 及 “其包装类的实例” …

个人倒计时页面源码,实用倒计时单页源码

一、源码描述 这是一款非常实用的个人倒计时页面&#xff0c;支持设置未来一年时间&#xff0c;支持设置背景音乐&#xff0c;支持自定义下拉页面&#xff0c;点击向下箭头查看。 二、源码截图 三、源码下载

docker 常用命令,后面不断更新

1.从Docker容器中下载文件到本地的方法 使用 docker cp 命令:该命令可以将文件或目录从容器复制到主机。该方法简单快捷&#xff0c;适用于少量文件的下载。 # 将容器名为my_container中的 /data/file.txt文件复制到本地/path/to/save/file.txt docker cp my_container:/data/…

深入探讨【C++容器适配器】:现代编程中的【Stack与Queue】的实现

目录 一、Stack&#xff08;栈&#xff09; 1.1 Stack的介绍 1.2 Stack的使用 1.3 Stack的模拟实现 二、Queue&#xff08;队列&#xff09; 2.1 Queue的介绍 2.2 Queue的使用 2.3 Queue的模拟实现 三、容器适配器 3.1 什么是适配器 3.2 为什么选择deque作为stack和…

kylin入门教程

Apache Kylin的入门教程主要涵盖以下几个方面&#xff1a; 一、Apache Kylin简介 Apache Kylin是一个开源的分布式分析引擎&#xff0c;提供Hadoop之上的SQL接口及多维分析&#xff08;OLAP&#xff09;能力以支持超大规模数据。最初由eBay Inc.开发并贡献至开源社区&#xf…

基于Vue和UCharts的前端组件化开发:实现高效、可维护的词云图与进度条组件

基于Vue和UCharts的前端组件化开发&#xff1a;实现高效、可维护的词云图与进度条组件 摘要 随着前端技术的迅速发展和业务场景的日益复杂&#xff0c;传统的整块应用开发方式已无法满足现代开发的需求。组件化开发作为一种有效的解决方案&#xff0c;能够将系统拆分为独立、…

Shell基础之函数和数组

目录 函数 什么是函数 函数的语法 函数的调用 函数的返回值 函数的案例 函数变量的作用域 递归函数 函数库文件 数组 定义数组语法 数组操作 获取所有元素 获取元素下标 获取数组长度 获取数组元素 数组添加元素 删除数组元素 删除数组 遍历数组元素 数组案…

解决pycharm无法识别miniconda

解决pycharm无法识别miniconda 找到miniconda安装目录下condabin/conda.bat文件&#xff0c;点击load即可识别codna环境 a环境

Spring Boot(七十九):SprngBoot整合Apache tika做文件类型检测

之前有一个章节介绍了Apache tika实现文档内容解析,地址如下:Spring Boot(六十八):SpringBoot 整合Apache tika 实现文档内容解析_springboot tika pptx-CSDN博客 下面我们介绍Apache tika实现文件类型检测 1 引入依赖 <dependency><groupId>org.apache.tika&…

Docker 挂载目录空间占满修改/var/lib/docker/overlay2 的路径解决方案

本文详细描述了在CentOS7系统中卸载旧版Docker、安装依赖、添加Docker源、配置存储路径并启动Docker&#xff0c;使其在/home目录下运行的过程。 以下是在CentOS 7下重新安装Docker并将其安装在/home/下的完整步骤&#xff1a; 卸载旧版本的Docker。如果您之前已经安装了Dock…

仕考网:没有学位证能考公务员吗?

公务员考试需要满足报名条件才能参加&#xff0c;没有学位证能考公吗? 没有学位证书的考生也有机会参与公务员考试虽然可以选择的岗位比较少&#xff0c;但可以报考参加那些不设定学位要求的岗位。当发布的公务员招录信息中某一职位的学位要求标注为“无要求”时&#xff0c;…

【C++】:继承[下篇](友元静态成员菱形继承菱形虚拟继承)

目录 一&#xff0c;继承与友元二&#xff0c;继承与静态成员三&#xff0c;复杂的菱形继承及菱形虚拟继承四&#xff0c;继承的总结和反思 点击跳转上一篇文章&#xff1a; 【C】&#xff1a;继承(定义&&赋值兼容转换&&作用域&&派生类的默认成员函数…

MATLAB Gazebo联合仿真

准备仿真环境&#xff1a;在Gazebo中设置仿真场景&#xff0c;包括机器人模型、环境布局、传感器和执行器等。编写MATLAB脚本&#xff1a;在MATLAB中编写控制算法和数据处理脚本&#xff0c;用于接收Gazebo中的传感器数据&#xff0c;并生成控制命令。建立通信&#xff1a;通过…

DEBUG:jeston卡 远程ssh编程

问题 jeston 打开网页 gpt都不方便 而且只需要敲命令就行 解决 下载MobaXterm(window执行) liunx需要虚拟机 软件 远程快速复制命令

PHP文字ocr识别接口示例、人工智能的发展

全球在人工智能升级的大背景下&#xff0c;有一定规模的制造商开始大量部署人工智能机器人、系统&#xff0c;以此取代危险、简单和重复性的工作。各种人工智能技术的迅猛发展&#xff0c;正在驱动各行业就业市场发现变革。 京东物流大家并不陌生&#xff0c;京东快递机器人在…