Linux下的C编程.ppt_第1页
Linux下的C编程.ppt_第2页
Linux下的C编程.ppt_第3页
Linux下的C编程.ppt_第4页
Linux下的C编程.ppt_第5页
已阅读5页,还剩88页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux与C编程基础 测试一下C语言基本功 思科面试题 用变量a给出下面的定义a 一个整型数 Aninteger b 一个指向整型数的指针 Apointertoaninteger c 一个指向指针的的指针 它指向的指针是指向一个整型数 Apointertoapointertoaninteger d 一个有10个整型数的数组 Anarrayof10integerse 一个有10个指针的数组 该指针是指向一个整型数的 Anarrayof10pointerstointegers 参考答案 答案是 a inta Anintegerb int a Apointertoanintegerc int a Apointertoapointertoanintegerd inta 10 Anarrayof10integerse int a 10 Anarrayof10pointerstointegers 思科面试题 f 一个指向有10个整型数数组的指针 Apointertoanarrayof10integers g 一个指向函数的指针 该函数有一个整型参数并返回一个整型数 Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger h 一个有10个指针的数组 该指针指向一个函数 该函数有一个整型参数并返回一个整型数 Anarrayoftenpointerstofunctionsthattakeanintegerargumentandreturnaninteger 参考答案 f int a 10 Apointertoanarrayof10integersg int a int Apointertoafunctionathattakesanintegerargumentandreturnsanintegerh int a 10 int Anarrayof10pointerstofunctionsthattakeanintegerargumentandreturnaninteger 死循环 Infiniteloops 2 嵌入式系统中经常要用到无限循环 你怎么样用C编写死循环呢 这个问题用几个解决方案 方案是 while 1 一些程序员更喜欢如下方案 for 您能写出更简洁的吗 面试题 更简洁是while 1 for 下面语句编译能通过吗 inta while 1 for 华为面试题 1 语句for 1 有什么问题 它是什么意思 答 和while 1 相同 华为面试题 2 do while和while do有什么区别 答 前一个循环一遍再判断 后一个判断以后再循环 华为面试题 3 请写出下列代码的输出内容 includemain inta b c d a 10 b a c a d 10 a printf b c d d d d b c d return0 答 b c d 10 12 120 华为面试题4 设有以下语句 说明其定义含义 并回答问题 typedefunion longi intk 5 charc DATE structdata intcat DATEcow doubledog too DATEmax 则语句printf d sizeof structdata sizeof max 的执行结果是 华为面试题4 设有以下语句说明和定义 解释各自的含义 答案 DATE是一个union 变量公用空间 里面最大的变量类型是int 5 占用20个字节 所以它的大小是20data是一个struct 每个变量分开占用空间 依次为int4 DATE20 double8 32 所以结果是20 32 52 当然 在某些16位编辑器下 int可能是2字节 那么结果是int2 DATE10 double8 20 5 请找出下面代码中的所有点错误 并给出修改方案说明 以下代码是把一个字符串倒序 如 abcd 倒序后变为 dcba 1 include string h 2 main 3 4 char src hello world 5 char dest NULL 6 intlen strlen src 7 dest char malloc len 8 char d dest 9 char s src len 10 while len 0 11 d s 12 printf s dest 13 return0 14 方法1 intmain char src hello world intlen strlen src char dest char malloc len 1 要为 0分配一个空间char d dest char s 方法2 include string h include stdio h main charstr hello world intlen strlen str chart for inti 0 i t str i str i str len i 1 str len i 1 t printf s str return0 vim命令学习 1 1 欲进入vim编辑器 从命令行提示符 请输入 vim文件名2 光标在屏幕文本中的移动既可以用箭头键 也可以使用hjkl字母键 h 左移 j 下行 k 上行 l 右移 3 欲退出vim编辑器 请输入以下命令放弃所有修改 q 或者输入以下命令保存所有修改 wq vim命令学习 2 4 在正常模式下删除光标所在位置的字符 请按 x5 在正常模式下要在光标所在位置开始插入文本 请按 i输入必要文本特别提示 按下键会带您回到正常模式或者取消一个不期望或者部分完成的命令 vim命令学习 3 1 欲从当前光标删除至单字 单词末尾 请输入 dw2 欲从当前光标删除至当前行末尾 请输入 d 3 欲删除整行 请输入 dd vim命令学习 4 4 在正常模式下一个命令的格式是 number commandobject或者command number object其意是 number 代表的是命令执行的次数command 代表要做的事情 比如d代表删除 object 代表要操作的对象 比如w代表单字 单词 代表到行末等等 totheendofline etc vim命令学习 4 dnw 删除n个单词dne 也可 只是删除到单词尾dnl 向右删除n个字母dnh 向左删除n个字母dnj 向下删除n行dnk 向上删除n行d 删除当前光标到改行的行尾的字母dd 删除一行 vim命令学习 4 5 欲撤消以前的操作 请输入 u 小写的u 欲撤消在一行中所做的改动 请输入 U 大写的U 欲撤消以前的撤消命令 恢复以前的操作结果 请输入 CTRL R vim命令学习 5 粘贴 p 这是粘贴用x或d删除的文本复制 ynw 复制n个单词yy 复制一行ynl 复制n个字符y 复制当前光标至行尾处nyy 拷贝n行完了用p粘贴 vim命令学习 5 split 分割一个窗口 splitfile c 为另一个文件file c分隔窗口 nsplitfile c 为另一个文件file c分隔窗口 并指定其行数CTRL W在窗口中切换 close 关闭当前窗口 C源程序的编译 在Linux下面 如果要编译一个C语言源程序 我们要使用GNU的gcc编译器 下面我们以一个实例来说明如何使用gcc编译器 假设我们有下面一个非常简单的源程序 hello c includeintmain printf WelcometoLinuxProgramming n return0 C源程序的编译 要编译这个程序 我们只要在命令行下执行 gcc ohellohello cgcc编译器就会为我们生成一个hello的可执行文件 执行 hello就可以看到程序的输出结果了 源程序的编译 gcc ohellohello c命令行中gcc表示我们是用gcc来编译我们的源程序 o选项表示我们要求编译器给我们输出的可执行文件名为hello而hello c是我们的源程序文件 gcc编译器有许多选项 一般来说我们只要知道其中的几个就够了 gcc编译器选项 o选项 表示我们要求输出的可执行文件名 c选项表示我们只要求编译器输出目标代码 而不必要输出可执行文件 g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息 gcc编译器选项 知道了这三个选项 我们就可以编译我们自己所写的简单的源程序了如果你想要知道更多的选项 可以查看gcc的帮助文档 那里有着许多对其它选项的详细说明 多源文件的编译方法 如果有多个源文件 基本上有两种编译方法 假设有两个源文件为test c和testfun c a 多个文件一起编译用法 gcctestfun ctest c otest作用 将testfun c和test c分别编译后链接成test可执行文件 多源文件的编译方法 b 分别编译各个源文件 之后对编译后输出的目标文件链接 用法 gcc ctestfun c 将testfun c编译成testfun o gcc ctest c 将test c编译成test o gcc otestfun otest o otest 将testfun o和test o链接成test 多源文件的编译方法 以上两种方法相比较 第一中方法编译时需要所有文件重新编译而第二种方法可以只重新编译修改的文件 未修改的文件不用重新编译 补充 如何利用gcc编译 C GCC是个功能很强大 但精通的掌握它也许需要几个月的时间 例如 编写my class cpp和my class h包含你自己创建的一个类 写一个test cpp 里面包含main函数并且调用my class 1 g cmy class cpp2 g otesttest cppmy class o实际上对于C 程序员 只要记住g 命令 记住 c和 o两个参数 就可以开始用gcc了 Makefile的编写 假设我们有下面这样的一个程序 源代码如下 main c include mytool1 h include mytool2 h intmain intargc char argv mytool1 print hello mytool2 print hello Makefile的编写 mytool1 c include mytool1 h voidmytool1 print char print str printf Thisismytool1print s n print str mytool1 h ifndef MYTOOL 1 H define MYTOOL 1 Hvoidmytool1 print char print str endif mytool2 h ifndef MYTOOL 2 H define MYTOOL 2 Hvoidmytool2 print char print str endif mytool2 c include mytool2 h voidmytool2 print char print str printf Thisismytool2print s n print str Makefile的编写 当然由于这个程序是很短的我们可以这样来编译gcc cmain cgcc cmytool1 cgcc cmytool2 cgcc omainmain omytool1 omytool2 o这样的话我们也可以产生main程序 而且也不很麻烦 但是如果我们考虑一下如果有一天我们修改了其中的一个文件 比如说mytool1 c 那么我们还要重新输入上面的命令 非常的麻烦 Makefile的编写 当我们把事情想的更复杂一点 如果我们的程序有几百个源程序的时候 难道也要编译器重新一个一个的去编译 为此 聪明的程序员们想出了一个很好的工具来做这件事情 这就是make 我们只要执行以下make 就可以把上面的问题解决掉 在我们执行make之前 我们要先编写一个非常重要的文件 Makefile Makefile的编写 在我们执行make之前 我们要先编写一个非常重要的文件 Makefile 对于上面的那个程序来说 可能的一个Makefile的文件是 注释行 这是上面那个程序的Makefile文件main main omytool1 omytool2 ogcc omainmain omytool1 omytool2 omain o main cmytool1 hmytool2 hgcc cmain cmytool1 o mytool1 cmytool1 hgcc cmytool1 cmytool2 o mytool2 cmytool2 hgcc cmytool2 c Makefile的编写 有了这个Makefile文件 不管我们什么时候修改了源程序当中的什么文件 我们只要执行make命令我们的编译器都只会去编译和我们修改的文件有关的文件 其它的文件不予理睬 节省了大量编译时间 Makefile的编写 下面我们学习Makefile是如何编写的 在Makefile中 开始的行都是注释行 Makefile中最重要的是描述文件的依赖关系的说明 一般的格式是 target componentsTABrule 第一行表示的是依赖关系 第二行是规则 Makefile的编写 比如说我们上面的那个Makefile文件的第二行main main omytool1 omytool2 o表示我们的目标 target main的依赖对象 components 是main omytool1 omytool2 o当倚赖的对象在目标修改后修改的话 就要去执行规则一行所指定的命令 就象我们的上面那个Makefile第三行所说的一样要执行gcc omainmain omytool1 omytool2 o注意规则一行中的TAB表示那里是一个TAB键 Makefile的编写 Makefile的常用变量 Makefile有三个非常有用的变量 其意义为 目标文件 所有的依赖文件 第一个依赖文件如果使用上面三个变量 上面那个Makefile文件可简化为 注释行 这是原来程序的Makefile文件main main omytool1 omytool2 ogcc omainmain omytool1 omytool2 omain o main cmytool1 hmytool2 hgcc cmain cmytool1 o mytool1 cmytool1 hgcc cmytool1 cmytool2 o mytool2 cmytool2 hgcc cmytool2 c 这是简化后的Makefilemain main omytool1 omytool2 ogcc o main o main cmytool1 hmytool2 hgcc c mytool1 o mytool1 cmytool1 hgcc c mytool2 o mytool2 cmytool2 hgcc c 目标文件 所有的依赖文件 第一个依赖文件 Makefile的缺省规则 c o gcc c 这个规则表示所有的 o文件都是依赖于相应的 c文件的 例如mytool o依赖于mytool c 这样上面那个Makefile还可以简化为 这是简化后的Makefilemain main omytool1 omytool2 ogcc o main o main cmytool1 hmytool2 hgcc c mytool1 o mytool1 cmytool1 hgcc c mytool2 o mytool2 cmytool2 hgcc c 这是再一次简化后的Makefilemain main omytool1 omytool2 ogcc o c o gcc c 目标文件 所有的依赖文件 第一个依赖文件 注释行 这是原来程序的Makefile文件main main omytool1 omytool2 ogcc omainmain omytool1 omytool2 omain o main cmytool1 hmytool2 hgcc cmain cmytool1 o mytool1 cmytool1 hgcc cmytool1 cmytool2 o mytool2 cmytool2 hgcc cmytool2 c c o gcc c 这个规则表示所有的 o文件都是依赖于相应的 c文件的 程序的调试 我们编写的程序不太可能一次性就会成功的 在我们的程序当中 会出现许许多多我们想不到的错误 这个时候我们就要对我们的程序进行调试了 最常用的调试软件是gdb GDB GNUsymbolicdebugger 简单地说就是一个调试工具 它是一个受通用公共许可证即GPL保护的自由软件 记得要在编译的时候加入 g选项 GDB概述 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具 或许 各位比较喜欢那种图形界面方式的 像VC BCB等IDE的调试 但如果你是在UNIX Linux平台下做软件 你会发现GDB这个调试工具有比VC BCB的图形化调试器更强大的功能 所谓 寸有所长 尺有所短 就是这个道理 GDB概述 一般来说 GDB主要帮忙你完成下面四个方面的功能 1 启动你的程序 可以按照你的自定义的要求随心所欲的运行程序 2 可让被调试的程序在你所指定的调置的断点处停住 断点可以是条件表达式 3 当程序被停住时 可以检查此时你的程序中所发生的事 4 动态的改变你程序的执行环境 一个调试示例 源程序 tst c1 include23intfunc intn 4 5intsum 0 i 6for i 0 i n i 7 8sum i 9 10returnsum 11 1213 14main 15 16inti 17longresult 0 18for i 1 i 100 i 19 20result i 21 2223printf result 1 100 d n result 24printf result 1 250 d n func 250 25 使用GDB 一般来说GDB主要调试的是C C 的程序 要调试C C 的程序 首先在编译时 我们必须要把调试信息加到可执行文件中 1 使用编译器 cc gcc g 的 g参数可以做到这一点 如 gcc ghello c ohello g ghello cpp ohello如果没有 g 将看不见程序的函数名 变量名 所代替的全是运行时的内存地址 当你用 g把调试信息加入之后 并成功编译目标代码以后 让我们来看看如何用gdb来调试程序 启动GDB的方法有以下几种 1 gdbprogram也就是你的执行文件 一般在当然目录下 2 gdbcore用gdb同时调试一个运行程序和core文件 core是程序非法执行后coredump后产生的文件 3 gdb如果你的程序是一个服务程序 那么你可以指定这个服务程序运行时的进程ID gdb会自动attach上去 并调试他 program应该在PATH环境变量中搜索得到 gdb基本命令 gdb支持很多的命令使你能实现不同的功能 这些命令从简单的文件装入到允许检查所调用的堆栈内容的复杂命令 下表列出了在用gdb调试时会用到的一些命令 想了解gdb的详细使用请参考gdb的指南页 gdb基本命令 小技巧 GDB启动后第一次list显示的是main函数的上下文6行可以用l 行号 可以显示选定行的上下6行list可以指定打开位置的 list1 15也可以指定要打开的文件 listmain c 10 使用GDB调试 gdbtst23intfunc intn 4 5intsum 0 i 6for i 0 i n i 7 8sum i 9 10returnsum gdb 直接回车表示 重复上一次命令11 121314main 15 16inti 17longresult 0 18for i 1 i 100 i 19 20result i gdb break16 设置断点 在源程序第16行处 Breakpoint1at0 x8048496 filetst c line16 gdb breakfunc 设置断点 在函数func 入口处 Breakpoint2at0 x8048456 filetst c line5 gdb infobreak 查看断点信息 NumTypeDispEnbAddressWhat1breakpointkeepy0 x08048496inmainattst c 162breakpointkeepy0 x08048456infuncattst c 5 gdb r 运行程序 run命令简写Startingprogram home hchen test tstBreakpoint1 main attst c 17 在断点处停住 17longresult 0 gdb n 单条语句执行 next命令简写 18for i 1 i 100 i gdb n20result i gdb n18for i 1 i 100 i gdb n20result i gdb c 继续运行程序 continue命令简写 Continuing result 1 100 5050 程序输出 Breakpoint2 func n 250 attst c 55intsum 0 i gdb n6for i 1 i n i gdb pi 打印变量i的值 print命令简写 1 134513808 gdb n8sum i gdb n6for i 1 i n i gdb psum 2 1 gdb n8sum i gdb pi 3 2 gdb n6for i 1 i n i gdb psum 4 3 gdb bt 查看函数堆栈 0func n 250 attst c 5 10 x080484e4inmain attst c 24 20 x400409edin libc start main from lib libc so 6 gdb finish GDB的命令概貌 启动gdb后 就你被带入gdb的调试环境中 就可以使用gdb的命令开始调试程序了 gdb的命令可以使用help命令来查看 gdb中 输入命令时 可以不用打全命令 只用打命令的前几个字符就可以了 当然 命令的前几个字符应该要标志着一个唯一的命令 在Linux下 你可以敲击两次TAB键来补齐命令的全称 如果有重复的 那么gdb会把其例出来 示例一 在进入函数func时 设置一个断点 可以敲入breakfunc 或是直接就是bfunc gdb bfuncBreakpoint1at0 x8048458 filehello c line10 示例二 敲入b按两次TAB键 你会看到所有b打头的命令 gdb bbacktracebreakbt gdb 示例三 只记得函数的前缀 可以这样 gdb bmake 再按下一次TAB键 你会看到 make a section from filemake environmake abs sectionmake function typemake blockvectormake pointer typemake cleanupmake reference typemake commandmake symbol completion list gdb bmake GDB把所有make开头的函数全部例出来给你查看 要退出gdb时 只用发quit或命令简称q就行了 GDB中运行Linux的shell程序 在gdb环境中 你可以执行Linux的shell的命令 使用gdb的shell命令来完成 shell调用Linux的shell来执行 环境变量SHELL中定义的Linux的shell将会被用来执行如果SHELL没有定义 那就使用Linux的标准shell bin sh 在Windows中使用C或cmd exe 还有一个gdb命令是make make可以在gdb中执行make命令来重新build自己的程序 这个命令等价于 shellmake gdb应用举例 下面一个实例教你一步步的用gdb调试程序 被调试的程序相当的简单 但它展示了gdb的典型应用 下面列出了将被调试的程序 这个程序被称为greeting 它显示一个简单的问候 再用反序将它列出 案例讲解 gdb调试程序 用一个实例教你一步步的用gdb调试程序 被调试的程序相当的简单 但它展示了gdb的典型应用 下面列出了将被调试的程序 这个程序被称为greeting 它显示一个简单的问候 再用反序将它列出 includemain charmy string hellothere my print my string my print2 my string voidmy print char string printf Thestringis s n string voidmy print2 char string char string2 intsize i size strlen string string2 char malloc size 1 for i 0 i size i string2 size i string i string2 size 1 0 printf Thestringbackwardis s n string2 运行结果 用下面的命令编译它 gcc otesttest c这个程序执行时显示如下结果 ThestringishellothereThestringprintedbackwardis输出的第一行是正确的 但第二行打印出的东西并不是我们所期望的 我们所设想的输出应该是 Thestringprintedbackwardiserehtolleh for i 0 i size i string2 size i string i size 11 string string2 调试 由于某些原因 my print2函数没有正常工作 让我们用gdb看看问题究竟出在哪儿 先键入如下命令 gdbgreeting注意 记得在编译greeting程序时把调试选项打开 调试 如果你在输入命令时忘了把要调试的程序作为参数传给gdb 你可以在gdb提示符下用file命令来载入它 gdb filegreeting这个命令将载入greeting可执行文件就象你在gdb命令行里装入它一样 这时你能用gdb的run命令来运行greeting了 当它在gdb里被运行后结果大约会象这样 调试 gdb runStartingprogram root greetingThestringishellothereThestringprintedbackwardisProgramexitedwithcode041 调试 这个输出和在gdb外面运行的结果一样 问题是 为什么反序打印没有工作 为了找出症结所在 我们可以在my print2函数的for语句后设一个断点 具体的做法是在gdb提示符下键入list命令三次 列出源代码 gdb list gdb list gdb list 技巧 在gdb提示符下按回车健将重复上一个命令 调试 第一次键入list命令的输出如下 1 include23main 4 5charmy string hellothere 67my print my string 8my print2 my string 9 10 调试 如果按下回车 gdb将再执行一次list命令 给出下列输出 11my print char string 12 13printf Thestrin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论