【编译、链接、装载一】预处理、编译、汇编、链接

news2024/11/26 20:18:34

【编译和链接一】预处理、编译、汇编、链接

  • 一、被隐藏了的过程
  • 二、预处理器(Prepressing)——cpp
    • 1、预处理指令
    • 2、预处理过程
    • 3、预处理生成的hello.i文件
  • 三、编译器(Compilation)——cc
    • 1、编译指令
    • 2、编译的过程
    • 3、编译生成的文件(如下图)
  • 四、汇编器(Assembly)——as
    • 1、汇编指令
    • 2、查看汇编生成的目标文件
  • 五、链接器(Linking)——ld
    • 1、链接器
    • 2、查看链接生成的程序
  • 六、执行hello.out
  • 七、gcc能做的事:预处理、编译、汇编、链接
  • 八、其他知识点
    • 1、cc、cc1、ccl、gcc
      • 1.1、cc
      • 1.2、cc1
      • 1.3、ccl
      • 1.4、gcc
      • 1.5、icc
    • 2、cpp
    • 3、gcc、g++
    • 4、问chatGPT:c语言预处理、编译、汇编、链接这四个过程,在linux分别由哪些实现方式
    • 5、问chatGPT:c语言预处理生成的hello.i文件,除了使用gcc可以编译成hello.s文件,还有哪些方式可以编译成hello.s文件

简介

对于平常的应用程序开发,我们很少需要关注编译和链接过程,因为通常的开发环境都是流行的集成开发环境(IDE),比如Visual Studio等。这样的IDE一般都将编译和链接的过程一步完成,通常将这种编译和链接合并到一起的过程称为构建(Build)。即使使用命令行来编译一个源代码文件,简单的一句“gcc hello.c”命令就包含了非常复杂的过程。

IDE和编译器提供的默认配置、编译和链接参数对于大部分的应用程序开发而言已经足够使用了。但是在这样的开发过程中,我们往往会被这些复杂的集成工具所提供的强大功能所迷惑,很多系统软件的运行机制与机理被掩盖,其程序的很多莫名其妙的错误让我们无所适从,面对程序运行时种种性能瓶颈我们束手无策。我们看到的是这些问题的现象,但是却很难看清本质,所有这些问题的本质就是软件运行背后的机理及支撑软件运行的各种平台和工具,如果能够深入了解这些机制,那么解决这些问题就能够游刃有余,收放自如了。

一、被隐藏了的过程

C语言的经典,“Hello World”程序。

使用c语言做例子吧,我使用cpp的预处理过,但是预处理的文件太长了。

#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}

在Linux下,当我们使用GCC来编译Hello World程序时,只须使用最简单的命令(源代码文件名为hello.c):

$gcc hello.c
$./a.out

Hello World事实上,上述过程可以分解为4个步骤,分别是预处理(Prepressing)、编译(Compilation)、汇编(Assembly)和链接(Linking),如图所示。
在这里插入图片描述

二、预处理器(Prepressing)——cpp

  • 预处理有的文章中,也被称为预编译

1、预处理指令

  • 使用预处理器cpp
    会把.c文件预处理成一个.i文件。
$cpp hello.c > hello.i
  • 实战
    在这里插入图片描述

2、预处理过程

预处理过程主要处理那些源代码文件中的以“#”开始的预编译指令。比如 “#include”、“#define ”等,主要处理规则如下:

  • 将所有的 “#define ”删除,并且展开所有的宏定义。
  • 处理所有条件预编译指令,比如 “#if”、“#ifdef”、“#elif”、“#else”、“#endif ”。
  • 处理 “#include ”预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,也就是说被包含的文件可能还包含其他文件。
  • 删除所有的注释“//”和“/* */”。
  • 添加行号和文件名标识,比如#2“hello.c”2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。
  • 保留所有的 #pragma 编译器指令,因为编译器须要使用它们。

