C/C++ 个人笔记

news2024/11/17 11:29:18

仅供个人复习,

C语言IO占位符表

%d十进制整数(int)
%ldlong
%lldlong long
%uunsigned int
%o八进制整型
%x十六进制整数/字符串地址
%c单个字符
%s字符串
%ffloat,默认保留6位
%lfdouble
%e科学计数法
%g根据大小自动选取f或e格式,去掉无效0

转义符表

转义符可以取消关键字符的特殊性,下面是常见的转义符使搭配

	printf("\b");//退格符
	printf("\n");//换行
	printf("\a");//响铃,电脑真的响一下,不可思议
	printf("\t");//水平制表符
	printf("\v");//垂直制表符
	printf("\130");//输出char对应130的字符
	printf("%% %d",12);//%的转义使用%,而不是\

C/C++ 语言数据类型大小

ANSI/ISO规范

sizeof(short int)<=sizeof(int)
sizeof(int)<=sizeof(long int) short
int至少应为16位(2字节)
long int至少应为32位。

16位编译器

数据类型字节数
char1
short2
int2
long4
float4
double8
bool1
指针2

32位编译器

数据类型字节数
char1
short2
int4
long4
long long8
float4
double8
bool1
long double12
指针4

64位编译器

数据类型字节数
char1
short2
int4
long8
long long8
float4
double8
bool1
long double16
指针8

宏函数和内联函数的区别

宏函数(Macro Functions):

  1. 替换规则:在编译预处理阶段的简单文本替换

  2. 参数展开:没有参数类型检查

  3. 适用场景:简单的、短小的代码片段,例如进行简单的数学计算、位操作等。

内联函数(Inline Functions):

  1. 替换规则:编译阶段处理。编译器会尝试将函数调用处直接替换为函数体。

  2. 参数类型检查:参数和返回值检查与正常函数无异

  3. 适用场景:内联函数适用于较短小的函数,包含一些简单的代码逻辑,且频繁调用的情况。

  4. 推荐用法:一般来说,内联函数应该是在类的定义中实现的,以便于对其进行封装和管理,或者在头文件中避免函数重定义问题。inline关键字只能建议编译器进行内联,是否采纳取决于编译器

内联函数可以优化函数进入和离开的开销,但内联可能会导致编译后的代码体积增大,宏函数的使用更需要小心,因为它在文本替换阶段可能会引发一些意想不到的问题。

差异案例

#include <iostream>

#define SQUARE_MACRO(x) x * x

inline int square_inline(int x) {
    return x * x;
}

int main() {
    int num = 5;
    // result = (++num) * (++num)   直接把参数替换进函数
    int result_macro = SQUARE_MACRO(++num); // 使用宏函数
    num = 5;
    //先自增再传入
    int result_inline = square_inline(++num); // 使用内联函数
	
    std::cout << "Number: " << num << std::endl;
    std::cout << "Result (Macro): " << result_macro << std::endl;
    std::cout << "Result (Inline): " << result_inline << std::endl;

    return 0;
}

在这里插入图片描述

STL标准库

vector

优点:

  • 内存是连续分配的,访问元素的速度较快。
  • 在末尾插入和删除元素的时间复杂度为常数。

缺点:

  • 在中间插入或删除元素的时间复杂度较高,需要移动后续元素。
  • 在内存不足时,可能会导致重新分配内存和复制元素。
#include <vector>

std::vector<int> v;

v.push_back(10); // 在末尾插入元素
v.pop_back();    // 删除末尾的元素
v.size();        // 返回容器中的元素数量
v.empty();       // 检查容器是否为空
v.clear();       // 清空容器中的所有元素
v.at(index);     // 访问指定索引的元素
v.front();       // 访问首元素
v.back();        // 访问末尾元素
v.begin();       // 返回指向容器第一个元素的迭代器
v.end();         // 返回指向容器最后一个元素之后的迭代器



list

优点:

  • 支持在任意位置快速插入和删除元素。
  • 在中间插入和删除元素的时间复杂度为常数。

