C语言总结.doc_第1页
C语言总结.doc_第2页
C语言总结.doc_第3页
C语言总结.doc_第4页
C语言总结.doc_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

目 录1.1c基础知识11.2函数与头文件21.3c预处理器31.4将一个字符转换为long型41.5strcpy函数41.6assert用法51.7itoa函数和atoi函数61.8strcmp函数实现81.9strcpy函数实现91.10memcpy函数实现101.11memcpy和memmove函数的实现111.12strcat函数实现131.13使用库函数atoi,将char *int131.14使用库函数itoa,将intchar *141.15不使用库函数,将intchar *141.16不使用库函数,将char *int151.17求两个整数的最大公约数161.18little_endian or big_endian171.19sizeof与strlen的区别191.20实现string类的big_four191.21struct和union的区别201.22char字符变量与int整型数据221.23字,字节,字符,比特231.24空格、空字符、字符数组结束符的区别251.1 c基础知识位运算符&按位与如果两个对应的二进制都为1,则该位结果值为1,否则为0 特殊用途:(1) 清0(2) 取一个数的特定位|按位或如果两个对应的二进制中只要有一个为1,则结果为1,否则为0按位异或两个二进制同号,则结果为0,否则为1(1) 与0相异或,保留原值(2) 交换两个值,不用临时变量将a,b交换a = a b ; b = b a ;a = a b ;取反右移& 与运算:表示如果y,z为真,则(y&z)为真,返回一个布尔值1| 或运算:表示如果y,z中有一个为真,则(y|z)为真,返回一个布尔值1说明:位运算符除了以外,均为二目运算符,即要求两侧各有一个运算量。运算量只能是整型或字符型的数据,不能为实型数据。1.2 函数与头文件#include using namespace std;函数:cout,endl#include 函数:getchar, putchar, scanf, printf等#include 函数:assert#include 函数:itoa, atoi, atof, atol, strtod, strtol,system等#include 函数:memcpy, strcpy, strcat,strlen等#include 函数:abs等1.3 c预处理器c预处理器是一种简单的宏处理器。预处理器是由特殊的预处理器命令行控制的,它们是以#符号开头的源文件行。预处理器的一般操作:从源文件中删除所有的预处理器命令行,并在源文件中执行这些预处理器命令所指定的转换操作 。预处理器代码行的语法与c语言其他部分的语法是完全独立的,但经过预处理所产生的源代码必须在上下文环境中合法 。常见的预处理器命令: #define 定义一个预处理器宏#undef 取消一个预处理器宏#include 插入另一个源文件的文本#if 测试一个常量表达式的值#ifdef 测试如果一个宏已被定义#ifndef 测试如果一个宏没有被定义#else 测试失败后#endif 终止条件文本 #line 提供用于编译器信息的行号 #elif 与else if相似defined 判断一个宏是否被定义,已定义返回1,否则返回0,其与#if和#elif联用# 将#后的宏标记转化为字符串 # 将两个相邻的宏标记连接成一个整体标记#pragma 指定依赖编译器的信息#error 用指定的信息产生一个编译时错误 常用的预定义的宏有: _line_ 当前源程序行的行号,用十进制整数常量表示 _file_ 当前源文件的名称,用字符串常量表示 _date_ 编译时的日期,用“mm dd yyyy”形式的字符串常量表示 _time_ 编译时的时间,用“hh:mm:ss”形式的字符串常量表示 _stdc_ 当且只当编译器遵循iso标准时,它的值是十进制常量1 _stdc_version_ 如果编译器遵循c99,则这个宏的值是199901l,其他情况下,该宏没定义 _stdc_hosted_ 当前是宿主系统,该宏值为1,当前是独立系统,这个宏值为0 _stdc_iec_559_ 如果浮点实现遵循iec 60599标准,这个宏值为1,否则无定义 _stdc_iec_559_complex_ 如果复数运算实现遵循iec 60559标准,则该宏值为1,否则未定义 _stdc_iso10646_ 定义为一个长整数常量 _line_和_file_在调试中的运用上面这段代码通过#ifdef #else #endif三个条件编译指令,根据_debug定义情况(该宏用于区分debug版本和release版本),决定了具体的trace_file_line_info宏函数的实现。使用者可以用如下方法使用 #标记符粘贴运算符ansi标准定义的标记符粘贴运算符#可以把宏定义中的两个标记符组合成一个标记符。例如 #define combine (s1, s2) s1#s2combine(total,sales)则为 totalsales #define name(i) name # i name(1)=name11.4 将一个字符转换为long型char cmax;long lmax;cmax = getch();lmax = cmax & 0xf;1.5 strcpy函数原型:extern char *strcpy(char *dest,char *src);用法:#include 功能:把src所指由null结束的字符串复制到dest所指的数组中。说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。给一个很经典版本的strcpy函数源码:char *strcpy(char *strdest, const char *strsrc); assert(strdest!=null) & (strsrc !=null); char *address = strdest; while( (*strdest+ = * strsrc+) !=0) null; return address ; 1.6 assert用法assert宏的原型定义在中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:#include void assert( int expression );assert的作用是现计算表达式expression,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。请看下面的程序清单badptr.c:#include #include #include int main( void ) file *fp; fp = fopen( test.txt, w );/以可写的方式打开一个文件,如果不存在就创建一个同名文件 assert( fp );/所以这里不会出错 fclose( fp ); fp = fopen( noexitfile.txt, r );/以只读的方式打开一个文件,如果不存在就打开文件失败 assert( fp );/所以这里出错 fclose( fp );/程序永远都执行不到这里来 return 0;rootlocalhost error_process# gcc badptr.crootlocalhost error_process# ./a.outa.out: badptr.c:14: main: assertion fp failed.已放弃使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。在调试结束后,可以通过在包含#include 的语句之前插入 #define ndebug 来禁用assert调用,示例代码如下:#include #define ndebug#include 用法总结与注意事项:1)在函数开始处检验传入参数的合法性如:int resetbuffersize(int nnewsize)/功能:改变缓冲区大小,/参数:nnewsize 缓冲区新长度/返回值:缓冲区当前长度/说明:保持原信息内容不变 nnewsize= 0);assert(nnewsize =0 & noffset+nsize= 0);assert(noffset+nsize = m_ninfomationsize);3)不能使用改变环境的语句,因为assert只在debug生效,如果这么做,会使用程序在真正运行时遇到问题错误: assert(i+ 100)这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i+这条命令就没有执行。正确: assert(i 100) i+;4)assert和后面的语句应空一行,以形成逻辑和视觉上的一致感5)有的地方,assert不能代替条件过滤1.7 itoa函数和atoi函数函数名:atoi功 能:把字符串转换成整型数用 法:int atoi(const char *nptr); 函数说明: atoi()会扫描参数nptr字符串,检测到第一个数字或正负符号时开始做类型转换,之后检测到非数字或结束符 0 时停止转换,返回整型数。需要用到的头文件: #include 程序例:1)#include #include int main(void) int n; char *str = 12345.67; n = atoi(str); printf(string = %s integer = %dn, str, n); return 0;执行结果string = 12345.67 integer = 12345 函数名: itoa 备注:该函数的头文件是#include 功 能:把整数转换为字符串用 法:char *itoa(int value, char *string, int radix);详细解释:itoa是英文integer to array(将int整型数转化为一个字符串,并将值保存在数组string中)的缩写。参数: value: 待转化的整数。 radix: 是基数的意思,即先将value转化为radix进制的数,范围介于2-36,比如10表示10进制,16表示16进制。 * string: 保存转换后得到的字符串。返回值:char * : 指向生成的字符串, 同*string。atoi和itoa的示范代码如下:#include #include void main( void ) char *s; int ix; char buffer20; int i = 3445; long l = -344115l; unsigned long ul = 1234567890ul; s = -9885 pigs; /* test of atoi */ ix = atoi( s ); printf( atoi test: ascii string: %sttinteger: %dn, s, ix ); _itoa( i, buffer, 10 ); printf( string of integer %d (radix 10): %sn, i, buffer ); _itoa( i, buffer, 16 ); printf( string of integer %d (radix 16): 0x%sn, i, buffer ); _itoa( i, buffer, 2 ); printf( string of integer %d (radix 2): %sn, i, buffer ); _ltoa( l, buffer, 16 ); printf( string of long int %ld (radix 16): 0x%sn, l, buffer ); _ultoa( ul, buffer, 16 ); printf( string of unsigned long %lu (radix 16): 0x%sn, ul,buffer );输出结果:atoi test: ascii string: -9885 pigs integer: -9885string of integer 3445 (radix 10): 3445string of integer 3445 (radix 16): 0xd75string of integer 3445 (radix 2): 110101110101string of long int -344115 (radix 16): 0xfffabfcdstring of unsigned long 1234567890 (radix 16): 0x499602d21.8 strcmp函数实现功 能: 串比较用 法: int strcmp(char *str1, char *str2);#include#includeusing namespace std; int mystrcmp(const char *str1,const char *str2)/错误 assert(str1!=null)&(str2!=null); for(;(*str1!=0)&(*str2!=0);str1+,str2+) if(*str1*str2) return 1; else return -1; return 0; int my_strcmp(const char *str1,const char *str2)/正确assert(str1!=null)&(str2!=null);for(;(*str1!=0)&(*str2!=0);str1+,str2+)if(*str1*str2)return 1;if(*str1*str2)return -1;if(*str1=0)&(*str2!=0)return -1;else if(*str1!=0)&(*str2=0)return 1;elsereturn 0;int main() char *string1=hanli; char *string2=hanlihaha;/-1/ char *string1=;/ char *string2=;/0 coutmystrcmp(string1,string2)endl; return 0;1.9 strcpy函数实现原函数作用:拷贝一个字符串到另一个#include#includeusing namespace std; char *mystrcpy(char *strdest, const char *strsrc)/程序员面试宝典p205 assert(strdest!=null)&(strsrc!=null); char *strdestcopy=strdest; while(*strdest+=*strsrc+)!=0) null; return strdestcopy;我的修改char *mystrcpy(char *strdest, const char *strsrc)/有错吗? assert(strdest!=null)&(strsrc!=null); char *strdestcopy=strdest; while(*strdestcopy +=*strsrc+)!=0) ; return strdest; int main(void) char *str1=abc; char str220; coutmystrcpy(str2,str1)endl; return 0;1.10 memcpy函数实现功 能: 从源source中拷贝n个字节到目标destin中#include#includeusing namespace std;void *mymemcpy(void *memdest, const void *memsrc, size_t size) assert(memdest!=null)&(memsrc!=null); char *tempdest = static_cast(memdest); const char *tempsrc = static_cast(memsrc);/*当目标地址比较大,且源地址和目标地址有部分空间重合时,需要从最大值读取,使目标地址最后能够存储源地址的所有数据*/ if(tempdesttempsrc)&(tempdesttempsrc+size) for(size_t i=size-1; i!=-1; -i) tempdesti=tempsrci; /*其它情况都可以按照从小到大读取*/ else for( size_t i=0;isize;+i) tempdesti=tempsrci; return memdest; int main() char strsrc=12345; char strdest20; mymemcpy(strdest,strsrc,4); strdest4=0;/以0结束,勿漏! coutstrsrcendlstrdestendl; return 0;1.11 memcpy和memmove函数的实现/* * 函数名: memcpy * 功 能: 从源source中拷贝n个字节到目标destin中 * 用 法: void *memcpy(void* destin, const void* source, size_t n); * 说 明: 自己实现此库函数*/#include /#include /memcpy库函数头文件#include /getch头文件#include /assert头文件typedef unsigned char byte; /typedef unsigned int size_t;/*memcpy自定义函数*/src要保留void* memcpy(void* dst,const void* src,size_t count) char* pbto = (char*)dst; char* pbfrom = (char*)src; assert(dst!= null & src != null);/不能存在空指针assert(pbto = pbfrom+count | pbfrom = pbto + count);/防止内存重叠 /assert(pbto = pbfrom+count& pbto= pbto + count& pbfrom 0) *pbto+ = *pbfrom+; return dst; /*memmove自定义函数*/src可以不保留char *_memmove(char* dest, const char *src, size_t len) assert(src != 0 & src != 0); if (dest src) char *p = dest; for (size_t i = 0; i src) char *p = dest + len - 1; src += len - 1; for (size_t i = len - 1; i = 0; i-) *p- = *src-; return dest;void* memmove(void* dst,const void* src,size_t count) char* pbto = (char*)dst; char* pbfrom = (char*)src; assert(dst != null & src != null);/不能存在空指针 if (dst = pbfrom + count)/没有overlap的情况,直接拷贝 while (count- 0) *pbto+ = *pbfrom+; else pbto = pbto + count -1;/overlap的情况,从高位地址向低位拷贝 pbfrom = pbfrom + count -1; while (count- 0) *pbto- = *pbfrom-; return dst; 1.12 strcat函数实现功 能: 字符串拼接函数#include#includeusing namespace std; char* mystrcat(char *strdest,const char *strsrc)/copy strstr to the end of strdest assert(strdest!=null)&(strsrc!=null); char *strdestcopy=strdest; strdest=strdest+strlen(strdest); while(*strsrc!=0) *strdest+=*strsrc+; return strdestcopy;int main() char string1100=hanli; char *string2=yuanlin; coutmystrcat(string1,string2)endl; return 0;1.13 使用库函数atoi,将char *int#include/#include/not necessary!using namespace std;int main() int number; char str10=12345; number=atoi(str);/const char *str coutnumberendlstrendl; return 0;1.14 使用库函数itoa,将intchar *#include/#include/not necessary!using namespace std;int main() int number=12345; char str10; itoa(number,str,10);/int value,char *str, int radix coutnumberendlstrendl; return 0;1.15 不使用库函数,将intchar *#include#includeusing namespace std; void myitoa(int value, char *str) assert(value=0)&(str!=null); char temp10; int i=0,j=0; while(value) tempi+=value%10 + 0;/整数加0就会隐性转化成char类型的数 value=value/10; i-; while(i=0) strj+ = tempi-; strj=0;/以0结束,勿漏! int main() int number; char str10; coutplease input an integernumber; myitoa(number,str); coutstrendl; return 0;1.16 不使用库函数,将char *int#includeusing namespace std; int myatoi(const char *str) int number=0; const char *ptr=str; if(*str=+)|(*str=-)/如果第一位为符号位 str+; while(*str!=0) if(*str9)/如果不是数字 break; number=number*10+(*str-0);/数字转换为字符 str+; if(*ptr=-)/如果有符号位,且为- number=-number; return number; int main() int number; char str10=12345; number=myatoi(str); coutstrendlnumberendl; return 0;1.17 求两个整数的最大公约数#include#includeusing namespace std; int getgcd(unsigned long int a,unsigned long int b) assert(a0)&(b0); unsigned long int temp; while(a%b != 0) temp=a%b; a=b; b=temp; return b; int main() unsigned long int x,y; unsigned long int gcd; coutplease input two integers:ab; gcd=getgcd(x,y); coutgcdendl; return 0;1.18 little_endian or big_endian/little_endian: cpu对操作数的存储方式是低字节在低地址;(intelx86)/big_endian :cpu对操作数的存储方式是低字节在高地址;#includeusing namespace std; int checkcpu() union w int a; char b; c; c.a=1; return (c.b=1);/little_endian(=1) int main() int temp; temp=checkcpu(); if(temp) coutlittle_endianendl; else coutbig_endianendl; return 0;字节序(endian),大端(big-endian),小端(little-endian)在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方将无法进行正确的编/译码从而导致通信失败。目前在各种体系的计算机中通常采用的字节存储机制主要有两种:big-edian和little-endian。字节顺序 endian现代的计算机系统一般采用字节(octet, 8 bit byte)作为逻辑寻址单位。当物理单位的长度大于1个字节时,就要区分字节顺序(byte order, or endianness)。常见的字节顺序有两种:big endian(high-byte first)和little endian(low-byte first),这就是表2.1中的be和le。intel x86平台采用little endian,而powerpc处理器则采用了big endian。举例来说,整型数字$1234abcd存储的时候就会有两种方式:大端big-endian低地址存放最高有效位(msb),既高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。计算机体系结构中一种描述多字节存储顺序的术语,在这种机制中最高有效位(msb)存放在最低端的地址上。采用这种机制的处理器有ibm3700系列、pdp-10、mortolora微处理器系列和绝大多数的risc处理器。小端little-endian 低地址存放最低有效位(lsb),既低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。计算机体系结构中一种描述多字节存储顺序的术语,在这种机制中最不重要字节(lsb)存放在最低端的地址上。采用这种机制的处理器有pdp-11、vax、intel系列微处理器和一些网络通信设备。该术语除了描述多字节存储顺序外还常常用来描述一个字节中各个比特的排放次序。中端 middle-endian除了big-endian和little-endian之外的多字节存储顺序就是middle-endian,比如以4个字节为例:象以3-4-1-2或者2-1-4-3这样的顺序存储的就是middle-endian。这种存储顺序偶尔会在一些小型机体系中的十进制数的压缩格式中出现。网络字节序 network ordertcp/ip各层协议将字节序定义为big-endian,因此tcp/ip协议中使用的字节序通常称之为网络字节序。主机序 host orader它遵循little-endian规则。所以当两台主机之间要通过tcp/ip协议进行通信的时候就需要调用相应的函数进行主机序(little-endian)和网络序(big-endian)的转换。c+怎样判别大端小端使用宏的方法:const int endian = 1;#define is_bigendian() ( (*(char*) &endian) = 0 )#define is_littlendbian() ( (*(char*) &endian) = 1 ) 方法二:bool islittleendian()union long val;char charsizeof(long);u;/1-小端(intel); 0-大端(motor)u.val = 1; if ( u.char0 = 1 )/小端return true; else if ( u.charsizeof(long)-1 = 1 )/ 大端return false; throw( unknown! );小知识 java使用的是big-endian。1.19 sizeof与strlen的区别(1)sizeof是运算符,strlen是函数(2)sizeof可以用类型做参数;strlen只能用char *做参数,且必须是以0结尾(3)sizeof大多在编译时已计算出结果;strlen的结果要在运行的时候才能计算出来即:sizeof是计算范围有多大;strlen是计算0之前有多少1.20 实现string类的big_four/构造函数string:string(const char *str) if(str=null) m_data=new char1; *m_data=0; else int length=strlen(str); m_data=new charlength+1; strcpy(m_data,str); /析构函数string:string(void) dalete m_data;/拷贝构造函数string:string(const string &other) int length=strlen(other.m_data); m_data=new charlength+1; ctrcpy(m_data,other.m_data);/赋值函数string &string:operator=(const string&other) if(this!=&other) char *temp=new charstrlen(other.m_data)+1; str(temp,other.m_data); delete m_data; m_data=temp; return *this;1.21 struct和union的区别 首先看看union,在c+中,union可能没有多大用处,在c语言中,可能我们要借助其完成很多巧妙的设计,下面是其一个完整的定义: union utest double dlone; char chone; byte barray4;好了,看到上面的定义,很像struct的定义,但是对于union来说,有几点是值得注意的:不能直接对其进行初始化;某个时候只能使用其中的一个元素;最后一点也是最重要的一点就是内存共享,分配给union内存的size是其中size最大的那个元素的size。说到这里,既然union最重要的是内存共享,那么我们做如下定义:union utest tele;然后赋值:tele.dlone = 2.0f;现在是dlone可用,下一步:tele.chone = a;到这里dlone失去了其意义,chone变得可用。然后,我们再来看看struct,在struct中每一个元素都是分配内存的,而且都是有单独意义的,也就是说对一个变量的赋值并不影响其它变量的取值。到这里,各位应该明白这两者之间的区别了吧,事实上我个人认为,它们最主要的区别是在内存的分配和使用上。知道这一点,一切也就不难理解了。最后,在使用union的时候,可能有时候我们会来用其来对字节流进行分解和重组,这样使用的时候一定要注意各种内存对数据的存储,比如intel是按高高低低的原则存储的,有些则是相反的。因此,这点因该值得注意,否则得到的可能和预期的结果不一样。举例:使用union结构输出主机字节序int main(void) union short s; char csizeof(shor); un; un.s = 0x0102; printf ( %s:, cpu_vendor_os ); if ( 2=sizeof(short) ) if ( 1=un.c0& 2=un.c1) printf ( big-endiann ); else if( 2=un.c0 & 1=un.c1) printf ( little-endiann ); else printf ( unknownn ); else printf ( sizeof(short) = %dn, sizeof(short) ); return 0;1.22 char字符变量与int整型数据字符型变量用来存放字符变量,请注意只能放一个字符,将一个字符常量放在字符变量中,实际

温馨提示

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

评论

0/150

提交评论