gcc和makefile用法总结(建议收藏)

2023-05-16

文章目录

    • @[toc]
    • 1. 用GCC制作静态链接库
      • 静态链接库的创建
      • 静态链接库的使用
    • 2. 用GCC制作动态链接库
      • 动态链接库的创建
      • 动态链接库的使用
    • 3. GCC找不到库文件怎么办?
      • GCC生成可执行文件时找不到库文件
      • GCC运行可执行文件时找不到动态库文件
    • 4. makefile
    • 5. makefile实战演练

本篇博文不是详细的gcc和makefile用法详解,而是基于实际使用过程中需要掌握的gcc和makefile的用法。其实是在makefile中需要用到的gcc.


1. 用GCC制作静态链接库

本节先给大家讲解静态链接库的创建和使用,至于如何创建动态链接库,会在下一节做详细介绍。

假设当前有一个 C 语言项目,其目录结构如下所示:

 demo项目
   ├─ headers
   │     └─ test.h
   └─ sources
          ├─ add.c
          ├─ sub.c
          ├─ div.c
          └─ main.c

其中,headers 用于表示该项目拥有的所有头文件;sources 表示该项目拥有的所用源文件,读者可按照此目录结构构建 demo 项目,也可以将所有文件统一放置在 demo 项目下,本节选择的是后者,即将所有文件统一放置在 demo 目录下。

可以看到,该项目中包含 1 个头文件( .h ),4 个源文件( .c ),它们各自包含的代码如下所示:

[root@bogon demo]# ls            <- demo 目录结构
add.c div.c main.c sub.c test.h
[root@bogon demo]# cat test.h      <- test.h 文件内容
#ifndef __TEST_H_
#define __TEST_H_

int add(int a,int b);
int sub(int a,int b);
int div(int a,int b);

#endif
[root@bogon demo]# cat add.c      <- add.c 文件内容
#include “test.h”
int add(int a,int b)
{
    return a + b;
}
[root@bogon demo]# cat sub.c      <- sub.c 文件内容
#include “test.h”
int sub(int a,int b)
{
    return a - b;
}
[root@bogon demo]# cat div.c      <- div.c 文件内容    
#include “test.h”
int div(int a,int b)
{
    return a / b;
}
[root@bogon demo]# cat main.c    <- main.c 文件内容
#include <stdio.h>
#include "test.h" //必须引入头文件
int main(void)
{
    int m, n;
    printf("Input two numbers: ");
    scanf("%d %d", &m, &n);
    printf("%d+%d=%d\n", m, n, add(m, n));
    printf("%d-%d=%d\n", m, n, sub(m, n));
    printf("%d÷%d=%d\n", m, n, div(m, n));
    return 0;
}

整个项目的逻辑很简单,其中 add.c、sub.c 和 div.c 这 3 个文件中各包含一个函数,分别实现将两个整数做相加、相减和除法操作,而 test.h 仅包含这 3 个函数的声明部分,main.c 是主程序文件,其通过引入 test.h 头文件调用了 3 个函数,从而分别完成了对用户输入的 2 个整数做相加、相减以及除法操作。

对于编译、运行 demo 项目,我们可以直接使用 gcc 命令完成:

[root@bogon demo]# gcc main.c add.c sub.c div.c -o main.exe
[root@bogon demo]# ls
add.c div.c main.c main.exe sub.c test.h
[root@bogon demo]# ./main.exe
Input two numbers: 10 2
10+2=12
10-2=8
10÷2=5

注意,由于在程序预处理阶段,GCC 编译器会自行处理各个 .c 文件内部引入的 .h 头文件(将 .h 文件中的代码直接拷贝到当前 .c 源文件中),因此编译运行 demo 项目时,我们只需要提供所有的源文件即可,不需要处理头文件。

注意,add.c、sub.c 和 div.c 这 3 个文件,其包含的都是一些功能模块(实现具体功能的函数),对于这样的源文件,只要我们愿意共享,每个人都可以直接用到自己的项目中。这就产生一个问题,如果仅希望别人使用我们实现的功能,但又不想它看到具体实现的源码,该怎么办呢?很简单,就是将它们加工成一个静态链接库。

