首先,声明一下这是一个系列的文章。至于整个系列有多少篇,笔者也不知道,不知道有多少篇,也不知道多久会更新一篇。反正只有一个原则,写出来的文 章能见得人才会公布出来。另外,我不是叫你逃课,而是觉得听课只是一般学生做的,听课的时候把该听的听了,不该听的听过就算了,课堂上的东西只不过是大千 编程界里细沙一粒也称不上,真正牛的人从不满足那一小点知识,有些事太认真你就输了,世界很大,不要局限自己的视野,那样会很累。

首先:整个系统环境都是基于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爱好者+云计算 刁金明”

课堂里学不到的C与C++那些事(一)的更多相关文章

  1. 从 3 个 IT 公司里学到的 57 条经验

    自1999年起我就开始发掘一些科技公司,并帮助它们运营.下面是从干这行中得到的57条经验.我可以列出更多,但恐怕会令你厌烦. 1.做你个人有热情的事情.你是你自己最好的民意代表. 2.用户体验很重要. ...

  2. 在微信公众号"码海"里学了一招:在update语句里使用case when 以避免多次更新导致的数据异常.

    需求:将emp表中工资大于一万的降到9成,工资少于一万的乘以1.2. 难点:如果分成两句update执行,在10000附近的值可能会执行两次. 钥匙:在update语句里采用case when,使更新 ...

  3. C++学了这么多年,你仍不知道的事

    C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类的实现放在cpp文件中.它们为什么能够关联到一起呢?你知道什么东西可以放在.h文件中,什么不能.什么东西又可以放在cpp文件中.如果 ...

  4. 跟我一起学.NetCore之静态文件处理的那些事

    前言 如今前后端分离开发模式如火如荼,开发职责更加分明(当然前后端一起搞的模式也没有完全褪去):而对于每个公司产品实施来说,部署模式会稍有差别,有的会单独将前端文件部署为一个站点,有的会将前端文件和后 ...

  5. inux平台的C与C++

    课堂里学不到的C与C++那些事(一) 首先,声明一下这是一个系列的文章.至于整个系列有多少篇,笔者也不知道,不知道有多少篇,也不知道多久会更新一篇.反正只有一个原则,写出来的文 章能见得人才会公布出来 ...

  6. <概要>

    虽然不知道这个博客园网站是中国还是国外,但是我倾向于中国,我是一名爱国者.我喜欢分享自己的学习经验,喜欢学习新的知识. 截止到2016年01月28日我到这个公司的第七天,在这七天里,我学习了一些东西, ...

  7. objectarx 批量倒角

    这个插件支持AcDbPolyline的倒角,封闭的和没封闭的都可以.刚开始做的时候,发现倒一个角借助云幽课堂里的代码就可以做,后来做一条从左开始画的非封闭的多段线,发现向上凹和向下凹的角不能同时被倒, ...

  8. 合适么?现在学ASP.NET Core入门编程……

    现在都快找不到ASP.NET的培训课程了. 知道我要开课做培训,有同学劝我:“憋讲那什么.NET,讲Java,现在这个火!”我说我Java不熟,“唉呀!C#转Java,分分钟的事!以飞哥你的经验,…… ...

  9. 在 2016 年学 JavaScript 是一种什么样的体验?

    转 译者:方应杭 嘿,我最近接到一个 Web 项目,不过老实说,我这两年没怎么接触 Web 编程,听说 Web 技术已经发生了一些变化.听说你是这里对新技术最了解的 Web 开发工程师? 准确地说,我 ...

随机推荐

  1. hdu5323 Solve this interesting problem(爆搜)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Solve this interesting problem Time Limit ...

  2. 客户端技术:Cookie 服务端技术:HttpSession

    客户端技术:Cookie 服务端技术:HttpSession 07. 五 / android基础 / 没有评论   一.会话技术1.什么是会话:客户打开浏览器访问一个网站,访问完毕之后,关闭浏览器.这 ...

  3. show_space/get_alert_log/get_trace_file

    1.get_alert_log 获取alert文件的路径和名称 set serveroutput on        --设置输出,让sqlplus在屏幕上可以输出.(要加入到login.sql中!) ...

  4. web api 返回数据XML JSON

    WEBAPI返回的数据格式一般是XML和JSON.能根据请求的要求返回.经过试验如下: public object Get(string uid) { return new {msg="成功 ...

  5. javascript数组方法鉴赏一

    创建数组 如果你习惯了用 new 来实例化对象的形式,那么在js中一定会疑惑,可选的参数数量代表的意义截然不同. new Array(size);//传一个参数的时候分两种情况,size是正整数时代表 ...

  6. /users/products.:format 这种写法的其对应解析字符写法

    “products.:format" 这种写法可以有对应的下面两种路由形式 /products.json /products.xml "products.:format?" ...

  7. sourceforge软件下载方式

    访问http://www.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/ 根据软件名称在文件列表中查找

  8. Android_Studio 及SDK下载

    Android Studio includes all the tools you need to build apps for Android. DOWNLOAD ANDROID STUDIO 2. ...

  9. Roman to Integer && Integer to Roman 解答

    Roman Numeral Chart V:5 X:10 L:50 C:100 D:500 M:1000 规则: 1. 重复次数表示该数的倍数2. 右加左减:较大的罗马数字右边记上较小的罗马数字,表示 ...

  10. Linux CPU 亲和性

    在Linux中,我们知道可以通过nice.renice命令改变进程的执行优先级,优先级高的进程优先执行,从而一定程度上保证重要任务的运行. 除了nice.renice外,可以通过CPU affinit ...