C语言编程需注意的方面

1437阅读 0评论2011-04-28 lcmust
分类:C/C++

《转自http://blog.chinaunix.net/space.php?uid=22534388&do=blog&id=184259

C语言编程需注意的方面
(2011-03-22 21:06)

一、书写风格
   良好的编程风格是提高程序可靠性非常重要的手段,也是大型项目多人合作开发的技术基础。具体的变成格式每家公司都有规范,但作为一个初学者养成良好的编程风格还是有必要的。
   1、空行的使用
   空行起着分隔程序段落的作用。空行得体(不过多也不过少)将使程序的布局更加清晰。空行不会浪费内存,所以不要舍不得用空行。但空行也不宜太多,一般情况是这样的:
   a、预处理语句后要加空行;
   b、变量声明或函数声明之后加空行;
   c、变量的声明与定义之间尽量加空行;
   d、一个功能段结束之后加空行,如:if、while等语句完毕以后加空行;
   e、程序返回return前加空行。
   2、修饰符的使用
   修饰符 * 和 & 应该靠近数据类型还是该靠近变量名,要靠个人的习惯,本人是将修饰符* 靠近变量定义的,因为靠近数据类型,例如:int*  x; 从语义上讲此写法比较直观,即x是int 类型的指针。但这很容易引起误解,例如:int*  x, y; 此处y容易被误解为指针变量。不益于程序的阅读。
   3、空格和括号的使用也要注意,尽量让程序清晰易读。
   4、程序的注释是不可少的。 
 
二、变量
   1、变量定义的次序
   最好把同类型的定义在一起,最好把长度小的定义在前面,这样可以优化存储器布局,有可能节约空间,特别是在嵌入式系统存储器比较紧张的情况下更是如此。
   2、变量的声明、定义和初始化
   变量声明时赋值可以使程序简洁,很多情况下推荐使用,但有时会给程序带来麻烦,特别是在多文件模块的程序中,所以全局变量尽量先声明后赋值(全局变量只能赋初值一次)。  
   3、变量类型转换
   整型与字符型的转换。
   #include
   int  main()
   {
        char a='2';
 
        printf("%c\n", a);
        printf("%d\n", a);
        printf("%d\n", (int)a);
   }
   大家可以试试输出什么,所以不要想当然。
   另外浮点型和整型的转换也要注意
   4、const修饰变量情况:
     const char *p;  //指向常量的指针,内容不可变,但指针可以变。
     char * const p; //指针为常量,不可变,但内容可以变。
 
三、运算符及表达式
   变量的值和表达式的值
   i++和++i的区别:
   i++是运算之后再加1;
   ++i是加1后再运算;
   例(注意区别):
int  main()
{
  int i = 1;
  printf("%d\n", i++); //打印出来的为表达式(i++)的值 1;
}
int  main()
{
  int i = 1;
  printf("%d\n",++i); //打印出来的为表达式(++i)的值 2;
}
int  main()
{
  int i = 1;
  i++;
  printf("%d\n",i); //打印出来的为变量i的值 2;
}
int  main()
{
  int i = 1;
  ++i;
  printf("%d\n",i); //打印出来的为变量i的值 2;
}
 
四、循环
   1、循环的退出
   循环的正常退出有四种方式:break、continue、exit、return,注意他们的区别:
   break:完全退出循环;
   continue:退出本次循环,继续下次循环;
   exit:退出整个程序;
   return:在子函数中,退出函数体,在main函数中退出整个程序。
   2、循环的使用
   a、嵌套循环中尽量将循环次数少的循环作为外循环,这样可以减少CPU跨切循环层的次数。
   b、我们通常写循环都是这样的for(i=0; i
   3、无限循环
   while(1)
   {
   }
   要比
   for(;;)
   {
   }
   好一些。通常用while循环。
 
五、比较语句
   比较语句中,千万要留意无论是float还是double类型的变量都有精度限制所以一定要避免将浮点变量用==或!=与数字比较应该设法转化成>=或<=形式。
  动手试着写出与零比较的if语句。
 
六、函数
  
函数接口的两个要素是参数和返回值,编程过程中经常出现函数功能实现没问题,但就是不能得到正确的值。
  1、函数的声明
  void SetValue(int width, int height); //我们经常使用的格式
  void SetValue(int, int);         //不良的风格,但经常看到
  float GetValue(void);          //良好的风格
  float GetValue();   //不良的风格,我们经常使用
  2、函数的返回值
  C语言中,凡不加类型说明的函数,一律自动按整型处理。经常会被误解为void类型。
  有的函数不需要返回值,但为了增加灵活性如支持链式表达,可以附加返回值。
  函数调用结果的返回可以通过三种方式实现:全局变量,return,指针参数。
  3、函数的功能要单一,不要设计多用途的函数。
  4、注意函数的形参和实参有各自的存储单元。
 
七、指针和数组
  C程序中,指针和数组在不少地方可以相互替换着用,让人产生一种错觉,以为两者是等价的。数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。 数组名对应着(而不是指向)一块内存,其地址与容量在程序运行的过程中保持不变,只有数组的内容可以改变。指针可以随时指向任意类型的内存块,它的特征是 “可变”,所以我们常用指针来操作动态内存。
  易出错的地方:
1、
  int * p;
  int q[10];  //声明指针和数组
  
  ++p;       //正确
  ++q;       //错误
  数组名只对应一块内存,不可改变,内容可变;
  指针指向一块内存,可改变。
2、
   free(p);  //释放后p并不等与NULL,只是将其指向的内容free掉了,如果在进行操作会带来不可预料的错误,常用的办法是在此句后面将p=NULL。
3、
  像void fun(char str[10]){};这样以数组作为参数时一定要注意:
  数组的长度是传不过来的这样 void fun(char str[10], int 10){};用一个整型数单独传数组的长度。
  在函数中使用sizeof(str) //=4,因为在参数传递时传的是数组的地址(指针),不在是数组名了。
4、
  int i, *j;
  scanf("%d", &i); //正确
  scanf("%d", j);  //错误,因为指针j为空指针,没有申请空间。
5、
  char str[6] = "hello";
  strlen(str)  //=5,不包括'\0'。
  sizeof(str)  //=6,注意区分。
6、
  char p[] = "hello"; //存在栈空间,函数结束就释放了。
  char *p = "hello";  //为字符串常量,存在于静态存储区。所以试图改变*p的操作都会失败。
7、    
  应当将指针变量用==或!=与NULL比较

《转自http://blog.chinaunix.net/space.php?uid=22534388&do=blog&id=184259
上一篇:没有了
下一篇:Linux系统下emacs基本操作(20130707-1700更新)