静态链接库的创建

通过前面的学习我们知道,静态链接库其实就相当于压缩包,其内部可以包含多个源文件。但需要注意的是,并非任何一个源文件都可以被加工成静态链接库,其至少需要满足以下 2 个条件:

  • 源文件中只提供可以重复使用的代码,例如函数、设计好的类等,不能包含 main 主函数;
  • 源文件在实现具备模块功能的同时,还要提供访问它的接口,也就是包含各个功能模块声明部分的头文件。

显然对于 demo 项目中的 add.c、sub.c 以及 div.c 这 3 个源文件来说,以上 2 个条件都符合,因此都可以被加工成静态链接库。并且根据实际需要,我们可以将它们集体压缩到一个静态链接库中,也可以各自压缩成一个静态链接库。

将源文件打包为静态链接库的过程很简单,只需经历以下 2 个步骤:

  1. 将所有指定的源文件,都编译成相应的目标文件:
[root@bogon demo]# gcc -c sub.c add.c div.c
[root@bogon demo]# ls
add.c add.o div.c div.o main.c sub.c sub.o test.h
  1. 然后使用 ar 压缩指令,将生成的目标文件打包成静态链接库,其基本格式如下:

ar rcs 静态链接库名称 目标文件1 目标文件2 …

有关 ar 打包压缩指令,以及 rcs 各选项的含义和功能,感兴趣的读者可自行查找相关资料了解。这里需要重点说明的是,静态链接库的不能随意起名,需遵循如下的命名规则:

libxxx.a

Linux 系统下,静态链接库的后缀名为 .a;Windows 系统下,静态链接库的后缀名为 .lib。

其中,xxx 代指我们为该库起的名字,比如 Linux 系统自带的一些静态链接库名称为 libc.a、libgcc.a、libm.a,它们的名称分别为 c、gcc 和 m。

下面,我们尝试将 add.o、sub.o 和 div.o 打包到一个静态链接库中:

[root@bogon demo]# ar rcs libmymath.a add.o sub.o div.o
[root@bogon demo]# ls
add.c add.o div.c div.o libmymath.a main.c sub.c sub.o test.h

其中,libmymath.a 就是 add.o、sub.o 和 div.o 一起打包生成的静态链接库,mymath 是我们自定义的库名。

通过以上 2 步操作,我们就成功创建出了 libmymath.a 静态链接库。那么,该如何使用它呢?

静态链接库的使用

静态链接库的使用很简单,就是在程序的链接阶段,将静态链接库和其他目标文件一起执行链接操作,从而生成可执行文件。

以 demo 项目为例,首先我们将 main.c 文件编译为目标文件:

[root@bogon demo]# gcc -c main.c
[root@bogon demo]# ls
add.c div.c libmymath.a main.o sub.c
test.h add.o div.o main.c sub.o

在此基础上,我们可以直接执行如下命令,即可完成链接操作:

[root@bogon demo]# gcc -static main.o libmymath.a
[root@bogon demo]# ls
add.c a.out div.o    main.c sub.c test.h
add.o div.c libmymath.a main.o sub.o

其中,-static 选项强制 GCC 编译器使用静态链接库。

注意,如果 GCC 编译器提示无法找到 libmymath.a,还可以使用如下方式完成链接操作:

[root@bogon demo]# gcc main.o -static -L /root/demo/ -lmymath
[root@bogon demo]# ls
add.c a.out div.o    main.c sub.c test.h
add.o div.c libmymath.a main.o sub.o

其中,-L(大写的 L)选项用于向 GCC 编译器指明静态链接库的存储位置(可以借助 pwd 指令查看具体的存储位置); -l(小写的 L)选项用于指明所需静态链接库的名称,注意这里的名称指的是 xxx 部分,且建议将 -l 和 xxx 直接连用(即 -lxxx),中间不需有空格。

由此,就生成了 a.out 可执行文件:

[root@bogon demo]# ./a.out
Input two numbers: 10 2
10+2=12
10-2=8
10÷2=5

2. 用GCC制作动态链接库

