c++ STL 与 C/C++知识

推荐:https://github.com/CyC2018/CS-Notes

一些STL

0. STL介绍

https://blog.csdn.net/m0_56051805/article/details/127131897

容器适配器(container adapter):

https://blog.csdn.net/weixin_57023347/article/details/119034017

空间配置器

https://blog.csdn.net/weixin_57023347/article/details/121207344

 

1. unordered_map

https://blog.csdn.net/weixin_45745854/article/details/122785542

2. 散列表

https://blog.csdn.net/weixin_47251999/article/details/113037111

3. vector

https://blog.csdn.net/wangzhening/article/details/124061904

4. string

https://blog.csdn.net/qq_42351880/article/details/90635883

字符串转int类型

https://www.techiedelight.com/zh/convert-string-to-int-cpp/

5. set

https://blog.csdn.net/qq_42185999/article/details/107031098

6. map

https://blog.csdn.net/forever__1234/article/details/89647975

7.Hashmap

https://blog.csdn.net/Misty_Rain_/article/details/122971817

8.list

https://blog.csdn.net/qq_44423388/article/details/126289452

9.deque

https://blog.csdn.net/mataojie/article/details/122310752

https://blog.csdn.net/weixin_45605541/article/details/122018739

deque<int> q;
q.push_back(3);
q.push_back(5);
q.push_back(7);
//  q.front() = 3   q.back() == 7 
// 3 5 7  

10.priority_queue

https://www.cnblogs.com/huashanqingzhu/p/11040390.html

11. C++迭代器失效的情况与解决方法

https://www.cnblogs.com/xiaohai123/p/16531415.html

 

 

来源:https://www.cnblogs.com/QG-whz/p/5152963.html

 

注意事项:

1. find 如果找到,返回值为对应的迭代器,找不到返回的是 end()。

2. end() 在vector、string里返回的是最后一个元素的下一个位置;而在map、set里返回的是最后一个值。

3. 在set中取最后一个元素时,*set.end() 的结果是set容器大小,尽量用rbegin()。

4.使用sort排序时,对map、pair这种是根据key和first来排序的。


一些操作

1. move() ------ 直接改变原对象所有权,不进行复制

https://blog.csdn.net/chengjian168/article/details/107809308

2.单调栈 ------ 求下一个更大的数

https://blog.csdn.net/nameofcsdn/article/details/113360679

样例:1 3 4 2  -> 找下一个更大的数

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums) {
        int len = nums.size();
        unordered_map<int, int> mp;
        stack<int> stk;
        vector<int> ans;
        for(int i = len-1; i >= 0; i--){
            while(!stk.empty() && nums[i] >= stk.top()){
                stk.pop();
            }
            mp[nums[i]] = stk.empty()? -1 : stk.top();
            stk.push(nums[i]);
        }
        for(int i = 0; i < len; i++)
            ans.push_back(mp[nums[i]]);
        return ans;
    }
};

..

 


一些算法技巧

1. 排序 ------ 桶排序、计数排序、基数排序

https://blog.csdn.net/qq_55624813/article/details/121316256

2. sort 递减排序与自定义排序

sort(score.begin(), score.end(), std::greater<>());

 

自定义排序

//作为sort函数的第三个参数的函数指针必须是全局函数指针或静态成员函数指针
//在力扣上刷题,如果有自定义比较函数的经历,一定了解非静态成员函数指针不能直接传递给std::sort

struct node {
	int a;
	string name;
};

//以全局函数的形式自定义排序函数
bool cmp(node x, node y) {
	return x.a < y.a;
}
sort(v.begin(), v.end(), cmp);


//以静态成员函数的形式自定义排序函数
class SNode {
public:
	//以静态成员函数的形式自定义排序函数,如果不加static,则会报错
	static bool cmp1(node x, node y) {
		return x.a < y.a;
	}
};

https://blog.csdn.net/weixin_45003868/article/details/124024557

 

3. 矩阵