缺点:

  • 元素在内存中不连续存储,访问元素的速度慢。
  • 占用更多内存,每个节点需要存储额外的指针。
#include <list>

std::list<int> lst;

lst.push_back(10); // 在末尾插入元素
lst.push_front(20); // 在开头插入元素
lst.pop_back();     // 删除末尾的元素
lst.pop_front();    // 删除开头的元素
lst.size();         // 返回容器中的元素数量
lst.empty();        // 检查容器是否为空
lst.clear();        // 清空容器中的所有元素
lst.front();        // 访问首元素
lst.back();         // 访问末尾元素
lst.begin();        // 返回指向容器第一个元素的迭代器
lst.end();          // 返回指向容器最后一个元素之后的迭代器

forawrd_list

与list类似,仅支持单向访问,效率更佳一些

#include <forward_list>
std::forward_list<T> fl;

fl.push_front(const value_type& value); // 在头部插入元素
fl.pop_front(); // 从头部删除元素
fl.insert_after(pos, const value_type& value); // 在指定位置后插入元素
fl.erase_after(pos); // 在指定位置后删除元素
fl.front(); // 访问第一个元素
fl.begin(); // 返回指向第一个元素的迭代器
fl.end(); // 返回指向最后一个元素之后的迭代器


deque

优点:

  • 支持在两端快速插入和删除元素。
  • 内存是分块分配的,访问元素的速度较快。

缺点:

  • 难以在中间插入或删除元素
  • 存储多个分块,占用较多内存
#include <deque>

std::deque<int> dq;

dq.push_back(10); // 在末尾插入元素
dq.push_front(20); // 在开头插入元素
dq.pop_back();     // 删除末尾的元素
dq.pop_front();    // 删除开头的元素
dq.size();         // 返回容器中的元素数量
dq.empty();        // 检查容器是否为空
dq.clear();        // 清空容器中的所有元素
dq.front();        // 访问首元素
dq.back();         // 访问末尾元素
dq.begin();        // 返回指向容器第一个元素的迭代器
dq.end();          // 返回指向容器最后一个元素之后的迭代器

map

优点:

  • 存储键值对,支持按键进行高效的查找和插入。
  • 根据键的顺序遍历元素。

缺点:

  • 内存使用较多,每个键值对都需要额外的内存存储键。
  • 没有连续存储,访问元素的速度相对较慢。
#include <map>

std::map<std::string, int> m;

m["one"] = 1; // 插入键值对
m["two"] = 2;
m.find(const key_type& k); // 查找键的位置
m.count(const key_type& k); // 计算具有特定键的元素数量
m.size(); // 返回容器中的键值对数量
m.empty(); // 检查容器是否为空
m.clear(); // 清空容器中的所有键值对
m.begin(); // 返回指向容器第一个键值对的迭代器
m.end(); // 返回指向容器最后一个键值对之后的迭代器

set

优点:

  • 存储唯一的元素,支持按值进行高效的查找和插入。

缺点:

  • 内存使用较多,每个元素都需要额外的内存存储。
  • 不连续存储,访问元素的速度相对较慢。
#include <set>

std::set<int> s;

s.insert(const value_type& val); // 插入元素
s.find(const key_type& k); // 查找元素
s.size(); // 返回容器中的元素数量
s.empty(); // 检查容器是否为空
s.clear(); // 清空容器中的所有元素
s.begin(); // 返回指向容器第一个元素的迭代器
s.end(); // 返回指向容器最后一个元素之后的迭代器

unordered_map (C++11)

优点:

  • 使用哈希表实现,支持快速的查找和插入操作,平均时间复杂度为常数。
  • 对于大数据集,查找效率高于std::map。

缺点:

  • 内存占用较高,需要存储哈希表和键值对。
  • 不保证元素的顺序。
#include <unordered_map>

std::unordered_map<std::string, int> um;

