找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3384|回复: 0

[原]C语言使用注意事项(一)

[复制链接]
发表于 2012-2-4 21:34:16 | 显示全部楼层 |阅读模式
原创作品,转载请表明
1、getchar()函数的使用方法
getchar()返回值为int型,如下使用方法不正确#include <stdio.h>
  1. int main()
  2. {
  3.         
  4.         char tmp;
  5.         while( (tmp=getchar())!=EOF )
  6.         {
  7.                 printf("%c",tmp);
  8.         }
  9.         return 0;
  10. }
复制代码
当EOF的宏定义超出char型数据所表示的范围时,这样就会出错,这种错误很难预料。
char的取值范围究竟是[-128,127]还是[0-255]取决于编译器。GCC编译器中的char表示signed char。
所以应该将tmp的类型改成int 型,防止出现错误。
2、全局变量的使用方法
cfaq.h#ifndef _CAFQ_H
  1. #define _CAFQ_H
  2. //DEFINE(int, ex);
  3. extern int ex;
  4. void print();
  5. #endif
复制代码
cfaq.c#include "cfaq.h"
  1. int ex;
  2. void print()
  3. {
  4.         printf("%d\n",ex);
  5. }
复制代码
main.c#include <stdio.h>
  1. #include "cfaq.h"
  2. int ex=3;
  3. int main(int argc,int **argv)
  4. {
  5.         print();
  6.         return 0;
  7. }
复制代码
3、extern关键字使用
声明变量extern修饰的表示全局变量
而修饰函数时有无extern修饰无实质差别
4、使用typedef声明复杂的声明
下面首先使用typedef声明大小为N的指向字符的指针的函数的指针的数组
typedef char *pc;//定义一个字符指针
typedef pc fpc();//定义一个返回字符指针的函数
typedef fpc *pfpc;//定义一个指向fpc()函数的函数指针
typedef pfpc fpfpc();//返回上述函数指针的函数
typedef fpfpc *pfpfpc;//上述函数的指针
pfpfpc a[N];//定义一个上面函数指针的数组
相当于下面一句话
char *(*(a[N])())();
5、main()函数的正确定义
main()函数必须声明为int main()或int main(void)或int main(int argc,int **argv)
不能定义为void main(){ }以消除无返回值警告,但是它可能导致与调用者期待的返回顺序不能的返回顺序
6、char a[]="String"和char *a="String"初始化字符串的区别
第一种方法初始化之后可以修改a的值,第二种无法修改a的值,当修改时出现错误。
7、C中参数传递的方式
C中确实没有按引用传递的参数传递方式。
严格地讲, C 总是按值传递。你可以自己模拟按引用传递, 定义接受指针的函数, 然后在调用时使用 & 操作符。事实上, 当你向函数传入数组 (传入指针的情况参见问题 6.4 及其它) 时, 编译器本质上就是在模拟按引用传递。但是 C 没有任何真正等同于正式的按引用传递或 C++ 的引用参数的东西。另一方面, 类似函数的预处理宏可以提供一种“按名称传递”的形式。
8、有关i++的定义
int i=3;
printf("%d",(i++)*(i++));我的编译器输出结果是9,而不是12。原因尽管后缀自加和后缀自减操作符 ++ 和 -- 在输出其旧值之后才会执行运算,但这里的“之后”常常被误解。没有任何保证确保自增或自减会在输出变量原值之后和对表达式的其它部分进行计算之前立即进行。也不能保证变量的更新会在表达式 “完成” (按照 ANSI C 的术语, 在下一个 “序列点” 之前, 参见问题 3.7) 之前的某个时刻进行。本例中, 编译器选择使用变量的旧值相乘以后再对二者进行自增运算。
9、*p++的含义是自增指针p,还是自增p的内容
*p++和*(p++)等价,++和--比前缀的一目操作运算符优先级高,它的含义是自增p并返回p增加前地址的内容。所以如果自己比较混淆,干脆使用括号消除自己的歧义。
10、左值与右值
顾名思义,左值就是只能出现在=号的左边,可以被赋值;右值是只能出现在=号的右端,不能被赋值也不能自增;
例如下面一个char *的指针恰好指向一个int型数据,要想对其做自增运算。
那么下面的代码正确吗?
((int *)p)++
答案是否定的,由于(int *)p是经过类型转换得到的,由于类型转换就是将部分二进位看作其他类型,并做相应的对待。数据类型转换所产生的是一个右值(R-value),故不能对其进行修改和自增操作。
作者:yming0221 发表于2012-2-4 17:17:59 原文链接


您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-1 03:23 , Processed in 0.017048 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表