5C语言强化训练.docx
《5C语言强化训练.docx》由会员分享,可在线阅读,更多相关《5C语言强化训练.docx(9页珍藏版)》请在冰豆网上搜索。
5C语言强化训练
C语言强化训练
1:
预处理命令与声明。
与处理部分:
在c程序编译成机器码的过程中第一步叫做预处理。
程序设计中的预处理(Preprocess),程序设计领域,预处理是在程序源代码被编译之前,由预处理器(Preprocessor)对程序源代码进行的处理。
这个过程并不对程序的源代码进行解析,但它把源代码分割或处理成为特定的符号用来支持宏调用。
C语言的预处理主要有三个方面的内容:
1.宏定义;2.文件包含;3.条件编译。
其余还有一些较少用到的特殊指令。
预处理命令以符号“#”开头。
预处理指令大多属于以下三种类型之一:
宏定义:
#define定义宏,#undef删除宏。
文件包含:
#include指定文件被包含。
条件编译:
#if、#ifdef、#ifndef、#elif、#else和#endif
特殊指令:
#error、#line、#pragma等
宏
1:
不带参数的宏定义:
宏定义又称为宏代换、宏替换,简称“宏”。
格式:
#define宏名字符串
例如:
#definename509
2:
带参数的宏:
除了一般的字符串替换,还要做参数代换
格式:
#define宏名(参数表)字符串
例如:
#defineADD(a,b)(a+b)
文件包含
一个文件包含另一个文件的内容
格式:
#include"文件名" 或 #include<文件名>
头文件的内容除了函数原型和宏定义外,还可以有结构体定义,全局变量定义:
(1)一个#include命令指定一个头文件;
(2)文件1包含文件2,文件2用到文件3,则文件3的包含命令#include应放在文件1的头部第一行; (3)包含可以嵌套; (4)<文件名>称为标准方式,系统到头文件目录查找文件, "文件名"则先在当前目录查找,而后到头文件目录查找; (5)被包含文件中的静态全局变量不用在包含文件中声明。
条件编译
有些语句希望在条件满足时才编译。
格式:
(1)
#ifdef标识符
程序段1
#else
程序段2
#endif
或
#ifdef
程序段1
#endif
当标识符已经定义时,程序段1才参加编译。
格式:
(2)
#ifndef标识符
格式:
(3)
#if表达式1
程序段1
#else
程序段2
#endif
当表达式1成立时,编译程序段1,当不成立时,编译程序段2。
声明部分:
计算机编程中声明的含义当一个计算机程序需要调用内存空间的时候,对内存发出的“占位”指令,我们称之为“声明”。
声明一个变量只是将变量名标识符的有关信息告诉编译器,使编译器“认识”该标识符,但是声明并不一定引起内存的分配!
而定义一个变量意味着给变量分配内存空间,用于存放对应类型的数据,变量名就是对相应的内存单元的命名。
声明一般格式为
声明说明符声明符;
声明说明符包括以下几类相互组合而成。
储存类型:
auto、static、extern、static、extern、register
类型限定符:
const、volatile、restrict(c99中使用)
类型说明符:
void、char、short、int、long、float、double、签名、unsigned、结构或联合说明符、枚举说明符、typedef名称
2:
数组与指针
大家都认为,c语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上。
因此,说指针是c语言的灵魂,一点都不为过。
以stm32为列
cpu的寻址代表着指针的位置与用途。
指针在带操作系统程序中显得相当重要而且容易混淆,比如有有:
指针函数、函数指针、指针数组、数组指针等。
指针数组:
一个数组里存放的都是同一个类型的指针,通常我们把他叫做指针数组。
int*a[10];
它里边放了10个int*型变量,由于它是一个数组,已经在栈区分配了10个(int*)的空间。
(注意,一般32位单片机int的大小为32b)
数组指针:
一个指向一维或者多维数组的指针;
int(*b2)[20];
//二级指针;b2指向一个大小为20*sizeof(int)的int型数组
int(*b3)[30][20];
//三级指针――>指向三维数组的指针;
数组的数组名具备一些指针的用法,近似于指针,例如:
intchao[12][31];
//数组的嵌套定义,
chao是一个含有12个数组类型元素的数组,其中的每一个元素是一个int数组,chao的类型是int[12][31],其指向的类型是int[31],可以理解为chao是指向数组的指针。
数组与指针
在一般情况下数组其实与指针非常的相似,但不可以说数组等于指针。
一般来说,数组是地址长量、指针是地址变量。
举个列子
int*a;
a[0]=0x86;
和
inta[];
a[0]=0x86;
在作用上是相同的。
intfunction(char**a)
{…………}
与
intfunction(char*a[])
{…………}
在作用上是相同的。
一个数组在建立之后会给数组分配一个首地址,在一定范围呢进行初始化,未初始化的内存被清“零”(\0)。
而数据a指针依然代表指针。
但是两种数据的类型依然是有区别的,比如:
在a.c中有一条
#include"a.h"
inta[8]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
那么如果我们在a.h中
#ifdef__A_H_
#define__A_H_
externinta[8];
#endif
是正确的,
但是
#ifdef__A_H_
#define__A_H_
externint*a;
#endif
就是错误的。
3:
结构、联合和枚举
在C中,结构也是一种数据类型,可以使用结构变量,因此,象其它类型的变量一样,在使用结构变量时要先对其定义。
定义结构变量的一般格式为:
struct结构名{类型变量名;类型变量名;...}结构变量;
结构名是结构的标识符不是变量名。
类型为第二节中所讲述的五种数据类型(整型、浮点型、字符型、指针型和无值型)。
构成结构的每一个类型变量称为结构成员,它象数组的元素一样,但数组中元素是以下标来访问的,而结构是按变量名字来访问成员的。
下面举一个例子来说明怎样定义结构变量。
structstring{charname[8];intage;charsex[2];chardepart[20];floatwage1,wage2,wage3,wage4,wage5;}person;
这个例子定义了一个结构名为string的结构变量person,如果省略变量名person,则变成对结构的说明。
用已说明的结构名也可定义结构变量。
这样定义时上例变成:
structstring{charname[8];intage;charsex[2];chardepart[20];floatwage1,wage2,wage3,wage4,wage5;};
structstringperson;
如果需要定义多个具有相同形式的结构变量时用这种方法比较方便,它先作结构说明,再用结构名来定义变量。
例如:
structstringTianyr,Liuqi,...;
如果省略结构名,则称之为无名结构,这种情况常常出现在函数内部,用这种结构时前面的例子变成:
struct{charname[8];intage;charsex[2];chardepart[20];floatwage1,wage2,wage3,wage4,wage5;}Tianyr,Liuqi;
结构是一个新的数据类型,因此结构变量也可以象其它类型的变量一样赋值、运算,不同的是结构变量以成员作为基本变量。
结构成员的表示方式为:
结构变量.成员名如果将"结构变量.成员名"看成一个整体,则这个整体的数据类型与结构中该成员的数据类型相同,这样就可象前面所讲的变量那样使用。
结构是一种新的数据类型,同样可以有结构数组和结构指针。
结构是一种新的数据类型同样可以有结构数组和结构指针。
1、结构数组结构数组就是具有相同结构类型的变量集合。
2、、结构指针结构指针是指向结构的指针。
它由一个加在结构变量名前的"*"操作符来定义,例如用前面已说明的结构定义一个结构指针如下:
structstring{charname[8];charsex[2];intage;charaddr[40];}*student;
也可省略结构指针名只作结构说明,然后再用下面的语句定义结构指针。
structstring*student;使用结构指针对结构成员的访问,与结构变量对结构成员的访问在表达方式上有所不同。
结构指针对结构成员的访问表示为:
结构指针名->结构成员其中"->"是两个符号"-"和">"的组合,好象一个箭头指向结构成员。
例如要给上面定义的结构中name和age赋值,可以用下面语句:
strcpy(student->name,"LuG.C");student->age=18;
实际上,student->name就是(*student).name的缩写形式。
注意:
1.结构作为一种数据类型,因此定义的结构变量或结构指针变量同样有局部变量和全程变量,视定义的位置而定。
2.结构变量名不是指向该结构的地址,这与数组名的含义不同,因此若需要求结构中第一个成员的首地址应该是&[结构变量名]。
3.结构的复杂形式一、嵌套结构嵌套结构是指在一个结构成员中可以包括其它一个结构,C允许这种嵌套。
联合也是一种新的数据类型它是一种特殊形式的变量。
联合说明和联合变量定义与结构十分相似。
其形式为:
union联合名{数据类型成员名;数据类型成员名;...}联合变量名;
联合表示几个变量公用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。
下例表示说明一个联合
a_bc:
uniona_bc{inti;charmm;};
再用已说明的联合可定义联合变量。
例如用上面说明的联合定义一个名为lgc的联合变量,可写成:
uniona_bclgc;
在联合变量lgc中,整型量i和字符mm公用同一内存位置。
当一个联合被说明时,编译程序自动地产生一个变量,其长度为联合中最大的变量长度。
联合访问其成员的方法与结构相同。
同样联合变量也可以定义成数组或指针,但定义为指针时,也要用"->"符号,此时联合访问成员可表示成:
联合名->成员名另外,联合既可以出现在结构内,它的成员也可以是结构。
例如:
struct{intage;char*addr;union{inti;char*ch;}x;}y[10];
若要访问结构变量y[1]中联合x的成员i,可以写成:
y[1].x.i;若要访问结构变量y[2]中联合x的字符串指针ch的第一个字符可写成:
*y[2].x.ch;若写成"y[2].x.*ch;"是错误的。
结构和联合有下列区别:
结构和联合有下列区别
1.结构和联合都是由多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了一个被选中的成员,而结构的所有成员都存在。
2.对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结构的不同成员赋值是互不影响的。