um["one"] = 1; // 插入键值对
um["two"] = 2;
um.find(const key_type& k); // 查找键的位置
um.count(const key_type& k); // 计算具有特定键的元素数量
um.size(); // 返回容器中的键值对数量
um.empty(); // 检查容器是否为空
um.clear(); // 清空容器中的所有键值对
um.begin(); // 返回指向容器第一个键值对的迭代器
um.end(); // 返回指向容器最后一个键值对之后的迭代器

unordered_set (C++11)

优点:

  • 使用哈希表进行实现,支持快速的查找和插入操作,平均时间复杂度为常数。
  • 对于大数据集,查找效率高于std::set。

缺点:

  • 内存占用较高,因为需要存储哈希表和元素。
  • 不保证元素的顺序。
#include <unordered_set>

std::unordered_set<int> us;

us.insert(const value_type& val); // 插入元素
us.find(const key_type& k); // 查找元素
us.size(); // 返回容器中的元素数量
us.empty(); // 检查容器是否为空
us.clear(); // 清空容器中的所有元素
us.begin(); // 返回指向容器第一个元素的迭代器
us.end(); // 返回指向容器最后一个元素之后的迭代器

stack

#include <stack>

std::stack<T> s;

s.push(const value_type& value); // 将元素压入堆栈顶部
s.pop(); // 弹出堆栈顶部的元素
s.top(); // 访问堆栈顶部的元素
s.empty(); // 检查堆栈是否为空
s.size(); // 返回堆栈中元素的数量

queue

#include <queue>

std::queue<T> q;

q.push(const value_type& value); // 将元素推入队列尾部
q.pop(); // 从队列头部弹出元素
q.front(); // 访问队列头部元素
q.back(); // 访问队列尾部元素
q.empty(); // 检查队列是否为空
q.size(); // 返回队列中元素的数量

priority_queue

#include <queue>

std::priority_queue<T> pq;

pq.push(const value_type& value); // 将元素推入优先队列
pq.pop(); // 从优先队列中弹出元素
pq.top(); // 访问优先队列中优先级最高的元素
pq.empty(); // 检查优先队列是否为空
pq.size(); // 返回优先队列中元素的数量

#include <iostream>
#include <queue>
#include <vector>

struct MyStruct {
    int value;
    // 比较操作符,根据 value 来比较 ,越大优先级越高
    bool operator<(const MyStruct& other) const {
        return value < other.value;
    }
};

int main() {
    std::priority_queue<MyStruct> pq;

    pq.push({5});
    pq.push({2});
    pq.push({8});
    pq.push({1});

    // 遍历优先队列按优先级输出
    while (!pq.empty()) {
        std::cout << pq.top().value << " ";
        pq.pop();
    }

    return 0;
}
// 8 5 2 1

构造函数执行顺序

  • 先成员的构造,再当前类型的构造
  • 父类构造优先于子类构造
  • 成员初始化按书写顺序,低于构造顺序
  • 虚基类只构造一次,非虚构造两次

例题:问输出结果是多少

#include <iostream>

class A {
public:
    A() {
        std::cout << "A Constructor" << std::endl;
    }
};

class B : public A {
public:
    B() {
        std::cout << "B Constructor" << std::endl;
    }
};

class C : public A {
public:
    C() {
        std::cout << "C Constructor" << std::endl;
    }
};

class D : public B, public C {
public:
    D() {
        std::cout << "D Constructor" << std::endl;
    }
};

int main() {
    D d;
    return 0;
}

在这里插入图片描述

智能指针

  • std::shared_ptr:允许多个智能指针共享同一个对象,通过引用计数来管理对象的生命周期。当最后一个引用被释放时,对象会被销毁。
auto sp = std::make_shared<int>(); // 分配堆空间,创建智能指针
auto sp2 = sp; // 创建另一个智能指针 
  • std::unique_ptr:用于独占地拥有一个对象,不能被多个智能指针共享。它提供了更轻量级的智能指针,适用于不需要共享所有权的情况。

  • std::weak_ptr:用于解决std::shared_ptr的循环引用问题。它可以与std::shared_ptr一起使用,但不会增加对象的引用计数。

今天到这里,改日再更

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

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

相关文章

epoll() 多路复用 和 两种工作模式

