Cpp 类型转换
关于C++的类型转换的整理笔记,主要关注C++相比于C语言多的部分,而且讨论的范围比较简单,不关注涉及到右值引用的类型转换。 概述 C++基本继承了C语言的类型转换规则,但是对类型转换的处理有很多区别,例如: 对于C语言,隐式转换和显式转换并没有太多区别,仅仅是危险的隐式转换可能会发出警告,使用显式转换会消除警告。 对于C++,安全的隐式转换可以通过编译,但是危险的隐式转换无法通过编译,必须使用显式转换才能顺利编译,C语言风格或C++风格的显式转换均可。 此外,C++相对于C语言还需要考虑很多很多额外的内容,我们将主要关注面向对象的部分,即自定义类型之间的类型转换,以及新加入的四个显式的强制类型转换关键词的使用 const_cast reinterpret_cast static_cast dynamic_cast 现代 C++ 不建议这么做: 避免使用C语言中常用的void *类型,C++提供了更好的工具; 避免使用C语言风格的显式类型转换,可读性太差,不利于后期检查。 现代 C++...
C语言类型转换
...
Cpp 函数参数默认值
C语言不支持函数重载,也不支持函数参数的默认值,这既可以说体现了C语言的简陋,也可以说是避免了很多麻烦。 C++的函数参数支持默认值的机制就比较烦人,因此需要整理一下。 为了提高代码的可读性,C++尽量也不要使用函数默认值,在讨论的最后提供了几种简单的方式可以替代。 基础 C++支持给函数参数提供默认值,例如 12345678910void func(int a, int b=1){ ...}int main(){ func(1,2); func(3); // == func(3,1), a=3,b=1 return 0;} C++要求参数的默认值必须从右向左连续地提供,保证无默认值的参数不能出现在有默认值的参数的右侧,否则编译器无法判断参数缺省时的对应关系,这是语法错误,例如 1234567void func(int a, int b=1, int c){ // compile error ...}void func(int a, int b=1, int c=2){ //...
Cloudreve个人云盘搭建
记录一下Cloudreve云盘的搭建。 概述 Cloudreve云盘的优点: 颜值可以; 部署很简单,连docker都不需要(还没鼓捣清楚docker),数据库之类的不用管,傻瓜式操作即可。 缺点: 功能比较简单,没什么插件扩展(其实也不需要); 部分开源,有一个付费的版本包含更多功能,社区环境不太友好; 只支持网页端和ios的app,不支持Windows和安卓(也不需要,因为有的开源网盘就算提供了app,UI也很简陋) 本地部署 Linux下直接下载压缩包到合适位置,解压执行即可完成本地部署,目前放置在~/cloudreve/目录下。 12345678#解压获取到的主程序tar -zxvf cloudreve_VERSION_OS_ARCH.tar.gz# 赋予执行权限chmod +x ./cloudreve# 启动...
C语言 数组和指针笔记
虽然在C++中完全不需要处理C语言中原始数组和原始指针等,C++提供了很多更好的替代实现,但是还是顺手整理一下吧。 在本文中的代码会涉及到几个运算符优先级的细节,这里备注一下: 数组取下标([])的优先级高于解引用(*)和取地址(&); 解引用(*)和取地址(&)的优先级相同,连续出现时,按照从右到左结合; 解引用(*)和取地址(&)是互逆的,因此连续出现时(&*和*&)直接抵消。 数组基础 一维数组 定义数组的语法很简单 1int a[5]; 此时变量a的类型是int [5]。 在定义时可以赋初值,此时可以省略数组长度,长度会通过初值个数自动获取,例如 1int a[] = {1,2,3,4,5}; 如果同时提供了数组长度和初值,那么数组长度必须大于等于提供的初值个数(否则报错),此时会对数组元素从前到后赋初值,剩余的元素会被初始化为0,例如 1int a[3] = {1}; // a[0] = 1, a[1] = 0, a[2] =...
密码学笔记——AES算法
现在仔细学习整理一下对称加密算法的典型代表——AES算法,并进行C++实现。 算法结构 这里我们只考虑AES-128,即密钥是128bit 的具体算法。 对于输入的明文,首先经过某种扩充处理,保证长度是128bit 的整数倍,然后对明文进行分组,每一组128bit 即16个字节的数据,在具体算法描述中通常会按列拼接为一个\(4\times 4\)的字节矩阵,并称为状态矩阵。 对于每一个分组执行相同的加密处理得到密文,将每一组的密文拼接即可得到最终的密文。 我们主要考虑单个分组的处理,下面的明文以及密钥均为16个字节的数据, 记明文为\(P\),密钥为\(K\),密文为\(C\)。 首先我们要进行密钥的扩展,从16字节的原始密钥\(K\)经过某种扩展算法得到10个辅助密钥\(K_1,\dots,K_{10}\),每一个\(K_i\)均是16字节的,对应一个状态矩阵,记\(K_0 =...
密码学入门笔记
...
Cpp 结构化绑定 学习笔记
结构化绑定是C++17引入的一个重要的语法糖,可以让代码写得简洁不少,值得好好整理一下语法。 概述 结构化绑定(structured binding)是 C++17 标准引入的一项特性, 允许开发者在解包元组 (std::tuple)、std::pair、数组或自定义结构体等数据结构时, 将其中各个元素直接绑定到多个变量上,使得代码更加简洁易读。 基本用法 最基本的语法形如 1auto [a0,a1,a2] = data; 这一行语句可以对data进行结构化绑定,要求: 左侧必须使用auto开头(其实还可以加上const,&等修饰,这里暂不讨论,见下文) 左侧具体需要的变量个数由右侧数据决定。 a0等是合法的C++标识符,并且不能是已经定义过的标识符 结构化绑定过程中会自动用a0等作为标识符定义变量,将其依次对应data中的元素值。 假设data是一个具有三个元素的自定义结构体 12345struct Person { std::string name; int age; double...
Cpp std::tuple 学习笔记
关于C++元组 std::tuple 的整理笔记。 概述 std::tuple是一个非常重要的C++标准库模块,它是一个固定大小且类型安全的数据容器, 提供了一种将任意数量的不同类型元素有序地打包组合在一起的方式, 在某些原本需要临时定义结构体的场合可以用std::tuple替代,使得代码更加简洁。 std::tuple的最大特点是编译期运算,与元组相关的标准库函数的实现属于模板元编程的范畴。在模板元编程中,元组也是一个重要角色,因为元组在编译期既含有整数信息也含有类型信息。 事实上从C++11开始,标准库的<tuple>就提供了std::tuple,但是语法既繁琐又简陋,一些直观的语法是不支持的。 在后续的标准中对std::tuple的支持在不断完善,用法变得更加简洁。 在本文中主要涉及的是C++20标准支持的用法,部分语法在C++11标准下是编译不过的。 简单示例 下面提供一个基于std::tuple实现具有多个返回值的函数示例 12345678910111213141516171819202122#include <format>#include...