C++ Primer Plus第五版笔记(p51-100)

news2025/4/7 8:59:03

45
在这里插入图片描述

46 常量指针必须初始化
47 一条语句可以定义出不同类型的变量 int i=10, *p=&i,&r =i;
48 应该是int p 而不是int p
49 **表示指向指针的指针 p52
50 指针是对象,所以存在对于指针的引用
int *p;
int *&r=p;

51 在默认状态下 ,const对象只是在文件内部有效
52 只在一个文件中定义const 而在其他多个文件中声明并使用它:
唯一的解决办法是 对于const变量不管是声明还是定义都添加 extern 关键字,这样只需要定义一次就够了
file_1.cc定义并初始化一个常量: extern const int bufsize = fcn();
file_1.h头文件:extern const int buffSize ;//与file_1.cc中定义的buffSize是同一个

53 const 的引用 (对常量的引用) 不能修改他所绑定的对象
const int ci=1024;
const int &r1=ci;

54 常量可以引用常量和非常量,非常量只能引用非常量
55 初始化常量引用时允许用任意的表达式作为初始值 p55
56 double dval =3.14;
const int &ri=dval;

这里编译器创建了一个临时量对象
const int temp=dval; //由双精度浮点数生成一个临时的整型常量
const int &ri=temp; //让ri绑定这个临时常量
而非常量无法跨类引用!!

57 int i=42;
const int &r2 =i; //r2绑定对象i,但是不允许通过r2修改i的值
(常量引用非常量)

58 允许令一个指向常量的指针指向非常量
double dval =3.14;
const double *cptr =&dval;(指向常量的指针不能通过cptr改变对象的值)
59 const(指向常量对象) double *const(常量指针) pip =& pi(z指向常量对象的常量指针) p56

60 顶层const:指针本身是个常量 (不允许改变指针pi的值(地址))
底层const:指针所指向的对象是个常量 (允许改变指针pi的值(地址))

声明引用&的const都是底层const (所引用的对象是个常量)

const int ci =42; 顶层const (不允许改变ci的值)

61 考入和考出的对象必须拥有相同的底层const资格,或者两个对象的数据类型必须能够转换,一般来说,非常量可以转换为常量

62 常量拷贝给非常量是可以的,但是不能非常量引用常量

63 指向常量的指针可以指向指向非常量的指针,但是反过来不行

64
在这里插入图片描述

65 允许将变量声明为constexpr 类型以便由编译器来验证变量的值是否是一个常量表达式,声明为constexpr的值一定是一个常量,而且必须由常量表达式初始化 (C++11特性)

66 字面值类型: 算数类型,引用,指针

67 定义于函数体内的变量没有固定地址,不能使用constexpr ;而函数体外部的对象定义时的地址固定不变,可以使用constexpr
68
如果constexpr声明中如果定义了一个指针,那么constexpr只对指针有效,对于其所指向的对象无关
constexpr int * q =nullptr 相等于 int const * q 表示q是一个指向整数的常量指针(顶层const)

constexpr const int *p= &i; 顶层 底层

69 类型别名 typedef /using 变量别名是&

typedef double wages; //wages 是double的一个别名
typedef wages base , *p; //base是 double的另一个别名 p是double *的别名
using SI= int; //SI是int 的别名

这里注意 typedef char * pstring ;
const pstring cstr=0; cstr是指向char的常量指针
上面这句话不等于 const char * cstr =0; p61
这种理解是错误的 ,用到了pstring 其基本数据类型是指针, 而用char *重写过后,数据类型就变成了char ,*成为了声明符的一部分

70 让编译器分析表达式类型 auto (C++11 新特性)

使用auto 时一条语句只能有一个基本数据类型
auto i = 0 , *p=&i; //i为整数,p为整型指针

71 使用引用其实是在使用引用的对象,当引用参与初始化时,真正参与初始化的是引用对象的值
72 auto一般会忽略顶层const 而底层const 会被保留下来
73 auto 对常量对象取地址是一种底层const
74 不能为非常量引用绑定字面值,可以为常量引用绑定字面值

75 设置一个类型为 auto的引用时,初始值中的顶层常量属性任然保留。和往常一样,如果我们给初始值绑定一个引用,则此时的常量就不是顶层常量了。

76
在这里插入图片描述在这里插入图片描述在这里插入图片描述

