当前位置: 首页 > news >正文

C++基础Ⅰ编译、链接

目录儿

  • 1 C++是如何工作的
    • 1.1 预处理语句
    • 1.2 include
    • 1.3 main()
    • 1.4 编译
      • 单独编译
      • 项目编译
    • 1.5 链接
  • 2 定义和调用函数
  • 3 编译器如何工作
    • 3.1 编译
      • 3.1.1 引入头文件
        • 系统头文件
        • 自定义头文件
      • 3.1.2 自定义类型
      • 3.1.3 条件判断
      • 拓展: 汇编
    • 3.2 链接
      • 3.2.1 起始函数
      • 3.2.2 被调用的函数
    • 3.3 总结,编译和链接的区别

1 C++是如何工作的

工具:Visual Studio

1.1 预处理语句

.cpp源文件中,所有#字符开头的语句为预处理语句

例如在下面的 Hello World 程序中

#include<iostream>int main() {std::cout <"Hello World!"<std::endl;std::cin.get();
}

#include<iostream>就是一个预处理语句(pre-process statement),编译器在加载源文件的时候,识别到#开头的语句,会优先处理这个语句,所以称为预处理语句。

注意:预处理语句是在 编译器加载源文件的时候处理的,那个时候还没有发生编译动作

1.2 include

include关键字的含义就是找到<xxx>里面指定名称的文件,然后把文件里面的内容拷贝到当前文件,以供调用;

这个被导入的文件称为头文件;

1.3 main()

main()函数是程序的入口,计算机从main()函数开始运行程序,每个程序都要有一个main()函数;

main()函数的返回值是int类型,但是在 Hello World 程序中我们没有返回任何值,这是因为main()函数比较特殊,如果没有显式返回一个int值,他会默认返回0

1.4 编译

单独编译

当写好了一个源文件,就可以对其进行编译操作,在Visual Studio上直接按快捷键ctrl + F7,或者点击编译按钮执行编译
在这里插入图片描述
编译结果在输出窗口就能看到:
在这里插入图片描述
注意,此时我们是针对一个源文件进行单独编译,而不是编译整个项目。

每次编译需要指定规则和目标平台
在这里插入图片描述

  • 规则:
    默认分为DebugRelease,代表着编译代码时按照设置选择的的规则设置进行编译,这些规则是可以自行设置的,但一般都用默认设置。比如在 Debug 规则的默认设置中,不会对程序进行优化
    在这里插入图片描述
    Release 规则的默认设置中,则会对程序进行链接优化
    在这里插入图片描述
  • 目标平台:
    意思就是你这个代码编译后是用在哪个平台的,比如x86/windows64位x64/windows32位或者是Android等移动平台(因为C++是不能跨平台运行的,所以不同的目标平台编译出来的二进制码不一样,不像Java

打开项目目录可以看到,在不同的规则下编译生成的文件分别放在不同的目录下面:
在这里插入图片描述
在目录里面可以看到.cpp文件编译生成的.obj文件
在这里插入图片描述
打开看, 里面的内容都是二进制机器码
在这里插入图片描述

项目编译

在资源文件窗口中,项目名称→右键→生成,这也是一个编译操作,但此时是编译整个项目;
它会把项目中的每个.cpp文件编译成.obj文件,然后再把这些.obj文件链接成一个程序比如.exe程序;
在这里插入图片描述
在输出窗口可以看到生成了一个.exe文件
在这里插入图片描述
打开对应的目录就能看到
在这里插入图片描述

1.5 链接

链接比较复杂,大概就是一个C++项目通常都包含这很多个源文件,而编译后每一个源文件对应地都会生成一个.obj二进制码文件,然后链接的作用就是把这些二进制码文件链接起来构成一个完整的项目。

2 定义和调用函数

写在同一个文件中:

#include<iostream>void Log(const char* message) {std::cout << message << std::endl;
}int main() {Log("Hello World!");std::cin.get();
}

写在不同的文件中:
在这里插入图片描述
Log.cpp

#include<iostream>void Log(const char* message) {std::cout << message << std::endl;
}

Main.cpp

#include<iostream>void Log(const char* message);
//void Log(const char*); // 声明函数时可以忽略参数名int main() {Log("Hello World!");std::cin.get();
}

