回答

收藏

[原创] c语言使用注意事项(三)

飞凌嵌入式 飞凌嵌入式 2529 人阅读 | 0 人回复 | 2014-01-23

本帖最后由 forlinx2013 于 2014-1-24 09:24 编辑

欢迎大家来到飞凌爱板网专区,对嵌入式技术感兴趣的朋友不妨多多关注一下,我们提供了公司所有开发板的所有资料,也会更新大量技术文章,欢迎大家一块学习提高!!!

1、自己实现itoa(int)函数,由整型转换成字符串。
大家看看下面的是否有错?
1 /*************************************
2  * 整型转换成字符串
3  * *********************************/  
4 char *itoa(int n)  
5 {  
6 #if 0  
7         int tmp = n;  
8         int cnt = 1;  
9         while(tmp != 0)  
10         {  
11                 tmp /= 10;  
12                 cnt++;  
13         }  
14         char *buf;  
15         buf = (char *)malloc(cnt * sizeof(char));  
16 #else  
17         char buf[20];  
18 #endif  
19         sprintf(buf,"%d",n);  
20         return buf;  
21 }  
运行结果标明得不到正确的结果。
但将char buf[20]修改成static char buf[20]结果正确。
这是由于函数内static修饰变量表示该变量是静态变量,在函数被调用过程中一直保持不变。如果不加static关键字,那么在函数体内定义的变量在函数调用完毕其内存就释放,所以无法得到正确的结果。
也可以根据整型变量的位数来动态分配内存
22 /*************************************
23  * 整型转换成字符串
24  * *********************************/  
25 char *itoa(int n)  
26 {  
27 #if 1  
28         int tmp = n;  
29         int cnt = 1;  
30         while(tmp != 0)  
31         {  
32                 tmp /= 10;  
33                 cnt++;  
34         }  
35         char *buf;  
36         buf = (char *)malloc(cnt * sizeof(char));  
37 #else  
38         char buf[20];  
39 #endif  
40         sprintf(buf,"%d",n);  
41         return buf;  
42 }  
但是要注意字符串使用完毕后记得使用free()函数来释放其内存。
所以说,函数的返回指针必须是静态分配的缓冲区或是由调用者传入的缓冲区或者是由被调用者使用malloc()函数动态申请的内存。

2sizeof(char)的值是什么?
我们经常会看到下面的代码
43 char *p;  
44 p=(char *)malloc(strlen(string)+1);  
45 strcpy(p,string);  

而我们经常写的时候是
p=(char *)malloc((strlen(string)+1)*sizeof(char) );
这说明,sizeof(char)的值恒为1,但是sizeof('a')的值为2,这是由于'a'表示一个整型的ASCII码,为int型。

3malloc()函数分配的内存必须由free()函数释放,且只能释放一次。
下面注意释放由malloc()分配内存的单链表的释放过程。注意使用的技巧。
46 LNode *listp,*nextp;  
47 for(listp = base;listp != NULL;listp = nextp)  
48 {  
49      nextp = listp->next;  
50      free(listp);  
51 }  

4calloc()malloc()的区别
其实calloc(m,n)实质上就是
p=malloc(m*n);
memset(p,0,m*n);
malloc()calloc()申请的内存都可以使用free()来释放。

5、如果有人给你提出这个问题:假设两个整型变量,你如何不用额外的临时存储变量从而达到交换两个变量的值的目的
52 int a=23;  
53 int b=45;  
54 a ^= b;  
55 b ^= a;  
56 a ^= b;  

6C语言中注释是不能嵌套的,因为/*会和最近的*/匹配,那么当要想注释掉大段包含注释的代码的时候需要使用什么方法呢?
对了,就是预处理
#ifdef XXX    #else    #endif
或者干脆使用
#if 0    #else     #endif

7C语言中assert()函数的使用和作用
assert.h中有assert()函数的宏定义
57 #define assert(test)    ( test ? (void)0 : _Assert(__FILE__":"_STR(__LINE__)"" #test) )  

作用个是在测试表达式为假(=0)时输出一条错误信息。
该函数只在程序调式时有用,在正常运行时不会执行,其是否起作用是通过宏来控制
关闭assert()    #define NDEBUG
打开assert()    #undef  NDEBUG

8、给一个日期,计算是星期几的简洁代码。由Tomohiko Sakamoto 提供
58 int dayofweek(int y, int m, int d) /* 0 = Sunday */  
59 {  
60        static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};  
61        y -= m < 3;  
62        return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;  
63 }  

9、使用#define 预处理定义输出语句TRACE()便于程序的调试
64 #define TRACE(var,fmt)   printf("TRACE: " #var " = " #fmt "\n",var)  
其中变量前的#用于和字符常量的连接。使用的一个实例。下面加入需要输出一个整型变量a
TRACE(a,%d);即可。

10printf()的使用技巧>>如何让程序根据输出的结果自动实现输出的合理的宽度,而不是认为的做如下规定
printf("%5d",a);
下面这种用法可以达到预想的效果
printf("%*d",width,a);


分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条