经过预编译后的.i文件不包含任何宏定义,因为所有的宏已经被展开,并且包含的文件也已经被插入到.i文件中。所以当我们无法判断宏定义是否正确或头文件包含是否正确时,可以查看预编译后的文件来确定问题。

3、预处理生成的hello.i文件

在这里插入图片描述

三、编译器(Compilation)——cc

1、编译指令

编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件,这个过程往往是我们所说的整个程序构建的核心部分,也是最复杂的部分之一。我们将在下一节简单介绍编译的具体几个步骤,这涉及编译原理等一些内容,由于它不是本书介绍的核心内容,所以也仅仅是介绍而已。

目前公司产品有用到这部分的内容,因为公司产品中有自己的语言。但是产品底层的词法分析和语法分析等部分不是我负责的。后面有机会的话继续深入的了解下。

上面的编译过程相当于如下命令:

$cc hello.i -S -o hello.s

可以得到汇编输出文件hello.s

2、编译的过程

  • 词法分析
  • 语法分析
  • 语义分析
  • 中间语言生成
  • 目标代码生成与优化

3、编译生成的文件(如下图)

后面分一篇文章,详细的介绍下以下的指令都是什么意思。
在这里插入图片描述

四、汇编器(Assembly)——as

1、汇编指令

汇编器是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。所以汇编器的汇编过程相对于编译器来讲比较简单,它没有复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译就可以了,“汇编”这个名字也来源于此。

  • 上面的汇编过程我们可以调用汇编器as来完成:
$as hello.s -o hello.o
  • 实战
    汇编生成的目标文件hello.o如下图所示
    在这里插入图片描述

2、查看汇编生成的目标文件

$objdump -h hello.o

在这里插入图片描述

五、链接器(Linking)——ld

1、链接器

  • 链接器是一个将编译器产生的目标文件打包成可执行文件或者库文件或者目标文件的程序。
    从这句话可以看出,链接器实际上是一个程序,它的输入是编译器产生的目标文件,输出是库、可执行文件或者其它目标文件。

目标文件:.so 文件生成.out文件

链接的指令

ld /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbeginT.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib64 -L/usr/lib --start-group -lgcc -lgcc_eh -lc --end-group hello.o -o hello.out

或者

ld /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbeginT.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib64 -L/usr/lib -lstdc++ -lm -lgcc_s -lc -lgcc hello.o -o hello.out

2、查看链接生成的程序

$objdump -h hello.out
  • 从下图可知,从汇编的6个,链接后变成了23个。

在这里插入图片描述在这里插入图片描述

六、执行hello.out

$./hello.out

在这里插入图片描述

  • 执行报错bash: ./test.out: /lib/ld64.so.1: bad ELF interpreter: 没有那个文件或目录?

bash: ./test.out: /lib/ld64.so.1: bad ELF interpreter: 没有那个文件或目录

解决方案见:/lib/ld64.so.1: bad ELF interpreter: 没有那个文件或目录,因为这个问题不太好处理,所以单独分了一篇文章,记录下解决问题的过程。

七、gcc能做的事:预处理、编译、汇编、链接

上面预处理、编译、汇编、链接,我们分别使用了cpp、cc、as、ld。
其实,预处理、编译、汇编、链接这四个过程,gcc自己就能干完了。

  • 1、使用gcc预处理(-E表示只进行预编译)。
$gcc -E hello.c -o hello.i
  • 2、编译
$gcc -S hello.i -o hello.s

或者使用如下命令:

$gcc -S hello.c -o hello.s

  • 3、汇编
$gcc -c hello.s -o hello.o 

或者使用gcc命令从C源代码文件开始,经过预编译、编译和汇编直接输出目标文件(Object File):

$gcc -c hello.c -o hello.o

备注:
gcc -c hello.c -o hello.o小写的-c才是仅仅汇编,
gcc -C hello.c -o hello.o如果是大写的-C,会进行链接的。

  • 4、链接
$gcc hello.o -o hello.out
或者
$gcc hello.o -o hello
  • 5、执行
    在这里插入图片描述
  • 5、查看gcc指令