想要在Main.cpp文件中调用Log函数,必须先声明,声明函数和定义函数的区别就是一个有方法体,一个没有方法体;

这里注意的点是,编译器在编译单个Main.cpp这个源代码文件的时候,并不会去检查这个声明的函数是否真实存在,而且编译单个文件的时候不会对编译文件进行链接;
但是当运行或者编译整个项目的时候,也就是进行文件链接的时候,如果声明的函数不存在,就会报错:
在这里插入图片描述

3 编译器如何工作

首先需要知道,编译分为两个阶段: 编译 + 链接

3.1 编译

不经过设置时, 执行编译默认会直接编译成.obj文件, 直接就是二进制码了
为了能够搞清楚从 源代码 → 二进制码 的过程中发生了什么, 我们接下来就先不直接编译成.obj文件
而是先把编译过程中预处理后产生的内容输出成文件, 看看预处理都处理了啥.

3.1.1 引入头文件

前面说过,编译器处理#include<xxx>这个语句就是把对应的xxx头文件里面的内容copy到当前文件中#include语句所在的地方

下面来证实一下
首先打开项目属性:
在这里插入图片描述
这一步是为了让编译器在预编译后把内容输出成一个文件, 这样我们就可以看到预编译的内容了, 注意这个设置也是精确到配合和平台的, 选择所有配置和自己的操作系统平台就行;

注意: 修改了输出预编译文件后, 编译器就不会输出.obj文件, 所以做完实验就要把它改回去!!

系统头文件

Main.cpp中, 我们引入了iostream头文件

#include<iostream>int main() {std::cout << "Hello World!" << std::endl;std::cin.get();
}

编译一下, 生成的.i文件就是预编译文件
在这里插入图片描述
可以发现这个文件有1.6M大, 我只写了几行代码
直接打开看
在这里插入图片描述
会发现这个文件有6万多行, 这些内容就是从iostream头文件中copy过来的, 所以整个文件很大
这就印证了#inclued引入语句的作用.

自定义头文件

下面我们要编译这个Mutiply.cpp

int Mutiply(int a, int b) {int result = a * b;return result;

可以看到这个函数是缺少了一个}的, 故意的
接下来创建一个头文件EndBrace.h
在这里插入图片描述
头文件里面的内容就是一个}

}

接下来在Mutiply.cpp中引入这个EndBrace.h头文件
在这里插入图片描述
引入后Mutiply.cpp内容如下:

int Mutiply(int a,int b) {int result = a * b;return result;
#include"EndBrace.h"

好,接下来编译一下这个Mutiply.cpp源文件
在项目对应目录中可以看到生成了一个Mutiply.i文件, 这个就是预编译生成的文件
在这里插入图片描述
直接打开看内容

#line 1 "D:\\workspace\\CPP\\cherno\\cherno\\Mutiply.cpp"int Mutiply(int a,int b) {int result = a * b;return result;#line 1 "D:\\workspace\\CPP\\cherno\\cherno\\EndBrace.h"
}
#line 5 "D:\\workspace\\CPP\\cherno\\cherno\\Mutiply.cpp"

忽略那些#line语句, 可以看到EndBrace.h头文件中的}被复制到了Mutiply.cpp

注意,在c++中,引入头文件有两种方式:

  • #include<>这个语法用于引入系统头文件, 这种引入方式下预处理器会在标准系统目录中搜索这些文件。例如引入iostream头文件,可以使用#include <iostream>
  • #include ""语法用于引入用户定义的头文件, 这种引入方式下预处理器会首先在当前目录中搜索这些文件,如果没有找到,则在标准系统目录中搜索。例如,如果当前目录中有一个名为myheader.h的头文件,则可以使用#include "myheader.h"将其包含到程序中。

3.1.2 自定义类型

还是在Mutiply.cpp中做修改,

#define ECHOO intECHOO Mutiply(int a, int b) {ECHOO result = a * b;return result;
}

这里我自定义了一个ECHOO类型, 实际上是一个int类型
然后我在Mutiply定义中用了这个ECHOO类型代替原来的int

接下来编译看一下预编译生成的文件内容:

#line 1 "D:\\workspace\\CPP\\cherno\\cherno\\Mutiply.cpp"
int Mutiply(int a, int b) {int result = a * b;return result;
}

编译器自动把ECHOO替换成了它的实际类型int,
所以说#define实际上是自定义别名, 用一个别名代替实际的类型或者字符,符号
这也是C++灵活的地方,可以给各种类型, 符号自定义别名

再改一下, 用ECHOO代替Hello

#define ECHOO HelloECHOO Mutiply(int a, int b) {ECHOO result = a * b;return result;
}

预编译:

#line 1 "D:\\workspace\\CPP\\cherno\\cherno\\Mutiply.cpp"
Hello Mutiply(int a, int b) {Hello result = a * b;return result;
}

有点意思

3.1.3 条件判断

改一下Mutiply.cpp, 用#if语句来做条件判断

#if 0
int MutiplyOne(int a, int b) {int result = a * b;return result;//#include "EndBrace.h"
}
#endif // 0#if 1
int MutiplyTwo(int a, int b) {int result = a * b;return result;//#include "EndBrace.h"
}
#endif // 1

函数MutiplyOne#if 0#endif包起来了
函数MutiplyTwo#if 1#endif包起来了

预编译:

#line 1 "D:\\workspace\\CPP\\cherno\\cherno\\Mutiply.cpp"
#line 8 "D:\\workspace\\CPP\\cherno\\cherno\\Mutiply.cpp"
int MutiplyTwo(int a, int b) {int result = a * b;return result;
}
#line 17 "D:\\workspace\\CPP\\cherno\\cherno\\Mutiply.cpp"

函数MutiplyOne不能被预编译
函数MutiplyTwo能正常被预编译
非常明显, 是因为判断条件的原因
我们可以通过#if condition这个语句来动态地禁用 / 启用某一段代码, 非常灵活
有点儿意思

拓展: 汇编

通过Visual Studio可以输出汇编文件, 设置一下汇编程序输出
,
接下来编译Mutiply.cpp:

int MutiplyOne(int a, int b) {int result = a * b;return result;//#include "EndBrace.h"
}

在项目目录中生成的.asm文件就是生成的汇编程序文件
在这里插入图片描述
打开可以看到一条一条的汇编指令,

; Listing generated by Microsoft (R) Optimizing Compiler Version 19.36.32537.0 include listing.incINCLUDELIB MSVCRTD
INCLUDELIB OLDNAMESmsvcjmc	SEGMENT
__B1702CDC_Mutiply@cpp DB 01H
msvcjmc	ENDS
PUBLIC	?MutiplyOne@@YAHHH@Z				; MutiplyOne
PUBLIC	__JustMyCode_Default
EXTRN	_RTC_InitBase:PROC
EXTRN	_RTC_Shutdown:PROC
EXTRN	__CheckForDebuggerJustMyCode:PROC
;	COMDAT pdata
pdata	SEGMENT
$pdata$?MutiplyOne@@YAHHH@Z DD imagerel $LN3DD	imagerel $LN3+63DD	imagerel $unwind$?MutiplyOne@@YAHHH@Z
pdata	ENDS
;	COMDAT rtc$TMZ
rtc$TMZ	SEGMENT
_RTC_Shutdown.rtc$TMZ DQ FLAT:_RTC_Shutdown
rtc$TMZ	ENDS
;	COMDAT rtc$IMZ
rtc$IMZ	SEGMENT
_RTC_InitBase.rtc$IMZ DQ FLAT:_RTC_InitBase
rtc$IMZ	ENDS
;	COMDAT xdata
xdata	SEGMENT
$unwind$?MutiplyOne@@YAHHH@Z DD 025051601HDD	01112316HDD	0700a0021HDD	05009H
xdata	ENDS
; Function compile flags: /Odt
;	COMDAT __JustMyCode_Default
_TEXT	SEGMENT
__JustMyCode_Default PROC				; COMDATret	0
__JustMyCode_Default ENDP
_TEXT	ENDS
; Function compile flags: /Odtp /RTCsu /ZI
;	COMDAT ?MutiplyOne@@YAHHH@Z
_TEXT	SEGMENT
result$ = 4
a$ = 256
b$ = 264
?MutiplyOne@@YAHHH@Z PROC				; MutiplyOne, COMDAT
; File D:\workspace\CPP\cherno\cherno\Mutiply.cpp
; Line 2
$LN3:mov	DWORD PTR [rsp+16], edxmov	DWORD PTR [rsp+8], ecxpush	rbppush	rdisub	rsp, 264				; 00000108Hlea	rbp, QWORD PTR [rsp+32]lea	rcx, OFFSET FLAT:__B1702CDC_Mutiply@cppcall	__CheckForDebuggerJustMyCode
; Line 3mov	eax, DWORD PTR a$[rbp]imul	eax, DWORD PTR b$[rbp]mov	DWORD PTR result$[rbp], eax
; Line 4mov	eax, DWORD PTR result$[rbp]
; Line 6lea	rsp, QWORD PTR [rbp+232]pop	rdipop	rbpret	0
?MutiplyOne@@YAHHH@Z ENDP				; MutiplyOne
_TEXT	ENDS
END