前面章节中,给读者详细阐述了什么是库文件、什么是静态链接库和动态链接库,同时还介绍了手动创建静态链接库的过程。在此基础上,本节继续讲解动态链接库的创建和使用。

有关动态链接库,以及它的特性、和静态链接库的区别,读者可阅读《GCC使用静态链接库和动态链接库》一节做详细了解,这里不再做赘述。

为了方便读者更好地理解创建和使用动态链接库的过程,本节仍以在《静态链接库的创建和使用》一节中创建好的 demo 项目(一个 C 语言多文件项目)为例,如下是该目录的具体构成和相关源码:

[root@bogon demo]# ls            <- demo 目录结构
add.c div.c main.c sub.c test.h
[root@bogon demo]# cat test.h      <- test.h 文件内容
#ifndef __TEST_H_
#define __TEST_H_

int add(int a,int b);
int sub(int a,int b);
int div(int a,int b);

#endif
[root@bogon demo]# cat add.c      <- add.c 文件内容
#include “test.h”
int add(int a,int b)
{
    return a + b;
}
[root@bogon demo]# cat sub.c      <- sub.c 文件内容
#include “test.h”
int sub(int a,int b)
{
    return a - b;
}
[root@bogon demo]# cat div.c      <- div.c 文件内容    
#include “test.h”
int div(int a,int b)
{
    return a / b;
}
[root@bogon demo]# cat main.c    <- main.c 文件内容
#include <stdio.h>
#include "test.h" //必须引入头文件
int main(void)
{
    int m, n;
    printf("Input two numbers: ");
    scanf("%d %d", &m, &n);
    printf("%d+%d=%d\n", m, n, add(m, n));
    printf("%d-%d=%d\n", m, n, sub(m, n));
    printf("%d÷%d=%d\n", m, n, div(m, n));
    return 0;
}

动态链接库的创建

总的来说,动态链接库的创建方式有 2 种。

  1. 直接使用源文件创建动态链接库,采用 gcc 命令实现的基本格式如下:

gcc -fpic -shared 源文件名… -o 动态链接库名

其中,-shared 选项用于生成动态链接库;-fpic(还可写成 -fPIC)选项的功能是,令 GCC 编译器生成动态链接库(多个目标文件的压缩包)时,表示各目标文件中函数、类等功能模块的地址使用相对地址,而非绝对地址。这样,无论将来链接库被加载到内存的什么位置,都可以正常使用。

例如,由 demo 项目中的 add.c、sub.c 和 div.c 这 3 个源文件生成一个动态链接库,执行命令为:

[root@bogon demo]# ls
add.c div.c main.c sub.c test.h
[root@bogon demo]# gcc -fpic -shared add.c sub.c div.c -o libmymath.so
[root@bogon demo]# ls
add.c div.c libmymath.so main.c sub.c test.h

注意,动态链接库的命令规则和静态链接库完全相同,只不过在 Linux 发行版系统中,其后缀名用 .so 表示;Windows 系统中,后缀名为 .dll。

  1. 先使用 gcc -c 指令将指定源文件编译为目标文件。仍以 demo 项目中的 add.c、sub.c 和 div.c 为例,先执行如下命令:
[root@bogon demo]# ls
add.c div.c main.c sub.c test.h
[root@bogon demo]# gcc -c -fpic add.c sub.c div.c
[root@bogon demo]# ls
add.c add.o div.c div.o main.c sub.c sub.o test.h

注意,为了后续生成动态链接库并能正常使用,将源文件编译为目标文件时,也需要使用 -fpic 选项。

在此基础上,接下来利用上一步生成的目标文件,生成动态链接库:

[root@bogon demo]# gcc -shared add.o sub.o div.o -o libmymath.so
[root@bogon demo]# ls
add.c add.o div.c div.o libmymath.so main.c sub.c sub.o test.h

以上 2 种操作,生成的动态链接库是完全一样的,读者任选一种即可。

动态链接库的使用

通过前面章节的学习我们知道,动态链接库的使用场景就是和项目中其它源文件或目标文件一起参与链接。以 demo 项目为例,前面我们将 add.c、sub.c 和 div.c 打包到了 libmymath.so 动态链接库中,此时该项目中仅剩 main.c 源程序文件,因此执行 demo 项目也就演变成了将 main.c 和 libmymath.so 进行链接,进而生成可执行文件。

