常犯错误记录

很久之前总结的犯错记录,现在看起来好傻,好多当初自认为得到的结论现在看起来一点也不正确,看来知识还得多酝酿啊

1.位运算和逻辑运算在一起时,小心优先级问题

plNodeState & testBit != 0

(plNodeState & testBit) != 0

后者为我的真正用意。

代价:花了近乎半个小时才发现这个错误。

2.fgets()能把最后的换行也读了:"\n\0"

3.getchar()读的是缓冲区。每当换行进入缓冲区,就从缓冲区队列前读入一个字符, IO函数要小心行缓冲等; 本质原因是stdin默认是行缓冲的。

4.socket通信中write如果写的不够参数长度会阻塞住,通信双方往往不知道对方写了多少字节,很容易出现同步错误。解决方案之一:使用定长字符串(自定义协议)来交换信息。

代价:ZTE比赛中,如果对这个原理理解透彻的话,就不会对发送接收的同步问题懊恼那么久了。

5.在较大数的运算中,不仅要关注变量的溢出,还要关注运算过程中的溢出

6.合理的使用assert可以判断库函数是否正确执行,同时又能保证代码简洁

7.strcpy,strcat末尾有'\0',而strncpy,strncat末尾没有

8.打印负数的十六进制,打出来的是补码,printf("0x%x", -9);负数也是用补码来参与位运算;负数的右移>>会高位填充1.

9.for循环中间的逻辑判断表示不合法就跳出for循环,而不是continue。(⊙﹏⊙b汗,居然在这卡了好半天)

10.switch语句中,一定进入某个case后,后续的所有case都会进,不管条件是否满足,除非遇到break.

11.对于自定义头文件的引入,须使用双引号,如果使用尖括号的话,编译器会无法找到。而对于标准头文件使用双引号是可以的。原因是搜索路径有先后顺序。

12.文件末尾其实是没有EOF这个东西的。只是一个抽象概念而已,返回-1(EOF)仅表示文件结束而已。

13.qsort使用的回调函数cmp的参数是所排序元素的“地址”。

int cmp(const void* a, const void* b) {
    return strlen(*(char**)b) - strlen(*(char**)a); //这里要转化为char**而不是char*;调了半天。
}

char** wordLib = (char**)malloc(sizeof(char*) * N);
int i = 0;
for (i = 0; i < N; i++) {
    char* tmp = (char*)malloc(1024);
    gets(tmp);
    wordLib[i] = tmp;
}

qsort(wordLib, N, sizeof(wordLib[0]), cmp);

14.使用系统调用等函数,一定要注意出错处理,不可能每次系统调用都能成功,特别是在socket通信中,作为初学者要注意呀

15.C++语言中,函数返回一个临时对象是可以的。因为返回的是一个值。我总多担心了。注意和JAVA在值对象和引用对象的区分,每段时间切换语言,总得适应一会儿。

16.……

你可能感兴趣的:(常犯错误记录)