77 使用decltype返回类型(c++11特性) 如果decltype使用的表达式是一个变量,那么decltype返回该变量的类型(包括顶层const以及引用在内)
p63
decltype(cj) x=0;

78 decltype®的结果是引用类型,如果想让结果是r所指的类型,那么可以把r作为表达式的一部分,如r+0,显然这个表达式的结果是一个具体值而不是引用
如果是解引用操作,那么decltype将得到引用类型 因此,decltype(*p)的结果类型是int &而不是int

79 decltype((variable))双层括号的结果永远是引用,而 devcltype(variable)的结果只有当变量本身就是一个引用的时候才是引用

80 类体后面可以紧跟变量名以示对该类型对象的定义,所以分号不能少
81 对象的定义 和类的定义 最好不要放在一起
82
在这里插入图片描述

83 2.41 习题复习

#include <iostream>
#include <string>
   
using namespace std;
class Sales_data {
friend std:: istream & operator >> (std::istream& , Sales_data&);
friend std:: ostream& operator <<(std::ostream&, const Sales_data&);
friend bool operator <(const Sales_data&, const Sales_data&);
friend bool operator==(const Sales_data&, const Sales_data&);
public:
	Sales_data() = default;
	Sales_data(const std::string& book) :bookNo(book) {}
	Sales_data(std::istream& is) { is >> *this; }
public:
	Sales_data& operator +=(const Sales_data&);
	std::string isbn() const { return bookNo; }
private:
	std::string bookNo;
	unsigned units_sold = 0;
	double sellingprice = 0;
	double saleprice = 0.0;
	double discount = 0.0;
};
inline bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{
	return lhs.isbn() == rhs.isbn();
}

Sales_data operator +(const Sales_data&, const Sales_data&);

inline bool operator == (const Sales_data& lhs, const Sales_data& rhs)
{
	return lhs.units_sold == rhs.units_sold && lhs.sellingprice == rhs.sellingprice && lhs.saleprice == rhs.saleprice && lhs.isbn() == rhs.isbn();
}

inline bool operator !=(const Sales_data& lhs, const Sales_data& rhs)
{
	return !(lhs == rhs);
}

Sales_data& Sales_data::operator+=(const Sales_data& rhs)
{
	units_sold += rhs.units_sold;
	saleprice = (rhs.saleprice * rhs.units_sold + saleprice * units_sold) / (rhs.units_sold + units_sold);
	if (sellingprice != 0)
	{
		discount = saleprice / sellingprice;
		return *this;
	}
}

Sales_data operator +(const Sales_data& lhs, const Sales_data& rhs)
{
	Sales_data ret(lhs);
	ret += rhs;
	return ret;
}

std::istream& operator>>(std::istream& in, Sales_data& s)
{
	in >> s.bookNo >> s.units_sold >> s.sellingprice >> s.saleprice;
	if (in && s.sellingprice != 0)
	{
		s.discount = s.saleprice / s.sellingprice;
	}
	else
	{
		s = Sales_data();
	}
	return in;
}
std:: ostream& operator <<(std::ostream& out, const Sales_data& s)
{
	out << s.isbn() << " " << s.units_sold << " " << s.sellingprice << " " << s.saleprice << " " << s.discount;
	return out;
}

int main()
{
	Sales_data book;
	cout << "请输入销售记录" << endl;
	while (cin >> book) {
		cout << "ISBN,售出本书,原始价格,实售价格,折扣为" << book << endl;
	}
	Sales_data trans1, trans2;
	cout << "请输入两条ISBN相同的销售记录" << endl;
	cin >> trans1 >> trans2;
	if (compareIsbn(trans1, trans2))
	{
		cout << "汇总信息:ISBN,售出本书,原始价格,实售价格,折扣为" << trans1 + trans2 << endl;
	}
	else
	{
		cout << "两条销售记录的ISBN不同" << endl;
	}
	Sales_data total, trans;
	cout << "请输入几条ISBN相同的销售记录" << endl;
	if (cin >> total) {
		while (cin >> trans)
		{
			if (compareIsbn(total, trans))
				total = total + trans;
			else
				cout << "当前书籍ISBN不同" << endl;
			    break;
		}
		cout << "有效汇总信息:ISBN,售出本数,原始价格,实售价格,折扣为" << total << endl;
	}
	else
	{
		std::cout << "没有数据" << endl;
		return -1;
	}
	int num = 1;
	cout << "请输入若干销售记录:" << endl;
	if (cin >> trans1) {
		while (cin >> trans2)
		{
			if (compareIsbn(trans1, trans2))
				num++;
			else
			{
				cout << trans1.isbn() << "共有" << num << "条销售记录" << endl;
				trans1 = trans2;
				num = 1;
			}
			cout << trans1.isbn() << "共有" << num << "条销售记录" << endl;
		}
	}
	else
	{
		cout << "没有数据" << endl;
		return -1;
	}
	return 0;
}

