Cpp构建和编译笔记——2.头文件和库
头文件
头文件的存在,目的是把接口和实现分离,便于多文件编程中的组织,比如
在多文件的项目中,把函数声明都集中到若干头文件中,在源文件中引用它们,便于跨文件的函数调用
在提供库的同时,我们也需要提供库的使用接口(头文件),通过头文件中的类和函数声明,用户可以知道如何使用这个库
在使用库的时候,首先需要在源代码中引用头文件,然后在链接步骤中链接需要的库文件
gcc 查找头文件
gcc 在编译过程中,预处理环节需要 include
相应的头文件,这里存在一个问题:如何找到头文件?
gcc
存在专门的选项:-Ipath,也可以写成-I path,带不带空格都可以,但是只能后接一个路径,如果使用多个路径就需要多个-I,例如
1gcc hello.c -I mydir1 -I mydir2
如果直接写完整路径加文件名,那么不存在查找文件的问题,但是如果使用的是不完整路径加文件名,则存在查找顺序的问题。在
include 语句中,双引号和尖括号引用头文件的查找顺序有一点区别:
双引号 include 的查找顺序:
使用#include的源文件所在的路径
-I 指定的路径
环境变量CPATH ...
Cpp构建和编译笔记——1.编译过程
打算开一个系列,写一些零零散散但自学了很久的东西——C/C++除了基本语法之外,还需要知道的东西——C++项目的编译与构建。
这一系列采用的编程环境为 Linux 系统,编译器为 gcc 11.2.0。(Windows
下的 mingw
作为两种平台间的畸形产物,曾经给我的学习造成了极大的困扰,尤其是静态库动态库部分)
如果使用 IDE 比如 VS 或 CLion
的话,这些东西可能都不需要了解,同样也可以写好 C++,但是我不喜欢使用 IDE
这种糊里糊涂,不清楚到底发生了什么的编程方式,更喜欢先搞懂每一步发生了什么,然后可以为了提高效率而使用
IDE,而非一直保持一种稀里糊涂的状态。
1. 编译过程的拆分
对于 c/c++编程,从源代码文件变成可执行文件,大致需要以下几步:
预处理(Pre-Processing),预处理器(preprocessor)处理#include #define等内容,把头文件
copy 到源文件中等,注意这种 include 是递归的,并且这里存在一个问题:gcc
如何找到头文件。
编译(Compiling),得到的文件是以汇编语言写的,可读。
汇编(A ...
Linux 几类重要命令
由于压缩解压、网络文件传输和定时任务都是实践中很常见的操作,这里进行更详细的命令介绍。
命令速查
解压缩并解包 1tar -xf archive.tar.(gz|bz2|xz)
解压缩并解包到指定位置 1tar -xf archive.tar.(gz|bz2|xz) -C /path/to/destination
打包并压缩 1tar -acf archive.tar.(gz|bz2|xz) file1 file2 directory
压缩解压
zip
zip和unzip命令用于创建和解压缩.zip格式的压缩文件。
压缩文件的基本使用如下:创建一个名为 archive.zip
的压缩文件,并包含了指定的文件。 1zip archive.zip file1 file2
需要注意的是,如果直接添加目录,那么只是添加了文件夹自身,不含其中的项!必须使用-r选项才能递归压缩整个目录
1zip -r archive.zip directory
混合添加文件和文件夹也需要使用-r选项 1zip -r archive.zip file1 file2 directory
解压缩文件的基本使用如下:解压 ...
Linux 常用命令
切换目录
cd命令(change directory)用于改变目录:
cd <path>:切换到<path>目录下,可以是相对路径或/开头的绝对路径;
cd:缺省<path>则会回到家目录~
cd .. 返回上一级目录
cd -可以回到上一次所处的位置
查看目录
ls命令(list
directory)用于列出目录下的文件,基本用法如下
ls <path>:列出目录下的所有文件
ls:缺省<path>则会列出当前目录下的文件
除此之外,还需要注意ls支持的一些选项
-a或--all:除了普通文件,还显示以.开头的隐藏文件(文件夹),可以用ls -a | grep '^\.'过滤,只显示隐藏文件(文件夹)
-A或--almost-all:和-a类似,但是不再显示.和..这两个特殊角色
-l:以列表模式显示文件信息,每一行包括文件的权限、链接数、所有者、组、文件大小、最后修改时间和文件名,对于链接还会显示指向的文件名
-F:
在条目的最后添加一个符号,以指示类型,包括*/=>@|,其中*代表可执行文件,/代表目录, ...
Linux 基础学习笔记
目录结构
各种 Linux 系统有着大致统一的标准目录结构:(FHS)
/ 根目录
可执行文件目录
/bin,/sbin
存放系统层面所必需的可执行文件,例如cp、ls等,其中/sbin存放的是需要root权限的部分
/usr/bin,/usr/sbin
存放用户层面的可执行文件,例如git、wget等
库目录
/lib
存放系统层面所必需的的动态库,理论上是为/bin和/sbin准备的,此外/lib/modules还存放内核模块
/usr/lib
存放用户层面的动态库,理论上是为/usr/bin和/usr/sbin准备的
除了lib,可能还有lib32,lib64,作用类似
/usr/local
(重要)存放管理员安装的程序,与使用apt等命令直接安装的不同,这里通常存放的是手动编译安装的软件,这个目录很重要,下面单独讨论
用户家目录(重要)
/root root 用户的家目录
/home 一般用户的家目录的父目录
/home/abc 名为 abc 的用户的家目录
/opt
(重要)一般用于安装第三方提供的,可选的大型应用程序
/etc
(重要)存放系统的配置文件和 ...
Stokes方程组与Lagrange乘子法
在前文中介绍了泛函语境下的 Lagrange
乘子法,接下来将它应用中不可压流的 Stokes 方程组中。
1. Stokes 方程组
1.1 原始方程组
不可压缩蠕动流满足如下的方程组
\[
\begin{aligned}
-\Delta u + \nabla p &= f\\
\nabla \cdot u &= 0\\
u|_{\partial \Omega} &= 0
\end{aligned}
\]
其中\(\Omega\)是有界区域,为了后续的讨论,我们定义如下空间
\[
\begin{aligned}
V &= [H_0^1(\Omega)]^n \\
Z &= \{v \in V | \nabla \cdot v = 0\}\\
\widetilde{L}^2(\Omega) &= \{q \in L^2(\Omega)| \int_{\Omega} q =
0\}
\end{aligned}
\]
1.2 虚功原理
将 Stokes 方程组转化为如下的变分形式(物理上也称为虚功原理):
(A1) find \(u \in ...
泛函中的Lagrange乘子法
1. 经典的 Lagrange 乘子法
经典的 Lagrange
乘子法是针对等式约束下的非线性方程最优化问题,将其转化为一个方程组的求解问题,具体形式如下:
\[
\left\{
\begin{aligned}
&\max f(\mathbf{x})\\
&s.t. g(\mathbf{x})=0
\end{aligned}
\right.
\]
其中\(\mathbf{x}\in R^N\),\(f,g:R^N \to R\),对于上述问题引入 Lagrange
乘子\(\lambda \in R\),定义 Lagrange
函数\(L(\mathbf{x},\lambda)\):
\[
L(\mathbf{x},\lambda) = f(\mathbf{x}) - \lambda \,g(\mathbf{x})
\]
则\(\mathbf{x}\)取到最优解的必要条件为\((\mathbf{x}, \lambda)\)满足如下方程组:
\[
\left\{
\begin{aligned}
\nabla f(\mathbf{x}) - \lambda \nabla ...
vim入门笔记
vim
被称为编辑器之神,学习难度很大,但是熟练掌握后可以更高效地敲代码,因此学一下。
安装与配置文件
vim 默认是命令行版本的,而 gvim 是 GUI 版本的 vim,这里我们使用的是
Git for Windows 里面附带的 vim(不含 GUI),可以按 Linux
风格进行配置和使用,感觉比直接下载Vim
官网的 Windows 版的 gvim 更方便,便于直接把配置应用到到 Linux
服务器上。
在 vim 中输入:version可以查看很多信息,例如
1234567// vim的版本号VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Nov 22 2021 19:31:05)Included patches: 1-3582Compiled by <https://www.msys2.org/>// vim的安装模式(tiny,small,normal,big,huge等,huge的功能最全)Huge version without GUI.
还有一个列表描述了当前编译的 vim
支持或不支持的功能列表,例如+cli ...
web自学3——JavaScript
在简单学习了 HTML 和 CSS 之后,接下来是 JavaScript
的学习,学习的重点不是 JavaScript 作为一个脚本语言的语法内容,而是
JavaScript 对于网页的控制,参考教程:https://developer.mozilla.org。
HTML 定义了网页的内容
CSS 描述了网页的布局
JavaScript 控制了网页的行为
1. 在 HTML 中使用 JS
在 HTML 和 CSS 一起组装成一个网页之后,浏览器的 JavaScript 引擎将执行
JavaScript 代码,这保证了当 JavaScript
开始运行之前,网页的结构和样式已经就位,然后 JS
可以更新这个网页的具体内容等。
对于浏览器,它的每一个标签页使用了一个独立的运行环境,不同标签页之间没有任何联系,JS
代码也相互独立运行,一定程度上保证了信息安全。
script 标签
在 HTML 的 head 或者 body 部分都可以使用,例如:
12345678910111213<!DOCTYPE html><html lang="en"> ...
web自学2——CSS
在简单学习了 HTML
之后,我们可以得到一个简单的静态网页,但是为了让网页呈现更加丰富的样式,一个明智的做法把样式信息和文本信息分离开,文本信息对应
HTML,样式信息对应 CSS,完成一个网页的组织分离,接下来是 CSS
的简单学习,参考教程:https://developer.mozilla.org
HTML 定义了网页的内容
CSS 描述了网页的布局
JavaScript 控制了网页的行为
CSS
1. 在 HTML 中使用样式
我们最终的目标是把 CSS 文件和 HTML
文件结合起来,但是在此之前,还有一些方法可以直接在 HTML
文件中使用简单的样式:
style 属性
例如添加背景色 background-color,
可以直接使用元素的style属性定义的样式
源代码如下:
1<p style="background-color: #00BFFF">可以直接使用元素的style属性定义的样式</p>
嵌入 CSS 语句
我们使用如下简单的 html
文件,在头部使用<style type="text/css"& ...