[dev1@localhost test01]$ gcc --help
用法:gcc [选项] 文件...
选项:
  -pass-exit-codes         在某一阶段退出时返回最高的错误码
  --help                   显示此帮助说明
  --target-help            显示目标机器特定的命令行选项
  --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]
                           显示特定类型的命令行选项
  (使用‘-v --help’显示子进程的命令行参数)
  --version                显示编译器版本信息
  -dumpspecs               显示所有内建 spec 字符串
  -dumpversion             显示编译器的版本号
  -dumpmachine             显示编译器的目标处理器
  -print-search-dirs       显示编译器的搜索路径
  -print-libgcc-file-name  显示编译器伴随库的名称
  -print-file-name=<库>    显示 <库> 的完整路径
  -print-prog-name=<程序>  显示编译器组件 <程序> 的完整路径
  -print-multiarch         Display the target's normalized GNU triplet, used as
                           a component in the library path
  -print-multi-directory   显示不同版本 libgcc 的根目录
  -print-multi-lib         显示命令行选项和多个版本库搜索路径间的映射
  -print-multi-os-directory 显示操作系统库的相对路径
  -print-sysroot           显示目标库目录
  -print-sysroot-headers-suffix 显示用于寻找头文件的 sysroot 后缀
  -Wa,<选项>               将逗号分隔的 <选项> 传递给汇编器
  -Wp,<选项>               将逗号分隔的 <选项> 传递给预处理器
  -Wl,<选项>               将逗号分隔的 <选项> 传递给链接器
  -Xassembler <参数>       将 <参数> 传递给汇编器
  -Xpreprocessor <参数>    将 <参数> 传递给预处理器
  -Xlinker <参数>          将 <参数> 传递给链接器
  -save-temps              不删除中间文件
  -save-temps=<arg>        不删除中间文件
  -no-canonical-prefixes   生成其他 gcc 组件的相对路径时不生成规范化的
                           前缀
  -pipe                    使用管道代替临时文件
  -time                    为每个子进程计时
  -specs=<文件>            用 <文件> 的内容覆盖内建的 specs 文件
  -std=<标准>              指定输入源文件遵循的标准
  --sysroot=<目录>         将 <目录> 作为头文件和库文件的根目录
  -B <目录>                将 <目录> 添加到编译器的搜索路径中
  -v                       显示编译器调用的程序
  -###                     与 -v 类似,但选项被引号括住,并且不执行命令
  -E                       仅作预处理,不进行编译、汇编和链接
  -S                       编译到汇编语言,不进行汇编和链接
  -c                       编译、汇编到目标代码,不进行链接
  -o <文件>                输出到 <文件>
  -pie                     Create a position independent executable
  -shared                  Create a shared library
  -x <语言>                指定其后输入文件的语言
                           允许的语言包括:c c++ assembler none
                           ‘none’意味着恢复默认行为,即根据文件的扩展名猜测
                           源文件的语言

以 -g、-f、-m、-O、-W 或 --param 开头的选项将由 gcc 自动传递给其调用的
 不同子进程。若要向这些进程传递其他选项,必须使用 -W<字母> 选项。

报告程序缺陷的步骤请参见:
<http://bugzilla.redhat.com/bugzilla>.

八、其他知识点

1、cc、cc1、ccl、gcc

1.1、cc

  • 一般的CC就是一个软件链接到GCC的。只不过CC是UNIX中常用的编译工具,而在linux中用的是GCC,有一些在UNIX中写好的程序要放在linux中要指定命令CC编译器,所以将CC指定为GCC。其实就是一个东西。
  • 从下图,我们可以看到,cc和gcc链接的库都一致,所以说他们是一个东西的说法是正确的,但是并不是cc链接了gcc.
    在这里插入图片描述

1.2、cc1

cc1是windows系统下提供的编译器,安装MinGW后,再安装gcc可以就可以看到,作用同gcc.

linux下也有,在/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1

在这里插入图片描述

