数组程序设计(一)
内容
说明
本讲内容
1,数组的概念
2.一维数组的定义、初始化、引用
3.二维数组的定义、初始化、引用
重点
一维数组的定义、初始化及引用、二维数组的定义、初始化及引用
难点
一维数组的定义、初始化及引用、二维数组的定义、初始化及引用
问题提出
当我们需要定义10个甚至更多的整型或其它类型时,怎么办?这时候就需要一个简便的操作方式,那么就可以用数组来实现。
举例
一、数组的概念由相同数据类型的变量按照一定的次序组织起来,就是数组。构成数组的变量称为数组元素。用一个数组名和下标来唯一确定数组中的元素。数组类型属于构造数据类型。
二、一维数组
【定义】
类型标识符 数组名 [常量表达式];
int aa[4];
【注意】
⑴类型标识符指明数组的数据类型,即数组中每个元素的数据类型;
⑵数组名的命名应遵循标识符的命令规则;
⑶“常量表达式”用以表示数组元素的个数,也就是数组长度,它可以是整型常量、整型常量表达式或整型符号常量。
⑷ 不允许对数组的大小作动态定义,即数组长度不容许是变量。
⑸ 数组的下标下限为0;数组的下标上限为“常量表达式-1”。
【初始化】
可以用下列方法对一维数组进行初始化:
⑴ 对数组的全部元素赋初始值。
如,int m[5]={1,21,35,4,58};
⑵ 对数组的部分元素赋初始值。
如,int num[5]={1,24,3};
只给数组的前三个元素赋指定的初始值,后两个元素按系统规定整型赋初始值为0,字符型赋初始值为’\0’。
⑶ 对数组的全部元素赋初始值时,可以将数组定义为一个不确定长度的数组。 如:int num[ ]={19,2,32,4,51};
【引用】
引用数组中的元素可以通过使用数组名及其数组名后的方括号中的下标来实现。只能引用数组元素而不能一次引用整个数组。引用数组元素时,数组元素的下标可以是整型常量、变量或表达式。
例 求10个数的最大值与最小值,10个数用数组描述。
main()
{ float a[10]; 
int i; 
float max=-1e20,min=1e20; 
for(i=0; i<=9;i++) /*输入 10 个数*/
举例
scanf (″%f″,&a[i] ); 
for (i=0; i<=9;i++) /*求最大值与最小值*/
{ if(a[i]>max) max=a[i]; 
if(a[i]<min) min=a[i];
}
printf (″最大值=%f,最小值=%f″,max,min);
}
三、二维数组
【定义】
数据类型 数组名 [常量表达式1] [常量表达式2];
float a[3][4];
【注意】
二维数组中元素的排列顺序是按行排列,即在内存中先顺序存放第一行的元素,再存放第二行的元素,即:a00→a01→a02→a03→a10→a11→a12→a13→a20→a21→a22→a23。
【初始化】
可以用下列方法对二维数组进行初始化:
⑴ 分行对二维数组初始化。
如,int a[3][4]={{1,28,3,4},{15,62,7,8},{9,100,111,12}};
⑵ 按数组排列的顺序对各元素赋初值。
如,int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
⑶ 可以对部分元素赋初值。
如,int a[3][4]={{1},{5},{9}};
只对每行的第一个元素赋初值,其余元素值自动为0。
(4) 如果对全部元素赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省略。
如:int a[ ][4]={1,2,3,4,5,6,7,8,9,10,11,12};
也可以只对部分元素赋初值。
如:int a[ ][4]={{0,0,3},{ },{1,3,5,9}};
【引用】
二维数组也只能引用数组元素,而不能引用整个数组。
例 利用二维数组从键盘上输入6个数,按2行3列的形式输出。
main()
{int a[2][3],i,j;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
scanf(“%d”,&a[i][j]);
for(i=0;i<2;i++)
{ for(j=0;j<3;j++)
printf(“%4d”,a[i][j]);
printf(“\n”);
}
}
注意:二维数组的元素在内存当中的存储形式
注意:引用数组的方法
例 分析下列程序的输出结果。
main()
{ int a[3][3]={{1,2},{3,4},{5,6}},i,j,s=0;
for(i=1;i<3;i++)
for(j=0;j<=i;j++)
s+=a[i][j];
printf("%d\n",s);
}
总结
通过对数组的学习,可以看到数组在处理多个相同的基本数据类型时非常方便,另外,数组和指针结合起来处理问题更是得心应手,这个我们将在后面学习。
数组程序设计(二)
内容
说明
本讲内容
1.数组排序方法---冒泡法
2.数组排序方法---选择法
详细讲解冒泡法比较大小的过程
重点
两种排序方法的思路
难点
将两种排序方法应用到实例当中
问题提出
当我们需要对多个相同数据类型的数据进行从大到小或从小到大排序时,这时我们就可以利用选择法和冒泡法实现。
举例
一、冒泡法排序的思路冒泡法排序也叫起泡法排序,是相邻两元素进行比较的一种排序方法。每遍都从第一个元素开始,两两比较,若不符合相应序列,则两数值交换位置。当比较完一遍后,最大(或最小)的数已沉底,被放置在最后的位置,而相应较小(或较大)的数则上浮。由于第一遍已找出最大(或最小)的数,第二遍不需要与其比较,所以第二遍比第一遍的比较次数少一次。同样需要n-1遍比较才能完成排序。
例 从键盘上输入10个数,用冒泡法排序(由小到大)。
参考程序如下:
main()
{ float a[10]; 
int i,j,t; 
printf(“请输入10个元素:”)
for ( i=0;i<10;i++)
scanf (,%f”,&a[i] );
for(i=0; i<=8; i++)
for(j=0; j<=8-i; j++)
if(a[j]>a[j+1])
{t=a[j]; a[j]=a[j+1]; a[j+1]=t; }
for (i=0; i<10; i++)
printf(,a[%d]=%f \n”,i,a[i] ); 
}
二、选择法排序的思路
选择法排序首先取数组中第一个元素,依次与后面的元素进行比较,若不符合相应的序列,记录较小(或较大)元素的下标,且用较小(或较大)的元素与后面的元素继续比较,直到内层循环结束。当内层循环结束后,记录的下标即为比较范围内最小(或最大)的元素的下标,同时将该元素交换到第一个元素的位置。这样每进行一遍比较只进行一次数据交换,若有n个元素则比较n-1次后,最小数值(或最大数值)就被交换到第一个元素的位置。然后再取第二个元素依次与后面的n-2个元素进行比较,方法同上。每一遍的比较次数比前一遍少一次。直到最后一遍比较次数为1,一共要进行n-1遍的比较。
例 用选择法对6个数进行排序。
参考程序如下,
举例
main() /*从小到大*/
{ int a[6]={5,8,9,4,7,2},i,j,t,k;
for(i=0;i<5;i++)
{
k=i;
for(j=i+1;j<6;j++)
if(a[k]>a[j])k=j;
if(i!=k)
{
t=a[i];a[i]=a[k];a[k]=t;
}
}
for (i=0;i<6;i++)
printf("a[%d]=%d\n",i,a[i]);
}
详细讲解选择法比较大小的过程
总结
排序是计算机进行数据处理的基本运算之一,排序后的数据便于进行查找,选择合适的排序方法可以提高编程效率。冒泡法和选择法是我们重点掌握的内容。
数组程序设计(三)
内容
说明
本讲内容
1.字符数组的定义、初始化及引用
2.字符串
3.字符串的输入输出
4.常用字符串处理函数
5.综合应用
重点
字符数组的定义、初始化及引用,字符串
难点
字符数组的定义、初始化及引用,字符串
问题提出
前面学习了关于数值型数组,那么当数组中存储的数据是字符型怎么操作呢?
一、字符数组字符数组是一种用来存放和处理字符数据的数组变量。
【定义】
char 数组名[常量表达式];
char cc[4];
【注意】
char cc[4]表示定义了一个长度为4的一维字符数组cc;
【初始化】
可以用下列方法对字符数组进行初始化,
⑴ 用字符逐个给字符数组中的元素赋值
如,char cc[5]={‘H’,’e’,’l’,’l’,’o’};
⑵ 用字符串常量给字符数组赋值。字符串常量用一对双引号括起来,编译系统对有N个字符组成的字符串常量总是分配N+1个字节的存储空间;
如:char cc[6]=“Hello”; 也可写成:char cc[ ]=“Hello”;
cc这个数组总共分配6个字节的存贮空间,在cc[5]中存入的是‘\0’。
存贮示意图如下:
【引用】
字符数组元素的引用与数值型数组的引用方法相同。
二、字符串字符串是作为一个整体对待的字符序列。在C语句中无字符串数据类型变量,对字符串变量的操作是利用字符数组进行的。
在字符数组中的有效字符后面加上‘\0’这一特殊字符时,可以把这种一维字符型数组看作“字符串变量”。字符串是字符数组中的一种特殊情况。
‘\0’是字符串的结束标志符。
如果一个字符数组用来作为字符串使用,在定义该字符数组时,数组的大小应该比是字符串的有效长度+1。
三、字符串的输入输出
⑴ 在scanf中利用“%s”实现对字符串的整体输入
如,static char str[20];
scanf(“%s”,str));
数组名是数组的起始地址,调用此函数,输入的字符串依次存入以数组名作为起始地址的存储单元中,用空格或回车符作为字符串输入结束,并字符串结束后自动在末尾加入‘\0’。
⑵ 在printf中利用“%s”实现对字符串的整体输出
如,printff(“%s”,str);
从字符串的起始地址依次输出存储单元中的字符,直到遇到第一个‘\0’为止。输出结束后不自动换行。‘\0’是结束标志符,不在输出字符之内。
四、常用字符串处理函数
⑴ 字符串输入函数gets
【格式】 gets(字符数组名)
【功能】从键盘上输入一字符串(遇到回车键结束输入)并把它存放在指定的数组中。返回值是字符数组的起始地址。
⑵ 字符串输出函数puts
【格式】puts(字符数组名)
【功能】将指定的字符数组中的字符串输出到显示器上。无返回值。
⑶ 字符串连接函数 strcat
【格式】strcat(s1,s2)
【功能】把字符串s2的全部内容(包括它的结束标志符’\0’)连接到字符串s1的后面,并把s1字符串结束标志符’\0’删除,形成新的字符串s1,新的字符串s1后保留一个‘\0’。返回值是s1的起始地址。
⑷ 字符串比较函数 strcmp
【格式】strcmp(s1,s2)
【功能】比较字符串s1和s2的大小。返回值是一个整型值,若s1>s2,返回一个正数;若s1=s2,返回0;若s1<s2,返回一个负数。
字符串比较的方法是:从左到右依次比较两个字符串中的对应字符,若相等继续比较,直到当前两个字符不相等,或遇到‘\0’结束。比较字符的大小,是比较两个字符的ASCII码的大小。
⑸ 字符串复制函数 strcpy
【格式】strcpy(s1,s2)
【功能】将字符串s2的内容复制到s1的字符数组中。必须保证s1的字符数组足以容纳字符串复制后的s1的全部内容。
⑹ 字符串长度测试函数 strlen
【格式】strlen(字符数组名)
【功能】测试字符数组中字符串长度。返回值是字符串中‘\0’之前的字符串有效长度值。
五、综合应用例1 从键盘接收一串字符,将其中的小写字母转换为大写字母,并输出到屏幕上。
注意:‘\0’是不输出的。
参考程序如下:
#include <stdio.h>
main( )
{
char ch[80];
int i;
gets(ch);
for(i=0;i<strlen(str);i++)
if(ch[i]>=97&&ch[i]<=122)
ch[i] =ch[i]-32;
printf(“%s”,str);
}
例2 输入一行字符,统计其中有多少单词,单词间用空格分隔开。
参考程序如下:
#include<stdio.h>
main()
{
char c,string[81];
int i,num=0,word=0;
gets(string);
for(i=0;(c=string[i])!='\0';i++)
if(c==' ') word=0;
else if(word==0)
{
word=1;
num++;
}
printf("There are %d words in the line.\n",num);
}
程序中变量i作为循环变量,num用来统计单词个数,word作为判别是否为单词的标志,当输入的字符为空格时,word置0,说明一个单词的结束或新单词还没开始。当输入非空格字符且word为0时,表示新单词的开始,在word置为1的同时,单词数num累加1。而当word为1,输入非空格字符时,表示该字符与前面的字符为同一单词中的字符,此时num不加1。
总结
通过对字符数组的学习解决了关于字符型数据在数组中的操作,并且讲述了一些常用的字符串处理函数,这也是本节的一个重点。