1.epoll API 介绍 typedef union epoll_data {void *ptr;int fd;uint32_t u32;uint64_t u64; } epoll_data_t;struct epoll_event {uint32_t events; /* Epoll events */epoll_data_t data; /* User data variable */ };常见的Epoll检测事件&#xff1a;- EPOLLIN- EPOLLOUT- …

C#---第十九课:不同类型方法的执行顺序(new / virtual / common / override)

本文介绍不同类型的方法&#xff0c;在代码中的执行顺序问题&#xff1a; 构造方法普通方法&#xff08;暂用common代替&#xff09;、虚方法&#xff08;Virtual修饰&#xff09;、New方法&#xff08;new修饰&#xff09;三个优先级相同overide方法&#xff08;会替换virtual…

Arduino驱动TEMT6000传感器(光照传感器篇)

目录 1、传感器特性 2、硬件原理图 3、驱动程序 TEMT6000是一个三极管类型的光敏传感器,其光照强度和基极的电流成正比。用起来也相当简单,可以简单的连接该传感器的基极到模拟电压输入,通过简单的检测电压值就可以判断当前的光照强度。 1、

基于Linux操作系统的keepalived双机热备和keepalived+lvs(DR)基本配置操作

目录 keepalived双机热备 一、概述 &#xff08;一&#xff09;具体工作原理如下&#xff1a; &#xff08;二&#xff09;实验拓补 二、安装NFS、配置 1、第一台机器配置&#xff1a;NFS &#xff1a;192.168.11.101 2、更改配置文件 3、安装NFS进行目录共享 4、编辑…

花5分钟判断,你的Jmeter技能是大佬还是小白!

jmeter 这个工具既可以做接口的功能测试&#xff0c;也可以做自动化测试&#xff0c;还可以做性能测试&#xff0c;其主要用途就是用于性能测试。但是&#xff0c;有些公司和个人&#xff0c;就想用 jmeter 来做接口自动化测试。 你有没有想过呢&#xff1f; 下面我就给大家讲…

C# textBox1.Text=““与textBox1.Clear()的区别

一、区别 textbox.Text "" 和 textbox.Clear() 都可以用于清空文本框的内容&#xff0c;但它们之间有一些细微的区别。 textbox.Text "": 这种方式会将文本框的 Text 属性直接设置为空字符串。这样会立即清除文本框的内容&#xff0c;并将文本框显示为空…

git 基础入门

Git基础入门 Git是一个分布式 版本管理系统&#xff0c;用于跟踪文件的变化和协同开发。 版本管理&#xff1a;理解成档案馆&#xff0c;记录开发阶段各个版本 分布式&集中式 分布式每个人都有一个档案馆&#xff0c;集中式只有一个档案馆。分布式每人可以管理自己的档案…

ThinkPHP 验证码扩展库的使用,以及多应用模式下,如何自定义验证码校验规则

ThinkPHP 验证码扩展库的使用&#xff0c;以及多应用模式下&#xff0c;如何自定义验证码校验规则 一、安装二、页面使用三、验证码相关配置属性1. 自定义验证码配置2. 自定义验证码&#xff08;一&#xff09;普通验证码3. 自定义验证码&#xff08;二&#xff09;算数验证码4…

搭建web网站

1.基于域名www.openlab.com可以访问网站内容为welcome to openlab!!! (1).安装所需软件HTTPD、mod_ssl [rootserver ~]# yum install httpd mod_ssl -y 添加域名映射&#xff1a;vim /etc/hosts (2)创建网站目录及网页&#xff0c;修改主配置文件新建openlab目录网站 配置文…

第二届828 B2B企业节启动,华为云携手上万伙伴共筑企业应用一站购平台

当前&#xff0c;数字技术与实体经济深度融合&#xff0c;为千行百业注入新动力、拓展新空间。数据显示&#xff0c;2022年中国数字经济规模超过50万亿&#xff0c;占GDP比重超过40%&#xff0c;继续保持在10%的高位增长速度&#xff0c;成为稳定经济增长的关键动力。 为加速企…