注意,test.h 头文件并不直接参与编译,因为在程序的预处理阶段,已经对项目中需要用到的头文件做了处理。

执行如下指令,即可借助动态链接库成功生成可执行文件:

[root@bogon demo]# gcc main.c libmymath.so -o main.exe
[root@bogon demo]# ls
add.c div.c libmymath.so main.c main.exe sub.c test.h

注意,生成的 main.exe 通常无法直接执行,例如:

[root@bogon demo]# ./main.exe
./a.out: error while loading shared libraries: libd.so: cannot open shared object file: No such file or directory

可以看到,执行过程中无法找到 libmymath.so 动态链接库。通过执行ldd main.exe指令,可以查看当前文件在执行时需要用到的所有动态链接库,以及各个库文件的存储位置:

[root@bogon demo]# ldd main.exe
linux-vdso.so.1 => (0x00007fff423ff000)
libmymath.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00000037e2c00000)
/lib64/ld-linux-x86-64.so.2 (0x00000037e2800000)

可以看到,main.exe 文件的执行需要 4 个动态链接库的支持,其中就包括 libmymath.so,但该文件无法找到,因此 main.exe 执行会失败。

运行由动态链接库生成的可执行文件时,必须确保程序在运行时可以找到这个动态链接库。常用的解决方案有如下几种:

  • 将链接库文件移动到标准库目录下(例如 /usr/lib、/usr/lib64、/lib、/lib64);
  • 在终端输入export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx,其中 xxx 为动态链接库文件的绝对存储路径(此方式仅在当前终端有效,关闭终端后无效);
  • 修改~/.bashrc 或~/.bash_profile 文件,即在文件最后一行添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx(xxx 为动态库文件的绝对存储路径)。保存之后,执行source .bashrc指令(此方式仅对当前登陆用户有效)。

本操作系统(CentOS 6.5 64 位)中,只需要将 libmymath.so 库文件移动 /usr/lib64 或者 /lib64 目录下,即可使 main.exe 成功执行:

[root@bogon demo]# ldd main.exe
linux-vdso.so.1 => (0x00007fff06fb3000)
libmymath.so => /lib64/libmymath.so (0x00007f65b2a62000)
libc.so.6 => /lib64/libc.so.6 (0x00000037e2c00000)
/lib64/ld-linux-x86-64.so.2 (0x00000037e2800000)
[root@bogon demo]# ./main.exe
Input two numbers: 10 2
10+2=12
10-2=8
10÷2=5

3. GCC找不到库文件怎么办?

我们已经了解了如何创建静态链接库和动态链接库,并学会了如何使用它们。但即便是相同的操作,由于所用操作系统的环境不同,很多读者在实操中会碰到各种各样的问题,其中 GCC 编译器提示“找不到库文件(No such file or directory)”,就是最常见的问题之一。

关于 GCC 提示找不到指定库文件的这个问题,通常出现在以下 2 个场景中:

  1. 利用静态库或者动态库文件实现链接操作(生成可执行文件)时,GCC 可能会提示“xxx:No such file or directory”(其中 xxx 表示查找失败的静态库或者动态库);
  2. 执行借助动态库生成的可执行文件时,GCC 可能会提示“./main.exe: error while loading shared libraries: xxx.so: cannot open shared object file: No such file or directory”(其中 xxx 表示动态库的文件名)。

本节将就以上这 2 种情况,给读者分析 GCC 编译器查找库文件失败的原因,同时会给出相应的解决方案。

GCC生成可执行文件时找不到库文件

要想彻底解决这个问题,读者就必须先了解在生成可执行文件时,GCC 编译器默认的查找库文件的路径。

通过前面的学习我们知道,程序链接阶段指明所用库文件的方式有 2 种。假设当前 mian.c 文件需要借助 libmymath.a 才能完成链接,则完成链接操作的 gcc 指令有以下 2 种写法:

