C语言使用注意事项(三)

来源:互联网 发布:windows基于什么内核 编辑:程序博客网 时间:2024/05/22 07:44

转载于http://blog.csdn.net/yming0221/article/details/7237762

1、自己实现itoa(int)函数,由整型转换成字符串。

大家看看下面的是否有错?

[cpp] view plaincopyprint?
  1. /*************************************
  2. * 整型转换成字符串
  3. * *********************************/ 
  4. char *itoa(int n) 
  5. #if 0 
  6.         int tmp = n; 
  7.         int cnt = 1; 
  8.         while(tmp != 0) 
  9.         { 
  10.                 tmp /= 10; 
  11.                 cnt++; 
  12.         } 
  13.         char *buf; 
  14.         buf = (char *)malloc(cnt *sizeof(char)); 
  15. #else 
  16.         char buf[20]; 
  17. #endif 
  18.         sprintf(buf,"%d",n); 
  19.         return buf; 
运行结果标明得不到正确的结果。

但将char buf[20]修改成static char buf[20]结果正确。
这是由于函数内static修饰变量表示该变量是静态变量,在函数被调用过程中一直保持不变。如果不加static关键字,那么在函数体内定义的变量在函数调用完毕其内存就释放,所以无法得到正确的结果。

也可以根据整型变量的位数来动态分配内存

[cpp] view plaincopyprint?
  1. /*************************************
  2. * 整型转换成字符串
  3. * *********************************/ 
  4. char *itoa(int n) 
  5. #if 1 
  6.         int tmp = n; 
  7.         int cnt = 1; 
  8.         while(tmp != 0) 
  9.         { 
  10.                 tmp /= 10; 
  11.                 cnt++; 
  12.         } 
  13.         char *buf; 
  14.         buf = (char *)malloc(cnt *sizeof(char)); 
  15. #else 
  16.         char buf[20]; 
  17. #endif 
  18.         sprintf(buf,"%d",n); 
  19.         return buf; 
但是要注意字符串使用完毕后记得使用free()函数来释放其内存。

所以说,函数的返回指针必须是静态分配的缓冲区或是由调用者传入的缓冲区或者是由被调用者使用malloc()函数动态申请的内存。


2、sizeof(char)的值是什么?

我们经常会看到下面的代码

[cpp] view plaincopyprint?
  1. char *p; 
  2. p=(char *)malloc(strlen(string)+1); 
  3. strcpy(p,string); 

而我们经常写的时候是

p=(char *)malloc((strlen(string)+1)*sizeof(char) );

这说明,sizeof(char)的值恒为1,但是sizeof('a')的值为2,这是由于'a'表示一个整型的ASCII码,为int型。


3、malloc()函数分配的内存必须由free()函数释放,且只能释放一次。

下面注意释放由malloc()分配内存的单链表的释放过程。注意使用的技巧。

[cpp] view plaincopyprint?
  1. LNode *listp,*nextp; 
  2. for(listp = base;listp != NULL;listp = nextp) 
  3.      nextp = listp->next; 
  4.      free(listp); 

4、calloc()和malloc()的区别

其实calloc(m,n)实质上就是

p=malloc(m*n);

memset(p,0,m*n);

malloc()和calloc()申请的内存都可以使用free()来释放。


5、如果有人给你提出这个问题:假设两个整型变量,你如何不用额外的临时存储变量从而达到交换两个变量的值的目的

[cpp] view plaincopyprint?
  1. int a=23; 
  2. int b=45; 
  3. a ^= b; 
  4. b ^= a; 
  5. a ^= b; 


6、C语言中注释是不能嵌套的,因为/*会和最近的*/匹配,那么当要想注释掉大段包含注释的代码的时候需要使用什么方法呢?

对了,就是预处理

#ifdef XXX    #else    #endif

或者干脆使用

#if 0    #else     #endif


7、C语言中assert()函数的使用和作用

assert.h中有assert()函数的宏定义

[cpp] view plaincopyprint?
  1. #define assert(test)    ( test ? (void)0 : _Assert(__FILE__":"_STR(__LINE__)"" #test) ) 

作用个是在测试表达式为假(=0)时输出一条错误信息。

该函数只在程序调式时有用,在正常运行时不会执行,其是否起作用是通过宏来控制

关闭assert()    #define NDEBUG

打开assert()    #undef  NDEBUG


8、给一个日期,计算是星期几的简洁代码。由Tomohiko Sakamoto 提供

[cpp] view plaincopyprint?
  1. int dayofweek(int y,int m, int d)/* 0 = Sunday */ 
  2.        static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; 
  3.        y -= m < 3; 
  4.        return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; 


9、使用#define 预处理定义输出语句TRACE()便于程序的调试

[cpp] view plaincopyprint?
  1. #define TRACE(var,fmt)   printf("TRACE: " #var " = " #fmt "\n",var) 

其中变量前的#用于和字符常量的连接。使用的一个实例。下面加入需要输出一个整型变量a

TRACE(a,%d);即可。


10、printf()的使用技巧>>如何让程序根据输出的结果自动实现输出的合理的宽度,而不是认为的做如下规定

printf("%5d",a);

下面这种用法可以达到预想的效果

printf("%*d",width,a);

原创粉丝点击