安全黑客
当前位置:安全黑客文章资讯编程技术VC/C++编程
日期:2012-03-13 17:48:00  来源:本站整理

超级新手问答(C/C++ Newbie's FAQ)[VC/C++编程]

赞助商链接



  本文“超级新手问答(C/C++ Newbie's FAQ)[VC/C++编程]”是由安全黑客为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

  新手必看.

  学习C/C++必定会问到以下几个问题,下面让这个经验帮你解惑吧!

  步骤/办法

  vi, vim是编译器么?

  vi means visual editor,是软件世界第一个全屏幕编辑器,最初的作者是目前Sun microsystem的Bill Joy.

  vim means Vi IMproved,可以看做是加强的vi.

  很不幸,他们都不是编译器,假如你已经写好了first.c,那么不能期望vi们将你的源代码变成执路程序.

  gcc, g++这些都是干什么用的

  gcc means GNU C Collector,是GNU的旗舰软件,安闲软件,C语言编译器.

  g++ 是GNU的C++编译器.

  那么cc, CC, ld, make这些程序又是干什么的呢?

  cc是unix world中对c编译器的叫法,就是c compiler.

  CC 是对c++编译器的叫法,这两个名称都不特指某一厂家的产品.比方HP供应的HP-UX上c编译器叫cc,Solaris上的c编译器也叫cc ld means link editor,是衔接器的通称,并不特指某一个具体的产品.但是他们都是用来衔接目标文件的.

  make means ???,make程序按照Makefile/makefile中指定的法则,以及一些默许的法则,完成从源代码到终究代码的处理历程.不光可以用来编译衔接程序,也可以做别的的一些有依靠,分阶段的事情.

  我已经安装了linux,若何开始我的C/C++之旅呢?

  step 1: typein a helloworld program(1) in your favorate editor, I think it must be a vim

  step 2: save your program to hello.c and then quit from the editor

  step 3: typein 'gcc hello.c'

  step 4: typein 'a.out'

  这时刻,你应当可以看到你的第一个程序已经顺利运行了!

  我们将上面的四个步骤概括一下,然后遵守这几个步骤,你便可以不断的生产出各样的程序了

  第一步:编辑程序

  第二步:编译程序

  第三步:运路程序

  我的程序运行后果与我想象的差别!

  假如你的第一反映是"printf这个函数(大概gcc大概其他的库什么的)有问题!",那么我想你是个自恋狂,记着,整个系统中唯一没有经过测试的就是你的代码,任何东西都是没有问题的,除了你的代码.(当然gcc也大概有问题,但是被你碰到的概率可以暂时看做是0)

  我们有两种方法来办理这个问题:

  第一种方法是利用printf函数在大概出问题的地方输出相关变量,好处是可以快速的上手,不需求其他的知识.害处是假如你没有充足的本领,你有大概忘掉删除这些函数,以及在程序对比大的时刻每次增添了新的printf都要重新编译,太浪费时间.

  第二种方法是利用调试器,比方gdb.但是gdb就象你知道的其他大部份调试器一样,是标记调试器,他们依靠于编译器产生的标记表.标记表普通可以通过给编译器指定-g参数来生成.假如没有标记表,gdb很难利用(仍旧可以利用,假如你熟习汇编语言的话).

  Core dump!

  你的程序目前已经很复杂了,在你增添了某一个非常强劲的功效后,一履行,屏幕上呈现一行小字:

  Segmentation fault(core dump)

  然后一切就都安静了下来.可以说太糟糕了,unix所能供应的最坏的界面都让你碰到了.怎么办呢?

  假如你记得了在编译程序的时刻利用-g参数,那么目前它就派上了用场.你可以:

  gdb a.out core

  然后你便可以通过gdb的where号令查看问题出在了什么地方.

  segmentation fault的意思是段违例,普通由于你的程序越界写造成.比方你的数组长度是8,但是你计划向相当于第10个元素的位置写入数据,便大概会产生这个问题. core dump产生的缘由不止是segment fault,还有大概是其他的,总之是因为有坏人向你的程序发送了一个不可捕捉的信号.假如这句话的意思你不懂得,没有关系,也不需求懂得,那是今后的事.

  printf的头文件在那边?

  你在星巴克里跟女朋友聊天并同时向邻座的单身女孩抛媚眼的时刻,头脑里还在想一个想了很长时间但是一向没有答案的问题,到底若何向屏幕输出一行文字呢?这时刻,两个笨蛋从你旁边经过,他们正在谈论printf,你听到后,认为:哦,这才是我想要的,对printf,没错.但是你那如编译器普通的大脑即刻提醒你,找不到函数原型,应当包含什么头文件呢?于是你终止聊天和抛接媚眼,翻开手提电脑,通过某种无线装配接入到internet,在bbs上发了一个帖子:

  where the printf() is defined?

  但是出乎你的意料,固然这是一个刚果人都常常光临的bbs,但是竟然过去了5分钟之后,仍旧没有人答复你.看来这个问题偏难,你浅笑着对你的女朋友说.

  事实上,你不该该问这样的问题.你应当学会自己办理这样的问题,我供应应你几个途径:

  main printf(假如该关键字有多个entry,则应当用man -a大概man -k,大概直接指定section)

  find /usr/include -name "*.h" -print | xargs grep printf

  search on Google

  我已经有多个.c 文件了,应当若何编译呢?

  经过一段时间的开辟,你的程序目前已经从一个简单的foo.c变成了两个文件,foo.c和bar.c,我们假定foo.c中定义了main函数.那么:

  gcc -g bar.c

  将报告你没有main函数.这让你很恼火,能否应当归并两个文件呢?还是...?

  精确的做法是编译时刻增添一个“只编译”的参数-c:

  gcc -g -c bar.c

  gcc -g -c foo.c

  gcc -o a.out foo.o bar.o

  这样之后,你的程序可以运行了.我们在前面提到三个步骤,编辑,编译,运行.但实际上,我们忽视了一个重要的步骤就是衔接,我们前面的例子中,编译和衔接都是一步完成的(不指定-c 的话),因此我们没有提起.但是你大约会问,衔接不该该是用ld么?为什么在这里用gcc完成了呢?ld当然是可以完成任务的,但是它并不知道我们在写一个c程序,c程序的main函数是由_start()函数调用的,而start函数是在runtime目标文件中(普通叫做xxcrt.o)实现的,任何 c程序都必须衔接这个runtime目标文件.假如用ld作为衔接器,我们不得不自己指定这个目标文件的位置以及文件名.但是,假如用gcc,则便利的多,它知道我们要额外衔接那些东西,它供应应我们一个更简单的利用界面,固然它仍旧是通过调用ld来工作的.

  Why a.out?

  迄今为止,你发现你的执路程序一向叫a.out,这个名字很古怪,也很土,你说呢?假如你想改变一下你的程序名字,应当:

  gcc -o win.exe foo.c bar.c

  这样,你的程序就叫做win.exe,而不是a.out了. a.out这个名字的发源预计是某人的一时冲动,比方我小时侯常常把程序中的变量顺次称为aint, bint...(绝对的坏习惯,这里先不说这个).但是后来履行文件因此得名,乃至履行文件的格局也因此得名(早期的unix履行文件格局称为a.out 格局,当然目前已经进化为ELF了).

  若何生成动态库和静态库?

  静态库是一个目标文件的简单调集.由ar(archive,归档的意思)生成.

  ar -cr libfoo.a foo.o bar.o

  普通命名方法是libxxx.a,但是你不服从也没有太大的问题.利用程序在利用你的库的时刻,普通只需求奉告ld你的库名字便可,这个名字就是 libxxx.a中的xxx,比方ld -lfoo.意思是奉告ld,衔接一个名字为libfoo.a大概libfoo.so的库.假如你的库名字不遵守libxxx.a的格局,ld就找不到,给利用开辟造成麻烦.

  别的,静态的意思是每个用到该库的利用程序都拥有一份自己的库拷贝,利用程序运行的时刻,即便将库删除也没有问题因为利用程序自己已经有了自己的拷贝.动态库构造复杂一些,普通是一个ELF格局的文件.可以有三种办法生成:

  ld -G

  gcc -share

  libtool

  用ld最复杂,用gcc -share就简单的多,但是-share并非在任何平台都可以利用.GNU供应了一个更好的工具libtool,专门用来在各种平台上生成各种库.

  动态库实际上应当叫做同享库,只是很多人从windows的Dynamic Linked Library这个词学习过来,把unix的同享库称做动态库.全部利用程序同享一份库拷贝,所以,即便衔接完了,也不能将其删除.并且需求在 LD_LIBRARY_PATH这个环境变量中精确的设置库所在的位置,不然程序运行会报告找不到这个库.

  我有了10个.c文件,还是一个一个编译么?有没有工程的概念(就象vc的dsp)?

  确切一个一个编译很土.我们有更好的办法,就是make.make程序是一个近似脚本执路程序一样的东西.它按照你供应的Makefile(大概小写的 makefile)来工作,它可以处理复杂的依靠关系,就象你但愿的那样,假如改正了一个头文件,那么包含它的全部.c程序都应当被重新编译.但是很不幸,这种依靠关系需求你自己指定.你首先要理解makefile的语法,然后按照语法来写makefile.当程序很多得时刻,makefile也变得复杂.假如你但愿得到makefile得更具体信息,可以man make大概在linux里面:

  info make

  但是没有更简单的办法么?好在世界上除了你我之外还有很多人注意到了这个问题.目前有两个简单的办法:

  imake,imake 是依靠已经成立好得一个库信息数据库,可以帮忙你完成衔接碰到的问题,特别是写X Window程序,很多人用imake automake/autoconf,这两个程序越发完善和简单.但是利用略微复杂一些,你需求看更多的手册才能掌握,但是非常好用,简单到假如你增添了一个.c文件,只需求在Makefile.am中增添一个文件名便可,头文件的依靠完好自动生成.这两个简单的办法已经超越了新手可以承受的范围,假如你确切是新手,还是学着自己写makefile好一些.

  我要学习linux kernel的源代码,碰到了一些问题,能奉告我怎么办么?

  假如前面的问题有你不清楚的,我倡议你还是找一本浅显一些的教材,然后敲些例子程序来学习.目前大家的趋向好象是言必称kernel,好象不太对劲.学习的对象假如不合适自己的层次,只能招致进度减慢.

  printf()这个函数若何利用?

  这个问题好象与前面的问题近似,但是因为太多人问近似的问题,所以只好单独列出来了.你不该该问这样的问题,你应当首先想到的是man,这个巨大的助手.

  man printf

  当然,差别的OS,可以供应应你的man略有差别,比方man的参数等等.所以当你接触到一个新的unix变种的时刻,有必要先:

  man man

  这样可以知道man应当若何利用.

  别的,当man办理不了你的问题的时刻,最好的办法是自己写一个测试程序,在自己的$HOME中保持一个test目录是我的习惯,碰到任何不能必定的问题,都可以在这里先实行一番.这些办法都比到bbs上去发问高效.

  Windows vs Linux?

  这里扯出这个问题好象有些奇特.这个文档主如果以linux为后台讲的,因此很少触及到Windows平台下面的东西.但是这不等于说Windows不好,只是顾及了我自己的一些偏好.开始学习的早期,这些因素的影响不大,不用加入到孰优孰劣的无聊争辩中.

  我要学习C++,需求C语言的知识么?

  C++和C这两种语言的关系在The C++ Programming Language这本书的1.6节讲的已经很清楚了,假如你有什么疑问,可以细心读一读.应当可以不需求C语言的知识便可以开始学习C++,但是有些C的基本常识,再学习C++,必定是有帮忙的.

  哪些东西应当放进头文件中,哪些不该该?

  头文件相当于一个模块接口的描写,应当尽大概的简单明了.

  我们可以按照下面的公式来判断哪些东西应当进入头文件,哪些只要在源程序中声明便可以了:

  这个构造能否会在别的源程序中被利用?

  yes

  进入头文件

  no

  不进入头文件

  实际上,还会有一些被“株连”的构造啊,宏啊什么的被编译器要求放进头文件.比方:

  struct A

  {
  以上是“超级新手问答(C/C++ Newbie's FAQ)[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看安全黑客为您推荐以下文章:

  • 超级新手问答(C/C++ Newbie's FAQ)
  • 本文地址: 与您的QQ/BBS好友分享!

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    免责条款 - 广告合作 - 下载声明 - 欢迎投稿 - 友情连接 - 网站地图 -
    Copyright © 2012-2013 www.110hack.com. All Rights Reserved .