[root@bogon demo]# gcc -static main.c libmymath.a -o main.exe
[root@bogon demo]# gcc -static main.c -lmymath -o main.exe

当以第一种写法完成链接操作时,GCC 编译器只会在当前目录中(这里为 demo 目录)查找 libmymath.a 静态链接库;反之,如果使用 -l(小写的 L)选项指明了要查找的静态库的文件名,则 GCC 编译器会按照如下顺序,依次到指定目录中查找所需库文件:

  1. 如果 gcc 指令使用 -L 选项指定了查找路径,则 GCC 编译器会优先选择去该路径下查找所需要的库文件;
  2. 再到 Linux 系统中 LIBRARY_PATH 环境变量指定的路径中搜索需要的库文件;
  3. 最后到 GCC 编译器默认的搜索路径(比如 /lib、/lib64、/usr/lib、/usr/lib64、/usr/local/lib、/usr/local/lib64 等,不同系统环境略有差异)中查找。

如果读者使用第一种方法完成链接操作,但 GCC 编译器提示找不到所需库文件,表明所用库文件并未存储在当前路径下,解决方案就是手动找到库文件并将其移至当前路径,然后重新执行链接操作。

反之,如果读者使用的是第二种方法,也遇到了 GCC 编译器提示未找到所需库文件,表明库文件的存储路径不对,解决方案有以下 3 种:

  • 手动找到该库文件,并在 gcc 指令中用 -L 选项明确指明其存储路径。比如 libmymath.a 静态库文件存储在 /usr 目录下,则完成链接操作的 gcc 指令应为gcc -static main.c -L/usr -lmymath -o main.exe
  • 将库文件的存储路径添加到 LIBRARY_PATH 环境变量中。仍以库文件存储在 /usr 目录下,则通过执行export LIBRARY_PATH=$LIBRARY_PATH:/usr指令,即可将 /usr 目录添加到该环境变量中(此方式仅在当前命令行窗口中有效);
  • 将库文件移动到 GCC 编译器默认的搜索路径中。

GCC运行可执行文件时找不到动态库文件

执行已生成的可执行文件时,如果 GCC 编译器提示找不到所需的库文件,这意味着 GCC 编译器无法找到支持可执行文件运行的某些动态库文件。

事实上,当 GCC 编译器运行可执行文件时,会按照如下的路径顺序搜索所需的动态库文件:

  1. 如果在生成可执行文件时,用户使用了-Wl,-rpath=dir(其中 dir 表示要查找的具体路径,如果查找路径有多个,中间用 : 冒号分隔)选项指定动态库的搜索路径,则运行该文件时 GCC 会首先到指定的路径中查找所需的库文件;
  2. GCC 编译器会前往 LD_LIBRARY_PATH 环境变量指明的路径中查找所需的动态库文件;
  3. GCC 编译器会前往 /ect/ld.so.conf 文件中指定的搜索路径查找动态库文件;
  4. GCC 编译器会前往默认的搜索路径中(例如 /lib、/lib64、/usr/lib、/usr/lib64 等)中查找所需的动态库文件。

注意,可执行文件的当前存储路径,并不在默认的搜索路径范围内,因此即便将动态库文件和可执行文件放在同一目录下,GCC 编译器也可能提示“找不到动态库”。

因此,对于 GCC 运行可执行文件时提示找不到动态库文件的问题,常用的解决方法是:

  • 将动态库文件的存储路径,添加到 LD_LIBRARY_PATH 环境变量中。假设动态库文件存储在 /usr 目录中,通知执行export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr指令,即可实现此目的(此方式仅在当前命令行窗口中有效);
  • 修改动态库文件的存储路径,即将其移动至 GCC 编译器默认的搜索路径中。
  • 修改~/.bashrc 或 ~/.bash_profile 文件,即在文件最后一行添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx(xxx 为动态库文件的绝对存储路径)。保存之后,执行 source .bashrc 指令(此方式仅对当前登陆用户有效)。

值得一提的是,GCC 编译器提供有 ldd 指令,借助该指令,我们可以明确知道某个可执行文件需要哪些动态库文件做支撑、这些动态库文件是否已经找到、各个动态库文件的具体存储路径等信息。

