版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C语言软件编程之经验交流1.这次报告比较局限于C语言,不会讲太多其他高级语言比方C++,JAVA,PYTHON等等,刚进实验室的学生我的建议是先学好C语言,掌握工程开发中软件的开发目的,开发流程,测试流程等。注意,做这个报告的目的是希望大家能够开发出高效的C程序,而不是让大家开发出复杂高难度高技巧的C程序。报告目的2.提纲一、C语言根底二、内存管理三、常用技巧四、调试五、例如3.开发软件工欲善其事,必先利其器------?论语?牢牢打好根底,紧紧抓住核心,真正实现目的-----深入学习科学开展观编辑软件:VC++6.0,VS20XX编程辅助软件:msdn功能性辅助软件:vcassistant,numegaboundschecker, intelvtune,sourceinsight推荐的资料:?高质量C/C++编程指南(林锐)?、?Windows核心编程?、?linux高级程序设计?4.一、C语言根底在C语言中使用的词汇分为六类:标识符,关键字,运算符,分隔符,常量,注释符。1.1.1C语言词汇5.标识符只能是字母、数字、下划线组成的字符串,并且其第一个字符必须是字母或下划线。
以下标识符是合法的:a,x,_3x,BOOK_1,sum5
以下标识符是非法的:3s以数字开头; s*T出现非法字符*;-3x以减号开头;
〔1〕标识符一、C语言根底6.在使用标识符时注意以下几点:标准C不限制标识符的长度,但它受各种版本的C语言编译系统限制,同时也受到具体机器的限制;在标识符中,大小写是有区别的。例如BOOK和book是两个不同的标识符;标识符虽然可由程序员随意定义,但标识符是用于标识某个量的符号。因此,命名应尽量有相应的意义,以便阅读理解,作到“顾名思义〞。intImgWidth;
〔1〕标识符一、C语言根底7.1、匈牙利命名法:开头字母用变量类型的缩写,其余局部用变量的英文或英文的缩写,要求单词第一个字母大写。 intiMyAge;“i〞是int类型的缩写;
charcMyName[10];“c〞是char类型的缩写;
floatfManHeight;“f〞是float类型的缩写;2、驼峰规那么: 又叫小驼峰式命名法。
第一个单词首字母小写,后面其他单词首字母大写。 intmyAge;
charmyName[10];
floatmanHeight;3.帕斯卡命名法: 又叫大驼峰式命名法。每个单词的第一个字母都大写。
intMyAge;
charMyName[10];
floatManHeight;一、C语言根底8.关键字是由C语言规定的具有特定意义的字符串,通常也称为保存字。用户定义的标识符不应与关键字相同。C语言的关键字分为以下几类:〔2〕关键字一、C语言根底类型说明符
用于定义、说明变量、函数或其它数据结构的类型。如char,short,int,double等语句定义符
用于表示一个语句的功能。如for,if,else,while,switch等。预处理命令字
用于表示一个预处理命令。如#define#pragma等。9.C语言中运算符与变量,函数一起组成表达式,表示各种运算功能。运算符由一个或多个字符组成,如>,<=,&&等。〔3〕运算符〔4〕分隔符在C语言中采用的分隔符有逗号和空格两种。一、C语言根底10.〔5〕常量C语言中使用的常量可分为数字常量、字符常量、字符串常量、符号常量、转义字符等多种。比方char*p=“helloworld〞;C语言中的常量是不接受程序修改的固定值。〔6〕注释符C语言的注释符是以“/*〞开头并以“*/〞结尾的串,C++中使用“//〞注释所在行。一、C语言根底11.什么是字节对齐,为什么要字节对齐?1.1.2字节对齐一、C语言根底12.〔1〕什么是字节对齐?现代计算机中内存空间都是按照byte划分的,从理论上讲对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规那么在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。一、C语言根底13.〔2〕为什么要字节对齐?对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。比方有些平台每次读都是从偶地址开始,如果一个int型〔假设为32位〕如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的上下字节进行拼凑才能得到该int数据。一、C语言根底14.〔3〕大小端〔例程〕在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。对于位数大于8位的处理器,由于存放器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中一、C语言根底15.〔3〕大小端〔例程〕写一个C函数,假设处理器是Big_endian的,那么返回0;假设是Little_endian的,那么返回1intcheckCPU(){ unionw { inta; charb; }c; c.a=1; return(c.b==1);}一、C语言根底16.〔3〕大小端〔例程〕采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节序是所有成员都从低地址开始存放。联合体union的存放顺序是所有成员都从低地址开始存放。一、C语言根底17.//作者版权版本说明,头文件声明,全局变量,函数声明,预处理块#include<stdlib.h>#include〞global.h〞voidoutput();//子函数声明intmain(intargc,char*argv[]){ inti,j; unsignedchar*data;//定义局部变量 //分配数据空间,分配在堆上 data=(unsignedchar*)malloc(1000*sizeof(unsignedchar)); for(i…){} //调用子函数 output(); //释放分配空间 free(data);data=NULL;}voidoutput(){…}一、C语言根底18.#ifndefGRAPHICS_H(作用:防止graphics.h被重复引用)
#defineGRAPHICS_H
#include....(作用:引用标准库的头文件)
#include...(作用:引用非标准库的头文件)
voidFunction1(...);(作用:全局函数声明)
classBox(作用:类结构声明)
{};
#endif1.2.1头文件一、C语言根底19.在头文件中,用ifndef/define/endif结构产生预处理块,用#include格式来引用库的头文件。头文件一般由三局部内容组成:1.2.1头文件头文件开头处的版权和版本声明;预处理块;函数和类结构声明等。一、C语言根底20.头文件的主要作用在于调用库功能,对各个被调用函数给出一个描述,其本身不包含程序的逻辑实现代码,它只起描述性作用,告诉应用程序通过相应途径寻找相应功能函数的真正逻辑实现代码。用户程序只需要按照头文件中的接口声明来调用库功能,编译器会从库中提取相应的代码。1.2.1头文件一、C语言根底21.注意:1)在.h文件中声明的函数,如果在其对应的.c文件中有定义,那么我们在声明这个函数时,不使用extern修饰符,如果反之,那么必须显示使用extern修饰符;2)不要在.h文件中编写实现代码,不要#include“.c〞文件。1.2.1头文件一、C语言根底22.所有全局变量尽量以g_开头,并且尽可能声明成static类型;尽量杜绝跨文件访问全局变量.如果确实需要在多个文件内访问同一变量,应该由该变量定义所在文件内提供GET/PUT函数实现;全局变量必须要有一个初始值,全局变量尽量放在一个专门的函数内初始化;如调用全局变量的函数少于三个,考虑改为局部变量实现。1.2.2谨慎使用全局变量一、C语言根底23.在实际的软件工程中,每个人负责的可能只是一个模块,对全局变量的使用没有小程序那样简单,在使用全局变量的时候更要谨慎,跨模块调用的全局变量使用时都需要申请,而且定义必须明确。1.2.2谨慎使用全局变量一、C语言根底24.voidmain(intargc,char*argv[])1.2.3main函数一、C语言根底命令行界面的程序,通常都需要输入命令行参数帮助程序执行。假定有一个可执行程序名为test.exe。运行该程序的的命令行如下:test.exe带命令行参数是同一行中的附加项:test.exe–cTEST其中–c和TEST就是命令行参数。C程序通过使用main()的参数来读取这些附加参数。25.main(intargc,char*argv[])这个函数中两个参数的意义:argc记录的是命令行中输入参数的数目;argv是一个拥有argc个元素的字符串数组,每个元素保存一个命令行中输入的参数。1.2.3main函数一、C语言根底26.
#include<stdio.h> intmain(intargc,char*argv[]) { inti; for(i=0;i<argc;i++) { printf("Argument%dis%s.\n",i,argv[i]); } return0; }1.2.3main函数一、C语言根底下面的程序演示argc和argv的使用:27.Argument0ishello.exe.Argument1isa.Argument2isb.Argument3isc.Argument4isd.Argument5ise.1.2.3main函数一、C语言根底运行结果:假设上述代码编译为hello.exe,那么运行:hello.exeabcde28.1.2.3main函数一、C语言根底在这个例子中,argc的值为6,命令行一共输入了六个参数:“hello.exe〞、“a〞、“b〞、“c〞、“d〞、“e〞对应程序输入为:argv[0]:repeat.exe,argv[1]:a,argv[2]:b,argv[3]:c,argv[4]:dargv[5]:e需要注意的是假设输入参数作为数值使用时,使用atoiatof进行字符转换看例程29.一、C语言根底1.3代码编写标准从书写清晰,便于阅读,理解,维护的角度出发,在书写程序时应遵循以下规那么:一个说明或一个语句占一行。if,for,while,do占一行,执行语句放后面并且使用大括号,多用对齐。用{}括起来的局部,通常表示了程序的某一层次结构。{}一般与该结构语句的第一个字母对齐,并单独占一行。低一层次的语句或说明可比高一层次的语句或说明缩进假设干格后书写。以便看起来更加清晰,增加程序的可读性。在编程时应力求遵循这些规那么,以养成良好的编程风格。多写注释,合理的使用注释可以让你的程序可读性更高。30.一、C语言根底另外一些编程风格说明:程序块要采用缩进风格编写,缩进少使用空格键;对齐多使用TAB键,少使用空格键;逗号、分号只在后面加空格。inta,b,c;比较操作符,赋值操作符“=〞,“+=〞,算术操作符“+〞,“%〞,逻辑操作符“&&〞,“&〞,位域操作符“<<〞,“^〞等双目操作符的前后加空格;31.一、C语言根底另外一些编程风格说明:“!〞,“~〞,“++〞,“--〞,“&〞〔地址运算符〕等单目操作符前后不加空格。“->〞,“.〞前后不加空格。p->id=pid;//“->〞指针前后不加空格if、for、while、switch等与后面的括号间应加空格,使if等关键字更为突出、明显。if(a>=b&&c>d)32.一、C语言根底33.一、C语言根底1.4命名规那么使用匈牙利命名法,标识符应直观意思明确尽量使用缩写,如intiImgWidth;不要使用大小写来区分变量,如intx,X;局部变量不要与全局变量同名;常量使用大写字母,合理使用前缀,静态变量加前缀s_,全局变量加前缀g_。34.一、C语言根底1.5表达式注意优先级的的上下以及结合顺序,多使用括号确定优先级35.一、C语言根底1.5表达式注意if常用的条件判断情况:布尔变量if〔flag〕if〔!flag〕整型变量if〔flag==0〕if〔flag!=0〕浮点变量if〔abs〔x-0〕<1e-5〕指针变量if〔p==NULL〕if〔p!=NULL〕if语句36.一、C语言根底1.5表达式注意以下几点:多重循环中,尽量将循环少的放在外层循环for〔i=0;i<N;i++〕,循环执行N次,最大执行到i=N-1,i最后执行完等于Nswitch的每个case都加上break,最后加上default尽量少用goto循环语句37.从静态存储区域分配,在程序编译的时候就已经分配好,整个运行期都存在。如全局变量和static变量。从栈上创立,从函数创立开始存在,函数结束就释放,效率高,但是分配大小有限。如函数内部变量。从堆上分配,也称动态内存分配。使用malloc分配,需要手动free释放。使用灵活,容易出问题。C语言中内存分配区域:二、内存管理38.二、内存管理2.1常见内存错误没有分配直接使用或者分配未成功却使用了它;没有初始化或者归零就直接使用〔分配内存后系统默认值不一定是0〕;使用时内存访问越界,使用完忘记释放内存,造成内存泄漏;对已分配内存的指针进行赋值操作,原来分配内存区域丧失,内存泄漏;释放了内存却继续使用,指针在释放后并不是变为NULL,仍然指向原来地址,成为“野指针〞。39.二、内存管理2.2指针与数组数组在栈上和静态存储区域创立,其地址与容量分配后不可改变,但内容可以改变;指针的特征是“可变〞,用于分配动态内存区域;不能直接对数组名进行复制和比较,使用strcpy和strcmp;指针存储的是动态内存区域的地址,可以直接传递地址,当对两块动态内存区域复制或比较时使用memcpy和memcmp;数组的大小,需要加上最后面的‘\0’,可以使用sizeof获得;指针使用sizeof获得的是指针变量的字节数;需要注意的是当数组作为函数参数传递时,自动退化为该类型的指针。40.二、内存管理2.2指针与数组例子:41.二、内存管理2.3指针指针的本质是地址,指针变量本身作为普通存放器变量被存储,特别是该存放器地址内存储的是另一个存放器地址,该存放器地址内存储的数据是指针指向的数据。栈maininti=200;char*p;0x123456假设已给p分配空间0x123456p=0x123456i=2000x1234560x123452100*p=1000x2021120x202116&p=0x202116&i=0x202120200栈42.二、内存管理2.3指针malloc在堆上分配动态内存区域,需要指定分配区域的大小,以字节作为单位。p=(char*)malloc(1*sizeof(char)); //分配到0x123456,存储在栈地址0x202116的内存地址中 *p=100;//修改0x123456中数值为100 //free将分配的动态内存区域释放 free(p); //虽然0x123456该地址被标志为已释放,但是p内存储的仍然是0x123456,p成为野指针 p=NULL; //将0x202116内数据改为0x00,该地址不可访问malloc与free:43.二、内存管理当子函数中使用指针时,子函数执行结束指针没有free掉,此时指针变量释放了,不代表它所指向的内存自动释放了。当内存被释放时,不代表指针不存在了或者指针成为NULL指针。需要查找程序内存泄漏。2.3指针需要注意的几点:44.三、常用技巧3.1宏的使用#defineceil_div(x,y)(x+y-1)/y宏执行的是简单的替换作用,需要注意由操作符优先级引起的问题,多加括号。那么a=ceil_div(b&c,sizeof(int));将被转化为:a=(b&c
+sizeof(int)-1)/sizeof(int);由于+/-的优先级高于&的优先级,那么上面式子等同于:a=(b&(c+sizeof(int)-1))/sizeof(int);为了防止这种情况发生,应当多写几个括号:#defineceil_div(x,y)(((x)+(y)-1)/(y))45.三、常用技巧3.1宏的使用函数变宏每行代码最后都加行连接符“\〞,即使是空行也要加“\〞,最后一行代码后面不需要加“\〞,每行“\〞最后不能有多余字符或者空格,返回的是最后一条语句的执行结果。可以在宏函数内定义变量,可以使用if等语句,可以在宏内调用其他宏,可以使用指针。函数变宏可以加快程序运行速度。看例子46.三、常用技巧3.2运行时间测量程序运行过程中,我们经常需要统计程序运行时间。下面给出例如:#include<time.h>main(){ clock_tbegin,end; begin=clock(); end =clock(); double
duration; duration=(double)(end-begin)/CLOCKS_PER_SEC;
printf(“Timeis%2.1fseconds\n",duration); //#defineCLOCKS_PER_SEC1000 //事实上end–begin获得的是毫秒计数}47.三、常用技巧3.2运行时间测量Time()函数是获得当前系统时间用的,一般不用于计时。当程序运行时间太短时,可以使用屡次执行的方法来获得。可以使用更精确的运行时间计数函数:“QueryPerformanceCounter()〞“QueryPerformanceFrequency()〞48.三、常用技巧随机数生成:#include<stdlib.h>#include<stdio.h>#include<time.h>voidmain(void){ inti;/*Seedtherandom-numbergeneratorwithcurrenttimesothat*thenumberswillbedifferenteverytimewerun.*/ srand((unsigned)time(NULL));/*Display10numbers.*/ for(i=0;i<10;i++) printf("%6d\n",rand());}Srand是产生伪随机序列的种子,种子一样产生的伪随机序列一样。RAND_MAX=0x7fffffffj=(int)(n*rand()/(RAND_MAX+1.0))产生一个0到n之间的随机数49.三、常用技巧3.3文件操作文件的翻开与关闭文件在进行读写操作之前要先翻开,使用完毕要关闭。翻开文件实际上是建立文件的各种有关信息,并使文件指针指向该文件,以便进行其它操作。关闭文件那么断开指针与文件之间的联系,也就禁止再对该文进行操作。在C语言中,文件操作都是由库函数来完成的。 fp=fopen(“filename〞,“r〞);50.三、常用技巧对于文件使用方式有以下几点说明:文件使用方式由r,w,a,b,t,+六个字符拼成,各字符的含义是:r(read):读w(write):写a(append):追加b(binary):二进制文件+:读和写凡用“r〞翻开一个文件时,该文件必须已经存在,且只能从该文件读出。用“w〞翻开的文件只能向该文件写入。假设翻开的文件不存在,那么以指定的文件名建立该文件,假设翻开的文件已经存在,那么将该文件删去,重建一个新文件。51.三、常用技巧if((fp=fopen(“readme.txt","rb")==NULL)
{
printf("\nerroronopenc:\\hzk16file!");
exit(1);
}假设要向一个已存在的文件追加新的信息,只能用“a〞方式翻开文件。但此时该文件必须是存在的,否那么将会出错。在翻开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成翻开文件的工作,并作相应的处理。52.三、常用技巧文件的读写对文件的读和写是最常用的文件操作。在C语言中提供了多种文件读写的函数:字符读写函数:fgetc和fputc字符串读写函数:fgets和fputs数据块读写函数:fread和fwrite格式化读写函数:fscanf和fprinf行操作。53.三、常用技巧文件的读写在文件内部有一个位置指针,用来指向文件的当前读写字节。在文件翻开时,该指针总是指向文件的第一个字节。使用fgetc函数后,该位置指针将向后移动一个字节。应注意文件指针和文件内部的位置指针不是一回事。文件指针是指向整个文件的,文件内部的位置指针用以指示文件内部的当前读写位置,每读写一次,该指针系统自动向后移动。54.三、常用技巧计算文件长度的程序例如longfilesize(FILE*stream){longcurpos,length;curpos=ftell(stream);fseek(stream,0L,SEEK_END);length=ftell(stream);fseek(stream,curpos,SEEK_SET);returnlength;}进行二进制文件读写时,翻开方式后面加“b〞55.四、调试编程出现error时,从第一个error处开始解决错误,可能是很小的书写错误引起的。warning也需要关注,有时候会导致程序运行错误发生。程序出现BUG时,单步跟踪,查看变量,查看内存,查看栈调用,可以边编辑边跟踪。参加适宜的断点,使用条件断点。程序调试结束后需要查找内存泄露,标准代码书写。使用assert,只有条件满足才继续向下执行,在release下不会编译该语句。程序编写完成不一定是完全正确的,需要进行测试并进行跟踪调试。56.四、调试4.1条件断点我们在调试的时候希望程序在某个断点处只有在满足一定的条件下中断,在不满足条件的时候正常运行,可以为程序调试带来极大的便利。例如57.四、调试4.2内存泄漏查找养成好的代码写作标准,掌握内存管理概念,减少不标准代码内存泄漏可能性。是否内存泄露:运行可执行文件,使用任务管理器查看内存占用情况是否一直增加。比较简单但是显示不一定精确。使用NumegaBounderChecker软件查找,程序中参加exit(0)强制中断,Debug至该代码行程序异常中断时查看内存泄露报告。例如58.四、调试4.3watch跟踪调试时多使用watch窗口,在watch窗口内可以进行有限运算,注意watch运算带来的影响。例如59.四、调试4.4C程序优化首先要确定优化目标,然后寻找优化方法。查找程序运行瓶颈,使用IntelVtune查看各局部运行时间,一步步进行优化。现在CPU,GPU开展方向都是多核,并行计算越来越方便,为优化提供了更多解决方案。任务级并行,使用多线程发挥多核优势。指令级并行,使用MMX,SSE,SSE2等指令集。参看Vtune使用指南60.五、例如5.1软件设计算法思想,思路清楚,注意细节质量控制,代码高效,风格良好测试调试,测试全面,调试认真软件设计过程关键局部:在编写软件程序之前,首先要明确你要解决的问题,软件只是思想的实现,不能通过编程来获得思想。所以在编写之前就需要对问题有透彻的理解,对解决问题的方法有清晰的思路,要考虑到可能遇到的所有问题,同时要考虑到软件的可靠性稳定性等。61.五、例如5.1软件设计在编写软件程序之前,首先要明确你要解决的问题,软件只是思想的实现,不能通过编程来获得思想。所以在编写之前就需要对问题有透彻的理解,对解决问题的方法有清晰的思路,要考虑到可能
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 江西省九江市少年宫科学动力机械课程(说课稿)-敲鼓器
- 2024年度煤炭买卖的综合性合同
- 2024年度新能源发电设备采购及安装合同3篇
- 2024年九年级语文上册 第四单元 第15课《诗人谈诗 宁静而深沉的意境》说课稿 苏教版
- 2024年个人租车合作协议模板 for 租赁公司版B版
- 二零二四年度智能路灯系统建设与维护合同3篇
- 二零二四年度研发合作合同:生物医药领域新技术研究3篇
- 2024年度场地准备及平整服务协议版B版
- 教科版高中信息技术选修3说课稿-2.3.2 设置IP 地址和子网掩码
- 14《学习有方法》第1课时 说课稿-2023-2024学年道德与法治二年级下册统编版
- 关于发布工程建设监理费上海收费指导
- 《义务教育法》学习教案(共3页)
- 2014新农人报告-阿里研究院
- 四措两案规范标准材料模板
- 人教版新版高一英语-第一册-welcome-unitPPT课件
- 小儿中医体质辨识量表
- 日照钢铁 6-150028.65吨 质量证明书
- 数字经济背景下提升中华优秀传统文化影响力的思考
- 安全工程—英语双专业(双学位)培养计划(精)
- 财神正朝科仪
- 体格检查基本规范
评论
0/150
提交评论