形式:#define 标识符字符串。
说明:宏名一般用大写。
宏定义不作语法检查,只有在编译被宏展开后的源程序时才会报错。
宏定义不是c语句,不在行末加分号。
宏名有效范围为定义到本源文件结束。
可以用#undef命令终止定义的作用域。
在宏定义时,可以引用已定义的宏名。
带参数的宏定义。
形式:#define 宏名(参数表) 字符串。
#include “文件1”
就是交文件1的全部内容复制插入到# include位置,作为一个源文件进行编译。
条件编译:指不对整个程序都编译,而是编译满足条件的那部分。有以下几种形式:
# 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_ 中包含:
#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_ 中包含:
#define os_globals
当然, 所有。c应该都包含#include ucos_这样才达到。c文件能访问全局变量 )
这样,当编译器处理ucos_时,它使得头文件变成如下所示,因为os_ext被设置为空。编译器就全局变量分配在内存,而当编译其他不含#define os_globals的。c文件时,os_ext被设置为extern,表示该变量为外部定义的全局变量,不用再分配内存了。
其实,这样是将一个c文件的所有全局变量定义在一个头文件中,而所有c文件都包含这个头文件,这样防止重复定义一个全局变量而发生错误。
其实,条件编译命令还有一种形式:
#if 标识符。
程序1#else
程序2#endif
这种方式有些不同,只有当标识符为真时,才执行程序1,否则执行程序2。
一个static的变量,其实就是全局变量,只不过它是有作用域,它可用于保存变量所在函数被累次调用期间的中间状态,比如:
int ncount()
static int cout=0;
count++;
cout变量的值会跟随着函数的调用次而递增,函数退出后,cout的值还存在,只是cout只能在函数中才能被访问(函数作用域)。而cout的内存也只会在函数第一次被调用时才会被分配和初始化,以后每次进入函数,都不为static分配了,而直接使用上一次的值。
注:如果在模块内(但在函数体外)声明一个静态变量,则模块内所有的函数都可访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
如果在模块内,用static声明一个函数,则这个函数只可被这一模块内的其它函数调用。也就是,这个函数被限制在声明它的模块的本地范围内使用。
指针:地址。
指针变量:就是用来存放指针(地址)的变量。
变量的指针(变量的地址)和指向变量的指针变量(用来存放变量的地址的变量)
“指针”可以理解为“地址”,而“指向”可以理解为“存放**的地址”
例: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)
对于一个复杂的计算器,switch语句将非常长。我们可用函数指针数组来完成。
double add(double,doble);
double sub(double,doble);
double(*oper_func)double, double)=;
这样,用一条语句就可替换前面整条switch语句:
result= oper_func[oper](op1,op2);
指针数组多用于存放若干个字符串的首地址。
例:static char *name=
注:不要写成:char (*name)这是指向一维数组的指针变量。
即定义一个不指向任何数据类型的指针变量,等用到的时候再强制转换类型。
例1:char *p1;
void *p2;
p1=(char *)p2;
例2:void *fun(ch1,ch2表示函数返回一个地址,指向空类型。
p1 = char *)fun(c1,c2); 强制转换为char型。
const常量无法在数组定义时作为数组长度。
例:静态存储:指在程序运行期间给变量分配固定的存储空间。
动态存储:指程序运行期间根据需要动态的经变量分配存储空间。
c规定,只有在定义全局变量和局部静态变量时才能对数组赋初值。
对数组初始化要用static
例:char str[14];
str = i love c!”;
这是错误的,对字符数组只能对各个元素赋值。
c允许交局部变量值放在寄存器中,这种变量叫register变量,要用register说明。但只有局部动态变量和形式参数可以作为register变量,其它不行。
局部变量也可以定义为static,即静态局部变量,这时它在函数内的值是不变的。
全局变量在函数外部定义,可以在程序中各个函数所引用。
多个文件的全局变量问题:
在一个文件定义的全局变量,若另一文件要用到该变量,则在此文件中用extern对该全局变量说明即可。
但若这个全局变量定义时用static的话,则此全局变量只能在本文件中引用,而不能被其它文件引用。若用static定义的变量,再在其它文件中用extern定义,将会发生链接错误。
c语言编译器会对用户书写的**进行优化,譬如如下**:
int a,b,c;
a = inword(0x100); 读取i/o空间0x100端口的内容存入a变量*/
b = a;
a = inword (0x100); 再次读取i/o空间0x100端口的内容存入a变量*/
c = a;
很可能被编译器优化为:
int a,b,c;
a = inword(0x100); 读取i/o空间0x100端口的内容存入a变量*/
b = a;
c = a;
在变量a的定义前加上volatile关键字可以防止编译器的类似优化,正确的做法是:
volatile int a;
volatile变量可能用于如下几种情况:
(1) 并行设备的硬件寄存器(如:状态寄存器,例中的**属于此类);
(2) 一个中断服务子程序中会访问到的非自动变量(也就是全局变量);
(3) 多线程应用中被几个任务共享的变量。
1. 不要对临时变量作取地址操作,因为你不知道编译器是否将这个变量映射到了寄存器。
2. 不要返回临时变量的地址,或临时指针变量,因为堆栈中的内容是不确定的(出了这个函数,存放在堆栈中的局部变量就没有意义了!)
3. 不要在申请大的临时变量数组,你的临时变量是在堆栈中实现的,太大的临时变量数组会冲掉堆栈。
枚举是一种用于定义一组命名常量的机制,以这种方式定义的常量一般称为枚举常量。
C语言笔记
第一课时。c语言标准格式。include vidomain 以 开头的语句称为预处理指令。include语句不是必须的,但是如果一旦有该语句就必须把它放在文件开始处是standared input output header的缩写standared 标准input 输入output 输出header...
C语言笔记
c语言算法和数据类型。整型。基本类型 字符型注释 基本类型的特点是其不可实型 单精度型以再分解为其他类型双精度型数组型。数据结构 构造型 结构体型共用体型指针型空类型。一 常量。define 语句不以分号结尾,它可以放在源 的任何位置。不过在定义常量时,只有在它定义后的源 中才有效。是一个修饰符,在...
c语言笔记
1.if中别忘了 而不是 2.写完程序别忘了检查前后大括号 小括号是否完全照应。3.遇到几分之几的分数可以方程两边同时乘以一个数来消去分母。4.写指针题时看准指针对应的是行还是列。例 int a 4 3 int p a 0 列指针。int ptr 3 a 行指针。5.考虑好哪些量会随着循环不断改变。...