以《动态链接库的创建和使用》一节中生成的 main.exe 可执行文件为例,执行如下 ldd 指令:

[root@bogon demo]# ldd main.exe
linux-vdso.so.1 => (0x00007fff06fb3000)
libmymath.so => /lib64/libmymath.so (0x00007f65b2a62000)
libc.so.6 => /lib64/libc.so.6 (0x00000037e2c00000)
/lib64/ld-linux-x86-64.so.2 (0x00000037e2800000)

注意,如果某个动态库文件未找到,则 => 后面会显示 not found,表明 GCC 编译器无法找到该动态库,此时该可执行文件将无法执行。


4. makefile

上面把我们常用的gcc用法进行了总结,主要就是静态库和动态库的创建和使用,以及在链接过程中找不到库文件的解决方法。

下面我们就开始将makefile的用法了,makefile文件中包含了一个项目中所有源代码文件的编译规则和依赖关系。

Makefile 文件描述了 Linux 系统下 C/C++ 工程的编译规则,它用来自动化编译 C/C++ 项目。一旦写编写好 Makefile 文件,只需要一个 make 命令,整个工程就开始自动编译,不再需要手动执行 GCC 命令。

一个中大型 C/C++ 工程的源文件有成百上千个,它们按照功能、模块、类型分别放在不同的目录中,Makefile 文件定义了一系列规则,指明了源文件的编译顺序、依赖关系、是否需要重新编译等。


makefile的东西还是很多的,一篇文章肯定是讲不完的。

这里推荐几个我觉得比较好的教程:

Makefile教程:Makefile文件编写1天入门

跟我一起写Makefile

Makefile用法,详细到让人吐

看完上面几个教程估计就对makefile很了解了。


5. makefile实战演练

后面我会以DEVC++和Tornado2.2中项目中自动生成的makefile来讲解一下实际情况中的makefile是怎样的。

此外我还会以一些C语言开源库中的makefile来讲解实际开源库中的makefile是怎样的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gcc和makefile用法总结(建议收藏) 的相关文章

