课堂里学不到的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文件然后编译运行下:

[email protected]:~/project/c> ls hellow.cpp

[email protected]:~/project/c> g++ hellow.cpp -o hellow.o

[email protected]:~/project/c> ls hellow.cpp  hellow.o

[email protected]:~/project/c>

-o是指定结果文件名,这里编译成目标文件hellow.o

如果不用-o指定文件名,默认是编译成a.out文件的。

.out文件是编译链接成的可执行文件,而.o文件一般是编译出来的一个目标文件,还没有链接的。

但是Linux下是不以后缀名来区别是否是可执行文件,区别的标准只有一个:该文件在对应的用户下有没有执行权限(x权限)。 好了,运行一下:

[email protected]:~/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运行一下:

[email protected]:~/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爱好者+云计算 刁金明”

时间: 2024-11-01 17:36:55

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

在QEMU里学C语言-01- #define

QEMU中对C语言的使用非常高级,这里想从QEMU中对C语言的用法中,来重新认识C语言,今天的任务就是从弄懂这几段代码的意思开始吧! #define module_init(function, type) static void __attribute__((constructor)) do_qemu_init_ ## function(void) { register_module_init(function, type); } #endif #define QTAILQ_INSERT_TAI

【转载】我多希望我学编程时,有人教我这些事!

1.学编程之前,想清楚自己想写什么. 学习编程基本就是在学习建造东西.如果你知道你到底想造什么,你的编程学习之路将会豁然开朗. 如果你的目标只是“学习如何编程”,却不知道自己到底想写出什么样的程序,也不知道这些程序将如何让你的生活变得更美好,你很有可能会感到编程学习令你沮丧受挫. 说起来还有点丢脸,我最早想学习编程,是因为我想证明我聪明.并且,我也想做一份属于聪明人的工作.我还喜欢思考数学及理论.因此,编程怎么看都和我很搭. 但是这些想法都不足以延续我的编程学习热情.直到有一天,当我终于发现如何

苏黄永郦第二周的读书报告

如何在大学里脱颖而出 从社团到求职 来到大学,我首先关注的内容竟然不是会有哪些难的课程,而是有没有我喜欢的社团.对,是社团!我认为,在大学既然不能回家,那我最好还是尽量地参加我感兴趣的社团去加入,这样我才能有家的赶脚.大学里社团所扮演一个介于课堂和社会的角色.对于我来说,社团既是课堂,又是社会.社团可以教给我一些在课堂里学不到的知识,还可以教会我如何与人打交道.如果我能在毕业之前学会这些必备技能,以后我在社会中就不愁找不到立足之地. 社团生活还考验我的团队组织能力.社团肯定会有活动,有活动就会有

objectarx 批量倒角

这个插件支持AcDbPolyline的倒角,封闭的和没封闭的都可以.刚开始做的时候,发现倒一个角借助云幽课堂里的代码就可以做,后来做一条从左开始画的非封闭的多段线,发现向上凹和向下凹的角不能同时被倒,代码只能倒向上凹的,向下凹的代码时反着的,后来我把凸度取反,向下凹的又可以倒角了.这时我觉得就行了,后来又出现问题,发现顺时针或逆时针画个半包围的图形时,在顶上的角或者底下的角倒出的角又是反着的.最后是画只有一个角的多段线,根据代码的bug,一个个的写判断条件瞎做出来的.光是if else 我都写了

《原来我还可以这样活:拆掉思维里的墙》作者:古典

第一部分 一.职业安全感奴隶 房子,月供,每月盈余资金少,舍不得投资学习交流,每每小心翼翼,梦想定格在了一点: 反过来,打开手脚,可能会更好(); 你 一定也有过这种感觉,自己陷入那种那种好像什么都有一点可能,但是又什么都做不到的恐惧.自己突然很弱小很弱小,禁不起任何的失败的.世界很大,我却没有 力量去任何地方:那是一种好像被什么东西囚禁住的感觉.这个时候你多希望有一个权威的声音说,去吧!你一定可以成!但是没有任何人会这样说.职业规划师们 也不会,他们会知道,这不是一个职业规划的问题,而是一个心

高考日里说教育:从网络公开课到碎片化教学,有多远

今天高考第二天,以往每年我都会在第一天的时候写一篇高考同题零分作文,今年没写,为何?因为觉得没有写的必要吧,挺无聊的! 文/张书乐 5月19日的株洲晚报上,一篇<孩子在学校上课,家长可以用手机看直播>的稿子引起了我的注意.原因有二,其一是看了内容,觉得被标题给"骗"了,新闻其实说的是天元区19个中小学通过"同步课堂"系统做了个串联,19个学校的学生,坐在课堂里就能够看到"联网"学校名师的课程,至于家长可以看直播,算是一个副产品吧:其二

跟着数百万人编程导师学C语言!

点击关注 异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书 --异步小编 为什么说这不是一本完全C语言的书?因为<"笨办法"学C语言>不仅仅是一本书,随书附赠5个多小时充满激情的视频,这是一套完整的C语言视频课程! 这本书刚拿到样书,运营经理兴奋的发来消息:"手机扫码看视频,太方便了,速度也很快,配的字幕也很赞!"而本书的责编杨海玲老师很淡定:"这个是我尝试的第一本扫码看视频的书,虽然遇到些问

对学代码的一些心得

大家好,我是一名大三的学生——小林.我在大学里学的是行政管理专业.因为我的这个专业是文科专业,所以我对代码的知识可谓是一窍不通.但是我又很喜欢代码,很想学习代码.于是我就参加了兄弟连培训机构,在这里,我接触到了代码. 在我刚接触到代码的时候,真的是头都大了.我什么都不懂,连最基本的代码语句,代码知识都不会.于是我学起来有点吃力.但是听到这里的老师说,代码这东西还是要多敲,在做作业的时候都思考,这样学起来就很轻松. 于是在以后的上课中,我都非常认真的听老师讲课,听老师用代码讲解每一个案例.当然,只

【转】程序员怎样学数学

I've been working for the past 15 months on repairing my rusty math skills, ever since I read a biography of Johnny von Neumann. I've read a huge stack of math books, and I have an even bigger stack of unread math books. And it's starting to come tog