1.3、ccl

  • 很多书籍和文章都说链接器使用ccl,但是我们并找不到ccl的指令。(除非自己吧gcc改名为ccl例外)。
  • 能找到的和编译相关的cll,链接如下

a:
Compiling Directly via the CCL Compiler,从网站我们可以看到,其生成的目标文件是.ccx,而非.s文件。而从下文可以看到其名字叫做c8_compiler 。

This section describes the CCL compiler, and how to invoke it on different platforms.
The CCL compiler is a separate program, which can be invoked by the user.The name of the program is c8_compiler (or c8_compiler.exe on Microsoft Windows) //软件的名字叫c8_compiler

b:
CCL
https://github.com/Clozure/ccl

Because CCL is written in itself, you need an already-working version of CCL to compile it.

b这个ccl,虽然和语言相关,但是并非是c语言的编译器。

c:
https://www.researchgate.net/figure/CCL-compiler-and-interpreter_fig1_228539904

综上所述:很多书籍中提到的ccl编译命令是不存在的,正确的应该是cc1\cc\gcc。

1.4、gcc

GCC:全称GNU Compiler Collection,GNU编译器套装,是广泛应用的Linux系统的默认编译器(特别是用于编译Linux内核)。GCC能够支持多种架构的处理器,跨平台特性相对出色。不过,GNU组织要求全部的代码由自己完成(防止版权问题),所以GCC虽然有广泛的硬件支持,但是在各硬件平台上却并不是性能最优的编译器。

1.5、icc

ICC:全称Intel C++ Compiler,是Intel开发的C/C++/Fortran编译器套装,适用于Linux、Microsoft和Mac OS X操作系统,没有非IA指令集版本(就是说仅供x86架构CPU使用)。ICC广泛应用于高性能计算、分布式计算等商业计算领域,其向量化和并行化性能是业界的标杆,能够充分发挥现代处理器的特性。

2、cpp

参考:
Oracle_手册页部分_用户命令_用户命令cpp

  • 名称
    cpp - C 语言预处理程序
  • 用法概要
/usr/lib/cpp [-BCHMpPRT] [
-undef] [-Dname] [
-Dname = def] 
     [-Idirectory] [-U
name] [-Ydirectory] 
     [input-file [output-file]]
  • 描述
    cpp 是 C 语言预处理程序。cpp 还用作其他 Sun 编译器的第一遍操作的预处理程序。
    cpp 可以接受两个文件名作为参数。 input-file 和 output-file 分别是用于预处理程序的输入和输出文件。缺省情况下,它们是标准输入和标准输出。

3、gcc、g++

gcc和g++是什么,有什么区别?

发展至今(2020 年 6 月份),GCC 编译器已经更新至 10.1.0 版本,其功能也由最初仅能编译 C 语言,扩增至可以编译多种编程语言,其中就包括 C++ 。

除此之外,当下的 GCC 编译器还支持编译 Go、Objective-C,Objective-C ++,Fortran,Ada,D 和 BRIG(HSAIL)等程序,甚至于 GCC 6 以及之前的版本还支持编译 Java 程序。但本教程主要讲解如何使用 GCC 编译器编译运行 C 和 C++ 程序,因此有关其它编程语言如何使用 GCC 编译器编译,将不再做具体讲解。

那么,在已编辑好 C 语言或者 C++ 代码的前提下,如何才能调用 GCC 编译器为我们编译程序呢?很简单,GCC 编译器已经为我们提供了调用它的接口,对于 C 语言或者 C++ 程序,可以通过执行 gcc 或者 g++ 指令来调用 GCC 编译器。

值得一提的是,实际使用中我们更习惯使用 gcc 指令编译 C 语言程序,用 g++ 指令编译 C++ 代码。需要强调的一点是,这并不是 gcc 和 g++ 的区别,gcc 指令也可以用来编译 C++ 程序,同样 g++ 指令也可以用于编译 C 语言程序。

那么,gcc 和 g++ 的区别是什么呢?接下来就给读者做详细的讲解。