对于一个行数为 ,列数为 ,行列下标都从 开始编号的二维数组,将其映射到一维:

   ( i, j ) i × n + j

 同样地,我们可以将整数 x 映射回其在矩阵中的下标,即

  i = x / n
  j = x % n
4. 后缀表达式​

https://blog.csdn.net/a8425/article/details/119253258

 


一些知识和c++特性

1. C++11新特性之nullptr

https://blog.csdn.net/weixin_43340455/article/details/124888946

2. 内存对齐

https://blog.csdn.net/qq_38289815/article/details/105746832

https://blog.csdn.net/weixin_40853073/article/details/81451792

3. pair

https://blog.csdn.net/sevenjoin/article/details/81937695

4. typedef

5. enum

6. const

https://blog.csdn.net/fuhanghang/article/details/124980382

7. constexpr

8. 类型转换

静态转换(static_cast)、动态转换(dynamic_cast)、常量转换(const_cast)

https://blog.csdn.net/u013250861/article/details/125229621

9. 结构体struct

10. 智能指针

11.  GC基本算法与C++ GC机制

12. new与malloc的区别

alloc()、malloc()、calloc()、realloc()区别及用法

https://blog.csdn.net/qq_32619837/article/details/89145778

13. c++内存空间布局

C语言代码内存空间布局:堆(heap)、栈(stack)、数据段(data段)、bss段、文本段(代码段)

14. 泛型编程--模板

15. 编译/运行时多态

16. C++异常机制

17. cv限定符

18. decltype类型说明符

19. C++11新特性之类型推导

20. C++11新特性之右值引用

 21. C++11新特性之lambda表达式

22. C语言中 # 和 ## 的用法

#可以将宏定义中的传入参数名转换为双引号括起来的参数名字符串,必须置于宏定义的参数名前;
##是将宏定义的多个形参转换成一个实际的参数名。

23. 关键字volatile

 
volatile 关键字用于告诉编译器当前变量是易变的,需要在每次使用时都从内存中重新获取值。它仅仅告诉编译器该变量是易变的,不应该使用寄存器来存储其值,但并不保证进程访问该变量的正确性,仍然需要考虑对多线程的并发安全问题,要遵循原子操作和加锁等操作。

使用场景:

1.并行设备的硬件寄存器(状态寄存器)

2.中断服务子程序会访问的变量

3.多线程应用中被几个任务共享的变量

24. 关键字extern

 
extern是C语言中的一个关键字,一般用在变量名前或函数名前,作用是用来说明“此变量/函数是在别处定义的,要在此处引用”,至少声明。不分配内存空间。

25. strlen与sizeof

1、strlen是库函数,用于计算字符串长度(),遇到\0结束。sizeof是关键字,以字节形式给出操作数存储大小。

2、strlen在运行期计算,sizeof在编译期计算。

 
不用sizeof如何求 int 占用的字节数?
#include <stdio.h>
#define Mysizeof(v) (char*)(&v+1)-(char*)&v
int main()
{
    int i;
    double f;
    double *q;
    printf("%d\r\n",Mysizeof(i));
    printf("%d\r\n",Mysizeof(f));
    printf("%d\r\n",Mysizeof(q));
    return 0 ;
}
4  8  8

(&a+1) - (&a):这里计算两个指针的差值,然而这个操作在 C 语言中是非法的,不能直接对两个指针进行减法运算,除非它们指向相同的数组。

为什么要转换成char*类型?

  在C语言中,指针的算术运算是根据指针的类型来执行的。指针运算的结果取决于指针指向的数据类型,因为不同数据类型可能占用不同的字节数。将指针转换为char*类型可以让指针算术按照字节为单位进行,而不会考虑数据类型的字节数。

 不用sizeof求电脑位数?
#include <iostream>
using namespace std;
int main() {
	void* a;
	void* b;
	int scope = (char*)&a - (char*)&b;
	cout << "&a:" << &a << endl;
	cout << "&b:" << &b << endl;
	cout << "scope:" << scope << endl;
	if(scope==8) {
		cout << "64bits" << endl;
	} else {
		cout << "32bits" << endl;
	}
}