随机推荐

  • 【VINS论文翻译】VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator

    回到目录 写在前面 港科大的VINS Mono作为目前state of the art的开源VIO项目 xff0c 是研究视觉与IMU紧耦合的必读算法 xff0c 网上的论文解读与代码实现也非常丰富 xff08 感谢 xff01 xff09
  • linux--进程控制2

    在进程控制的章节我们讲解了我们的进程创建 xff0c 这章节对进程控制进行补充 xff0c 进程终止 在我们创建一个进程之后我们避免不了我们去终止我们的进程 终止场景 正常退出 xff0c 结果符合我们的预期正常退出 xff0c 结果不符合
  • VINS-Mono论文学习与代码解读——目录与参考

    前言 港科大的VINS Mono作为目前state of the art的开源VIO项目 xff0c 是研究视觉与IMU融合的必读算法 xff0c 网上的论文解读与代码实现也非常丰富 xff08 感谢 xff01 xff09 为更好地进行学
  • VINS-Mono代码解读——视觉跟踪 feature_trackers

    前言 本文主要介绍VINS的视觉处理前端的视觉跟踪模块 xff08 feature trackers xff09 论文第四章A节 xff08 IV MEASUREMENT PREPROCESSING A Vision Processing
  • 视觉SLAM中的数学——解方程AX=b与矩阵分解:奇异值分解(SVD分解) 特征值分解 QR分解 三角分解 LLT分解

    前言 本博客主要介绍在SLAM问题中常常出现的一些线性代数相关的知识 xff0c 重点是如何采用矩阵分解的方法 xff0c 求解线性方程组AX 61 B 主要参考了 计算机视觉 算法与应用 附录A以及Eigen库的方法 本博客可能不会对分解
  • pycharm 每次打开文件都要配置解释器的解决方案

    今天在打开pycharm的时候 xff0c 又发现那个解释器不能用了 xff0c 然后在网上找解决方案 xff0c 有的说是用defautsetting解决 xff0c 然是我没有找到那个default setting 在哪里 233333
  • PS多边形套锁工具在框选区的时候一按shift键PS

    微软输入法更新导致的BUG xff0c 把微软拼音输入法设置中兼容性里使用旧版就解决了 步骤 xff1a 右键输入法 xff0c 选择设置 xff0c 选择常规 xff0c 然后拖到最下面 xff0c 勾上兼容性就可以 xff0c 如下图
  • N卡怎么修改录屏文件保存位置

    N卡的视频录制非常好用 xff0c 但是有时候找不到保存位置在哪里 xff0c 这里转载下文章记录下 xff0c 方便后续查看 首先告诉你默认位置 我的电脑下的 34 视频 34 文件夹 xff08 有的电脑里叫video xff09 如果
  • 常见的设计模式

    目录 工厂模式单例模式观察者模式策略模式代理模式装饰模式 工厂模式 这个模式有三个对象 xff1a 工厂 用户 产品 xff1b 这么说可能还有点抽象 xff0c 说具体点 xff0c 就是当我们在代码中需要生成一个类实例时 xff0c 不
  • C# 的静态构造函数和BeforeFieldInit含义

    1 静态初始化函数 xff1a 静态初始化函数 xff0c C 语法可以保证在一个程序中只调用一次 xff0c 但是会去掉默认的beforefieldinit 标记 xff08 C 默认会加 xff09 xff0c 会导致加载时机的变化 x
  • Unity万向锁

    结论 xff1a 当第二轴旋转 90 时会产生万向锁 xff0c 万向锁只发生在程序中 xff0c 现实世界不会发生 发生万向锁的底层原因是由于程序中会指定旋转顺序 xff0c 且前后顺序为父子包含关系 旋转顺序 xff1a 因为同样一组数
  • python脚本与shell脚本的相互调用

    python脚本与shell脚本的相互调用 python脚本调用shell脚本 xff1a 存在的shell脚本 xff08 test sh sh xff09 xff1a span class token comment bin csh s
  • 自动实现一个minishell更新(增加重定向功能)

    增加重定向功能 1 include lt stdio h gt 2 include lt unistd h gt 3 include lt stdlib h gt 4 include lt string h gt 5 include lt
  • linux sh 运行csh类型脚本报错

    初入linux xff0c 脚本用的是csh版本 xff0c 在尝试的过程中 xff0c 突然发现按照csh的语法写的指令 xff0c 运行不了 xff0c 例如 1 sh xff1a span class token function s
  • QT creator导入现有工程

    QT creator导入现有工程 如果从gitlib或者其他代码库下载了一些源文件 xff0c 用QT creator打开步骤如下 xff1a 点击 菜单栏的 File gt New File or Project点击 Import Pro
  • 腾讯测试开发面试题

    唉 xff0c 今天面试腾讯的测试开发工程师 xff0c 脸被打肿了 xff0c 下来查阅资料 xff0c 把一道面试题讲一讲吧 xff0c 题目是 xff1a O N 求一个数字串能整除3的连续子串的个数 xff0c 前缀和数组 43 对
  • bat命令调用rar进行文件夹压缩

    64 echo off set 34 ymd 61 date 0 4 date 5 2 date 8 2 date 11 2 date 14 2 34 rem ymd 就是当前的时间 例如20181022 34 C Program File
  • vbs执行相应的bat文件

    set ws 61 createobject 34 wscript shell 34 rem 新建一个脚本对象 do rem do loop 执行循环 ws run 34 C Users Administrator Desktop rar
  • 思岚科技RPlidar A3激光雷达ROS源码详解

    思岚科技RPlidar A3激光雷达ROS源码详解 使用 RPLIDARD 的 SDK 其实重点在于看懂client cpp和node cpp两个sample代码 xff0c 因此在这里我们讲从这里入手学习 RPLIDAR A3 的SDK
  • gcc和makefile用法总结(建议收藏)

    文章目录 64 toc 1 用GCC制作静态链接库静态链接库的创建静态链接库的使用 2 用GCC制作动态链接库动态链接库的创建动态链接库的使用 3 GCC找不到库文件怎么办 xff1f GCC生成可执行文件时找不到库文件GCC运行可执行文件