看汇编指令在某些需要极致性能优化的时候会很有用, 但一般很少没多少人会这样做.

3.2 链接

当源文件被编译成一个个.obj文件的时候, 它们实际上还是一个一个独立的文件, 彼此直接没有关系
链接就是把所有.obj文件链接在一起,形成一个完整的程序
而这个程序必须有一个起始函数,如果没有特殊指定,这个起始函数默认是main函数!

3.2.1 起始函数

所以当一个项目是没有main函数的时候,单独编译文件不会报错,但是build或者运行项目的时候会报错

例:
当前项目中只有两个源文件,都不包含main函数
在这里插入图片描述
单独编译这两个源文件都没问题
但是当我生成整个项目时,发生了报错LNK1120
在这里插入图片描述
LNK 开头的错误是链接阶段发生的错误;
C 开头的错误是编译阶段发生的错误,比如语法错误;

现在我加一个源文件,里面声明了MutiplyOneLog函数,定义了main函数
并且在main函数中调用MutiplyOneLog函数

#include<iostream>int MutiplyOne(int a, int b);
void Log(const char* message);int main() {Log("Hello World!");std::cout << MutiplyOne(5, 18) << std::endl;std::cin.get();
}

在这里插入图片描述
直接运行项目,成功

Hello World!
90

这就代表着程序编译成功,链接器也成功找到了程序的起始函数,并成功把相关的函数找到、链接起来了。

3.2.2 被调用的函数

如果被调用的函数没有在当前源文件中声明

#include<iostream>int MutiplyOne(int a, int b);
//void Log(const char* message);int main() {Log("Hello World!");std::cout << MutiplyOne(5, 18) << std::endl;std::cin.get();
}

会报编译错误,因为这个属于语法错误:
在这里插入图片描述
如果被调用的函数不存在
会报链接错误:
在这里插入图片描述
所以很明显,链接的作用是把以起始函数为根节点,所有被调用到的函数链接起来,形成一整条调用链(或者说一整棵调用树)
在这里插入图片描述

如果想要指定其他函数作为程序的起始函数,可以通过链接器的高级设置指定:
在这里插入图片描述

3.3 总结,编译和链接的区别

编译:是先对源文件进行预处理,引入头文件,把头文件内容copy到源文件中,然后再把这些源文件编译成.obj或其他格式的二进制文件

链接:是把编译好的.obj文件里面相互调用的函数链接起来,形成一个完整的程序

相关文章:

C++基础Ⅰ编译、链接

目录儿 1 C是如何工作的1.1 预处理语句1.2 include1.3 main()1.4 编译单独编译项目编译 1.5 链接 2 定义和调用函数3 编译器如何工作3.1 编译3.1.1 引入头文件系统头文件自定义头文件 3.1.2 自定义类型3.1.3 条件判断拓展: 汇编 3.2 链接3.2.1 起始函数3.2.2 被调用的函数 3.3 …...

VMware和ubuntu配置Hadoop环境

目录 一、获取VMware安装包 1、官网获取 1&#xff09;首先先进入官网&#xff0c;官网首页是下面这样&#xff1a; 2&#xff09;接着点击产品选项 3&#xff09;进入后点击查看所有产品&#xff0c;然后在右上角选择排序方式为Z到A&#xff0c;然后向下滑动找到Workstation…...

