C语言的多做之过
- C语言对于作用域提供的可选方案非常少,ALL or NOTHING,而且默认是全局可见性,即函数前加不加extern都是全局的,只有加static才是本文件可见性,这有的时候会造成一些问题,用户编写的函数覆盖了标准库函数等等问题,而且这样不利于模块化
- C语言的switch的go-through策略
C语言的误做之过
- 处于相同优先级的函数,先后顺序是不固定的
- 处于相同优先级的操作符,由结合性来消除歧义
- 标准函数库的一些问题,详见下节
- 关键字的各种重载,一个符号的多种含义
- p = N * sizeof * q; 是何含义?
- apple = sizeof(int) * p;又是何含义?
# include <stdio.h>
# include <time.h>
# include <malloc.h>
#define N (20)
int main(int argc, char **argv)
{
char *q = NULL;
int p = N * sizeof * q; // 20 * sizeof(*q),q所指类型的大小
printf("%d \n",p); // 20
void *r = malloc(p);
int apple = sizeof(int) * p; // p * sizeof(int)
printf("%d \n",apple); //80
return 0;
}
//hack 所以,记住乘除优先级高于加减,其他情况全部加括号!
C语言的少做之过
- 命令行的解析,使用argc和argv,无法有效的区分运行时选项和文件名参数,即”-i -o “之类的开关选项,比如下例,以及rm无法删除以连字符开头的文件名,只能给出完整路径来删除
ls -l | grep ->
ls -l | grep "->"
file -h | grep link
- 空格引起的问题
- 诸如z = y+++x, ratio = *a/*b
- 注释相关的内容,如下
a //*
//*/ b
//C中是a/b
//C++中是a
- 返回一个函数内部栈内存的错误,为了不出错,方法有5种
- 返回一个指向常量字符串的指针,return “XXXXX”,缺点是只能读不能写
- 使用全局变量,缺点是增加了全局变量
- 使用静态数组,缺点是下一次调用会覆盖上一次的内容,即线程不安全,而且如果太大浪费空间
- malloc后返回指针,缺点是程序员要自己free,很难记得去free
- 传入一个已经malloc好的内存指针,这样就可以记得去free了,malloc和free在一个函数内部比较容易处理
- lint程序被剥离出了编译器,所以在编译之前,保证pc-lint无错误很重要,可以有效的提升软件质量
C标准库中不安全的函数
每条不安全的函数都已经提供了可替代的安全函数,之所以未取消不安全函数是因为大量软件还在使用它们.
- gets() 使用 fgets() 替代
- strcmp()使用 strncmp() 替代,最好使用memcmp()
- stract()使用 strncat() 替代
- strcpy()使用 strncpy() 替代 最好使用memcpy()
- 使用memcpy,因为没有人保证出现’\0’,而且非常容易不出现这个值,这个时候它就不再是字符串,字符串工具函数必须是专款专用,而memcpy则要宽泛得多;
Reference
C专家编程