实际上,只要是 GCC 支持编译的程序代码,都可以使用 gcc 命令完成编译。可以这样理解,gcc 是 GCC 编译器的通用编译指令,因为根据程序文件的后缀名,gcc 指令可以自行判断出当前程序所用编程语言的类别,比如:

  • xxx.c:默认以编译 C 语言程序的方式编译此文件;
  • xxx.cpp:默认以编译 C++ 程序的方式编译此文件。
  • xxx.m:默认以编译 Objective-C 程序的方式编译此文件;
  • xxx.go:默认以编译 Go 语言程序的方式编译此文件;

当然,gcc 指令也为用户提供了“手动指定代表编译方式”的接口,即使用 -x 选项。例如,gcc -xc xxx 表示以编译 C 语言代码的方式编译 xxx 文件;而 gcc -xc++ xxx 则表示以编译 C++ 代码的方式编译 xxx 文件。有关 -x 选项的用法,后续会给出具体样例。

但如果使用 g++ 指令,则无论目标文件的后缀名是什么,该指令都一律按照编译 C++ 代码的方式编译该文件。也就是说,对于 .c 文件来说,gcc 指令以 C 语言代码对待,而 g++ 指令会以 C++ 代码对待。但对于 .cpp 文件来说,gcc 和 g++ 都会以 C++ 代码的方式编译。

4、问chatGPT:c语言预处理、编译、汇编、链接这四个过程,在linux分别由哪些实现方式

chatGPT答复如下:

在Linux系统上,C语言预处理、编译、汇编和链接这四个过程可以使用以下工具实现:

  1. 预处理 - 可以使用GNU C Preprocessor (cpp)工具进行预处理。例如,在终端中输入以下命令来生成预处理后的代码:
   cpp hello.c > hello.i
  1. 编译 - 可以使用GCC(GNU Compiler Collection)或Clang等C语言编译器进行编译。例如,在终端中输入以下命令将预处理后的代码编译成目标文件:
   gcc -c hello.i -o hello.o
  1. 汇编 - 可以使用GNU Assembler (gas)或其他汇编器将编译后的目标文件转换为汇编代码。例如,在终端中输入以下命令将目标文件汇编成汇编代码:
   objdump -d hello.o > hello.s
  1. 链接 - 可以使用GNU Linker (ld)或其他链接器将多个目标文件连接成一个可执行文件。例如,在终端中输入以下命令将多个目标文件链接成可执行文件:
   gcc -o hello hello.o

请注意,不同的Linux系统可能会使用不同的工具和命令来进行C语言编译和开发。以上示例仅供参考,实际操作时应根据自己的需求和情况进行调整。

5、问chatGPT:c语言预处理生成的hello.i文件,除了使用gcc可以编译成hello.s文件,还有哪些方式可以编译成hello.s文件

除了使用GCC编译器,您可以使用其他C语言编译器或预处理工具来将预处理后的"hello.i"文件编译成汇编代码(".s"文件)。例如:

  1. Clang - Clang是另一个流行的开源C语言编译器,与GCC类似,可以将预处理后的C源文件编译成汇编代码。您可以使用以下命令生成汇编代码文件:

    clang -S hello.i

  2. LLVM IR - LLVM IR是一种中间表示形式,可以通过LLVM编译器将其转换为汇编代码。您可以使用以下命令将预处理后的C源文件编译为LLVM IR:

    clang -emit-llvm -S hello.i

    然后,您可以使用以下命令将LLVM IR编译为汇编代码:

    llc -march=x86-64 hello.ll -o hello.s

  3. CPP - 除了使用C语言编译器,您还可以使用预处理工具CPP将预处理后的C源文件转换为汇编代码。您可以使用以下命令生成汇编代码文件:

    cpp hello.i > hello.cpp
    g++ -S hello.cpp

请注意,不同的编译器和工具可能会产生不同的汇编代码,因此生成的".s"文件可能会有所不同。

