首页 > 代码库 > C学习笔记

C学习笔记

《C陷阱与缺陷》学习笔记
void (*func)();//初始化函数指针;
(*func)();
//等价于 
func();
(*(void (*)())0)();
//等价于
typedef void (*HANDLER)(int);
typedef HANDLER *FUNCPTR(int,HANDLER);
//等价于
void (*func(int,void(*)(int))) (int);
 
函数操作符优先级:
技术分享

注意:
同类多等级:算术运算符、比较运算符、逻辑运算符;
从右至左结合:单目运算符、赋值运算符; 

前述运算符>单目运算符>双目运算符>算术运算符>移位运算符>关系运算符>逻辑运算符>赋值运算符>条件运算符
常见:
(*p)++,*p++;*(p++);
1/2*a,(1/2)*a,1/(2*a);
a<b==c<d;
a = b>100&&c>111 ? TRUE:FALSE;
a=b=fun(0);
while((c=getc(in))!EOF);

符号‘;’注意 不可缺省:
if while return 类型声明struct;

switch()
{
    case 0:{break; }
    case 1:{ break;}
    case 2: {}
    case 3:{}
    default:break;
}
注意:switch中case为跳转标识,跳转后按顺序执行;
ASK:数组初始化出现多余的逗号;


C语言中会自动转换:
作为参数的数组声明转换为相应的指针声明;
exp:int strlen(char s[]){}  转换为 int strlen(char* s){}
exp:void main(int argc,char* argv[]){}转换为void main(int argc,char** argv){}


char* p; p = "asd"; 指针p指向‘a‘,‘s‘,‘d‘,‘\0‘

将一整数转换一指针,结果取决于C编译器实现;
例如常数0,转换为指针后为无效指针,访问该指针指向的内存存储是非法的;  
空指针: #define NULL  0;
if(p==(char*)0)    合法;if(strcmp(p,(char*)0))非法;

数组边界:
char buf[N];
边界比较:
数组有效偏移 {n>=0;     n<N;}或者 {bufptr>=&buf[0];    bufptr<&buf[n];  }
溢出判断:{n=N}或者{bufptr==&buf[N]}
偏移位数:n=bufptr-&buf[0];    剩余位数:n=N-(bufptr-&buf[0])=N+&buf[0]-bufptr=&buf[N]-bufptr
buf 拷贝函数:
void bufwrite(char* destbuf,char* srcbuf ,int n)
{
    char* bufptr = &detbuf[0];
    while(--n>=0)
    {
        if(bufptr==&detbuf[N]) flushbuffer();
        *bufptr++ = *srcbuf++;
    }
}

求值运算符:
&&和||    :先对左边求值,根据需要再对右边求值;如(y!=0&&x/y)
a?:b:c    :先对a求值,如果a为真则对b求值,如果a为假则对c求值;如value = http://www.mamicode.com/a?b:c;
a,b       :先对a求值扔掉,再对b求值;如g((x,y))先对x求值扔掉,再对y求值传参


整数溢出:
INT_MAX 是一个已定义常量,代表可能最大整数值;
if(a>INT_MAX-b)    complain();

函数main返回值0为程序执行成功,非0为程序执行失败;

int c;//int类型能储存所有字符类型,而char类型不能;
clrscr();
printf("Press key...");
while((c=getchar())!=‘Q‘)
{
  clrscr();
  printf("key: %c\nvalue: %x",c,c);
}



类型转换:
窄字符转宽字符:
unsinged无符号扩展(movzx),如:(u_char)01->(int)00 00 00 01
singed有符号扩展(movsx),如:(char)FF->(int)FF FF FF FB
宽字符转窄字符:字符截取低位;(int)FF F0 BD C0->(char)BD C0
移位操作:如果被移对象是无符号(unsinged)对象,那空出位用0填充;如果被移动对象为有符号(singed)对象空出位可以用0填充和符号位填充

C语言缺陷:
一个输入操作符(fread)随后不能紧跟一个输出操作符(fread),反正亦然,必须在其中插入fseek()函数。


缓冲输出:
设置输出流的缓冲区,当缓冲区填满,buf缓冲区中的数据写入stdout中,其中缓冲区buf长度为<stdio.h>中BUFSIZ定义;
当未写满要输出到stdout中调用fflush()即使输入到stdout数据流中;
setbuf(stdout,buf);
主程序执行完后,程序释放过程;
main()函数结束->交付std内存给运行时库释放内存->交付内存给操作系统;
因此buf内存 开辟为静态存储空间或者动态存储空间;

程序出错调试手段:
errno 是记录系统的最后一次错误代码。代码是一个int型的值,在errno.h中定义
errno在库函数在执行失败后才更改,因此不能根据错误码来判断,库执行失败或成功

signal:当程序执行失败后,发送异步信号,因为c库signal定义模糊因此很少用;


_FILE_和_LINE_是内建于C语言预处理器中的宏;
#define assert(e) if(!e) assert_error(_FILE_,_LINE_)
声明精简表达式#define assert(e) ((void)((e)||_assert_error(_FILE_,_LINE_)))










来自为知笔记(Wiz)


C学习笔记