uview2.0自定义tabbar

tabbar组件 <template><u-tabbar :value"tab" change"changeTab" :fixed"true" :border"true" :placeholder"true":safeAreaInsetBottom"true"><u-tabbar-item text"消息" icon"c…...

Star History 月度开源精选|Llama 2 及周边生态特辑

7 月 18 日&#xff0c;Meta 发布了 Llama&#xff0c;大语言模型 Llama 1 的进阶版&#xff0c;可以自由免费用于研究和商业&#xff0c;支持私有化部署。 所以本期 Star History 的主题是&#xff1a;帮助你快速把 Llama 2 在自己机器上跑起来的开源工具&#xff0c;无论你的…...

修改电脑上路由表使笔记本默认走无线

如果笔记本上即连接了有线&#xff0c;也连接了无线&#xff0c;默认电脑会走有线的&#xff0c;通过route print命令查看路由表就可以看出来&#xff0c;因为无线的“metric”跳数要比有线的高 解决方法&#xff1a; 如果想实现让默认走无线&#xff0c;就需要修改自己电脑的…...

Spring Cache的介绍以及怎么使用(redis)

Spring Cache 文章目录 Spring Cache1、Spring Cache介绍2、Spring Cache常用注解2.1、EnableCaching注解2.2、CachePut注解2.3、CacheEvict注解2.4、Cacheable注解 3、Spring Cache使用方式--redis 1、Spring Cache介绍 Spring Cache是一个框架&#xff0c;实现了基于注解的缓…...

软考高级系统架构设计师系列论文六十九:论信息系统的安全风险评估

一、信息系统相关知识点 软考高级信息系统项目管理师系列之四十三:信息系统安全管理软考高级系统架构设计师:系统安全分析与设计...

Ubuntu系统安装之后首需要做的事情

Ubuntu系统的初步环境搭建 1、换源2、显卡3、浏览器4、输入法5、终端6、ROS7、VSCode8、设置时间与win一致9、 TimeShift10、 Anaconda&#xff08;考虑装不装&#xff09; 1、换源 点开Software&&Update&#xff0c;找到Ubuntu Software中的Download from&#xff0c…...

Qt——QPushButton控件的常见属性、方法和信号

Qt中QPushButton控件的常见属性、方法和信号 一、QPushButton控件常见属性 一、QPushButton控件常见方法 一、QPushButton控件常见信号 一、QPushButton控件常见属性&#xff08;Properties&#xff09; 1. text: 描述&#xff1a;按钮上显示的文本。 用法&#xff1a; butto…...

AUTOSAR规范与ECU软件开发(实践篇)5.5 基于ISOLAR-A的系统级设计与配置方法(上)

目录 前言 1 系统配置输入文件创建与导入 2、 Composition SWC建立 前言 如前所述, AUTOSAR支持整车级别的软件架构设计, 开发人员可以进行整车级别的软件组件定义, 再将这些软件组件分配到各个ECU中, 这就是AUTOSAR系统级设计需要完成的主要任务。 下面结合AUTOSAR方法论…...

mongoDB的CRUD

...

flutter TARGET_SDK_VERSION和android 13

