
@Shadow
记录C/C++学习 后续学Linux
偶遇明师指导
长期写作
连更大王
本文章旨在记录C/C++学习过程中遇到的疑难杂症知识点很杂但尽可能的清晰(强烈建议读者收藏)
目录
2/2.行缓冲(不同编译器优化程度不同,显示可能以下不符合描述)
1.编译时的注释替换:
编译时注释会被替换为一个空格
如:integral/*wa bi ba bu*/type 编译后→integral type
1.1占位忽略符:%*c %*d等
图解
输入:1 2 3

※2编译与链接
2.1汇编语言还是反汇编语言?
int a = 10;
00007FF7470D1ACE mov dword ptr [a],0Ah
int& b = a; //!!!!!!!!!!!!!!!!!!!!!!!!!
00007FF7470D1AD5 lea rax,[a] //引用位于寄存器(一般位于栈中 具体位置还要看编译器)。
//!!!!!!!!!!!!!!!!!!!!!!!!!
00007FF7470D1AD9 mov qword ptr [b],rax
答:这是汇编语言。来自于微软Visual的编译器,是机器码经过反汇编生成的汇编指令。
↓
生成方式
2.2程序的编译链接过程
预处理————编译——————汇编—————————链接————————执行——
文本替换 转换为汇编语言 将汇编代码转换为机器指令 多个目标文件的合并 …………
语法语义检查 二进制形式不可读 函数定位函数间连接
优化
3.数据类型值(根据不同情景可能变化)
| signed char | SCHAR_MIN | |
| short | SHRT_MIN | |
| int | INT_MIN | |
| long | LONG_MIN | |
| long long | LLONG_MIN | |
| float | FLT_MIN | |
4.※scanf返回EOF与0与非零
scanf的返回值取决于scanf成功读取了几个数据 //Ctrl+Z 表示什么都不输入
※do {……}while(); //其后的" ; "不要落下
5.#ifdef ………… #endif 的合理使用
#define USE_OVERLOADING 1 //此处的define控制是否调用全缺省重载构造函数
class Date
{
public:
#ifdef USE_OVERLOADING
// 全缺省的构造函数 //无参构造函数
Date();
//带参构造函数(与无参构成函数构成重载) 那么全缺省无法存在
Date(int year, int month, int day);
#else
Date(int year = 1900, int month = 1, int day = 1);
#endif //必须具备
};
6.解决竞赛中需求高io效率的的代码
主要是解决缓冲区的问题以提高效率:
ios_base::sync_with_stdio(false); //C++关联的C的绑定关系关闭
std::cin.tie(nullptr); //cin与其绑定关系关闭
std::cout.tie(nullptr); //cout与其所有绑定关系关闭
7.※C中NULL与C++中nullptr
1.C中NULL本质为0不是指针 在使用过程中可能会造成偏离。
2.而nullptr本质就是指针。
3.nullptr可以转化为其他任意类型的指针。
※4.使用nullptr可以避免类型转换的问题因为nullptr只能被隐式地转化为指针类型,而不能为整型。
8.C++中流提取运算符 << 流插入运算符 >>
由于缓冲区过于抽象理解其作用远远比理解其定义重要~
8.1缓冲区
8.1.1作用:
暂存数据-集合输出——提高效率!!
1/2批量处理
***************************
没有缓冲区:每个字符都立即输出 (揭示了cout流插入运算符的本质)
***************************
cout << 'H';
cout << 'e';
cout << 'l';
cout << 'l';
cout << 'o';
// 每次都要系统调用,非常慢
// 有缓冲区:先存起来,一次性输出
cout << "Hello";
对于hello:
// 先存在缓冲区
// 遇到换行或缓冲区满才真正输出
// 一次系统调用就搞定,效率高
2/2.行缓冲(不同编译器优化程度不同,显示可能以下不符合描述)
#include <iostream>
using namespace std;
int main()
{
cout << "正在计算";
for (int i = 0; i < 5; i++)
{
cout << "."; // 这些点可能不会立即显示
// 模拟计算
for (int j = 0; j < 100000000; j++);
}
cout << "完成!" << endl; // 在执行完这一行后才一次性显示所有点
return 0;
}
8.1.2刷新缓冲区的目的:
保证数据的及时输出提高交互性。
前言:在执行流提取运算符cin前如果有cout先刷新其缓冲区(使得内容显示在屏幕上)。
8.2"cin 于 cout有各自的i/o流"怎么解释?
前言:i/o流是什么?
#include <iostream>
using namespace std;
int main() {
cout << "输出到屏幕"; // cout 是输出流
cin >> x; // cin 是输入流
cerr << "错误信息"; // cerr 也是输出流(无缓冲)
clog << "日志信息"; // clog 也是输出流(有缓冲)
return 0;
}
1/3.二者相互独立的一面:
(1).cout于cin有各自的数据结构:
// 简化理解(实际更复杂)
struct istream { // cin 的类型
streambuf* rdbuf; // 输入缓冲区
// ...
};
struct ostream { // cout 的类型
streambuf* rdbuf; // 输出缓冲区
// ...
};
(2).cout于cin有独立的缓冲区:
int main() {
cout << "Hello"; // 数据进入 cout 的缓冲区
// cout 的缓冲区:['H','e','l','l','o']
int x;
cin >> x; // 数据进入 cin 的缓冲区
// cin 的缓冲区:['1','2','3','\n']
// 两个缓冲区是独立的,互不影响
return 0;
}
2/3.二者相互关联的一面:
原因:二者虽然缓冲区相互独立但是它们共享一个底层终端 所以需要配合
这种关联在C++咨询网址中也被体现:

翻译:cin与cout相互关联,这种关联体现于在cin执行前cout的流会被刷新——以显示在屏幕上。
int main() {
cout << "请输入:"; // 存在 cout 缓冲区
// 如果没有关联,这行可能还没显示
int x;
cin >> x; // cin 操作时,会先刷新 cout 缓冲区
// 确保上面的提示先显示出来
return 0;
}
3/3#include<algorithm>快排
#include<iostream>
#include<algorithm>
using namespace std;
bool mysort(int i, int j) { return i < j; }
int main()
{
int arr1[] = { 12,32,14,314,325,435,345 };
//默认升序 "mysort"可写可不写 若改为">"则降序
sort(arr1, arr1 + sizeof(arr1) / sizeof(arr1[0]), mysort);
int arr2[] = { 12,32,14,314,325,435,345 };
//降序
greater<int>l;
sort(arr2, arr2 + sizeof(arr2) / sizeof(arr2[0]), l);
return 0;
}
9.※区分:类作用限定符、域访问限定符
※类作用限定符:public private protected,"作用"体现在限制区域能否被访问。
域访问限定符"::" 内用于类名后访问内部成员。
10.类内常量的初始化与非全局函数的初始化:

10.1关于类名Date和对象名d1的使用:
| 对比项 | Date:: | d1. |
|---|---|---|
| 右侧 | 静态成员 | 非静态成员 |
| 本质 | 告诉编译器去类的静态区找 | 告诉编译器去对象的内存找 |
| 内存 | 不依赖具体对象,类只有一份 | 依赖具体对象,每个对象一份 |
11.运算符重载为全局函数与成员函数原因
如果你有以下疑问,那么这节可以解决你的问题:
1.赋值运算符为什么必须重载为成员函数?重载为全局函数会发生什么?
2.那为什么运算符,像"<"就可以重载为全局函数呢?
11.1对称性与非对称性
非赋值运算符的重载中(如对:比较运算符 )我们发现其运算符两侧的量的级别具有一致性原则。
而赋值运算符可能导致级别不同。
class Number {
int value;
public:
Number(int v = 0) : value(v) {}
int get() const { return value; }
};
************
✅ "<" 是对称操作:左右操作数地位平等
************
bool operator<(const Number& a, const Number& b) {
return a.get() < b.get();
}
*****************
❌ "=" 是非对称操作:左操作数被修改,右操作数只读
*****************
// Number& operator=(Number& lhs, const Number& rhs); // 不允许
11.2混合类型、类型隐式转换
比较运算符适合全局类型的关键在于其支持混合类型。
class Integer {
int value;
public:
Integer(int v = 0) : value(v) {}
// 转换为int
operator int() const { return value; }
};
// ✅ 全局函数可以处理多种组合
bool operator<(const Integer& i, int n) {
return i.value < n;
}
bool operator<(int n, const Integer& i) {
return n < i.value;
}
// 如果作为成员函数,只能处理一种情况:
// class Integer {
// public:
// bool operator<(int n) const { return value < n; } // Integer < int
// // 无法处理 int < Integer 的情况(除非加转换)
// };
同样的全局函数也支持了隐式类型的转换。
由此可见赋值运算符只能定义为全局函数的规定利大于弊。此外还有原因,因此赋值运算符规定只能重载为全局函数。
12.友元函数的类内定义格式:
#include <iostream>
using namespace std;
class Point
{
private:
int x, y;
public:
Point(int x = 0, int y = 0)
: x(x), y(y)
{}
// 友元函数在类内定义
friend void printPoint(const Point& p)
{
cout << "Point(" << p.x << ", " << p.y << ")" << endl;
// 可以直接访问私有成员 x, y
}
};
int main() {
Point p(10, 20);
****************************************
printPoint(p); // 直接调用,不需要通过对象
return 0;
}
13.赋值运算符要注重考虑的有:
1.参数是否加const。
2.返回是否为引用类型。
14.杂项
const定义常量可以类内初始化。
析构函数无参数。
本文到此结束,感谢观看。
不妨留下个赞是对我最大的支持
如果觉得有回顾意义不妨点个收藏 但收藏后一定要及时看哦~
&spm=1001.2101.3001.5002&articleId=158353259&d=1&t=3&u=e0e36f1aa70447ee9e5407ebccad6aa3)
13万+

被折叠的 条评论
为什么被折叠?



