C/C++从main()函数开始梳理的一些知识点(普及小贴)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Aoulun/article/details/79050991

由于C/C++用的比较多,而感觉在工作中很多同事在用的时候没有注意一些知识点,而我也是一个菜鸡,所以就想借一个项目来写写其中的知识点,也算是一个复习吧。

1、包含头文件

头文件是每个程序中都必不可少的,头文件的包含方式有两种,“ some.hpp”和<some.hpp>。

其实这两种区别并不是太大,他不会关心里面的内容是什么,而是决定了在编译的时候,头文件的找寻方式。

“some.hpp”一般用户自己定义的头文件可以用这种方法调用,在编译的时候,会按照下面的顺序搜索这个头文件:当前目录--》系统目录--》环境变量。

<some.hpp>一般调用第三方的头文件可以用这种方法调用,在编译的时候,会按照下面的顺序搜索这个头文件:环境变量--》系统目录--》当前目录

2、main()函数

main()函数有两种表示方法:

int main() 和 int main( int argc, char** argv ),其实还有第三种,int main( int argc, char** argv,char**  env)

int main():

输入类型是一个空类型,返回值是一个int类型

int main(int argc, char** argv):

也可以用这种方式表示:( int argc, char* argv[] )

一个参数表示输入参数的个数(argument count),有系统自动计算,第二个参数是一个指针数组。当通过命令行的方式输入字符串时,都会被存储到系统内存中,并把字符串的首地址赋值给argv(argument value),命令行的各个参数字符串使用空格隔开的,第一个字符串是本可执行程序的文件名字。第三个参数表示当前系统的环境变量参数。下面用一个例子来说明:

编写一段控制台程序

编译完成后会在目录下生成exe文件,然后在开始菜单(Windows系统,我用的双系统,这个是在win10上写的),cmd,跳到制定目录,运行此EXE,并输入命令行参数,可以看到argc,argv和env参数的值是多少,如下:

3、动态链接库与静态链接库

本文只写最浅显的理解,而不是深究里面的原理,为的还是帮助解决实际中碰到的问题。(主要以VS中如何建立和生成为主要讲解)

首先,建一个空的解决方案(里面可以包含很多工程),假设我建立了一个compile_and_link的解决方案。

至于动态链接库和静态链接库的生成过程会在本文第四章中介绍。

3.1、如何生成静态链接库及特点

静态链接库生产的时候,只会有一个.lib的文件(不包含一些调试文件等)。这个.lib文件即包含了各个函数的索引信息,同时也包含了各个函数具体实现过程。因此,静态链接库是很大的。

在VS中,静态链接库的配置生成可以采用如下的方式。

     

静态链接库的生成位置如下:


提到静态链接库,就不得不说可执行程序。当可执行程序(exe)调用静态链接库中的函数时,在编译的时候,实际上就把代码实现部分都封装到了exe中。所以exe可以单独执行。那么,可执行程序如何使用静态链接库呢?大致可以分为以下几个步骤。

1、首先,建立一个可执行程序的工程main_test,需要用到静态链接库中的函数math_add()。

2、为了能让程序正常的跑起来,需要做如下的事情。(关于编译和链接在第四节中介绍)

第一,要用到math_add()这个函数,所以,要包含这个头文件,保证编译能够通过。进行如下的设置。

右键工程目录(main_test这个工程目录)--》属性(properties)--》C\C++ --》常规(general)--》附加包含目录(additional include directories)--》输入math_add.h这个文件的路径。一般推荐采用相对路径,那么相对路径怎么设置呢?比如说,当前main_test.vcxproj所在目录是:D:\my_program\compile_and_link\compile_and_link\main_test,往前一个目录是D:\my_program\compile_and_link\compile_and_link,而这个compile_and_link目录下面的static_lib目录里面有math_add.h这个头文件,所以采用相对路径时,“..”就表示上一个目录,如果再上一个目录那就是“..\..\”,所以设置如下:

第二,保证能够找到函数的实现,所以,就要链接到静态链接库的位置。这个时候,也采用形同的相对路径设置方式。如下:

先设置静态链接库的路径:右键工程目录(main_test这个工程目录)--》属性(properties)--》链接(Linker)--》常规(general)--》附加库目录(additional library directories)--》输入static_lib.lib这个文件的路径.

再设置依赖项,右键工程目录(main_test这个工程目录)--》属性(properties)--》链接(Linker)--》输入(input)--》附加依赖项(additional dependencies)--》输入static_lib.lib。

当我把生成的exe文件copy到其他地方,而不需要这个static_lib.lib时,仍然可以正常运行。

3.2、如何生成动态链接库及特点

动态链接库生成之后,会有两个比较有用的文件,即.dll 文件和 .lib文件。.lib文件包含了各个函数的索引信息,而.dll则是各个函数的具体实现。

在VS中,新建一个工程,动态链接库的配置生成如下所示

动态链接库中的函数,变量及类等,需要导出才可以被其他地方调用。如果是dll内部使用某个函数,就没有必要导出了。

3.2.1、动态链接库中函数的导出方式及如何使用

动态链接库中的导出函数有两种方式:第一种是采用def文件,第二种是采用声明导出。
def文件导出的方式:
工程右键--》添加(add)--》新项目(new item)--》选择def--》命名
然后在def文件里面输入想导出的函数
配置完成之后,build这个工程,那么就在相应的文件中生成dll文件和lib文件。例如,我的例子在debug文件夹中生成dynamic_lib.dll 和 dynamic_lib.lib文件。其中 dynamic_lib.lib是想用函数的一些索引信息,而 dynamic_lib.dll则是这些函数的具体实现。在使用的时候,main_test这个工程会加载dll到内存里面。而lib文件在build这个main_test这个工程的时候会用到。VS中的配置方式如下:
然后会在debug文件中生成对应文件,打开main_test.exe就可以运行了。
当把,dynamic_lib.dll这个文件移除这个文件夹的时候,再运行exe就会报错,说找不到dynamic_lib.dll这个文件。所以,也就说明了,exe的运行离不开dll。
声明导出的方式:

声明导出的方式比较直接,建议采用这种方式。在dynamic_lib这个工程的配置如下
main_test这个工程的配置如下

4、程序编译的过程

4.1、预处理
预处理的过程就是对源代码的一个初步处理,包括宏定义的替换(例如把宏定义替换为文字)、头文件的替换(把#include这些替换成头文件中的内容)、条件编译指令的省略、注释的去除等。
4.2、编译
此阶段是将上一个预处理阶段产生的文件进一步处理,例如词法分析,语法分析(就是对里面的加减乘除等做一个分析--不贴切,大概可以这样理解),这一步生成的是汇编代码。
4.3、汇编
汇编的过程就是将上一步产生的汇编代码,翻译为机器可以识别的机器代码,生产的文件就是目标文件。
4.4、链接
此过程就是生成最终文件的过程,例如生成exe,生成静态链接库lib,动态链接库dll的过程,它是将多个目标文件链接起来的过程(因为这些文件中可能是相互调用内部函数,所以有这个过程)。


持续更新中。。。。。。。。。。。。。。。。。。。。。。。





猜你喜欢

转载自blog.csdn.net/Aoulun/article/details/79050991