C编程常见问题总结
本文是C编程中一些常见错误的总结,有些是显而易见的,有些则是不容易发现
本文地址:http://www.cnblogs.com/archimedes/p/get-screwed-c.html,转载请注明源地址。
1.忘记注释结束符
代码
a = b; /* 出现bug
c = d; /* c = d将不会执行*/
2.意外的赋值/意外的bool表达式
代码:
if(a = b) c; /*a恒等于b,只有当b!=0的时候才执行*/
再看下面的代码:
if( < a < ) c; /*布尔表达式恒为真*/
上面代码中的bool表达式恒为真,由于0 < a的值为0或1,永远都小于5成立,当然C中没有bool表达式,这里只是假设
3.有缺陷的宏
代码:
#define assign(a,b) a=(char)b
assign(x,y>>)
变成
x=(char)y>> /* 可能不是你的目的 */
4.不匹配的头文件
代码:
//foo.h:
struct foo { BOOL a};
//F1.c
#define BOOL char
#include "foo.h"
//F2.c
#define BOOL int
#include "foo.h"
F1与F2对结构体foo中的BOOL类型定义不一致,如果交互就会出现错误
5.飘忽不定的返回值
可能你会写下面的代码:
int foo (a)
{ if (a) return(); } /* bug,因为有时候没有值返回 */
6.不可预知的结构体
看下面的比特包结构:
struct eeh_type
{
uint16 size: ; /* 10 bits */
uint16 code: ; /* 6 bits */
};
取决于用哪个C编译器,还有你的机器使用大小端,这段代码实现为:
<10-bits><6-bits> 或 <6-bits><10-bits>
同时取决于C编译器、机器体系结构、不可思议的优先设置,这些项可能对齐到最近的8, 16, 32, or 64 bits.
7.不确定的求值顺序
foo(pointer->member, pointer = &buffer[]);
不同的编译器针对函数参数有不同的求值顺序,gcc是从左到右的求值顺序,有的编译器是从右往左
8.容易改变的块作用域
代码:
if( ... )
foo();
else
bar();
当加上调试输出信息:
if( ... )
foo();
else
printf( "Calling bar()" ); /* 注意! else止于此 */
bar(); /* 注意! bar永远会被执行 */
9.不安全的返回值
代码:
char *f() {
char result[];
sprintf(result,"anything will do");
return(result); /* 注意! result 被分配在栈上. */
}
int g()
{
char *p;
p = f();
printf("f() returns: %s\n",p);
}
10.未定义副作用(side effects)
哪怕一个简单的表达式,C没有定义副作用的顺序,结果取决于你的编译器,i/i++可能等于0或1,看下面的代码:
#include <stdio .h>
int foo(int n) {printf("Foo got %d\n", n); return();}
int bar(int n) {printf("Bar got %d\n", n); return();}
int main(int argc, char *argv[])
{
int m = ;
int (*(fun_array[]))();
int i = ;
int ii = i/++i;
printf("i/++i = %d, ",ii);
fun_array[] = foo; fun_array[] = bar;
(fun_array[++m])(++m);
return ;
}
11.未初始化的局部变量
事实上这个bug不是那么出名,但是一旦发生严重性不会输给其他的bug,看下面的代码:
void foo(a)
{ int b;
if(b) {/* bug! b没有被初始化 */ }
}
现代编译器会发出错误的警告,看下面代码:
void foo(int a)
{ BYTE *B;
if(a) B=Malloc(a);
if(B) { /* BUG! B 可能没被初始化 */ *b=a; }
}
12.杂乱的编译时环境
编译时环境产生成百上千的编译信息,我们对此知之甚少。有些危险的常用名,导致很难被发现:
#include <stdio.h>
#define BUFFSIZE 2048
long foo[BUFSIZ]; //注意拼写: BUFSIZ != BUFFSIZE
编译器不会报错,因为BUFSIZ已经在stdio.h中定义
13.八进制数
在C中,八进制数以0开始,如果数字中没有‘8’或‘9’出现,编译器不会警告
int numbers[] = { ,
, // 8 而不是 10
014 }; // 12, 而不是 14
14.有符号字符
C中的有符号char可能出现各种错误,比如128是一个负数,另外,任何使用低精度整数都必须十分的小心,C使得这些太容易被忽略了
char s = ;
unsigned char u = ;
s++; /* 结果是负数 */
if (s<u) { /* true!*/ }
if(s>) { /* 永不可能为true */ }
if(u<) { /* 永不可能为true*/ }
15.糟糕的“标准库”
代码:
{ int a=,b=;
char buf[];
scanf("%d %d",a,b); // &a,&b?
sprintf(buf,"this is the result: %d %d"); // 溢出
}
C编程常见问题总结的更多相关文章
- android编程常见问题-程序真机中不显示
新手编程常见问题: 问题表现:连接上手机后,程序不显示 解决版本:检查AndroidManifest.xml 文件中SDK版本的设置(要求要兼容当前手机版本系统),如下:
- android编程常见问题-程序在模拟器中不显示
新手编程常见问题: 问题表现:程序运行成功,但是在模拟器中不显示 解决办法:检查项目版本和模拟器版本是否匹配或兼容,如果不匹配,选择和模拟器版本一致 项目版本:右键-Properties-androi ...
- Python 编程常见问题
Python 编程常见问题 经常使用Python编程,把经常遇到问题在这里记录一下,省得到网上查找,因此这篇文章会持续更新,需要的可以Mark一下.进入正题: 1.Python常用的文件头声明 #!/ ...
- 【Networking】网络编程常见问题汇总
[百度分享]网络编程常见问题总结 串讲(一)网络编程常见问题总结 在网络程序中遇到的一些问题进行了总结, 这里主要针对的是我们常用的TCP socket相关的总结, 可能会存在错误, 有任何问题 ...
- 基于RequireJS和JQuery的模块化编程——常见问题解析
由于js的代码逻辑越来越重,一个js文件可能会有上千行,十分不利于开发与维护.最近正在把逻辑很重的js拆分成模块,在一顿纠结是使用requirejs还是seajs的时候,最终还是偏向于requirej ...
- android编程常见问题-No Launcher activity found!
新手编程常见的问题: 问题表现: console提示:No Launcher activity found! The launch will only sync the application pac ...
- Java编程常见问题汇总
每天在写Java程序,其实里面有一些细节大家可能没怎么注意,这不,有人总结了一个我们编程中常见的问题.虽然一般没有什么大问题,但是最好别这样做.另外这里提到的很多问题其实可以通过Findbugs( h ...
- IO模式设置网络编程常见问题总结—IO模式设置,阻塞与非阻塞的比较,recv参数对性能的影响—O_NONBLOCK(open使用)、IPC_NOWAIT(msgrcv)、MSG_DONTWAIT(re
非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明: 基本概念: 阻塞IO:: socket 的阻塞模式 ...
- CUDA编程常见问题 转
http://blog.csdn.net/yutianzuijin/article/details/8147912 分类: 编程语言2012-11-05 10:55 2521人阅读 评论(0) 收藏 ...
随机推荐
- Knockout 新版应用开发教程之Computed Observables
Computed Observables 如果你有监控属性firstName和lastName的话,此时如果你想要显示全名? 这个时候computed(以前叫做依赖)监控属性就出马了,这是一个函数用来 ...
- js实现无刷新表单提交文件,将ajax请求转换为form请求方法
最近在做项目的时候遇到一个需要上传文件的需求,因为ajax请求是无法上传二进制文件流的,所以只能用form表单提交,而form提交有一个问题就是会使页面刷新,本文解决了form表单提交文件时页面刷新的 ...
- 如何使用DDMS Heap查看Android应用内存情况
作为大四毕业生,而且还是二本,加上技术基础不咋样,找工作自然也是辛酸得很...最糟糕的情况就是一开始实在是太小看了求职之路的艰辛,整个9月都是无所事事的度过,直到月底面试腾讯被鄙视后才顿然醒悟,意识到 ...
- 探秘重编译(Recompilations)(1/2)
这篇文章我想谈下SQL Server里一个非常重要的性能调优话题:重编译(Recompilations) .当你执行非常简单的存储过程(使用临时表)时,就会发生.今天我想奠定SQL Server里重编 ...
- spring AspectJ的Execution表达式
Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式 execu ...
- IOS开发UI基础之Plis文件-字典转模型
什么是plist文件? 在开发中直接将数据写在代码里面 不是一种合理的做法 如果数据经常改变 就需要经常翻开对应的代码进行修改 造成代码扩展性低 因此,可以考虑将经常变的数据放在⽂文件中进⾏行存储,程 ...
- IOS开发UI基础UIView
主要介绍下UIView得基本概念和一些属性的介绍至于属性的用户后面会由详细的介绍 -.UIView基本概念 1.什么是控件? 屏幕上所有的UI元素都叫做控件 (也有很多书中叫做视图 组件) 比如 按钮 ...
- 专题——web.xml 中 url-pattern
一.映射什么? 一个请求发送到 servlet 容器,servlet 容器会将当前请求的 url 路径减去 协议.端口号.contextPath,剩下 servletPath 就是用来做 url-pa ...
- C#写文本日志帮助类(支持多线程)
代码: using System; using System.Configuration; using System.IO; using System.Threading.Tasks; namespa ...
- sencha动态向容器里添加控件出现重叠问题
sencha动态向容器里添加控件出现重叠问题原因是由于动态生成控件的id有重复导致的.(js取时间到毫秒来做id,放在for里面会出现几个控件id是相同的情况.).解决掉重复id的问题就好了. 版权声 ...