inux平台的C与C++
首先,声明一下这是一个系列的文章。至于整个系列有多少篇,笔者也不知道,不知道有多少篇,也不知道多久会更新一篇。反正只有一个原则,写出来的文 章能见得人才会公布出来。另外,我不是叫你逃课,而是觉得听课只是一般学生做的,听课的时候把该听的听了,不该听的听过就算了,课堂上的东西只不过是大千 编程界里细沙一粒也称不上,真正牛的人从不满足那一小点知识,有些事太认真你就输了,世界很大,不要局限自己的视野,那样会很累。
首先:整个系统环境都是基于linux平台上的,如果有兴趣你可以参考这里去学习linux:如何成为一个真正在路上的Linuxer ,也推广下团队刚搭建出的LinuxCoder 社区。
编译器用的gcc、g++,没有请先自行安装。
编译第一个可执行文件
第一篇文章,照例写个最经典的hellow word 程序吧。(代码1)
// code by lfly
// 2014-11-22
#include <iostream>
using namespace std ;
int main( int argc, char **argv)
{
cout << “Hellow World!” << endl ;
return 0 ;
}
很简单的一段代码,最后返回0表示成功退出,返回其它值代表的是某种错误(看具体值)。保存为hellow.cpp文件然后编译运行下:
lfly@programfish:~/project/c> ls hellow.cpp
lfly@programfish:~/project/c> g++ hellow.cpp -o hellow.o
lfly@programfish:~/project/c> ls hellow.cpp hellow.o
lfly@programfish:~/project/c>
-o是指定结果文件名,这里编译成目标文件hellow.o
如果不用-o指定文件名,默认是编译成a.out文件的。
.out文件是编译链接成的可执行文件,而.o文件一般是编译出来的一个目标文件,还没有链接的。
但是Linux下是不以后缀名来区别是否是可执行文件,区别的标准只有一个:该文件在对应的用户下有没有执行权限(x权限)。 好了,运行一下:
lfly@programfish:~/project/c> ./hellow.o
Hellow World!
正是我想要的结果: Hellow World!
main 函数参数:
main 函数里有两个参数,第一个是int类型argc,表示传入main函数的参数个数。第二个是一个二维字符指针argv,保存了各个传入的参数。这里注 意,argv[0]是保存了执行这个可执行文件时的路径,后面argv[1]到argv[argc-1]才是保存了用户传入的参数(如果有的话)。 这里改动一下程序:(代码2)
// code by lfly
// 2014-11-22
#include <iostream>
using namespace std ;
int main( int argc, char **argv)
{
cout << “argc is: ” << argc << endl ;
for ( int i=0; i<argc; ++i )
{
cout << argv[i] << endl ;
}
return 0 ;
}
改成这个样子,输出数量argc和argv里的各个字符串。依然是上面的编译命令然后:
g++ hellow.cpp -o hellow.o
然后随便加两个参数hellow、world运行一下:
lfly@programfish:~/project/c> ./hellow.o hellow world
argc is: 3 .
/hellow.o
hellow
world
可以看到参数数量为3,因为默认的第一个参数是执行的路径(这里为./hellow.o)其余两个为传入的hellow 及world
注意:main函数可以写成不带参数或(void)的。而main函数最初最初是不带参数的。想了解main函数身世请看这里:你所未必了解的main()函数的事情 http://www.nowamagic.net/librarys/veda/detail/96
窥探编译与链接过程
g++编译链接文件过程:
预处理 —> 编译(汇编文件) —> 汇编(机器码) —> 链接(可执行程序)
1预处理过程
生成.i文件,这一下由预处理器cpp程序执行。
cpp是一个可执行程序,一般路径为/usr/bin/cpp(可能是一个链接),你可以用find命令去搜索一下具体路径。预处理器会读入源代码然后查找出预处理指令(宏定义、文件包含、条件编译),这些指令以#开头。
- 宏定义
宏定义是指#define指令,预处理过程会把这些宏展开,例如 #define DF 10
预处理会把程序代码里出现的DF独立组合替换成10,这是简单的宏定义,至于带参数的宏定义在这里不作讨论。
- 文件包含
指#include 指令,预处理器会把包含到的头文件的内容替换到这个#include 指令。
- 条件编译
#ifdef(#ifndef)与#endif指令,这些指令很大作用是使编译出来的目 标文件不会过大,你想想上面的#include指令会把一个头文件的内容替换到cpp文件里,假如你大意重复包含了文件(文件A包含文件B,在文件C里包 含了A,然后也用到B所以包含了B,那么C就包含了两次B),这种情况在复杂的工程很难避免。所以用条件编译可以优化你的程序,当然它还有其它别的重要的 作用,这里不讨论。
除了处理预编译指令,预处理器还会删掉你的注释(机器不看你的注释,估计也看不懂)。然后还有保留#pragma指令。
好了,现在来看看我们的hellow world预处理后会是什么样子的。简单起见,使用上面代码1作为源代码,使用g++ -E 预编译(当然你可以直接使用cpp命令)
g++ -E hellow.cpp -o hellow.i
然后来看一下预编译得到hellow.i这个文件的内容:
简单几行代码预编译后得到的文件足足有17563行。而我开头的两行注释确实没有了。
2编译成汇编文件
这个过程是把预编译后的代码编译成汇编代码,由编译器egcs执行。下面来编译一下我们得到的hellow.i文件:
g++ -S hellow.i -o hellow.s
然后查看一下hellow.s文件:
都是汇编代码,学汇编的记得保重身体啊…..
3汇编过程
这一步就可以得到.o目标文件了。过程由汇编器as执行,把上面得到的hellow.s文件里的汇编指令逐条翻译成机器码。
g++ -C hellow.s -o hellow.o
4链接过程
由链接器ld完成,把多个.o的机器码链接成.out这样的可执行文件(当然后缀名不是重点)。注意,我这里的只有一个.cpp文件,所以就只有一个.o文件,不需要链接,这只是示例,但是正常工程下肯定不止这一个文件,那时候就要链接成可执行文件才可以运行了。
以上是Linux平台里的示例,你可以在windows下使用g++做上面同样的步骤。但作为程序猿,建议你使用linux做开发,不要问为什么,可以找我博客里关于linux的文章看看。 第一篇就讨论到这里吧,下次更新再讨论其它问题。
欢迎访问本人网站:http://www.programfish.com
LinuxCoder 社区: http://linuxcoder.org
注意:转载请注明 “作者:广州Linux爱好者+云计算 刁金明”
inux平台的C与C++的更多相关文章
- linux平台及windows平台mysql重启方法
各个平台mysql 重启: inux平台及windows平台mysql重启方法 Linux下重启MySQL的正确方法: 1.通过rpm包安装的MySQL service mysqld restart ...
- 十分钟轻松让你认识Entity Framework 7
EF7不是在EF6上更新,而是完全重写了.它完全支持.NET Core runtime,也就是说以后你可以在Mac或者是Linux机器上使用EF了. https://github.com/nichol ...
- HW弹药库之红队作战手册
红方人员实战手册 声明 Author : By klion Date : 2020.2.15 寄语 : 愿 2020 后面的每一天都能一切安好 分享初衷 一来, 旨在为 "攻击" ...
- inux监控平台搭建-监控项
linux监控平台搭建-监控项 本人运维某生态互联网监控平台服务.过程中遇见了很多问题.目前互联网有很多的开源监控工具:nagios.zabbix.falcon.cacti...各有优点.这里不讲解监 ...
- inux设备驱动归纳总结(五):2.操作硬件——IO内存【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-80627.html inux设备驱动归纳总结(五):2.操作硬件——IO内存 xxxxxxxxxxxx ...
- inux软件安装管理之——dpkg与apt-*详解
inux软件安装管理之--dpkg与apt-*详解 Nosee123关注 0.5922017.09.12 17:47:44字数 3,894阅读 8,565 [Linux软件安装管理系列]- - 传送门 ...
- inux操作系统测试工具
inux操作系统测试工具 转载minions_222 最后发布于2017-08-02 11:42:13 阅读数 1481 收藏 展开 转自:http://blog.csdn.net/crisscha ...
- Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级
Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 5.安装Database软件 5. ...
- Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作
Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 1.实施前准备工作 1.1 服务器安装操 ...
随机推荐
- myeclipse中间classpath
myeclipse中间classpath这是一个非常重要的问题 myeclipse是搜索寻找在按照时间其,和myeclipse有一个特殊的文件来保存classpath信息.这也是别人的项目文件的副本时 ...
- [Java Web]Struts2加起来(一个)
Struts2环境配置 进口Struts2的需要jar包 在WEB-INF/classes(src)文件夹下创建struts.xml文件 在web.xml文件里加入Struts过滤器信息 经常使用配置 ...
- 跳跃Java一些周期,双跳FOR周期
今天写的代码写在一个双层for周期,目前仍在使用Iterator,大致意思是假定在第二个周期在排位赛中给了整个双回路跳. 刚開始,直接使用break.巴拉巴拉的敲了一堆代码,信心满满的就直接执行.等到 ...
- 视频和音频播放的演示最简单的例子6:OpenGL广播YUV420P(T经exture,采用Shader)
===================================================== 最简单的视频和音频播放的演示样品系列列表: 最简单的视音频播放演示样例1:总述 最简单的视音 ...
- Webpact打包React后端Node+Express
Webpact打包React后端Node+Express 前言 React官方推荐用Browserify或者Webpack 来开发React组件. Webpack 是什么?是德国开发者 Tobias ...
- 注册表 ControlSet001、ControlSet002以及CurrentControlSet
首先说说ControlSet几组控制之间的关系. 注册表HKLM\system注意 注册表项包含windows启动的三个控件组(额外还可能存在一个备份控件组).在初始状态下.它们各自是Con ...
- NSIS常用代码整理
原文 NSIS常用代码整理 这是一些常用的NSIS代码,少轻狂特意整理出来,方便大家随时查看使用.不定期更新哦~~~ 1 ;获取操作系统盘符 2 ReadEnvStr $R0 SYSTEMDRIVE ...
- Tick and Tick------HDOJ杭州电(无法解释,直接看代码)
Problem Description The three hands of the clock are rotating every second and meeting each other ma ...
- Visual studio 2013 bug:visual studio no editoroptiondefinition export found for the given option nam
昨天VS 2013打开项目,双击cs当文件,下面出现bug. Google没有理由.最后,在刚刚好清理C磁盘缓存用户文件夹. 然后就OK了. 详细的路径是:C:\Users\{当前用户}\AppDat ...
- 标准差(standard deviation)和标准错误(standard error)你能解释一下?
by:ysuncn(欢迎转载,转载请注明原始消息) 什么是标准差(standard deviation)呢?依据国际标准化组织(ISO)的定义:标准差σ是方差σ2的正平方根.而方差是随机变量期望的二次 ...