常用编程语言
本文列举并简要介绍了常用的编程语言,顺序参考TIOBE 排行榜,但是删除了作者从未使用过的部分语言。 本文主要包括通用编程语言(GPL,general-purpose language),不包括大部分领域特定语言(DSL,domain-specific language),例如在 bash,powershell 中使用的脚本语言,或者 CMake 也能算一门语言。当然,本文列举的数值计算领域的 MATLAB,Mathematica 严格来说也应该被归类为 DSL。 Python Python 是一种著名的胶水语言,脚本语言,学习门槛低,代码可读性很高。 Python 的运算效率很低,尤其是原生数组的运算和循环等。通常科学计算为了达到高效率,都会调用 Numpy 等库进行向量化操作,这些库主要基于 C/C++/Fortran。 Python 是机器学习,人工智能时代的宠儿,深度学习主要都是使用 Python 来搭建神经网络。(在投入实际生产,对速度有要求时可能会使用...
Cpp 单例模式
单例模式作为最简单但最常用的设计模式,整理一下 C++的相关语法吧。 单例模式简介 单例模式(Singleton Pattern),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例被构造,并提供一个访问它的全局访问接口,该实例被程序的所有模块共享。 大致的做法为: 定义一个单例类; 私有化构造函数,防止外界直接创建单例类的对象; 禁用拷贝构造,移动赋值等函数,可以私有化,也可以直接使用=delete; 使用一个公有的静态方法获取该实例; 确保在第一次调用之前该实例被构造。 在 C++中我们需要考虑: 在什么时机构造?程序一开始,第一次调用前? 如何构造这个实例?在堆上构造,还是通过静态变量?如果单例在堆上构造,是否存在内存泄漏? 实例构造失败会如何?抛异常?返回空指针? 通过接口返回指针还是引用? 线程安全?多线程下会不会重复构造?加锁? 我们暂时不考虑类的继承问题,以及需要给单例的构造传参数的问题。 关于构造时机的不同,有以下两种习惯的称呼: 饿汉模式(Eager Singleton),在程序启动后立刻构造单例; 懒汉模式(Lazy...
Cpp 基本数据类型
C/C++很烦人的一点在于,它最基本的数据类型都是不确定的,为了兼容某些奇怪的设备,C++标准并没有强制规定基本数据类型的位数,这可能导致很多 bug。 我们只考虑 64 位系统,考虑 x86-64 的 Windows/Linux 平台(32 位系统可能字节数更少,但是已经很少用了,本文不考虑)。 非常不建议使用整数类型long,以及浮点数类型long double,因为它们在不同的平台很可能位数不同。 整数类型 基本的整数类型大概有如下几种:(有符号类型,还有对应的无符号类型) char short (int) int long (int) long long (int) 注意:标准并没有严格规定它们的字节数大小,但是规定了字节数的大小关系(即表示范围的大小关系),以及它们至少需要的字节数。 1short <= int <= long <= long long 主要参考 cpp reference 和 wiki,下图取自cpp reference 上图中的 64 位数据模型包括 LP64(主要对应 Unix-like 平台)和 LLP64(主要对应...
Cpp 历史介绍与学习资源
C++历史和标准 简要回顾 C++的起源: 1979 年,Bjarne Stroustrup(C++之父)受到 Simula 语言(首个支持面向对象的语言)的启发,将面向对象的语法和 C 语言结合,得到了最早版本的"C with Classes",它提供面向对象的基本语法,然后先翻译成 C 的源码进一步进行处理。 1983 年,这个新语言正式被命名为 C++。许多重要的特性被加入,包括引用机制(符号为&)、虚函数、函数重载、const 关键字等。 1985 年,Stroustrup 的 C++参考手册《C++ Programming Language》出版,此时并没有 C++语法规范,只有这份参考手册。 1998 年,C++标准委员会发布了 C++语言的第一个国际标准:C++98。最早的标准模块库(Standard Template Library,STL)也被纳入了该版标准。 C++的主要标准: C++98: 第一个标准。 C++03: C++98 的修订版。 C++11: C++98之后最重要的一个标准,它带来了巨大的变革,此后的 C++称为 Modern...
Cpp练习——SafeInput获取安全的输入
概述 在学习 C/C++ 的一开始,我们就接触到基本的输入输出,例如printf/scanf或者cout/cin, 但是在涉及用户输入时总是存在可靠性问题:我们无法确保用户输入的信息是合法的,比如要求输入一个数字,但是用户提供的是一串字符串等等,或者要求数字满足一定范围等,我们只能每次手动在外层加一个循环和判断条件,非常繁琐。 在本文中实现了一个简单的获取安全输入的封装SafeInput,使得在编程中尽可能摆脱这类涉及用户输入参数的处理细节。 使用示例 指定获取一个int类型的值,要求大于 0 且小于 5,如果输入不满足要求,则会提示重新输入 12int s = SafeInput().get<int>("Please input a int in (0,5): ", [](int p) { return 0 < p && p < 5;...
Cpp练习——MTest测试框架(gtest的模仿实现)
主要参考了Google test(gtest)和知乎上的一篇文章qtest: 一个单元测试库的从头实现以及作者提供的代码,尤其是宏的部分。一直不喜欢也没有学明白宏的各种用法,但是实现这种风格的测试框架也绕不开宏。 在其基础上进行了整理和重构,并且扩展和完善了一些细节的功能。 本文作为 C++ 学习中的小练习,若有疏漏,欢迎指正。 MTest 介绍 MTest 是一个 header-only 的简易框架,只包含两个头文件: mtest.hpp 负责 MTest 和 MTest::MTestMessage 两个类的实现,不含有任何的宏。 mtest_macro.hpp 负责对外提供相应的宏,可以在编译时使用-DUNUSE_MTEST关闭所有的宏,避免与 gtest 产生冲突。 测试文件需要 include 这两个文件,include顺序无所谓,也可以直接合并成一个文件,但是我个人的喜好是对宏敬而远之,因此单独仍在一个头文件中。主要功能实现在mtest.hpp,其中不含有任何的宏。 为什么重复造轮子? 我希望将 MTest 作为 gtest 的简易替代,尤其是它具有...
Tmux 学习笔记
这是一份简要的tmux笔记和速查手册,主要参考 Tmux 的 Github 文档 基本概念 tmux 为终端复用器,可以启动一系列终端会话,可以将会话和终端窗口分离:关闭终端窗口再打开,会话并不终止,而是继续运行在执行,这可以有效避免因网络波动等导致的会话中断,也便于开启多窗口任务。 tmux 在逻辑上主要有三层概念:session(会话)> window(窗口)> pane(窗格)。 session session 具有索引(默认从0开始),同时也有名称(默认名称是数字编号) 远程登录时开启 tmux client 客户端,然后可以 attach 到一个 session session 可以被一个或多个 client attach(相当于从多个设备同时登入),或者处于 detached 状态,此时 session 保持在后台运行 session 可以包含一组 window:一个屏幕装不下了,把所有东西暂移出去,新建一个空的 window。在同一时刻只能呈现一个 current window window window...
Linux bash 启动配置
bash是默认的shell,有必要了解一下它不同启动方式下的配置过程。 当执行bash命令或者用户登录系统时,会陆续加载各种bash配置文件,还会设置或清空一系列变量,有时还会执行一些自定义的命令,这些行为都算是启动bash时的过程。在不同的系统中具体的逻辑还是不同的,目前只关注Ubuntu和CentOS。 启动过程有两个维度的分类方式: 交互式和非交互式 交互式的标准情景:输入一个命令,然后输出user@host:path$,等待用户输入; 非交互式的标准情景:bash执行一个脚本,例如bash demo.sh。 登录和非登录:顾名思义,非登录情景可以加上--login或-l选项来伪装为登录情况。 可以通过下面的方法进行判断: 交互式的判断: 交互式环境下的$-变量会含有字母i; 交互式定义了提示符$PS1,但是非交互式会清空这个变量,因此echo $PS1可以区分。 登录和非登录的判断:shopt login_shell,返回on或off。 1echo $PS1;shopt...
Cpp构建和编译笔记——9.CMake库的开发
这个环节我们从库的使用者切换为库的开发者,假设我们开发了一个库 Abc,那么如何处理 Abc 库的安装和导入?在导入环节,如何按照 modern cmake 的规范提供 AbcConfig.cmake? 尤其在这部分内容,网上教程非常混乱,CMake 官方文档写的非常复杂难懂,似乎是为超复杂的大型库开发所准备的,而且早期语法和 modern cmake 语法混杂在一起,难以分辨。本文将从简单的示例开始,吸取各个教程的内容,逐渐完善。 方式一:直接安装 我们首先考虑一种最无脑的安装方式:直接把可执行文件,库文件和头文件放到需要的地方去,并且不考虑复用。(CMake 不会导出它的配置信息文件) CMake 支持这种直接无脑的安装,不需要我们真的在文件系统中进行手动拷贝。 示例如下 123install(TARGETS demo4lib1 demo4lib2 demo4exe1 demo4exe2)install(DIRECTORY include/Demo4 TYPE INCLUDE)install(FILES src/Demo4_b.h TYPE INCLUDE) 这里安装四个...
Cpp构建和编译笔记——8.CMake依赖管理
这一篇关注 CMake 的依赖管理,这是最重要的部分:由于 C++没有如 pip,npm 那样统一的包管理(既有历史原因,也是 C/C++的包管理需求太复杂导致的),在使用第三方库时通常需要使用源码编译安装,然后手动管理依赖,涉及到的 CMake 操作非常繁琐。 本文围绕以下内容展开: 项目安装命令 第三方库的使用: 库已经安装到本地,并且支持 CMake:需要导入库的信息 库并不在本地:需要从仓库拉取源码,合并到当前项目中 我们面临很多问题: 不同平台的影响:例如 Windows 平台下的安装位置等非常混乱,而 Linux 则比较统一,使得安装和第三方库的导入都非常规范化 不同的语法风格:例如 CMake 早期的语法风格需要如何导入库,Modern CMake 的语法风格需要如何导入库。CMake 为了适应不同的第三方库,提供了许多不同的接口,语法越来越混乱。 项目安装命令 单独的安装命令通常如下(当前位置是项目根目录,而非在 build 子文件夹中) 12345678(1)make install(2)cmake --build build --target...