c陷阱与缺陷
leafinsnowfield
这个作者很懒,什么都没留下…
展开
-
更新顺序文件
FILE *fp;struct record rec;...while(fread((char *)&rec,sizeof(rec),1,fp)==1){ ...//对rec执行某些操作 if(){//如果rec必须被重新写入 fseek(fp,-(long)sizeof(rec),1);//fseek要求第二个参数必须是long型,应为int类型的整数可能无法包含一个文件的大小原创 2015-01-21 20:06:11 · 587 阅读 · 0 评论 -
去掉#include 《stdio.h》这个程序在许多系统中仍然能够运行,但是在某些系统中运行起来却慢很多是为什么
#include main(){ register int c; while((c=getchar())!=EOF) putchar(c); return 0;}上面程序的作用是把它的输入复制到输出:从这个程序黄总去掉#include语句,将导致程序不能通过,因为这时EOF是未定义的,假定我们手工定义了EOF(当然这时一种不好的做法):#define EOF -1ma原创 2015-01-21 23:01:24 · 1957 阅读 · 0 评论 -
bufwrite memcpy
#include #define N 1024static char buffer[N];static char *bufptr;void memcpy(char *dest,const char *source,int k){ while(--k>=0) *dest++=*source++;}void bufwrite(char *p,int n){ while(n>0)原创 2015-01-21 15:40:14 · 326 阅读 · 0 评论 -
(x) ((x)-1)能否成为一个合法的c表达式
C陷阱与缺陷--6 预处理器 一、知识点1、getchar和putchar经常被实现为宏,以避免在每次执行输入或者输出一个字符这样简单的操作时,都要调用相应的函数而造成系统效率的下降。(P100) 2、宏只是对程序的文本起作用,宏提供了一种对组成C程序的字符进行变换的方式,而并不作用于程序中的对象。(P101) 3、对于宏定义:(P101)#define转载 2015-01-22 00:21:43 · 721 阅读 · 0 评论 -
二分法查找数
#include int *bsearch(int *t,int n,int x)//利用不对称原理{ int lo=0,hi=n; while(lo<hi) { int mid=(hi+low)/2; if(x<t[mid]) hi=mid; else if(x>t[mid]) lo=mid+1; else return t+mid; } retu原创 2015-01-21 17:35:35 · 542 阅读 · 0 评论 -
typedef函数
1.typedef void (*funcptr)();(*(funcptr)0)();等价于(*(void(*)())0)();2typedef void (*HANDLER)(int);HANDLER signal (int,HANDLER);等价于void (*signal(int,void(*)(int)))(int);原创 2015-01-20 22:21:48 · 386 阅读 · 0 评论 -
使用varargh.h来实现可变参数列表以及varargh.h实现
#include void error(va_list)va_dcl{ va_list ap; char *format; va_start(ap); format=va_arg(ap,char *); fprintf(stderr,"error: "); //某些实现方式暂时未知的工作 va_end(ap); fprintf(stderr,"\n"); exit(1);原创 2015-01-22 16:24:35 · 492 阅读 · 0 评论 -
为什么一个程序终止会导致程序输出的最后几行消失
一个异常终止的程序可能没有机会来清空缓冲区,所以该程序生成的输出可能位于内存中的某个位置,但却永远不会被写出来。在某些系统上,这些无法被写出的数据肯能长达好几页,对于试图调试这类程序的编程者而言,这种丢失输出的情况经常会误导他们,应为它会造成这样一种印象,程序发生失败的时刻要比实际上运行失败的真正时刻要早得多解决方案就是在调试时候强制不允许对输出进行缓冲,要做到这点,不同的系统有不同的做法,这些做原创 2015-01-21 22:51:55 · 1438 阅读 · 2 评论 -
r+与a+与w+
r+ 以可读写方式打开文件,该文件必须存在。 w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。 a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)转载 2015-01-21 19:59:54 · 567 阅读 · 0 评论 -
stdarg.h:ANSI版的varargs.h
#include #include void error(char *format,...){ va_list ap; va_start(ap,format); fprintf(stderr,"error: "); vfprintf(stderr,format,ap);//与可变参数有关的打印用vfprintf va_end(ap); fprintf(stderr,"\n");原创 2015-01-22 16:39:06 · 574 阅读 · 0 评论 -
缓冲输出和内存分配
程序输出有两种方式:一种是即时处理方式,另一种是先暂存起来,然后再大块写入的方式,前者往往造成较高的系统负担。因此,C语言实现通常都允许程序员进行实际的写操作之前控制产生的输出数据量。 这种控制能力一般是通过库函数setbuf实现的。如果buf是一个大小适当的字符数组,那么 setbuf(stdout,buf); 语句将通知输入/输出库,所有写入到stdout的输出都应该使原创 2015-01-21 20:47:03 · 572 阅读 · 0 评论 -
用一个不带原型声明的函数时默认实际参数提升
在C语言中,调用一个不带原型声明的函数时:调用者会对每个参数执行“默认实际参数提升(default argument promotions)”。同时,对可变长参数列表超出最后一个有类型声明的形式参数之后的每一个实际参数,也将执行上述提升工作。提升工作如下:——float类型的实际参数将提升到double——char、short和相应的signed、unsigned类型的实际转载 2015-01-22 15:12:49 · 579 阅读 · 0 评论 -
可移植版本的atol
long atol(char *s){ long r=0; int neg=0; switch(*s) { case '-': neg=1; case '+': s++; break; } while(*s>='0'&&*s<='9') { int n=*s++-'0'; if(neg) n=-n; r=r*10+n; } return r;原创 2015-01-22 15:46:35 · 399 阅读 · 0 评论 -
算术运算的隐式转化
算数运算的隐式转换 算数运算中,首先有如下类型转换规则: 1、字符必须先转换为整数(C语言规定字符类型数据和整型数据之间可以通用) 。 2、short型转换为int型(同属于整型) 。 3、float型数据在运算时一律转换为双精度(double)型,以提高运算精度(同属于实型) 。 其次,有下面的规则。 当不转载 2015-01-22 15:08:14 · 511 阅读 · 0 评论 -
使用errno检测错误
很多库函数,特别是那些与操作系统有关的,当执行失败时会通过一个名称为errno的外部变量,通知程序该函数调用失败。如: /* 调用库函数 */if(errno)/* 处理错误 */ 上面看似清楚明了的代码,其实是错误的,出错原因在于,在库函数没有失败的情况下,并没有强制要求库函数一定要设置errno为0,这样errno的值可能是前一个执行失败的库函数设置的值。做如下修改原创 2015-01-21 22:02:45 · 558 阅读 · 0 评论 -
typedef void (*funcptr)()
typedef int (*funcptr)(); 这个的意思是:定义一个返回值为int,不带参数的函数指针,就是说funcptr 是 int (*)()型的指针funcptr table[10]; 定义一个数组,这个数组是funcptr类型的。就是说这个数组内的内容是一个指针,这个指针指向一个返回值为int,不带参数的函数原创 2015-01-20 22:14:35 · 737 阅读 · 0 评论