config.gradle ext{SDK_VERSION 33MIN_SDK_VERSION 23TARGET_SDK_VERSION 33COMPILE_SDK_VERSION SDK_VERSIONBUILD_TOOL_VERSION "33.0.0"//兼容库版本SUPPORT_LIB_VERSION "33.0.0"}app/build.gradle里面的 defaultConfig {// TODO: Specify your…...

大数据Flink(六十六):Flink的重要概念和小结

文章目录 Flink的重要概念和小结 一、​​​​​​​​​​​​​​数据流图(Dataflow Graph)...

Rider 添加NuGet软件包 (NuGet Package)

如图&#xff0c;在解决方案中选择自己的项目右键&#xff0c;点击管理 NuGet 软件包即可 在搜索栏中搜索自己要使用的软件包安装即可使用...

什么是JVM ?

一、JVM 简介 JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java 虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。 常见的虚拟机&#xff1a; JVM 、 VMwave 、 Virtual Box 。 JVM 和其他两个虚拟机的区别…...

【大数据】Hive 中的批量数据导入

Hive 中的批量数据导入 在博客【大数据】Hive 表中插入多条数据 中&#xff0c;我简单介绍了几种向 Hive 表中插入数据的方法。然而更多的时候&#xff0c;我们并不是一条数据一条数据的插入&#xff0c;而是以批量导入的方式。在本文中&#xff0c;我将较为全面地介绍几种向 H…...

【Modbus通信实验三】数据切片问题

在做两个串口相互通信的实验中&#xff0c;当发送频率快一点时偶尔会遇到以下情景&#xff0c;即一次send中把原数据拆成两份发送&#xff0c;就会导致CRC校验错误。下图中6字节数据拆成42是把SetRThreshold()阈值设为2&#xff0c;当设为1的情况下则会拆成51。 一开始以为是缓…...

记录《现有docker中安装spark3.4.1》

基础docker环境中存储hadoop3--方便后续查看 参考&#xff1a; 实践&#xff1a; export JAVA_HOME/opt/apache/jdk1.8.0_333 export SPARK_MASTER_IP192.168.0.220 export SPARK_WORKER_MEMORY4g export SPARK_WORKER_CORES2 export SPARK_EXECUTOR_MEMORY4g export HADOOP_H…...

【3ds Max】练习——制作衣柜

目录 步骤 一、制作衣柜顶部 二、制作衣柜门板 三、制作衣柜底部 四、制作柜子腿部 五、制作柜子底板 步骤 一、制作衣柜顶部 1. 首先创建一个平面&#xff0c;然后将图片素材拖入平面 2. 平面大小和图片尺寸比例保持一致 3. 单机鼠标右键&#xff0c;选择对象属性 勾选…...

Spring-MVC的数据响应-19

在访问服务端MVC的时候&#xff0c;这个controller层进行相应操作之后 他要做两件事&#xff1a;页面跳转和返回字符串&#xff0c;在做完这些操作之后&#xff0c;我们一般进行页面展示:排除页面展示之外&#xff0c;有些需求可能直接回写给我们一些数据&#xff1a; 页面跳…...

(三)行为模式:5、中介者模式(Mediator Pattern)(C++示例)

目录 1、中介者模式&#xff08;Mediator Pattern&#xff09;含义 2、中介者模式的UML图学习 3、中介者模式的应用场景 4、中介者模式的优缺点 &#xff08;1&#xff09;优点 &#xff08;2&#xff09;缺点 5、C实现中介者模式的实例 1、中介者模式&#xff08;Media…...

期权是什么?期权的优缺点是什么?

期权是一种合约&#xff0c;有看涨期权和看跌期权两种类型&#xff0c;也就是做多和做空两个方向&#xff0c;走势标的物对应大盘指数&#xff0c;这也是期权与其他金融工具的主要区别之一&#xff0c;可以用于套利&#xff0c;对冲股票和激进下跌的风险&#xff0c;下文介绍期…...

目标检测任务数据集的数据增强中,图像垂直翻转和xml标注文件坐标调整

需求&#xff1a; 数据集的数据增强中&#xff0c;有时需要用到图像垂直翻转的操作&#xff0c;图像垂直翻转后&#xff0c;对应的xml标注文件也需要做坐标的调整。 解决方法&#xff1a; 使用pythonopencvimport xml.etree.ElementTree对图像垂直翻转和xml标…...

html5提供的FileReader是一种异步文件读取文件中的数据

前言&#xff1a;FileReader是一种异步文件读取机制&#xff0c;结合input:file可以很方便的读取本地文件。 input:file 在介绍FileReader之前&#xff0c;先简单介绍input的file类型。 <input type"file" id"file"> input的file类型会渲染为一个按…...

Linux学习记录——이십오 多线程(2)

文章目录 1、理解原生线程库线程局部存储 2、互斥1、并发代码&#xff08;抢票&#xff09;2、锁3、互斥锁的实现原理 3、线程封装1、线程本体2、封装锁 4、线程安全5、死锁6、线程同步1、条件变量1、接口2、demo代码 1、理解原生线程库 线程库在物理内存中存在&#xff0c;也…...

单片机(二)使用位移 让灯亮

一&#xff1a;硬件电路 P2 口&#xff1a; P2.0~ P2.7 是这些 I0 口 LED 阳极接 电源 &#xff0c; P20 口 为低电平 可以让 LED灯 亮 二&#xff1a;软件实现部分 两种 ① 通过循环 来展示从左 到右 #include "reg52.h"#define LED_PORT P2 // 定义单片机的P2端…...

探究代理服务器在网络安全与爬虫中的双重作用

在如今高度互联的世界中&#xff0c;代理服务器已经成为网络安全和爬虫开发的关键工具。本文将深入探讨Socks5代理、IP代理、网络安全、爬虫、HTTP等关键词&#xff0c;以揭示代理服务器在这两个领域中的双重作用&#xff0c;以及如何充分利用这些技术来保障安全和获取数据。 …...

JavaWeb-学习目录

技术栈介绍 文章目录 1.数据库&#xff1a;1.1 Mysql1.2 JDBC1.3 Maven1.4 Mybatis 2.前端2.1 HTMLCSSJS2.2 AjaxVueElementUI 3. Web核心3.1 TomcatHttpServlet3.2 RequestResponse3.3 JSP3.4 CookieSession3.5 FilterListener 1.数据库&#xff1a; 1.1 Mysql mysql&#…...

C语言题目 - 调用qsort函数对数组进行排序

题目 如题 思路 其实没什么难的&#xff0c;只要严格按照 qsort 函数的参数来填充即可&#xff0c;这里要用到函数指针。 qsort 函数的原型如下&#xff1a; void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *)); 参数说明&…...

Matplotlib学习笔记

Matplotlib数据可视化库 jupyter notebook优势 画图优势&#xff0c;画图与数据展示同时进行。数据展示优势&#xff0c;不需要二次运行&#xff0c;结果数据会保留。 Matplotlib画图工具 专用于开发2D图表以渐进、交互式方式实现数据可视化 常规绘图方法 子图与标注 想要…...

上海哪里有做网站的/google学术搜索

elasticsearch 7.6 教你简单上手下载( windows)访问/测试/配置在kibana开发工具里玩一玩Rest风格说明自动增加索引创建索引规则默认信息 _doc拓展 get _cat/...修改索引删除索引文档操作条件查询简单条件查询字段过滤排序分页布尔值查询匹配多个精确查询连个类型 text 和keywor…...

青海省住房和建设厅网站首页/市场调研与分析

https://mp.weixin.qq.com https://mp.weixin.qq.com/s?__bizMzI3NzE0NjcwMg...

mip手机网站模板/新闻发稿平台有哪些?

前段时间&#xff0c;进行USB拷贝方面的测试&#xff0c;积累了几个测试脚本&#xff0c;也可以进行磁盘间的拷贝&#xff0c;放在这里备份。 主要实现功能&#xff1a; 从一个存储设备拷贝数据到另一个位置&#xff0c;并比较两次拷贝的数据是否一致&#xff0c;并判断系统是…...

爱站网长尾关键词搜索/企业网站设计要求

1、Symbol es6新增的数据类型 1&#xff09;概念 提供一个独一无二的值 let aSymbol() let bSymbol() 或 let cSymbol.for(c) let dSymbol.for(c) c是一个key&#xff0c;标识着这个独一无二的变量 2、数据结构 1)set Set中的元素不可重复 其长度用.size表征 添加重复元素&…...

北京网站建设服务中心/简单网页制作成品免费

戴尔服务器以稳定著称&#xff0c;但服务器维护人员要想进入BIOS设置就非常困难&#xff0c;甚至出现进入不了的毛病&#xff0c;应该如何解决&#xff1f;按理说&#xff0c;戴尔服务器开机之后&#xff0c;只要出现戴尔的启动画面&#xff0c;摁下F2就可以顺利进入BIOS&#…...

做的比较好的b2b网站/磁力链 ciliba

在本视图中&#xff0c;每一个连接到数据库实例中的 session都拥有一条记录。包括用户 session及后台进程如 DBWR&#xff0c; LGWR&#xff0c; arcchiver等等。 V$SESSION中的常用列 V$SESSION是基础信息视图&#xff0c;用于找寻用户 SID或 SADDR。不过&#xff0c;它也有一…...