Linux应用程序开发基础知识目录1.C语言基础1.1.数据类型1.2.关键字1.3.变量等级1.4.特殊字符的表示方法:1.5.格式化字符串1.6.指针与数组1.7.结构体1.8.typedef--自定义类型名1.9.函数和宏1.10.ANSI标准头文件2.预处理3.使用GCC编译程序4.使用gdb调试程序5.Linux程序开发基础5.1.路径5.2.库文件5.3.预处理5.4.系统调用(systemcall)6.文件处理7.Linux环境编程7.1.参数选项7.2.环境变量7.3.时间7.4.临时文件7.5.用户信息7.6.日志信息8.进程8.1.进程状态9.串口编程9.1.常用函数9.2.设置串口属性9.3.c_iflag输入标志说明9.4.c_oflag输出标志说明9.5.c_cflag控制模式标志说明9.6.c_cc[]控制字符说明9.7.c_lflag本地模式标志说明9.8.下面介绍一些常用串口属性的设置方法。10.安全10.1.内核漏洞介绍11.数据结构(DataStructure)11.1.基础概念11.2.线性数据结构12.网络编程12.1.TCP/IP协议分析12.2.入门示例程序13.存储器寻址14.设备驱动程序开发15.字符设备驱动程序15.1.设备号15.2.设备号的分配和释放15.3.重要的数据结构15.4.读和写16.PCI设备17.内核初始化优化宏18.访问内核参数的接口19.内核初始化选项20.内核模块编程20.1.入门20.2.为模块添加描述信息20.3.内核模块处理命令介绍21.网络子系统21.1.sk_buff结构21.2.sk_buff结构操作函数21.3.net_device结构21.4.网络设备初始化21.5.网络设备与内核的沟通方式21.6.网络设备操作层的初始化21.7.内核模块加载器21.8.虚拟设备21.9.8139too.c源码分析21.10.内核网络数据流22.备忘录ListofTables1.1.特殊字符的表示方法Chapter1.C语言基础TableofContents1.1.数据类型1.2.关键字1.3.变量等级1.4.特殊字符的表示方法:1.5.格式化字符串1.6.指针与数组1.7.结构体1.8.typedef--自定义类型名1.9.函数和宏1.10.ANSI标准头文件Linux是使用C语言开发的,基于Linux平台的应用程序开发,C语言是首选的开发语言。本章记录C语言的基本概念和基础知识。1.1.数据类型整数类型(int),各种整数数制表示法:ddd,十进制表示法,d为0--9的整数,但不能以0开头。如:123,345。0ooo,八进制表示法,以0(数字0)开头,o为0--7的整数。如:010(八进制)=8(十进制),014(八进制)=12(十进制)。0xhhh,十六进制表示法,以0x或0X开头,h为0--9、A、B、C、D、E、F。如:0x10(十六进制)=16(十进制),0xA(十六进制)=10(十进制)。以L或l结尾的数表示长整数(longint),编译器会以32位空间存放此数字,但GCC默认是以32位存放整数,所以此表示法在Linux下没什么作用。1.2.关键字关键字是C语言本身保留使用的,不能用于变量和函数名。autodoubleintstructbreakelselongswitchcaseenumregistertypedefcharexternreturnunionconstfloatshortunsignedcontinueforsignedvoiddefaultgotosizeofvolatiledoifstaticwhile1.3.变量等级auto,内部变量,在函数内部声明。只能在函数内部使用,它的生命周期从调用函数开始,到函数执行完时消失。内部变量以堆栈存放,必须在函数执行时才会存在,这种方式称为声明。auto可省略。如:autointi=0;/*可写成inti=0;*/内部变量的优缺点:o内部变量只在函数内有效,能提高函数的安全。o内部变量在函数结束时消失,不会长期占用内存空间,能提高内存的利用率。o内部变量的缺点是生命周期短,函数运行结束后不能保留。staticauto,内部静态变量,在函数内部定义,auto也可省略。内部静态变量以固定地址存放,编译时就已分配置内在空间,这种方式称为定义。由于有固定地址,函静态变量不会随函数的结束而消失。static变量会一直保存在内存空间中,当函数再次执行时,上次保留的使用静态变量可以继续使用。如:staticinti=0;extern,外部变量,是在函数外定义的变量,可被多个函数存取。在外部变量定义覆盖范围之内的函数内可以自由使用外部变量。不在外部变量定义覆盖范围之内的函数要使用外部变量就要先使用extern关健字来声明外部变量。inti;/*外部变量定义,在main函数外*/intmain(void){i=1;/*main()函数位于外部变量i定义的下面,不用声明可直接使用*/printf(%d\n,i);}不在外部变量定义覆盖范围之内的函数要使用外部变量就要先使用extern关健字来声明外部变量。intmain(void){externinti;/*外部变量i在main()函数之后定义,需用extern关键字声明后才能使用*/i=1;printf(%d\n,i);}inti;...在另外的程序文件中我们也可以通过扩展声明使用其它程序文件中的外部变量。程序1hello.c#includestdio.hintmain(void){externinti;//扩展声明外部变量i=333;printf(%d\n,i);externdes(void);//扩展声明外部函数des();}inti;//外部变量定义程序2hello1.c#includestdio.hexterninti;//扩展声明其它程序文件中的外部变量voiddes(){i++;printf(%d\n,i);}编译debian:~/c#gcchello.chello1.cdebian:~/c#./a.out333334外部变量有效范围总结:o由外部变量定义的位置开始,至文件结尾。o不在有效范围内的函数,也可通过extern扩展声明使用定义的外部变量,且可在多个函数中使用。注意:在各函数中使用的外部变量是一样的,对该变量的修改会影响到其它函数内的同一变量。o可用extern扩展声明使用另外一个程序文件中的外部变量。外部变量的优点是生命周期长,可在函数间共享数据和传输数据。缺点是变量安全性较低,但可通过合理设置外部变量的有效范围提高安全性。staticextern,外部静态变量,在函数外部定义,只供单一程序文件使用,即使其它程序文件定义了同样名称的变量,编译器也把它当成另外一个变量处理。外部静态变量能有效隔离变量在一个程序文件中。staticinti;register,register变量是以寄存器(register)来存放变量,而不是一般内存。只有内部变量才能使用register类型变量。使用这种变量能加快变量的处理速度。但缺点是要占用CPU寄存器。如:registerinti;registerintj;变量等级的概念也同样适用于函数。若想调用不在有效范围内的函数,则要用extern扩展声明函数的有效范围。内部变量是以堆栈方式存放的,必须在函数执行时才会存在,所以称为声明(Declaration)。其它如staticauto、extern和staticextern等级的变量,都是以固定的地址来存放的,而不是以堆栈方式存放的,在程序编译时就已分配了空间,所以称之为定义(Definition)。1.4.特殊字符的表示方法:Table1.1.特殊字符的表示方法符号ASCII字符(十六进制)句柄符号作用\a07BEL响铃\b08BS回格\f0CFF换页\n0ALF换行\r0DCR回车键\t09HT[tab]键\v0BVT空行\000NUL空字符\\5C\反斜杠\'2C'单引号\22双引号\?3F?问号1.5.格式化字符串%c,表示字符变量。%s,表示字符串变量。%f,表示浮点数变量。%d,表示整数变量。%x,表示十六进制变量。%o,表示八进制变量。1.6.指针与数组C语言中专门用来存放内存地址的变量叫指针(pointer)变量,简称指针。&运算符用来取得变量地址,*运算符用来取得指针变量的值。数组名就是地址变量,指向内存中存放第一个数组元素的地址。数组元素编号从0开始,如a[0]表示数组a的第一个元素。数组是内存中的连续区间,可根据声明类型存放多种数值类型。如:inta[10];声明一个有10个int元素的数组charb[20];声明一个有20个char元素的数组指针示例:int*p;/*p是一个指针,p的内容是内存的地址,在这个地址中将存放一个整数。数组名和指针都是用来存放内存地址的,不过数组名具有固定长度,不可变。而指针与一般变量一样,其值是可变的。1.7.结构体结构体是用户定义的由基本数据类型组成的复合式数据类型。数组也是复合式数据类型,但二者是不同的,数组是相同类型数据的集合,而结构体是不同类型数据的集合。如我们可以把一个人的姓名、性别,年龄组成一个单一结构体。这样在程序处理时就把它当成一个独立对象进行处理。结构体声明方法有两种,一种是分离式声明,一种是结合式声明。分离式声明是先把声明结构体,在程序中再声明结构体变量。结合式声明是把结构体声明和变量声明同时完成。分离式声明示例structperson{charname;charsex;intage;};main(void){structpersonworker;...}结合式声明示例structperson{charname;charsex;intage;}worker;每个结构体可以表示一个工人的信息,如果要表示多个工人的信息,则可以用结构体数组。structperson{charname;charsex;intage;};main(void){structpersonworker[20];//表示20个工人...}结构体初始设置。structperson{charname;charsex;intage;}worker={jims,male,30};用.和-运算符存取结构体中的数据。.是直接存取法,-为间接存取法,用于结构体指针。如果p是一个指向person结构体的指针,则p-name和(*p).name的结果是一样的。1.8.typedef--自定义类型名结构体可以自定义数据类型,而typedef可以自定义新的类型名。如:#includestdio.htypedefchar*STRING;//定义一个新的字符指针类型名STRINGmain(void){STRINGa;a=abc;printf(theavalueis%s.\n,a);}a为字符指针类型,自定义类型名通常以大写方式表示,以示区别。#define与typedef的区别是:#define只是单纯地进行变量替换,而typedef是创建新的类型名。typedef的一个主要作用是简化声明,提高程序的可读性。如:typedefstructperson{charname;charsex;intage;}p这样我们就定义一个新的结构体类型名p,在程序中我们可以使用它来声明变量。如main(void){pworker;worker={jims,male,30};}1.9.函数和宏函数是C代码的集合,每个C程序由一个或多个函数组成,main()是一个特殊的函数,是C程序的入口,每个C程序必须有且只能有一个mian()函数。ANSI函数定义:类型函数名(类型参数1,类型参数2,...){函数代码;}示例:intfunc(inti,charc){...}在程序中要使用我们设计开发的函数,需要先进行声明,函数声明的作用是把函数类型告诉编译器。函数声明与定义差不多,只是不包括程