参考
1、《程序员的自我修养链接装载与库》
2、深入理解计算机系统第七章 链接知识整理
3、C编译器翻译c程序的四个阶段
4、程序员C语言快速上手——工程篇(十二)
5、GCC命令 (预处理cpp --> 编译ccl --> 汇编as --> 链接ld)(转载)
6、GCC\LD

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

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

相关文章

chatgpt赋能python:Python读取Mat文件的完整教程

Python 读取Mat文件的完整教程 在数据科学领域&#xff0c;Matlab&#xff08;或简称Mat&#xff09;是最受欢迎的编程语言之一。Matlab可用于数学计算、数据预处理、建模和数据分析。然而&#xff0c;Matlab的开销和许可证成本会限制公司和个人的使用。因此&#xff0c;Pytho…

渗透必学神器:BurpSuite教程(一)

0x00 前言 Burp Suite (简称BP&#xff0c;下同)是用于攻击web 应用程序的集成平台。它包含了许多工具&#xff0c;并为这些工具设计了许多接口&#xff0c;以促进加快攻击应用程序的过程。 从本节开始将为大家陆续带来BP各个模块的使用说明 0x01 中间人攻击 中间人攻击&am…

ChatGPT | Bing | Google Bard | 讯飞星火 | 到底哪家强?实测

最近AIGC战场依然热闹&#xff0c;微软的new bing、Google的Bard、国内的讯飞星火认知大模型&#xff0c;都接连上阵&#xff0c;我们对比ChatGPT一起来看看&#xff0c;我把实际使用测试结果发出&#xff0c;供大家参考。有些测试结果可能会出乎大家的预料哦… 今天我们暂时主…

第十四章 (Set)

一、Set 接口&#xff08;P518&#xff09; 1. Set 接口基本介绍 &#xff08;1&#xff09;无序&#xff08;添加和取出的顺序不一致&#xff09;&#xff0c;没有索引。 &#xff08;2&#xff09;不允许重复元素&#xff0c;所以最多包含一个 null。 2. Set 接口的常用方法…

阿里云服务器ECS云盘扩容

前言 对于云服务器&#xff0c;相信大多数开发的铁子们都玩过&#xff0c;但是云盘爆满的情况&#xff0c;对于新手或者没有自己运营业务的铁子们&#xff0c;平台给的初始容量也不算小&#xff0c;所以这种情况碰到的概率还是比较小。由于我的服务器应用的复杂度随着业务的发…

ubuntu安装搜狗输入法,图文详解+踩坑解决

搜狗输入法已支持Ubuntu16.04、18.04、19.10、20.04、20.10&#xff0c;本教程系统是基于ubuntu18.04 一、添加中文语言支持 系统设置—>区域和语言—>管理已安装的语言—>在“语言”tab下—>点击“添加或删除语言”。 弹出“已安装语言”窗口&#xff0c;勾选中文…

chatgpt赋能python:Python在SEO领域的优势

Python在SEO领域的优势 Python作为一种高效、灵活的编程语言&#xff0c;已经被广泛应用于多个领域&#xff0c;包括Web应用、数据科学、自然语言处理等。在SEO领域&#xff0c;Python也有其独特的优势。 爬虫 Python强大的爬虫库和框架&#xff0c;如BeautifulSoup、Scrapy…

chatgpt赋能python:Python行列转换教程:如何轻松实现行列转换

Python行列转换教程&#xff1a;如何轻松实现行列转换 在数据处理和分析中&#xff0c;经常需要将行和列进行转换。Python是一种优秀的编程语言&#xff0c;提供了多种方法来实现行列转换。在本教程中&#xff0c;我们将介绍如何使用Python实现行列转换&#xff0c;并提供简单…

《Spring Guides系列学习》guide66 - guide68及小结

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gui…

深入了解Golang中的反射机制

目录 反射 反射的分类 值反射 类型反射 运行时反射 编译时反射 接口反射 结构体反射 常用函数 值反射 类型反射 值反射和类型反射的区别 结构体反射 示例代码 反射 反射是指在程序运行时动态地检查和修改对象的能力。在Go语言中&#xff0c;通过反射可以在运行时…

chatgpt赋能python:Python逆序对:什么是逆序对,如何使用Python进行逆序对计算?

Python逆序对&#xff1a;什么是逆序对&#xff0c;如何使用Python进行逆序对计算&#xff1f; 在计算机科学中&#xff0c;逆序对是指在一个数组中&#xff0c;如果存在下标i < j&#xff0c;但是a[i] > a[j]&#xff0c;则a[i]和a[j]构成一个逆序对。逆序对对于理解和…

pthread多线程:传入参数并检查 data race

文章目录 1. 目的2. 给子线程传入参数&#xff1a;万能类型 void*3. data race3.1 什么是 data race3.2 怎样检测 data race 4. data race 的例子4.1 子线程传入同一个 data4.2 使用栈内存 5. 解决 data race 问题5.1 忽视问题&#xff1f;5.2 避开同一个变量的使用5.3 使用互斥…

Office project 2010安装教程

哈喽&#xff0c;大家好。今天一起学习的是project 2010的安装&#xff0c;Microsoft Office project项目管理工具软件&#xff0c;凝集了许多成熟的项目管理现代理论和方法&#xff0c;可以帮助项目管理者实现时间、资源、成本计划、控制。有兴趣的小伙伴也可以来一起试试手。…

每天一道面试题之String str=“i“与 String str=new String(“i”)一样吗?

String str"i"与 String strnew String(“i”)一样吗&#xff1f; 要想知道二者是否一样&#xff0c;我们只需要通过进行比较&#xff0c;为什么不用equals的原因&#xff0c;大家可以认真阅读这篇文章 测试代码如下&#xff1a; public class Test1 {public stati…

chatgpt赋能python:Python选择器:优化你的SEO

Python 选择器&#xff1a;优化你的SEO 介绍 随着搜索引擎优化(SEO)变得越来越重要&#xff0c;Web 开发人员需要采取各种措施来提高网站的搜索排名。其中之一就是通过使用正确的 HTML 标签和优秀的内容来提高搜索引擎爬虫对网站的理解。这时候 Python 选择器就变得尤为重要。…

chatgpt赋能python:Python选择函数

Python 选择函数 Python是一种流行的编程语言&#xff0c;是许多开发人员的首选。在Python中&#xff0c;有许多函数可供开发人员使用。这些函数不仅提高了开发的速度&#xff0c;而且还可以帮助我们更快地解决许多问题。在本文中&#xff0c;我们将重点介绍Python选择函数。 …

iostat详解

iostat在centOS中默认没有 安装 yum install sysstat 使用 iostat -dxk 5 rrqm/s 每秒进入队列的合并读写请求数 wrqm/sr/s每秒发送到设备的读写请求数w/srKB/s每秒读写的吞吐量&#xff0c;单位KBwKB/savgrq-sz 以扇区为大小的请求大小 avgqu-sz设备队列中等待的请求数await在…

HNU-电路与电子学-综合设计-模型机

写在前面&#xff1a; 每一年的综合设计肯定都有改动&#xff0c;故肯定不能照搬照抄&#xff0c;大家可以借鉴思路&#xff0c;复现成果&#xff0c;但要注意不同之处&#xff0c;以免被0分处理。 模型设计的指导书我不放在这里了&#xff0c;因为那是课程组老师们的成果。 …

HNU-电路与电子学-学习建议

电路与电子学我考的并不好&#xff0c;最后总评只有85分。 &#xff08;主要是期末考太差了&#xff0c;只有70分&#xff0c;前面基本全拿满了&#xff0c;也无济于事&#xff09; 但我自认为学的还可以&#xff0c;于是写下一些感想。 我姑妄言之&#xff0c;诸位姑妄信之…

【华为OD机试】投骰子【2023 B卷|200分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 骰子是一个立方体,每个面一个数字,初始为左1,右2,前3(观察者方向),后4,上5,下6, 用123456表示这个状态,放置在平面上, 可以向左翻转(用L表示向左翻转1次), 可以向右翻转(用…