26. struct 与 union 的区别

struct 和union是两个不同的复合结构,区别在于:

1、联合体共用一块地址空间,一个联合体变量的长度等于最长的成员长度;结构体不同成员放在不同的地址中,占用空间是累加的(考虑空间对齐);

2、对联合体不同成员赋值将会对他的其他成员重写,原来的成员的值就不存在了。对结构体的不同成员赋值是互不影响的。

27. 短路求值

 https://blog.csdn.net/shanhejieshiwo/article/details/118544726

 && 和 || 运算符,先计算左操作数,如果为假,则 && 直接返回假,这种行为称为短路求值。
位操作符 & 和 |  不是,会全部计算。

28. C语言是怎么进行函数调用的

大多数的CPU的程序是通过栈来实现函数调用的,栈是被用于传递函数参数,存储返回信息,临时保存寄存器原有的值以备恢复以及用来存储局部变量的。

函数调用操作所使用的栈部分叫做栈帧结构,每个函数调用都有自己的栈帧结构,栈帧结构由两个指针指定,帧指针(指向起始),栈指针(指向栈顶),函数对于大多数数据的访问都是基于栈指针的。

参数列表实例化是从右向左
 
但是有个问题:
#include <iostream>
using namespace std;
int main() {
	int p=0;
	printf("%d %d  %d\n",p++,++p,p++); 
}
我的编译器输出是2 3 0,但按理应该是2 2 0。可能是编译器的问题?

29. 编译过程

1. 预编译阶段:gcc -E main.c -o main.i

  预编译阶段主要:

  • 删除#define,并做文本替换;
  • 递归展开头文件;
  • 处理以#开头的预编译指令;
  • 删除注释部分;
  • 添加行号和文件标识;
  • 保留#pragma指令,供给编译器

2. 编译阶段:gcc -S main.i -o main.s

  • 词法分析;
  • 语法分析;
  • 语义分析;
  • 代码优化;
  • 生成汇编指令

3.汇编阶段:gcc -c main.s -o main.o

  将汇编语言翻译成机器语言

4.链接阶段:gcc -o main.o main

链接阶段主要做汇编阶段未做的事情:
(1)强弱符号的处理;
(2)外部符号的处理;
(3)指令段中虚假地址和虚假偏移的处理;
(4)符号的重定位
 

30. #include<filename.h>和#include “filename.h”区别

#include<filename.h>是从标准库路径开始搜索

#include“filename.h”是先从工作路径开始搜索,再从标准库路径开始搜索

31. 静态链接和动态链接的联系与区别

动态库

1、链接时不复制,程序运行由系统动态加载到内存中,只加载一次;

2、加载速度比静态链接慢

3、发布程序需要提供依赖的动态库

静态库

1、静态库被打包在程序中,加载速度快

2、程序发布无需提供静态库,因为静态库已经包含在程序中

3、更新,发布麻烦,存在冗余拷贝;

32. c语言attribute关键字

  GNU C编译器增加了一个__attribute__ 关键字用来声明一个函数、变量或类型的特殊属性。申明这些属性主要用途就是指导编译程序进行特定方面的优化或代码检查。

  让函数在main函数之前运行

#include <stdio.h>
void before() _attribute_((constructor));
void after() _attribute_((destructor));
 
void before(){
    printf("this is function %s\n",_func_);
    return;
}
 
void after(){
    printf("this is function %s\n",_func_);
    return;
}
 
int main(){
 
printf("this is function %s\n",_func_);
    return 0;
 
}
//输出结果
//this is function before
//this is function main
//this is function after
 
33. 
 
 
 
 
 
 
 
 
 
 
 

甚至有一些QT

1. QT信号槽机制

 
 
 
 

还有I/O复用

1. I/O多路复用

 

2. 文件描述符

 
 

数据结构

1. AVL树

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2022-11-16 19:42  莫莫君不恋爱  阅读(44)  评论(0编辑  收藏  举报