各类数据在编程中的使用.docx_第1页
各类数据在编程中的使用.docx_第2页
各类数据在编程中的使用.docx_第3页
各类数据在编程中的使用.docx_第4页
各类数据在编程中的使用.docx_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

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

文档简介

各类数据在编程中的使用一、在计算机程序设计中,回调函数,简称回调,是指通过函数参数传递到替他代码的,某一块执行代码的引用。这一设计允许了底层代码用在高层定义的子程序。使用回调的用途十分广泛。例如,假设有一个函数,其功能为读取配置文件并由文件内容设置对应的选项。若这些选项由散列值所标记,则让这个函数接受一个回调会使得程序设计更加灵活,函数的调用者可以使用所希望的散列算法,该算法有一个将选项名转变为散列值的回调函数实现,因此,回调允许调用者在运行时调整原始函数的行为。回调的另一种用途在于处理信号或者类似物。例如一个POSIX程序可能在收到SIGTERM信号时不愿立即终止,为保证一切运行良好,该程序可以将清理函数注册为SIGTERM信号对应的回调。回调亦可以用于控制一个函数是否为XLib允许自定义的谓词用于决定程序是否希望处理特定的事件。例子下列C语言代码描述了利用回调处理POSIX风格的信号(在本示例中为SIGUSRI)的过程。值得注意的是,在处理信号的过程中,调用printf(3)是不安全的。#include#include#includeVoid sig (int signum)Printf(“Receivd signal number%d!n”,signum);Int main(int argc,char*argv)Signal(SIGUSRI,sig);pause();return();系统调用pause(3)会导致这个例子不做任何有意义的是,但这样可以给你充分的时间来给这个进程发送信号。(在类Unix系统上,可以调用”Kill-USR1”,其中代表该程序的进程号。运行之后,回调应当有反应。)注意:如果利用循环代表pause()会导致CPU占用率攀升到100%。实现回调的形式因程序设计语言的不同而不同。C,C+and Pascal允许将函数指针作为参数传递给其它函数,其它语言。例如JavaScript,Pythom,Perl12和PHP,允许简单的将函数名作为参数传递。Ob jective-C中允许利用selector关键字传递SEL类型的函数名、在实现中,SEL类型被定义为函数名字符串。在类似于C#与VB.NET的运用.NET Framework的语言中,提供了一种类别安全的引用封装,所谓的“委托”,用来定义包含类型的函数指针,可以用于实现回调。NET语言中用到的事件与事件处理函数提供用回调的通用语法。函数式编程语言通常支持第一级函数,可以作为回调传递给其它函数,也可以作为数据类型存储或是返回给其它函数。某些语言,比如Algol 68,Perl,新版本的NET语言以及多函数式编程语言中,允许使用匿名较大的代码块(lambda表达式),可以替代在别处定义的独立的回调函数。在Apple或是LLVM的C语言扩展中,包括称为快的语言特性,可以作为函数的参数传递,作为回调的一种实现。在缺少函数类型的参数的面向对象的程序语言中,例如Java,回调用传递抽象类型或接口来模拟。回调的接受者会用抽象类或接口的方法,这些方法由回调者提供实现。这样的对象通常是一些回调函数的集合,同时可能包含他所需要的数据。这种方法在实现某些设计模式时比较有用。例如访问者模式,观察者模式与策略模式。C+允许对象提供其自己的函数调用操作的实现,即重载opertor()。标准模板库和函数指针一样接受这类对象(称为函数对象)作为各种算法的参数。C语言中的原型:extern int strcm(constructionchar*s1,const char* s2);用法:#include 功能:比较字符串s1和s2. 说明:当s1s2.时,返回值s2时,返回值0. 即:两个字符串自左向右逐个字符相比(按ASC|值大小相比较),直到出现不同的字符或遇“0”为止。如:”A”A” “computer”compare”特别注意:strcmp(const char*s1, const char*s2)这里面只能比较字符串,不能比较数字等其他形式的参数。原型:extern char*strncpy(char*dest,char*scr, int n);用法:#include功能:把scr所指由NULL结束的字符串前n个字节复制到dest所指的数组中。说明:如果scr的前n个字节不含NULL字符,则结果不会以NULL字符结束。 如果scr的长度小于n个字节,则以NULL填充dest知道复制完n个字节。 scr和dest所指向内存区域不可以重叠且dest必须有足够的空间来容纳scr的字符串。返回指向dest的指针(该只想dest的最后一个元素)相关函数:memccpy, memcpy, stpcpy, strcpy二、strcpy,strncpy,strlcpy的用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界。但是如果还要运行考虑运行效率的画,也许strlcpy是一个更好的方式。1strcpy 我们知道,strcpy是依据0作为结束判断的,如果to的空间不够,则会引起buffer overflow。Strcpy常规的实现代码如下(来自OpenBSD3.9):char*strcpy(char*to, const char*from)char*save=to;for(;(*to=from)!=0;+from,+to);return(save);但通常,我们的from都来源于用户的输入,很可能是非常大的一个字符串,因此strcpy不够安全。2.strncpy在ANSIC中,石头人才培养的安全版本是strncpy。char*strncpy(char*s1, const char*s2,size_tn);但strncpy其行为是诡异的(不符合我们的通常习惯)。标准规定n并不是sizeof(s1),而是要复制的char的个数。一个最常见的问题,就是strncpy并不是帮你保证0结束。char buf8;strncpy(buf,”abcdefgh”,8);看这个程序,buf将会被”abcdef”填满,但却没有0结束符了。另外,如果s2的内容比较少,而n又比较大的话,strncpy将会把之间的空间都用0填充。这又出现了一个效率上的问题,如下char buf80;strncpy(buf,”abcdefgh”,79);上面的strncpy会填写79个char,而不仅仅是”abcdefgh”本身。Strncpy的标准用法:(手工上写0)strncpy(path,src,sizeof(path)-1);pathsizeof(path)-1=0;len=strlen(path);3.strlcpy/Copysrc to string dst of size siz.At most siz-1 characters/wil be copied.Always NUL terminates (unless siz=0)./Returns strlen(src);if retval=siz,truncation occurred.size_tstrlcpy(char*dst,const char*src,size_t size);而是用strlcpy,就需要我们去手动负责0了,仅需要把sizeof(dst)告知strlcpy即可:strlcpy(path,src,sizeof(path);len=strlen(path);if(len=size(path)printf(“src is truncated. ”);并且strlcpy传回的是strlen(str),因此我们也很方便的可以判断数据是否被截断。*一点点历史*strlcpy并不属于ANSIC,至今也还不是很标准。Strlcpy来源于OpenbSD2.4,之后很多unix-like系统的libe重都加入了strlcpy函数,我个人在FreeBSD、Linux里面都找到了strlcpy(Linux使用的是glibc,glibc里面有strlcpy,则所有的Linux版本也都应该用strlcpy)。但Windows下是没有strlcpy的,对应的是strcpy_s函数strncpy原型:extern char *strncpy(char *dest, char *src, int n );用法:#include功能:把src所指由NULL结束的字符串的前n个字符复制到dest所指的数组中。说明:如果src的前n个字节不含NULL字符,则结果不会以NULL字符结束。 如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。 src和dest所指内存区域不可以重复且dest必须由足够的空间来容纳src的字符串。举例: /strncpy.c #include #includemain()char *s=” Golden Global View”;char *d=” Hello, GGV Programmers”;char *p=strdup(s);clrscr();textmode(0x00); /enable 6 lines modestrncpy(d.s.strlen(s);printf(“%s” ,p);getchar();return 0;三、memcopy和memmove1.memmove 函数原型:void*memmove(void*dest,const void*sourse, size_t count)返回值说明:返回值向dest的void*指针参数说明:dest, sourse分别为目标串和源串的首地址。Count为要移动的字符的个数。函数说明:memmove用于从sourse拷贝count个字符到dest,如果目标区域和源区域重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。 view plaincopy to clipboardparint?void*memmove(void*dest,const void*src,size_t n)if(n=0)return 0;if(dest=NULL) return 0;if(src=NULL) return 0;char*psrc=(char*)src;char*pdest=(char*)dest;/检查是否有重叠问题If(dest=psrc=n)/正向拷贝NonOverlapping Buffers copy from lower sddresses to higher addressesfor( i=0;in;i+)*pdest=*psrc;psrc+;pdest+else /反向拷贝Overlapping Buffers copy from higher sddresses to lower addresses psrc+=n;pdest+=n;for(int i=0;in;i+) psrc-; pdser-;*pdest=*psrc;return dest;void*memmo

温馨提示

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

最新文档

评论

0/150

提交评论