目录
一. 在Ubuntu系统下用c语言编写一个简单的输出hello world 的程序,并编译、运行。
1.1 gcc/g++简介
1.2 c++程序输出 Hello World:
1.3 c语言程序输出 Hello World:
二. 编写一个主程序文件main1.c和一个子程序文件sub1.c,实现函数间的调用
2.1 编写sub1.c 和main1.c 函数
2.1.1 编写sub1.c函数
2.1.2 编写main1.c函数,赋值a=3,b=2
2.2 将sub1.c程序封装为动态库或者静态库
2.2.1 生成静态库
2.2.1 生成动态库
2.2.3 动态库和静态库的区别
三. 在windows下系统下用DVC++编程实现
3.1 编辑主程序
3.2 编辑子程序
3.3 运行效果
四. 用CMakefile方式编程主程序
4.1 CMakefile 简介
4.2 创建CMakeListss.txt
4.3 在CMakeLists.txt中添加添加可执行文件,给sub1.c添加静态库,并添加链接
4.4 执行 CMakeLists.txt,并查看是否生成上述文件
4.5 分别执行连接动态库和静态库的可执行文件
五. 总结
一. 在Ubuntu系统下用c语言编写一个简单的输出hello world 的程序,并编译、运行。
1.1 gcc/g++简介
gcc/g++都是GUN开发的编译器,前者用于对c语言程序的编译,后者用于对c++程序的编译。
其语法格式大同小异。
常用命令:
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面。例子用法: gcc -E hello.c > pianoapan.txt gcc -E hello.c | more 慢慢看吧,一句`hello word`也要预处理成800行的代码。 -S 只激活预处理和编译,就是指把文件编译成为汇编代码。例子用法: gcc -S hello.c 将生成.s的汇编代码,可以用文本编辑器查看。 -c 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件。例子用法: gcc -c hello.c 将生成.o的目标文件(object file)。 -o 指定目标名称,缺省的时候,gcc/g++编译出来的文件是a.out。例子如下: g++ -o hello.out hello.cpp g++ -o hello.asm -S hello.cpp
目录选项:
-I[dir] 在你是用#include "file"的时候,gcc/g++会先在当前目录查找你所指定的头文件,如果没有找到,会到系统默认的头文件目录找。如果使用-I指定了目录,编译器会先在指定的目录查找,然后再去系统默认头文件目录查找。对于#include <file>,gcc/g++会到-I指定的目录查找,查找不到,然后再到系统默认的头文件目录查找。-include [file] 相当于“#include”,用于包含某个代码,简单来说,就是编译某个文件,需要另一个文件的时候,就可以 用它设定,功能就相当于在代码中使用#include。例子用法: gcc hello.c -include /root/pianopan.h -I- 就是取消前一个参数的功能,所以一般在-Idir之后使用 -idirafter [dir] 在-I的目录里面查找失败,将到目录dir里面查找。-iprefix [prefix],-iwithprefix [dir] 一般一起使用,当-I的目录查找失败,会到prefix+dir下查找。-L[dir] 编译的时候,指定搜索库的路径。比如你自己的库,可以用它指定目录,不然编译器将只在标准库的 目录找。这个dir就是目录的名称。-l[library] 指定编译的时使用的库,例子用法 gcc -lcurses hello.c 使用curses库编译连接,生成程序。
更多命令可在ubuntu终端中输入 man gcc 查看
1.2 c++程序输出 Hello World:
首先创建一个文件 格式: nano+文件名
在所创的文件中输入c++代码:
#include<iostream>using namespace std;int main(){ cout<<"Hello World!"<<endl; return 0;}
退出并保存文件。
g++ a -o b 将a文件用c++的编译方式编译出名字b的可执行文件
用g++编译该文件
g++ Hello_World.c -o Hello_World.cpp
用 ls 查看是否生成可执行文件,并运行。
运行Hello_World.cpp 文件
运行后输出了 Hello World!
1.3 c语言程序输出 Hello World:
若用c语言,需要用gcc进行编译,语法相差不大
首先创建一个文本文件
在文件中输入c语言代码
#include <stdio.h>int main(){ printf("%s\n","Hello World!"); return 1;}
保存文件,并编译文件为可执行文件
查看是否生成可执行文件
运行可执行文件
输出Hello World!
二. 编写一个主程序文件main1.c和一个子程序文件sub1.c,实现函数间的调用
要求:子程序包含算术运算函数float x2x(int a,int b),此函数功能对输入两个整数作运算,结果返回浮点数;主函数定义并赋值两个整形变量,然后调用x2x函数,将结果打印出来。
思路:先编写sub1.c程序,再将封装为库函数,在主函数中引用sub1.c的头文件,调用其库函数。
2.1 编写sub1.c 和main1.c 函数
2.1.1 编写sub1.c函数
#include <stdio.h>float x2x(int a,int b){ float x=(float)a; float y=(float)b; return x/y;}
2.1.2 编写main1.c函数,赋值a=3,b=2
#include "sub1.h"void main(){ int a=3,b=2; printf("%f", x2x(3,2));}
2.2 将sub1.c程序封装为动态库或者静态库
先将其转为 .o 二进制文件
gcc -c sub1.c
查看是否生成sub1.o文件
2.2.1 生成静态库
ar -crv lib+库名.a +所用程序
当前目录下生成libsub.a静态库文件
对主程序进行编译,编译需要用到刚才生成的库
当前目录生成了名为main1的可执行文件,运行并查看结果:
输出结果为1.500000
2.2.1 生成动态库
生成动态库的方法跟静态库的方法类似
gcc -shared -fPIC -o lib+库名.so 所用程序
当前目录下生成libsub1.so动态库文件
用此库将main1.c文件编译为可执行文件
执行当前目录下生成的main_1可执行文件
同样输出了结果1.500000
2.2.3 动态库和静态库的区别
在Linux中,库函数分为静态库和动态库两种。静态库以.a作为后缀名,共享库以.so结尾。所有库都是一些函数打包后的集合,差别在于静态库每次被调用后都会生成一个副本,而动态库则只有一个副本,更省空间。
三. 在windows下系统下用DVC++编程实现
3.1 编辑主程序
3.2 编辑子程序
3.3 运行效果
四. 用CMakefile方式编程主程序
4.1 CMakefile 简介
理论上,任意一个c语言程序都可以用gcc来编译。但是当程序规模越来越大时,一个工程可能有许多个文件夹和源文件,这时输入的编译命令就越来越长。通常,一个小型的c语言项目可能含有几十类,各类间还存在着复杂的依赖关系。其中一部分要编译为可执行文件。另一部分编译成库文件。如果仅靠gcc命令,则需要输入大量的编译指令,整个编译过程会变得异常繁琐。因此对于c项目,使用一些工程管理工具会更加高效。在历史上,工程师们曾使用makefile进行自动编译,但是cmake比它更加方便。并且cmake在工程上广泛应用。总之,cmake是用来管理源代码的工具,可以对源代码进行编译、生成库等。
4.2 创建CMakeListss.txt
CMakeLists.txt文件用来告诉cmake要对目录下的文件做什么事情。
第一句是要求cmake编译器的最小版本
第二句是创建一个工程文件名为D
4.3 在CMakeLists.txt中添加添加可执行文件,给sub1.c添加静态库,并添加链接
1. 将main1.c转为名为main2的可执行文件
2. 将main1.c转为名为main3的可执行文件
3. 将sub1.c封装为名为libsub1的静态库
4. 将sub1.c封装为名为libsub2的动态库
5. 生成的main2可执行文件与动态库进行连接
6. 生成的main3可执行文件与静态库进行连接
4.4 执行 CMakeLists.txt,并查看是否生成上述文件
调用cmake对该工程进行cmake编译
cmake会输出一些编译信息,然后再当前目录下生成一些中间文件,其中最重要的就是MakeFile。
由于其是自动生成的,不用修改它。现在用make对该工程进行编译:
查看生成的文件
生成了main2 main3 可执行文件,liblibsub1.a静态库 以及liblibsub2.so动态库
4.5 分别执行连接动态库和静态库的可执行文件
运行生成的main2 和main3文件
都输出1.500000
五. 总结
1. 在ubuntu18环境下,可以用gcc对c语言程序进行编译和运行,用g++可以对c++语言程序进行编译和运行。
2. ubuntu环境下用gcc编译一个文件比较简单,只需将程序转为二进制可执行文件即可,但是在运用到函数之间的调用的时候,即运用到库时,较为复杂。
3. windows环境下对c语言的编写和运行也是同样的步骤,但是windows系统中用到的DEV C++是集成开发的软件,比较迅速、方便。 ubuntu中也有IDE软件,比如KDV。
4. 在执行很多程序之间的相互调用时候,gcc生成库较为复杂,用Makefile的方式比较简便。
5. ubuntu中的库分为静态库和动态库,运用动态库更加节省空间。
PS:参考资料: g++入门教程 - 码农教程 (manongjc.com)
《视觉SLAM十四讲从理论到实践》第二版 高翔 张涛 刘毅 颜沁睿 著