C语言好的编码风格
来源:互联网 发布:dots像素软件 编辑:程序博客网 时间:2024/06/05 02:25
多用assert(),这样可以定位错误,方便调试
注意:assert是宏,而不是函数。在C的assert.h头文件中。
assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:
#defineassert(expr)\((expr)\?__ASSERT_VOID_CAST(0)\:__assert_fail(__STRING(expr),__FILE__,__LINE__,__ASSERT_FUNCTION))
assert的作用是先计算表达式expr,如果其值为假(即为0),那么它会打印出来assert的内容和__FILE__,__LINE__, __ASSERT_FUNCTION,然后执行abort()函数使kernel杀掉自己并coredump(是否生成coredump文件,取决于系统配置);否则,assert()无任何作用。宏assert()一般用于确认程序的正常操作,其中表达式构造无错时才为真值。完成调试后,不必从源代码中删除assert()语句,因为宏NDEBUG有定义时,宏assert()的定义为空。[1]
请看下面的程序清单badptr.c:
#include<stdio.h>#include<assert.h>#include<stdlib.h>int main(void){ FILE* fp; fp=fopen("test.txt","w");//以可写的方式打开一个文件,如果不存在就创建一个同名文件 assert(fp);//所以这里不会出错 fclose(fp); fp=fopen("noexitfile.txt","r");//以只读的方式打开一个文件,如果不存在就打开文件失败 assert(fp);//所以这里出错 fclose(fp);//程序永远都执行不到这里来 return 0;}
[root@localhost error_process]# gccbadptr.c
[root@localhost error_process]# ./a.out
a.out: badptr.c:14: main: Assertion `fp'failed.
如果使用动态链接libc,那么除了__FILE__, __LINE__, __ASSERT_FUNCTION会让目标变的稍稍大了一点,并不会因为多次使用assert()增加目标很多。不过好处也很明显,就是会在assert的地方会打印出来文件名,行数,和函数名。另外,要注意用assert()的错误程度。如果assert()的条件fail了,那么会调用abort()函数让kernel杀掉自己,哪怕用户自己重新注册了SIGABRT信号的行为(abort()会先向自己发送信号SIGABRT保证用户的handler正确执行,然后修改SIGABRT信号的行为为默认行为coredump,再次像自己发送SIGABRT,coredump)。
在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #defineNDEBUG 来禁用assert调用,示例代码如下:
#include <stdio.h>#define NDEBUG#include <assert.h>
使用enum
enum gg_type {
type1,
type2
};
这样就定义了一个类型。这里type1成了一个代表整数0的命名常量。在使用整数常量的任何地方都能使用枚举常量。
然后在使用的时候就enum gg_type type。这里的type是枚举变量。
在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。
C允许对枚举变量使用运算符++,而C++不允许
宏定义的使用
#if defined(DEBUG)extern int nmallocs;extern int nfrees;#define debug_malloc(size) \({\ void *p = malloc(size); \ nmallocs++; \ printf("malloc() size=0x%lu, %s:%d:%s:p=0x%lx\n", (unsigned long)(size), \__FILE__, __LINE__, __func__, (unsigned long)p);\p; \}) #define malloc(s) debug_malloc(s)#define free(p) do { \ printf("free() %s:%d:%s:p= 0x%lx\n", __FILE__, __LINE__, \ __func__, (unsigned long)p); \ nfrees++, free(p); \ } while (0)#define debug_strdup(src) \({ \ char *dst; \ dst = malloc(strlen(src) + 1); \strcpy(dst, src); \dst[strlen(src)] = '\0'; \ dst; \})#define strdup(p) debug_strdup(p)
在使用中所有的malloc在预处理阶段都会被改变成debug_malloc(s)宏多对应的形式。free也一样。在预处理阶段__FILE__, __LINE__,会被处理成文件名和行号,而__func__没有变化。他的处理不是在预处理阶段进行的。
#define debug(level, ...) do { \if (level < TPOOL_DEBUG) {\flockfile(stdout); \printf("###%p.%s: ", (void *)pthread_self(), __func__); \printf(__VA_ARGS__); \putchar('\n'); \fflush(stdout); \funlockfile(stdout);\}\} while (0)
<pre name="code" class="cpp">debug(1,"hehehe",100,10.8);//被扩展成do { if (1 < 3) { flockfile(stdout); printf("###%p.%s: ", (void *)pthread_self(), __func__); printf("hehehe",100,10.8); putchar('\n'); fflush(stdout); funlockfile(stdout); }} while (0);这里的使用不是很好,在debug后面首先应该是"%s,%d,%f",然后才是真正要打印的东西。因为里面用到了printf。这里__VA_ARGS__代表着后面的一系列参数。
- C语言好的编码风格
- C语言编码风格
- C语言编码风格
- Linux下C语言编码的风格
- Linux C语言编码风格
- C语言的编码风格-文件描述(1)
- C语言的编码风格-缩进(5)
- C语言的编码风格-函数说明(6)
- C语言的编码风格-变量命名(7)
- 好的编码风格和不好的
- C语言编码风格和标准
- 高级C语言教程编码风格
- C语言入门(19)——C语言的编码风格
- c语言的编程风格
- c语言的编程风格
- c语言的编程风格
- c语言的编程风格
- c语言的编程风格
- 一点小感想
- Leetcode Problem.119—Pascal's Triangle II
- 在MFC 窗口中运行 cocos2d-x 3.2 (一) 基本配置
- 判断std::string和CString
- jquery iframe自适应高度
- C语言好的编码风格
- 第二节:导演类Director介绍
- java、C++-带标签的break 和 continue语句
- linux- idr机制
- 黑马程序员——Java基础---单例设计模式
- 在MFC 窗口中运行 cocos2d-x 3.2 (二) 让其在MFC picture控件中运行
- String format 使用
- 八数码问题 poj 1077 康拓展开
- BitMap 学习