84 确保头文件多次包含还是能安全工作的常用技术是预处理器
预处理功能(头文件保护符)
#ifdef 当且仅当变量已定义为真
#ifndef 当且仅当变量未定义为真,一旦检查结果为真,则执行后续操作指导遇到#endif指令为止
85
如果后面再包含sales_data.h 那么#ifndef的检查结果为假,那么编译器将会忽略#ifndef到#endif 之间的部分

86 基于头文件中类的名字构建保护符的名字,以确保其唯一性,一般把预处理变量的名字全部大写

87 头文件即使还没有包含在任何其他头文件中,也应该设置保护符

88 const 对象一旦定义就无法再赋新值,所以必须初始化

89 #ifndef #define #endif

90 两种重要的标准库类型:string vector
91 用using 声明不需要后面专门使用前缀
using namespace::name;
每一个名字都需要单独的声明

92 头文件不应该包含using 声明,如果这样,每个使用该头文件的文件都会有这个声明,会产生一些不必要的名字冲突

93 六种初始化string 的方式

94 拷贝初始化和直接初始化:没有等号的是直接初始化

95 string的操作 p77

96 cin>>s //将string对象读入s,遇到空白停止
97 string 连续输入输出
98 使用getline函数读一行数,直到遇到换行符为止,

在这里插入图片描述

99 size_type是size函数返回的类型
s.size()<n如果n是负数,那么n会转化为一个比较大的无符号值

100 如果一条表达式中已经有了size()函数就不要使用int 了,这样可以避免混用int 和 unsigned 可能带来的问题
101 字符串之间比大小,先是比长度再是比第一对相异字符
102 当字符字面值和字符串字面值相加时,必须保证加号两边的运算对象其中一个是string类型(字符串字面值不是string对象)

103 string的输入运算符自动忽略开头的空白,从第一个真正的字符开始读起,知道遇到下一处空白为止
getline从输入流中读取数据,知道遇到换行符位置,换行符也被读进去,但是不会储存在最后的字符串中

104 cctype头文件 #include 函数和定义 p82
105 基于范围的for语句
想要改变对象中的字符值,必须把循环变量定义成引用类型
106 使用下标时,将下标的类型设为string::size_type 这个是个无符号数,所以不会小于0,只要让其小于size()就可以了

107 vector 是一个类模板 而 非类型
vector<vector > a c++11特性 后面要空一格
其中每个元素都是vector的对象

108 vector 初始化 对象 p88
109 push_back函数 p90
运用push_back给vector对象添加新元素

110 vector对象的高效增长 先定义一个空的vector对象,再在运行时向其中添加具体值(动态添加元素)

111 vector操作 p91

112 vector ::size_type 正确(必须指定它是由哪种类型定义的)
113 不是所有的vector对象都能互相比较
114 vector对象不能直接通过下表添加元素,必须使用push_back,下标运算只能用于访问已经存在的元素,而不能用来添加元素

在这里插入图片描述

115 遍历vector对象不同元素的每个字符

116 练习3.20
117 string 和 vector都支持迭代器(除了下标运算可以访问string对象的字符或vector对象的元素,也可以使用迭代器)
118 begin是负责返回指向第一个元素的迭代器
end是负责范围指向容器尾部元素的下一个位置(尾后迭代器)
如果容器为空begin和end同时返回同一个迭代器,都是尾后迭代器

119 如果两个迭代器指向的元素都是同一个容器的尾后迭代器,那么他们相等;否则不等
120 标准容器迭代器的运算符 p96
121 可以通过解引用迭代器来获得它所指示的元素
122 const_iterator iterator 是可以表示迭代器的类型,两者区别是后者可读可写,前者不可写(每个容器类定义了一个名为iterator的类型,该类型支持迭代器概念所规定的一套操作)

