810 likes | 908 Views
第八章 数组. 8.1 一维数组 8.2 二维数组 8.3 字符数组与字符串 8.4 数组与函数 8.5 数组程序设计举例. 8.1 一维数组. 8.1 一维数组. 什么是数组呢 ?. 数组是有序数据的集合。数组中的每一个元素都属于 同一个数据类型 。用一个 统一的数组名 和下标来唯一地确定数组中的元素。. a[0] a[1] … a[9]. 分配内存. 8.1 一维数组. 8.1.1 一维数组的定义. 1. [ 存储类型 ] 类型说明符 数组名 [ 常量表达式 ]; 例 : int a[10];
E N D
第八章 数组 8.1 一维数组 8.2 二维数组 8.3 字符数组与字符串 8.4 数组与函数 8.5 数组程序设计举例
8.1一维数组 8.1一维数组 什么是数组呢? • 数组是有序数据的集合。数组中的每一个元素都属于同一个数据类型。用一个统一的数组名和下标来唯一地确定数组中的元素。
a[0] a[1] … a[9] 分配内存 8.1一维数组 8.1.1一维数组的定义 1.[存储类型] 类型说明符 数组名[常量表达式]; 例:int a[10]; float b[20],c[15]; 2.在内存分配若干连续空间给数组.
8.1一维数组 3.说明: (1.数组名遵循标识符命名规则; (2.常量表达式用方括弧括起来; (3.常量表达式为数组元素个数,即数组长度; 其值从0开始. (4.数组类型为数组中每一个元素类型
8.1一维数组 例如: /*以下是一个典型的错误定义方式!*/ int n; scanf(“%d”,&n); int a[n];
8.1一维数组 8.1.2 一维数组的引用 • 1.数组同变量一样,必须先定义后引用。 • 2.引用数组元素的方法是: 数组名[下标] 可以是整型常量 或整型常量表达式 其最小值默认为0.
8.1一维数组 例如: 有定义 int a[10]; 数组元素引用举例 /*可以引用元素的从a[0]到a[9]*/ a[5]=6; a[7]=a[5]++; a[6]=3; a[0]=a[5]+a[7]-a[2*3];
8.1一维数组 【例8-1】输入10个整数,分别按顺序和逆序输出。 #include <stdio.h> void main() {int i,a[10]; printf("input 10 numbers:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); printf("\n"); for(i=0;i<=9;i++) printf("%d ",a[i]); printf("\n"); for(i=9;i>=0;i--) printf("%d ",a[i]); } 程序的运行情况: input 10 numbers: 1 2 3 4 5 6 7 8 9 10↙ 1 2 3 4 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1
8.1一维数组 8.1.3 一维数组的初始化 • 1.初始化--在定义数组时对数组元素赋初值; • 2.初始化方法: • [static] 数组类型 数组名 [数组长度]={数组元素值};
8.1一维数组 ①给全部元素赋初值 static int a[5]={0,1,2,3,4}; ②可以只给一部分元素赋初值;static float b[5]={1.4,7.2}; ③在对全部数组元素赋初值时,可以不指定数组长度。 static int a[]={1,2,3};
8.1一维数组 注意 static型数组不进行初始化时,如果是数值类型数组(如整型、实型)默认值为0;如果是字符型数组默认值为空字符’\0’(ASCII码为零的字符)。 auto型数组不进行初始化时,编译器不为其自动指定初始值。其初始值为系统分配给数组各元素的内存单元原来的值,这个值是不可预知的。
8.1一维数组 定义数组 • 数组的输入输出 基本方法 输入/赋值 运算 输出
8.1一维数组 【例8-2】分析下面程序的运行结果。 #include ”stdio.h” void main() {int i,a[5]; static int c[5]; for(i=0;i<5;i++) printf(”%d ”,a[i]); printf(”\n”); for(i=0;i<5;i++) printf(”%d ”,c[i]); } 程序运行情况: 816 0 1312 200 0 0 0 0 0 0
8.1一维数组 #include ”stdio.h” void main( ) {static int a[10]={1,1} int i;; • [例8.2]利用数组,求斐波拉契数列的前10项。 定义数组 计算 for(i=2;i<10;i++) a[i]=a[i-1]+a[i-2]; for(i=0;i<10;i++) printf(”%d”,a[i]); } 输出
8.1一维数组 [例5.3]求若干个数(不多于10个)的最大数、最小数 • #define N 10 • #include ”stdio.h” • void main( ) • {int i,n; • float a[N],max,min; • printf(”input data numbers:”); • scanf(”%d”,&n); • printf(”enter numbers:”); • for(i=0;i<n;i++) • scanf(”%f”,&a[i]);
8.1一维数组 (续上) max=min=a[0]; for(i=1;i<n;i++) {if(a[i]>max) max=a[i]; if(a[i]<min) min=a[i]; } printf(”\nmax=%f,min=%f\n”,max,min); }
8.1一维数组 【例8-5】将10个人员的考试成绩进行分段统计,考试成绩放在a数组中,各分数段的人数存到b数组中:成绩为60到69的人数存到b[0]中,成绩为70到79的人数存到b[1],成绩为80到89的人数存到b[2],成绩为90到99的人数存到b[3],成绩为100的人数存到b[4],成绩为60分以下的人数存到b[5]中。
#include "stdio.h" void main() {int i,a[10];static int b[6]={0,0,0,0,0,0}; printf("enter the score:\n"); for (i=0;i<10;i++) {scanf(“%d”,&a[i]); switch(a[i]/10) {case 6:b[0]++;break; case 7:b[1]++;break; case 8:b[2]++;break; case 9:b[3]++;break; case 10:b[4]++;break; default:b[5]++; } } printf("the result is: "); for (i=0;i<6;i++) printf("%d\t ",b[i]); }
学生练习 [例5.5]判断任意整数x是否为回文数 (回文数:顺读与反读都一样的数) 提示: (1)求出x的每一位数,放入数组各个元素中 (2)数组元素首尾比较,判断是否为回文 for( i=首下标,j=末下标; i<j; i++,j--)
参考程序: • main() • {long x; int i,j,n,d[20]; • /*n为x的位数,d数组用来存放每位数,数组长度应设计的大一些*/ • scanf(“%ld”,&x); • n=0; • do{d[n]=x%10;x=x/10;n++; • }while(x!=0); • for(i=0,j=n-1;i<j;i++,j--) • if(d[i]!=d[j]) break; • if(i<j) printf(“NOT”); • else printf(“YES”); • }
行数 列数 8.2 二维数组 8.2二维数组 8.2.1 二维数组的定义 • 1.定义方式: • 类型 数组名[表达式1][表达式2]; 例:float a[3][4],b[5][10];
8.2 二维数组 2.说明: • 二维数组可看作特殊的一维数组; • 元素在内存排列顺序为按行存放; • 多维数组定义亦类似于二维数组,如: float a[2][3][4]; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 例: int a[2][3]; 它在内存情况:
8.2 二维数组 8.2.2 二维数组元素的引用 • 数组名[行下标] [列下标]; • 例:a[2][3]
8.2 二维数组 ⒈分行初始化。如: static int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; • 8.2.3 二维数组的初始化 ⒉按数组排列的顺序将所有数据写在一个花括号内,如:static int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
0 1 0 0 0 6 0 0 0 0 11 0 8.2 二维数组 ⒊部分元素初始化。如:static int a[3][4]={{,1},{0,6},{0,0,11}};
8.2 二维数组 ⒋如果对全部元素都赋初值,则定义数组时可以不指定第一维的长度,如:static int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};
8.2 二维数组 8.2.4 二维数组元素值的输入与输出 二维数组的输入与输出是通过对二维数组的每个元素的输入与输出实现的。 【例8-6】二维数组输入与输出方法示例。
8.2 二维数组 include "stdio.h" void main() {int i,j,a[3][4]; printf("input array numbers:\n"); for(i=0;i<3;i++) for(j=0;j<4;j++) scanf("%d",&a[i][j]); printf("output array numbers:\n"); for(i=0;i<3;i++) { for(j=0;j<4;j++) printf("%d ",a[i][j]); printf("\n"); } }
8.2 二维数组 程序运行情况: input array numbers: 1 2 3 4↙ 5 6 7 8↙ 9 10 11 12↙ output array numbers: 1 2 3 4 5 6 7 8 9 10 11 12
8.2 二维数组 【例8-7】在N行M列的二维数组x中,找出数组的最大值以及此最大值所在的行、列下标。 #define N 2 #define M 3 #include "stdio.h" void main() {int i,j,x[N][M],max,line,col; printf("input array numbers:\n"); for(i=0;i<N;i++) for(j=0;j<M;j++) scanf("%d",&x[i][j]); max=x[0][0];line=col=0; for(i=0;i<N;i++) for(j=0;j<M;j++) if(max<x[i][j]) {max=x[i][j];line=i;col=j;} printf("\nmax=%d\tline=%d\tcol=%d\n",max,line,col); }
8.2 二维数组 程序运行情况: input array numbers: 12 3 4↙ -5 67 89↙ 10 11 12↙ nmax=89 line=1 col=2
8.3 字符数组与字符串 8.3字符数组与字符串 8.3.1 字符数组的定义 • 定义方法与数值型数组类似:[存储类型] char 数组名[常量表达式];如: char a[5]; • 元素为:a[0],a[1],…….,a[4],每一个元素的值为一个字符。
a[0] a[1] a[2] a[3] a[4] A B o y 8.3 字符数组与字符串 8.3.2 字符数组的存储结构 同数值型数组一样,系统在内存为字符数组分配若干(和数组元素个数相同)连续的存储单元,每个存储单元为一个字节。 例如:char a[5]; 假设a[0]='A';a[1]=' '; a[2]='B';a[3]='o'; a[4]='y'; 则数组a在内存存储示意图如下图
8.3 字符数组与字符串 8.3.3 字符数组的初始化 1. 逐个元素初始化,如: static char c[10]={’h’,’a’,’p’,’p’,’y’}; 2. 说明: • 如果初值个数>数组长度,则作语法错误处理; • 如果初值个数<数组长度,则只将这些字符赋给数组中前面那些元素,其余元素自动定为空字符(即’\0’); • 如果初值个数=数组长度,则在定义时可省略数组长度。
I a m a b o y \0 8.3 字符数组与字符串 4. 用字符串来初始化字符数组 例如:static char a[11] = {”I am a boy”};
8.3 字符数组与字符串 8.3.4 字符数组与字符串的输入输出 • 假设有定义char a[10]; 1.用格式符”%c”逐个字符输入输出: scanf(”%c”,&a[0]); printf(”%c”, a[0]); /*每次输入输出一个字符*/
8.3 字符数组与字符串 2. 用格式符“%s”整个字符串输入输出: char c[10]; scanf("%s",c); /*注意此处用数组名c*/ printf("%s", c); /*注意此处用数组名c*/
8.3 字符数组与字符串 注意: • 用“%s”格式输出字符数组时,遇'\0'结束输出,且输出字符中不包含'\0'。若数组中包含一个以上'\0',则遇第一个'\0'时即结束输出。 • 用“%s”格式输入或输出字符数组时,函数scanf的地址项、函数printf的输出项都是字符数组名。这时数组名前不能再加“&”符号,因为数组名就是数组的起始地址。
8.3 字符数组与字符串 • 用语句“scanf("%s",s);”为字符数组s输入数据时,遇空格键或回车键时结束输入。但所读入的字符串中不包含空格键或回车键,而是在字符串末尾添加'\0'。 • 用一个scanf函数输入多个字符串,输入时应以空格键或回车键作为字符串间的分隔。
8.3 字符数组与字符串 C \0 P r o g \0 例如: char s1[5],s2[5]; scanf("%s%s",s1,s2); 若输入数据: C Prog↙ 则字符数组s1和s2的存储情况如下图所示
8.3 字符数组与字符串 【例8-8】用户从键盘输入一个字符串(字符中不包含空格),当输入回车时认为输入结束,统计输入字符串中小写英文字母、大写英文字母、数字字符、其他字符的个数。
8.3 字符数组与字符串 #include "stdio.h" void main() {int i,m,n,x,y; char s[80]; printf("input a string:\n"); scanf("%s",s); m=n=x=y=0;i=0; while(s[i]!='\0') {if(s[i]>='a'&&s[i]<='z') m++; else if(s[i]>='A'&&s[i]<='Z') n++; else if(s[i]>='0'&&s[i]<='9') x++; else y++; i++;} printf("a~z:%d\nA~Z:%d\n0~9:%d\nothers:%d\n",m,n,x,y); }
8.3 字符数组与字符串 3.用字符串输入函数gets实现输入 : 字符串输入函数gets的函数原型在头文件“stdio.h”中被说明,调用该函数时,应在程序中加入文件包含命令: #include"stdio.h"
8.3 字符数组与字符串 • 函数原型: char *gets (char *s); • 调用形式:gets(字符数组); • 举例: char a[10]; gets(a); printf(" %s" ,a);
8.3 字符数组与字符串 • 函数功能:调用该函数时,要求用户从标准输入设备上(比如键盘)输入一个字符串,以回车键作为输入结束标志;然后将接收到的字符依次赋值给数组各个元素,并自动在字符串末尾加字符串结束标记'\0'。函数的返回值为该字符数组的首地址。与形参对应的实参应该定义为字符数组名。
8.3 字符数组与字符串 • 函数原型:int puts (const char *s); • 调用形式:puts(字符串/字符数组); • 函数功能: 输出一个字符串。 • 应用举例: char a[10]; gets(a); puts(a); • 4.用字符串输出函数puts实现输出
8.3 字符数组与字符串 【例8-9】将字符串s1从第m个字符开始剩余的所有字符,送入字符数组s2中。 #include "stdio.h" void main() {int i,j,m; char s1[80],s2[80]; printf("input a string:\n"); gets(s1); printf("input start point:\n"); scanf("%d",&m); i=m-1;j=0; while(s1[i]!='\0') {s2[j]=s1[i];i++;j++;} s2[j]='\0'; puts(s2); }
8.3 字符数组与字符串 • 何时自动添加’\0’ 1)以字符串初始化时 如:static char c[ ]={”I am happy”}; 或:static char c[ ]=”I am happy”; 2) 以%s输入字符串时 scanf(”%s”,c); 3)用gets接收字符串时
8.3 字符数组与字符串 8.3.5 字符串处理函数 使用时应在程序头文件处添加声明 #include”string.h”
8.3 字符数组与字符串 1. 字符串拷贝函数 • 函数原型: • char *strcpy(char *dest,const char *src); • 函数功能:将字符串src复制到字符数组dest中,返回被复制的字符串。 • src可以是字符数组名、字符串常量或字符指针变量。dest可以是字符数组名或字符指针变量。若dest是字符指针变量,要注意给该指针变量赋初值。