C语言笔记_me

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

预编译处理:

1.宏定义

形式:#define 标识符字符串

说明:

宏名一般用大写。

宏定义不作语法检查,只有在编译被宏展开后的源程序时才会报错。

宏定义不是C语句,不在行末加分号。

宏名有效范围为定义到本源文件结束。

可以用#undef命令终止定义的作用域。

在宏定义时,可以引用已定义的宏名

带参数的宏定义

形式:#define 宏名(参数表)字符串

2.文件包含处理

#include “文件1”

就是交文件1的全部内容复制插入到# include位置,作为一个源文件进行编译。

3.条件编译

条件编译:指不对整个程序都编译,而是编译满足条件的那部分。有以下几种形式:

①.# ifdef 标识符

程序段1

#else

程序段2

#endif

作用:当标识符在前面已经被定义过(一般用#define),则对程序段1编译,否则

对程序段2编译。

②.# if 标识符

程序段1

#else

程序段2

#endif

作用:和# ifdef相反,当标识符没被定义过时,才对程序段1编译。

③.# ifndef 表达式

程序段1

#else

程序段2

#endif

作用:当表达式值为真(非0)时,对程序段1编译,否则对程序段2编译。

条件编译的应用

全局变量应该是得到内存分配且可以被其他模块通过C语言中extern关键字调用的变量。因此,必须在.C 和.H 文件中定义。这种重复的定义很容易导致错误。

以下讨论只需用在一个头文件中定义一次,

1.首先,说明一个条件编译命令:

#ifdef 标识符

程序1

#else

程序2

#endif

先在一个头文件(.h)中输入条件编译命令。

那么,对C程序(.c)进行编译时,若程序包令:

#include标识符

或#include标识符0

即:只要有标识符出现,编译时就会加入程序1,一并进入编译。否则,加入程序2。

例:在uCOS_II.H 中包含:

#ifdef OS_GLOBALS

#define OS_EXT

#else

#define OS_EXT extern

#endif

OS_EXT INT32U OSIdleCtr;

OS_EXT INT32U OSIdleCtrRun;

OS_EXT INT32U OSIdleCtrMax;

同时,uCOS_II.C中包含:

#define OS_GLOBALS

(当然,所有.C应该都包含#include uCOS_II.H,这样才达到.C文件能访问全局

变量)

这样,当编译器处理uCOS_II.C时,它使得头文件变成如下所示,因为OS_EXT被设置为空。编译器就全局变量分配在内存,而当编译其他不含#define OS_GLOBALS的.C文件时,OS_EXT被设置为extern,表示该变量为外部定义的全局变量,不用再分配内存了。

其实,这样是将一个C文件的所有全局变量定义在一个头文件中,而所有C文件都包含这个头文件,这样防止重复定义一个全局变量而发生错误。

其实,条件编译命令还有一种形式:

#if 标识符

程序1

#else

程序2

#endif

这种方式有些不同,只有当标识符为真时,才执行程序1,否则执行程序2。

使用static定义的问题

一个static的变量,其实就是全局变量,只不过它是有作用域,它可用于保存变量所在函数被累次调用期间的中间状态,比如:

int nCount()

{

static int cout=0;

……

count++;

……

}

cout变量的值会跟随着函数的调用次而递增,函数退出后,cout的值还存在,只是cout 只能在函数中才能被访问(函数作用域)。而cout的内存也只会在函数第一次被调用时才会被分配和初始化,以后每次进入函数,都不为static分配了,而直接使用上一次的值。

注:如果在模块内(但在函数体外)声明一个静态变量,则模块内所有的函数都可访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

如果在模块内,用static声明一个函数,则这个函数只可被这一模块内的其它函数调用。也就是,这个函数被限制在声明它的模块的本地范围内使用。

数据类型

1.指针:

指针:地址。

指针变量:就是用来存放指针(地址)的变量。

变量的指针(变量的地址)和指向变量的指针变量(用来存放变量的地址的变量)

“指针”可以理解为“地址”,而“指向”可以理解为“存放**的地址”

例:

int a; //定义一个整型数

int *a; //定义一个指向整型数的指针

int **a; //定义一个指向指针的指针,它指向的指针是指向一个整型数

int a[10]; //定义一个有10个整型数的数组

int *a[10]; //定义一个有10个指针的数组,该指针指向一个整型数

int (*a)(int); //一个指向函数的指针,该函数有一个整型参数并返回一个整型数

int (*a[10])(int); //一个有10个指针的数组,该指针指向一个函数, 该函数有一个整型参数并返回一个整型

例:要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。

解:int *ptr;

ptr = (int*)0x67a9

*ptr = 0xaa55;

①.指向函数的指针变量

一个函数在编译时被分配一个入口地址,这个入口地址就称为函数的指针。

函数名代表函数的入口地址。

例:Int max(int x,int y);

函数的调用方法:

常用方法“

Int c;

c = max(a,b);

通过指针来调用:

Int (*p)(); //定义一个指向函数的指针变量

p=max; //函数的入口地址赋给函数指针变量p

c=(*p)(a,b);

返回指针值的函数:

定义形式:类型标识符*函数名(参数表)

例:int *a(x,y)//返回一个指向整型的指针

注:在调用时,要先定义一个适当的指针来接收函数的返回值。

注意:int *func(void)和int (*func)(void)的区别

int *func(void);//这是返回一个整型指针的函数

int (*func)(void); //这是一个函数指针

②.函数指针数组(应用)

例:在一计算器的中有如下一些语句:

Switch(oper){

Case ADD:

Result = add(op1,op2);break;

相关文档
最新文档