123 cbegin cend 是c++11新特性为了得到const_iterator类型的返回值(无论vector是否是常量)
124 (*it).empty() 解引用调用迭代器所指向类的成员函数 it->empty()也行
125 不能在范围for循环中向vector对象添加元素,改变vector容量的操作会使得vector对象的迭代器失效
凡是使用迭代器的循环体,都不要像迭代器所属的容器添加元素!

126 迭代器运算 p99-100
difference_type是带符号整型数,是两个迭代器距离的返回类型

127 二分搜索法 p100

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

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

相关文章

【教材】2022/11/27[指针] 指针与函数基础

程序&#xff1a;求10个数的最大数 1、定义指向函数的指针变量调用函数的方法 一般定义形式为&#xff1a;类型名 &#xff08;*指针变量名)()&#xff1b; #include<stdio.h> int main() {int i, m, a[10], max(int* p);int (*f)();for (i 0; i < 10; i)scanf_s(&q…

day7【代码随想录】移除链表元素

文章目录一、链表定义二、移除链表元素&#xff08;力扣203&#xff09;1、直接使用原来的链表来进行删除操作2、设置一个虚拟头结点在进行删除操作三、删除链表中的节点&#xff08;力扣237&#xff09;一、链表定义 public class ListNode {// 结点的值int val;// 下一个结点…

如何安装Jmeter监控服务器资源插件(JMeterPlugins + ServerAgent 方法二)?

一、服务器端插件 1、下载链接:https://pan.baidu.com/s/1Is1kuC656cB0mC4vOLHyhw?pwd12f1 提取码:12f1 &#xff08;或者这个下载服务器插件&#xff1a;ServerAgent 下载地址&#xff1a;https://github.com/undera/perfmon-agent&#xff09; 2、服务器端插件 将下载的Se…

Redis最全详解(一)——基础介绍

Redis介绍 redis是基于内存可持久化的日志型、Key-Value数据库。redis安装在磁盘&#xff0c;但是数据存储在内存。非关系型数据库NoSql。开源免费&#xff0c;遵守BSD协议&#xff0c;不用关注版权问题。 redis作者github&#xff1a;github.com/antirez redis是一种基于键…

【数字信号去噪】小波阙值数字信号去噪和求信噪比【含Matlab源码 2191期】

⛄一、小波阈值法去噪概述 电能质量扰动信号的噪声大多以高斯白噪声的形式存在&#xff0c;利用小波变换对信号进行多分辨率分解&#xff0c;由于小波变换具有去除数据相关性的特点&#xff0c;故可以将有用信号与噪声的能量分离开来。信号中有效的信息主要集中在较大的小波系…

[阶段4 企业开发进阶] 2. Redis--实战篇

文章目录实战篇1 短信登录1.1 导入项目导入SQL有关当前模型导入后端项目导入前端工程运行前端项目1.2 基于Session实现登录流程1.3 实现发送短信验证码功能1.4 实现登录校验拦截器1.5 隐藏用户敏感信息1.6 session共享问题实战篇 1 短信登录 1.1 导入项目 导入SQL 有关当前模…

多监控系统产生的告警如何高效管理 - 运维事件中心

随着互联网服务深入千行百业&#xff0c;数字化成为企业和机构为用户提供服务的重要形式。在企业的IT基础架构趋于复杂化的过程中&#xff0c;运维管理工作的技术性也有了更高的要求。如果针对相关的故障&#xff0c;企业无法做到及时的发现和响应&#xff0c;将会延长上层业务…

ElasticSearch中基础API操作

1:首先我们需要连接ElasticSearch客户端&#xff0c;需要一个连接操作&#xff1a; RestHighLevelClient package com.atguigu.es.test;import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient;…

分布式全局唯一ID生成方案(附源码)

1、概述 ID&#xff0c;全称Identifier&#xff0c;中文翻译为标识符&#xff0c;是用来唯一标识对象或记录的符号。比如我们每个人都有自己的身份证号&#xff0c;这个就是我们的标识符&#xff0c;有了这个唯一标识&#xff0c;就能快速识别出每一个人。 在计算机世界里&…

客快物流大数据项目(八十八):ClickHouse快速入门

