作者 张小波
float a[10]; ???。。
} 是非法的!
(7)允许在同一个类型说明中,说明多个数组和多个变量; 例如: int a,b,c,d[10],e[5]; 2、一维数组元素的初始化
有下列方法初始化:
1)在定义数组时,对数组元素赋初值;
例如: int a[10]={0,1,2,3,4,5,6,7,8,9}; 上面的语句等价于 a[0]=0,a[1]=1,
2)可以只给一部分元素赋初值,例如:int a[10]={0,1,2,3,4};
表示只给数组的前5个元素赋初值,后5 个元素的值,系统自动默认为0 3)在对全部数组元素赋初值时,可以不指定数组长度;例如:int a[5]={0,1,2,3,4};可以改写为: int a[]={0,1,2,3,4};但是,int a[10] ={0,1,2,3,4}; 不能改写为: int a[]={0,1,2,3,4}; 3、一维数组的引用
数组必须先定义,后使用。C语言规定: 只能逐个引用数组元素,而不能一次引用整个数组!
数组的引用形式为: 数组名[下标] 其中,下标可以是整型常量也可以是整型表达式。例如: a[0]=a[5]+a[7]+a[2*3] 4、一维数组的程序举例
(1)读10个数存入数组中,输出数组中的所有数据。 main() {
int i,a[10];
for(i=0;i<=9;i++)
a[i]=i; /*顺序给数组元素赋初*/ for(i=0;i<=9;i++)
printf(“%d”,a[i]); /*顺序输出数组元素*/} (2)读10个整数存入数组中,输出平均值。 #include
int x[size],i; float s=0,ave;
for(i=0;i printf(“%d\\n”,ave);} 二、二维数组 1、二维数组的定义 作者 张小波 定义格式:类型说明符 数组名[常量表达式1][常量表达式2] 其中表达式1表示第一维下标的长度;表达式2表示第二维下标的长度; 例如:int a[2][3];说明了一个2行3列的数组,数组名为a,数组元素的类型为整型,该数组共有2*3个元素;即: a[0][0],a[0][1],a[0][2],a[1][0],a[1][1],a[1][2] 注意的是:二维数组在概念上是二维的,就是说其下标在两个方向上变化,数组元素在数组中的位置也处于一个平面中,并不向一维数组,所有的元素是线性的,但是,二维数组中的元素和一维数组中的元素一样,也是按线性存储的; 如何存储呢? 首先,它和一维数组一样,也是按线性存储的。在C语言中,二维数组是按行排列的,即存完一行后,顺序存入第二行;还是上面那个例子: int a[2][3];由于数组a说明为int型,所以数组的每个元素在内存中占两个字节的存储空间, 2、二维数组的引用 引用形式:数组名[下标][下标] 其中下标应该为整型常量或整型表达式; 例如:int a[3][4];a[2][3] 表示数组a的第三行第四列的元素。 注意:下标变量和数组说明在形式上有些相似,但这两者具有完全不同的含义;数组说明的方括号中给出的是某一维的长度;而数组元素中的下标是该元素在数组中的位置标识;数组说明中的方括号内只能是常量。而数组元素中方括号中的下标可以是常量,变量或表达式。 3、二维数组的初始化 二维数组初始化也是在类型说明时给各下标变量赋以初值。二维数组可以按行分段赋值,也可以按行连续赋值 1)按行分段赋值 int a[2][3]={{1,2,3}, {4,5,6}}; 2)按行连续赋值 int a[2][3]={1,2,3,4,5,6}; 这两种赋值的结果是完全相同的; 说明: 1)可以只对部分元素赋值,未赋值的元素自动取0; 例如: int a[3][3]={{1},{2},{3}}; 是对每行的第一列元素赋值,未赋值的元素自动取0 2)如果对所有的元素赋初值,则第一维的长度可以不给出; 例如: int a[3][3]={1,2,3,4,5,6,7,8,9}; 可以改为: int a[][3]={1,2,3,4,5,6,7,8,9}; 3)数组是一种构造类型的数据,二维数组可以看作是一维数组的嵌套,设一维数组的每个元素又都是一个数组,就组成了一个二维数组,当然,前提是每个元素的类型必须一致;同理,一个二维数组也可以分解为多个一维数组,例如: a[3][4],可分解为3个一维数组,其数组名分别是: a[0],a[1],a[2];对这三个一维数组不需另作说明即可使用,这三个一维数组都有4个元素,例如: 一维数组a[0]的元素是a[0][0],a[0][1],a[0][2],a[0][3];必须强调的是,a[0],a[1],a[2]不能当作下标变量使用,因为它们是数组名,不是一个单纯的下标变量; 对于一个数组,例如: a[3][4]可以通过循环语句来赋值; for(i=0;i<3;i++) 作者 张小波 for(j=0;j<4;j++) scanf(“%d”,&a[i][j]); 4、二维数组的使用举例 1)将一个二维数组的行和列元素互换,存到另一个二维数组中。 #include int a[2][3]= {{1,2,3},{4,5,6}}; int b[3][2],i,j; for(i=0;i<=1;i++) { for(j=0;j<=2;j++) { printf(“%d”,a[i][j]); b[j][i]=a[i][j]; } printf(“\\n”); } for(i=0;i<=2;i++) { for(j=0;j<=1;j++) printf(“%d”,b[i][j]); printf(“\\n”); } } 三、字符型数组 1、字符型数组的定义 定义: 每个数组元素的数据类型是字符型的一维数组。 字符数组的引用,存储,初始化的方法和一维数组相同 例如: 字符型数组的定义 char c[10];定义了字符型数组c,它的数组元素有10个,由于字符型和整型是相通的,因此,上面的定义也可以改为:int c[10]; 例如: 字符型数组的初始化 char c[3]={?a?,?b?,?c?}; 注意: 如果花括号提供的数组元素个数大于数组长度,则作语法错误处理;如果初值个数小于数组长度,则只将这些字符赋给前面的元素,其余的元素自动定为空字符(?\\0?); 比如:char c[5]={?a?,?b?,?c?}; a b c \\0 \\0 如果提供的初值个数和预定的数组长度相同,在定义时可以省掉数组长度,系统自动根据初值个数确定数组长度。 例如:char a[]={?a?,?b?,?c?,?d?,?e?}; 也可以用字符串常量赋值; 如:char ch[6]={“hello”}; char ch[6]=”hello”; char ch[]=”hello”; 作者 张小波 h e l l o \\0 2、字符型数组的引用 可以引用字符数组中的一个元素即得到一个字符! 例如: 输出一个字符串 Main() { char a[5]={?a?,?b?,?c?,?d?,?e? }; int i; for(i=0;i<5;i++) printf(“%c”,a[i];) printf(“\\n”); } 四、字符串 1、字符串定义 定义: C语言中用双引号括起来的任意字符序列就是字符串。 C语言中没有字符串变量,对程序中的字符串,系统用字符数组方式保存,连续,顺序的存放每一个字符,最后加上一个空字符”\\0”作为结束标志! 2、字符串的输入输出 1)通过逐个字符输入和输出: 使用%c; 2)通过整个字符串输入和输出:使用%s; 3、字符串数组 字符串数组就是数组中的每个元素又都是存放字符串的数组。例如: 可以将一个二维字符数组看成是一个字符串数组;char line[10][80]; 数组line共有10个元素,每个元素可以存放80个字符(79个普通字符,一个结束字符),第一个下标决定字符串的个数,第二个下标决定字符串的最大长度,line是有十个字符串的数组,这些字符串的最大长度是79。 字符串的初始化方法: 例如: char str[3][5]={“a”,”ab”,”abc”}; /*根据定义的大小初始化*/ char str[][5]={“a”,”ab”,”abc”}; /*根据右边字符串的个数,定义数组大小*/ 该数组的存储示意图为: a \\0 a a b b \\0 c \\0 3.4 软件硬件的仿真调试 1、首先利用ISIS-Professional软件设计好硬件电路图。 2、其次,利用KEIL软件建立工程项目,把用C语言编好的程序通过该软件平台进行编译,直至把C程序修改无错误为止,并生成HEX文件。 3、在ISIS-Professional软件平台下导入由KEIL软件生成的HEX文件,进行仿真,仔细观察产生的现象和效果,根据仿真的效果,边修改边调试,直到仿真效果与我们对项目的要求一致为止。 作者 张小波 本任务我们用单片机和时钟芯片DS1302和液晶LCD1602设计了一个电子时钟, 通过仿真,本系统能够准确的显示秒、分、时、星期、年、月、日等时间,由于使用了专门的时钟芯片和液晶显示芯片,比前一个任务无论视觉效果更佳。 3.5 知识拓展-I/O接口扩展(二) 一、I/O扩展常用芯片 (1)TTL/CMOS锁存器/缓冲器芯片: 如74LS377、74LS374、74LS373、74LS273、74LS244、74LS245等; (2)通用可编程I/O接口芯片: 如8255、8155、8729等; (3)可编程阵列: 如GAL16V8、GAL20V8等。 I/O扩展中应注意的几个问题 (1)访问扩展I/O的方法与访问外部数据存储器完全相同,使用相同的指令。 (2)扩展多片I/O芯片或多个I/O设备时,注意总线的驱动能力问题; (3)扩展I/O口的目的是为了单片机与外部设备进行信息交换而设臵的一个输入输出通道,I/O口最终与外设相连。 (4)在软件设计时,I/O口对应初始状态设臵、工作方式选择要与外接设备相匹配。 二、扩展简单并行接口 1.扩展并行输出口 (1)用74LS377扩展并行输出口 74LS377 是带有输出允许端的8D锁存器,有8个输入端口、8个输出端口、1个时钟输入端 CLK(上升沿有效)和1个允许控制端OE。如图3-9所示,OE与P2.7相连,74LS377的地址为7FFFH; 若与P2.0相连,则地址相应为0EFFH。 图3-9 MCS-51扩展输出口74LS377 【例3.1】 若以图3-8为接口电路,将片内RAM地址为50H单元的数据通过该电路输出。程序清单如下: MOV DPTR,#7FFFH ;数据指针指向74LS377 MOV A,50H ;输出的50H单元数据送累加器A