DevOps系列文章之 Python基础

列表 Python中的列表类似于C语言中的数组的概念&#xff0c;列表由内部的元素组成&#xff0c;元素可以是任何对象 Python中的列表是可变的 简单的理解就是&#xff1a;被初始化的列表&#xff0c;可以通过列表的API接口对列表的元素进行增删改查 1、定义列表 1.可以将列表当成…

网络模型分析

# 用户空间和内核空间 # 阻塞IO # 非阻塞IO # IO多路复用 IO多路复用-select 内核中遍历找到就绪的fd并保留&#xff0c;不匹配的就置为0&#xff0c; 以上的操作重复&#xff0c;知道所有的FD都完成 IO多路复用-poll IO多路复用-epoll IO多路复用-事件通知机制 很多进程都要用…

WebGL非矩阵变换

目录 平移 示例代码&#xff1a; 齐次坐标矢量的最后一个分量w 旋转 p的坐标&#xff0c;可得等式 R1&#xff1a; 使用r、α、β来表示点p的坐标&#xff0c;可得等式 R2&#xff1a; 利用三角函数两角和公式&#xff0c;可得等式 R3&#xff1a; 最后&#xff0c;将…

8.27周报

文章目录 前言论文阅读摘要介绍模型算法 总结 前言 本周学习了GAN论文《Generative Adversarial Nets》&#xff0c;了解GAN主要由两部分组成&#xff1a;生成器和判别器&#xff0c;知道生成器G和判别器D的作用及原理&#xff0c;相比于其他的生成模型&#xff0c;了解GAN的优…

【java】【项目实战】[外卖六]套餐管理业务开发

目录 一、新增套餐 1 需求分析 2 数据模型 3 代码实现 3.1 实体类SetmealDish 3.2 SetmealDto 3.3 SetmealDishMapper 3.4 SetmealDishService 3.5 SetmealDishServiceImpl 3.6 SetmealController 3.7 DishController 3.8 SetmealService 3.9 SetmealServiceImp…

4.21 用了 TCP 协议,数据一定不会丢吗?

目录 数据包的发送流程: 建立连接时丢包 流量控制丢包 网卡丢包 RingBuffer过小导致丢包 网卡性能不足 接收缓冲区丢包 两端之间的网络丢包 ping命令查看丢包&#xff1a; mtr命令&#xff1a; 发生丢包了怎么办 用了TCP协议就一定不会丢包吗​编辑 这类丢包问题怎…

Mysql--技术文档--基本概念--《世界上最流行的关系型数据库之一》

官方网址 MySQL 阿丹&#xff1a; 作为关系型数据库管理的老大哥&#xff0c;一个合格的程序员多多少少一定要了解mysql库。 官方解释 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管…

浙大MBA冲刺上岸经验分享:紧急备战的大龄考生

前些天我在朋友圈分享了一组我们前段时间在浙大开学前同学聚会的照片。结果&#xff0c;许多朋友都开始询问与浙大有关的情况&#xff0c;并且他们最关心的问题集中在以下几点&#xff1a;我去年备考花费了多少时间&#xff1f;要不要报班学习&#xff1f;现在开始备考还有机会…

postman-使用Postman的模拟服务来模拟(mock)后端数据,完成前端模拟API调用

最近项目上比较忙&#xff0c;任务多时间紧&#xff0c;导致后端开发任务繁多&#xff0c;无法及时开发完毕&#xff0c;但是前端同学已经把对应功能开发完成&#xff0c;需要进行前后端联调来验证API及一些交互问题&#xff1b;这不能因为后端的进度来影响前端的工作完成情况&…

c++ 判断基类指针指向的真实对象类型

在 c 面向对象使用中&#xff0c;我们常常会定义一个基类类型的指针&#xff0c;在运行过程中&#xff0c;这个指针可能指向一个基类类型的对象&#xff0c;也可能指向的是其子类类型的对象&#xff0c;那现在问题来了&#xff0c;我们如何去判断这个指针到底执行了一个什么类型…