单片机C语言笔记
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数组是同类型的一组变量,引用这些变量时可用同一个标志符,借助于下标来区分各个变量。
数组中的每一个变量称为数组元素。
数组由连续的存储区域组成,最低地址对应于数组的第一个元素,最高地址对应于最后一个元素。
数组可以是一维的,也可以是多维的。
数组的定义和引用
一维数组的表达形式如下:
类型说明符数组名[常量];
方括号中的常量称为下标。
C语言中,下标是从0开始的。
示例如下:
Int a[10]; //定义整型数组a,它有a[0]~a[9]共10个元素,每个元素都是整型变量
一维数组的赋值方法有以下几种:
1:在数组定义时赋值:int a[10]={0,1,2,3,4,5,6,7,8,9};
2:也可以部分赋值:int b[10]={0,1,2,3,4,5};//对于没有赋值的b[6]~b[9],默认的初始值为0 3:如果一个数组的全部元素都已赋值,可以省去方括号中的下标
Int a[]={0,1,2,3,4,5,6,7,8,9};
数组元素的赋值与普通变量相同,可以把数组元素像普通变量一样使用。
二维数组一般表达形式如下:
类型说明符数组名[下标1][下标2];
unsigned char x[3][4];//定义无符号字符型二维数组x,有3×4=12个元素
二维数组以行列矩阵的形式存储。
第一个下标代表行,第二个下标代表列。
上一数组中各数组元素的顺序排列如下:
x[0][0].X[0][1]. X[0][2]. X[0][3]
x[1][0]. X[1][1]. X[1][2]. X[1][3]
x[2][0]. X[2][1]. X2[][2]. X[2][3]
二维数组的赋值方法:
1:按存储顺序整体赋值
Int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
如果是全部元素赋值,可以不指定行数,写成如下形式:
Int a[][4]={0,1,2,3,4,5,6,7,8,9,10,1};
2:按每行分别赋值
Int a[3][4]={{0,1,2,3},
{4,5,6,7},
{8,9,10,11}};
字符数组:用来存放字符型数据的数组。
与整型数组一样,字符数组也可以在定义时进行初始化赋值。
char a[8]={‘B’,’e’,’i’,’-’,’J’,’i’,’n’,’g’};
还可以用字符串的形式来对全体字符数组元素进行赋值:
char str[]={“Now,Temperature is:”};
或者写成更简洁的形式:
char str[]=”Now,Temperature is:”;
注意:字符串是以’\0’作为结束标志的,所以当我们把一个字符串存入数组时,也把结束标志’\0’存入了数组。
因此,上面定义的字符数组“str[]”最后一个元素不是“:”,而是’\0’.
必须先定义数组,然后才能使用。
C语言中只能逐个引用数组。
一个数据的指针就是它的地址。
通过变量的地址能找到该变量在内存中的存储单元,从而能得到它的值。
指针是一种特殊类型的变量。
它具有一般变量的三要素:名字·类型和值。
指针的命名与一般变量相同,它与一般变量的区别在于类型和值。
指针存放的是某个变量在内存中的地址值。
被定义过的变量都有一个内存地址。
如果一个指针存放了某个变量的地址值,就称这个指针指向该变量。
由此可见,指针本身具有一个内存地址,另外,它还存放了它所指向变量的地址值。
指针的类型就是该指针所指向变量的类型。
例如,一个指针指向int型变量,该指针就是int 型指针。
指针变量不同于整型或字符型等其它类型的数据,使用前必须将其定义为“指针类型”
类型说明符*指针名字
int i; //定义了一个整型变量
int *pointer; //定义整型指针,名字为pointer
可以用取地址运算符“&”使一个指针变量指向一个变量
Pointer=&i; //”&i”表示取i的地址,将i的地址存放在指针变量pointer中
在定义指针时要注意两点:
1:指针名字前的“*”表示该变量为指针变量
2:一个指针变量只能指向同一个类型的变量。
在引用指针变量前,必须使它指向一个确定的变量。
在一个指针变量中只能存放同一类型变量的地址。
例如,不能将一个整型变量的地址赋给一个字符型指针变量;否则,可能导致不可预见的严重错误。
C语言中有两个与指针有关的运算符:
&:取地址运算符,其作用是取得某变量的地址
*:指针运算符,其作用是取得指针所指某变量的值
例如,&x代表变量x的地址,*p是指针变量p所指向变量的值
可以用赋值语句使指针变量指向一个变量
int a,b;
int *p1,*p2;
P1=&a;
P2=&b;
再如:
unsigned char *p;
unsigned char m;
m=0xf9;
P=&m;
P3=*p;
指针在使用之前必须经定义说明和初始化
类型说明符指针变量=初始地址值
unsigned char *p;
unsigned char m;
P=&m; //将m的地址存在p中(指针变量p有了确定指向,即被初始化了)
未经初始化的指针变量严禁使用,否则,将引起严重后果
指针数组:以指针变量为元素的数组。
这些指针变量应具有相同的存储类型,并且指向的数据类型也必须相同。
指针数组定义的一般格式如下:
类型说明符*指针数组名[元素个数];
int *p[2];
指针数组的初始化可以在定义时同时进行
unsigned char a[]={0,1,2.3};
unsigned char *p[4]=={&a[0],&a[1],&a[2],&a[3]}; //存放的元素必须为地址
如果一个指针存放了某数组的第一个元素的地址,就说该指针是指向这一数组的指针。
数组的指针即数组的起始地址。
unsigned char a[]={0,1,2,3};
unsigned char *p;
p=&a[0]; //将数组a的首地址存放在指针变量p中
经上述定义后,指针p就是数组a的指针。
C语言规定,数组名代表数组的首地址,也就是第一个元素的地址。
例如下面两个语句等价P=&a[0];
P=a;
P指向数组a的首地址后,p+1就指向数组的第二个元素a[1],p+2指向a[2],……p+i指向a[i]。
引用数组元素可以用下标(如a[3]),但使用指针速度更快且占用内存少,这正是使用指针的优点和c语言的精华所在。
如果指针p指向二维数组的首地址(可以用a表示,也可以用&a[0][0]表示),那么p[i]+j指向的元素就是a[i][j]。
这里i,j分别表示二维数组的第i行和第j列。
例如,p[1]+2指向的元素是a[1][2];
C语言的函数
一个c语言程序可由一个主函数main()和若干个其它函数构成。
由主函数调用其它函数,其它函数也可以互相调用,但其它函数不能调用主函数。
函数的定义
从函数的形式看,函数可分为无参数函数和有参数函数。
无参数函数在被调用时没有参数传递,有参数函数在被调用时有参数传递。
无参数函数定义的一般形式如下:
类型说明符函数名(void)//用void声明该函数无参数
{
说明部分
语句部分
}
类型说明符定义了函数返回值的类型。
例如,要让函数返回一个无符号字符型数据时,需要用unsigned char来作为类型说明符;如果函数没有返回值,需要用void作为说明符。
如果没有类型说明符出现,函数返回值默认是整型值。
例如延时函数的定义:void delay(void) //第一个void声明还是无返回值
{
unsigned int n; //函数体的说明部分
for(n=0;n<200;n++) //语句部分
;//语句部分
}
有参数函数调用的一般形式如下:
类型说明符函数名(形式参数列表)//注:形式参数超过一个时,用逗号隔开
{
声明部分
语句部分
}
该类函数在被调用时,主调函数将实际参数传递给这些形式参数。
;例如://函数功能:计算x和y的最小值
int min(int x,int y) //定义整型函数,x和y为形式参数
{
int z; //函数体的声明部分
z=x<y?x:y; //语句部分
return(z); //语句部分,如果要返回一个数值给主函数,需要用关键字return }
//函数功能:主函数
void main(void)
{
int R;
R=min(2008,3008); //调用函数min(),获得返回值,‘2008,3008’为实际参数}
关于返回值要注意:
1 返回值是通过return语句获得的。
2 返回值的类型必须和函数定义的类型一致。
3 如果函数无返回值,需要用void声明无返回值。
在函数内部定义的变量称为局部变量。
局部变量只在该函数内有效。
例如,一个函数定义了变量x为整型数据,另一个函数则把变量x定义为字符型数据,两者之间互不影响。
全局变量又称为外部变量,它定义在函数体的外部,最好是在程序的顶部。
它的有效范围从定义开始的位置到源文件结束。
全局变量可以被函数内的任何表达式访问。
如果全局变量和某一函数的局部变量同名时,在该函数内,只有局部变量被引用,全局变量被自动屏蔽。
函数的参数不仅可以是数据,也可以是指针类型,它的作用是将一个变量的地址传送到另一个函数中。
例如:
//函数功能:计算两个整数的和
int sun(*p1,*p2) //定义整型函数sum(),其形式参数为两个整型指针p1,p2
{
int z; //定义整型变量z
z=*p1+*p2; //用指针运算符*取得两个指针所指变量的值,求和后存入z
return(z); //返回计算结果给主函数
}
//函数功能:主函数
void main(void)
{
int u,v,w; //定义整型变量
int *pointer_1,*pointer_2; //定义两个整型指针
u=12345;
v=67890;
pointer_1=&u; //将pointer_1指向变量u
pointer_2=&v; //将pointer_2指向变量v
z=sum(pointer_1,pointer_2); //将两个指针pointer_1,pointer_2作实参传递}
除了可以用变量作为函数的参数之外,还可以用数组名作为函数的参数,一个数组的名字表示该数组的首地址,所以用数组名作为函数的参数时,被传
递的就是数组的首地址,所以被调用函数的形式参数必须定义为指针型变量。
用数组名作为函数的参数时,应该在主调函数和被调函数中分别进行定义,而不能只在一方定义数组,并且两个函数中定义的数组类型必须一致。
如果不一致,将导致编译出错。
实参数组和形参数组的长度可以一致,也可以不一致。
编译器不检查形参数组的长度,只是将实参数组的首地址传递给形参数组。
为保证两者长度一致,最好在定义形参数组时不指定长度,只在数组名后面跟一个空的[]。
编译时,系统会根据实参数组的长度为形参数组自动分配长度。
示例如下:
//函数功能:计算十个整数的总和
int sum(int a[]) //定义整型函数,其形参为整型数组的首地址
{
int total;
unsigned char i;
total=0;
for(i=0;i<10;i++)
{
total=total+a[i];
}
return(total); //返回计算结果
}
//函数功能:主函数
void main(void)
{
int x;
int b[10]={1,2,3,4,5,6,7,8,9,10};//定义整型数组b
x=sum(b); //将整型数组b的名字作为实际参数传递给函数sum }
函数型指针
在c语言中,指针变量除能指向数据对象外,也可以指向函数。
一个函数在编译时,分配了一个入口地址,这个入口地址就称为函数的指针。
可以用一个指针变量指向函数的入口地址,然后通过该指针变量调用此函数。
定义指向函数的指针变量的一般形式如下:
数据类型说明符(*指针变量名)(形参列表)
函数的调用可以通过函数名调用,也可以通过函数指针来调用。
要通过函数指针来调用函数,只要把函数的名字赋给该指针就可以了。
//函数功能:求两个整型数中的最大值
int max(int x,int y) //定义整型函数,其形参为两个整型数x,y
{
int z;
z=x<y?x:y;
return(z); //返回计算结果给主函数
}
//主函数
void main(void)
{
int (*p)(int a,int b);//定义指向函数型指针变量p,形参为a,b
int u,v,w;
u=1234;
v=5678;
p=max; //把被调用函数的名字(地址)赋给指针变量p,即p指向被调用函数
w=(*p)(u,v); //通过函数型指针调用函数maxL(),并把返回值存入w }。