文章目录 ClickHouse快速入门 一、​​​​​​​​​​​​​​安装ClickHouse&#xff08;单机&#xff09; 1、安装yum-utils工具包 2、添加ClickHouse的yum源 3、安装ClickHouse的服务端和客户端 4、关于安装的说明 5、查看ClickHouse的版本信息 二、在命令行中操作…

【深度思考】5年开发经验,不知道git rebase,是否应该被嘲笑?

最近逛脉脉&#xff0c;发现了一个热度挺高的帖子&#xff0c;一位同学发帖说&#xff1a;同事5年经验&#xff0c;竟然不知道git rebase&#xff0c;真牛批 ☆ 今天咱们不讨论git rebase是干什么用的&#xff0c;因为讨论半天可能三两句话就说出来了&#xff0c;实在没有意思&…

Linux的进程互调技术(多语言互调)

Linux的进程互调技术(多语言互调) 文章目录Linux的进程互调技术(多语言互调)1.函数与进程之间的相似性2.多语言程序互调技术1.函数与进程之间的相似性 如果你学过C语言&#xff0c;你应该有以下认识&#xff1a; 一个C程序由很多函数组成&#xff0c;一个函数可以调用另一个函数…

STC 51单片机42——汇编 定时器 舵机

ORG 0000H HighH EQU 30H; 定义变量&#xff0c;高电平高八位 TimerH EQU 31H; 定义变量&#xff0c;高电平高八位定时值 TimerL EQU 32H; 定义变量&#xff0c;高电平低八位定时值 Right BIT P2.0 ; 右转 Left BIT P2.1 ; 左转 N…

IDEA搭建SSM框架【配置类、新手向】

以下操作基于2020.3企业版 1.创建Java Enterprise项目 直接默认即可 输入项目相关信息 点击完成后&#xff0c;得到以下目录结构 2.搭建项目目录结构 java目录下 controller&#xff1a;实现控制转发&#xff0c;基本参数校验&#xff0c;不复杂的简单业务处理 config&#x…

SpringBoot实现多数据源(一)【普通版切换】

在实际开发中&#xff0c;经常可能遇到在一个应用中可能需要访问多个数据库的情况。以下是两种典型场景 业务复杂&#xff08;数据量大&#xff09; 数据分布在不同的数据库中&#xff0c;数据库拆了&#xff0c;应用没拆。一个公司多个子项目&#xff0c;各用各的数据库&#…

Springboot——拦截器

目录 一、拦截器概念 二、拦截器的使用 2.1 拦截器的创建&#xff08;preHandle实用性最强&#xff09; 2.2 将拦截器添加到容器当中 三、拦截器参数 3.1 获取请求头 request.getHeader 3.2 Object handler 是什么参数 3.3 ModelAndView modelAndView 3.4 Exception ex 3.…

多重定义的全局符号,链接器会如何链接的情况

多重定义的全局符号&#xff0c;链接器会如何链接的情况实例1&#xff1a;1.规则12.规则13.规则24.规则3实例2总结以下只针对于gcc编译器&#xff0c;而且不同环境&#xff0c;不同编译器的情况可能不同。 假如说有多重定义的全局符号&#xff0c;链接器会如何链接呐&#xff…

[论文评析]AdaptivePose: Human Parts as Adaptive Points,AAAI 2022

AdaptivePose: Human Parts as Adaptive Points文章信息背景AdaptivePose身体表示方法Body RepresentationAdaptivePosePart Perception ModuleEnhanced Center-aware BranchTwo-hop Regression BranchLoss function推理Inference总结References文章信息 论文题目&#xff1a;…

Spring Boot JPA 存储库派生查询示例

在之前的文章中&#xff0c;您已经知道如何使用JPQL和本机查询通过注释从数据库中检索数据。今天&#xff0c;我将向您展示如何使用派生查询方法在 Spring 引导中实现 Spring Data JPA 存储库查询&#xff1a;Query 派生查询方法的结构配置 Spring 引导应用程序以使用不同的数…

【教学类-19-02】20221127《ABCABC式-规律排序-A4竖版2份》(中班)

展示效果&#xff1a; 单人使用样式&#xff1a; 单页打印样式 ​ 背景需求&#xff1a; 中班幼儿需要掌握ABCABC的排序规律 ​ 前文制作了ABAB单元格色块&#xff0c;微调word表格的列数&#xff0c;调整python的参数&#xff0c;随机生成ABC排序样式&#xff0c;引导幼儿…