c专家编程总结
(一)编译器设计金科玉律:效率(几乎)就是一切
- 运行效率(代码的运行速度);
- 变异效率(产生可执行代码的速度);
(二)c早期体验
数组:偏移量的概念
基本数据类型:底层硬件
Float与double转换非常小的代价;
NUL,用于结束一个ACAII字符串,NULL表示一个空指针
(三)运算法优先级问题
1. ==和!=高于赋值符c=getchar()!=EOF运行实际结果c=(getchar()!=EOF)
2. 算数运算符高于移位运算法msb<<4+lsb实际运行结果是msb<<(4+lsb);
3. “++i”表示取i的地址,增加它的内容,然后把值放在寄存器中;“i++”则表示取i的地址,把他的值放入寄存器中,然后增加内存中的x的值。
(四)函数
1.拒绝用gets()应该用fgets()取代,gets()会将多余的字符压到堆栈中,黑客可以通过这个更改计算机里边的内容。
(五)指针与数组
1. char *p=”wersffs”,
Float *pip=3.14/*不能通过编译*/这种定义的方式只限于字符串。
2.数组访问For(i=0;i<10;i++) a[i]=0;
把左值(a)装入R1(可以提到循环外), 把左值(i)装入R2(可以提到循环外),
吧(R2)装入R3, 如果需要对R3的步长进行调整到R1+R3的结果装入R4中
把0存储到R4
3 指针备选方案1 p=a;for(i=0;i<10;i++)p[i]=0;
把左值(p)装入R0(可以提到循环外) 把[R0]转入R1(可以提到循环外)
把左值(i)转入R2(可以提到循环外) 把[R2]装入R3
如果需要对R3的步长进行调整,把R1+R3的结果装入R4中
把0存储到[R4]
4.指针备选方案2 p=a; for(i=0;i<10;i++) *(p+i)=0;
与指针备选方案一相同
5. 指针备选方案3 p=a; for(i=0;i<10;i++) *p++=0;
把p所指对象的大小装入R5(可以提到循环外) 把左值(p)装入R1(可以提到循环外)
把[R0]装入R1 把0存储到R1;
把R5+R1的结果装入R1 把R1存储到[R0];
6.char carrot[10][20]; typedef vegetable[20]; vegetable carror[10];
(六)代码优化
1.消除循环,函数代码就地扩展,公共子表达式消除,改进寄存器分配,省略运行时对数组边界的检查,循环不变量代码移动,操作符长度削减(把指数操作转换为乘法操作,把乘法操作转换为以为操作或加法操作);
2.貌似还可以操作系统作弊。
(七)库函数
1.错误: char *p=NULL;printf(“%s”,p);
C标准规定%s说明符的参数必须是有一个指向字符数组的指针,应及早发现这个错误。