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

news/2024/11/23 5:22:08/

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;elsecout << "当前书籍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.ppmy.cn/news/278378.html

相关文章

16、DMA直接存储区访问

0x01、DMA简介 DMA(Direct Memory Access)一直接存储器存取&#xff0c;是单片机的一个外设&#xff0c;它的主要功能是用来搬数据&#xff0c;但是不需要占用 CPU&#xff0c;即在传输数据的时候&#xff0c;CPU 可以于其他的事情&#xff0c;好像是多线程一样数据传输支持从…

JavaScript全解析——Ajax(下)

Ajax(下) ●http 传输协议 ○http(s) 协议规定了, 只能由前端主动发起 ○并且在传输的过程中, 只能传递 字符串 ●http 协议过程 1.建立连接 浏览器和服务器进行连接建立 基于 TCP/IP 协议的三次握手 2.发送请求 要求前端必须以 请求报文 的形式发送 报文由浏览器组装,…

相机靶面尺寸与镜头尺寸之间的选择关系

为保证画面整体的可应用性&#xff0c;选用镜头的像面尺寸应大于相机芯片的对角线尺寸&#xff08;以下简称靶面&#xff09;&#xff0c;否则会出现边缘暗角/黑角等情况&#xff0c;影响使用。 ———————————————— 版权声明&#xff1a;本文为博主「hackpig」…

工业相机的镜头接口知识介绍

工业相机的镜头接口知识介绍 物镜的接口尺寸是有国际标准的&#xff0c;共有三种接口型式&#xff0c;即F型、C型、CS型。F型接口是通用型接口&#xff0c;一般适用于焦距大于25mm的镜头&#xff1b;而当物镜的焦距约小于25mm时&#xff0c;因物镜的尺寸不大&#xff0c;便采用…

机器视觉工业相机和镜头选型

一、视野计算 1、倍率芯片尺寸&#xff08;靶面&#xff09;/视野----远心镜头选择 2、焦距倍率x相机高度&#xff08;工作距离&#xff09; 2、像素精度要求检查精度/&#xff08;3-5&#xff09;个像素 3、相机分辨率视野/像素精度 4、芯片尺寸&#xff08;靶面&#xff09;…

工业相机及镜头的相关概念与相机及镜头的选型

工业相机及镜头的相关概念与相机及镜头的选型 一、相机的主要参数 1.像素&#xff08;pixel&#xff09; ​ 像素是图像上的最小组成单元。图像由小方格即像素组成的&#xff0c;这些小方块都有一个明确的位置和被分配的色彩数值&#xff0c;小方格颜色和位置就决定该图像所…

工业相机、镜头、选型计算方式

1. 面阵相机和镜头选型 已知&#xff1a;被检测物体大小为AB,要求能够分辨率小于C&#xff0c;工作距离为D [1]相机选型步骤&#xff1a; (1). 相机的最低分辨率(AB)/(CC) &#xff0c; (2). 相机在选型时&#xff0c;最好缺陷的面积在3到5个像素以上&#xff0c;在选择相机时&…

视觉-相机、镜头选择

文章目录 成像系统模型机器视觉成像系统中的相关参数 镜头镜头技术参数镜头分辨率视场角景深接口 相机常用接口相机设置 相机/镜头选择流程 成像系统模型 机器视觉成像系统中的相关参数 视场&#xff1a;摄像头能观测到的最大范围 工作距离&#xff1a;镜头的下端到物体表面的…