C语言笔记me

发布 2021-05-12 01:14:28 阅读 6472

形式:#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.考虑好哪些量会随着循环不断改变。...