内容正文:
第 3 章 一维数组
2024年8月11日
内容概述
1.一维数组的定义。
2.一维数组元素的引用。
3.一维数组的初始化。
4. C程序调试
5. 算法描述
2024年8月11日
教学目标
1.掌握一维数组的概念、定义方法。
2.掌握一维数组初始化和元素的引用方法。
3.能用一维数组设计简单的程序。
4.掌握VC6.0下调试工具的使用
5. 掌握用流程图描述算法的方法
2024年8月11日
在程序的实际处理过程中,很多时候需要处理的数据不止一个,而是一批数据类型相同且具有联系的数据,如要想表示某班50个学生的C程序设计课程成绩,某部门40名员工年终考核成绩的录入与统计等,都属于这类问题。
3.1 为什么要使用数组
2024年8月11日
编程计算全班40人某门课的平均成绩
#include "stdio.h"
void main()
{
int a,i,sum=0,avg;
for(i=0;i<40;i++)
{
scanf("%d",&a); /* 输入学生成绩 */
sum=sum+a;
}
avg=sum/40;
printf("avg=%d
",avg);
}
一个变量被循环使用,无法保存40个人的成绩。
定义40个变量?
太繁琐
C语言提供了一种简单的构造数据类型——数组来解决这个问题。
2024年8月11日
数组实现
#include "stdio.h"
void main()
{
int a[40],i,sum=0,avg;
for(i=0;i<40;i++)
{
scanf("%d",&a[i]); /* 输入学生成绩到数组中 */
sum=sum+a[i];
}
avg=sum/40;
printf("avg=%d
",avg);
}
2024年8月11日
数组是一组具有相同类型且在内存中有序排列的数据集合。数组中的每个元素都具有相同的数据类型,用数组名加下标的方式来表示。数组元素的下标从0开始。
数组可分为一维数组、二维数组和高维数组。本章主要介绍一维数组的定义和使用。
2024年8月11日
3.2.1 一维数组的定义方式
在C语言中使用数组必须先进行定义。马厩
一维数组的定义方式为:
类型说明符 数组名 [常量表达式];
其中:
类型说明符是任一种基本数据类型或构造数据类型。
数组名是用户定义的数组标识符。
方括号中的常量表达式表示数据元素的个数,也称为数组的长度。
例如:
int a[10]; 定义整型数组a,有10个元素。
int b[10]; 定义实型数组b,有10个元素;
3.2 一维数组
2024年8月11日
对于数组类型说明应注意以下几点
数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。
数组名的书写规则应符合标识符的书写规定。
数组名不能与其它变量名相同。
例如:
int a;
int a[10]; 是错误的。
4.方括号中常量表达式表示数组元素的个数,其下标从0开始计算。例如int a[5],则数组a的5个元素分别为a[0]、a[1]、a[2]、a[3]、a[4]。
2024年8月11日
5. 不能在方括号中用变量来表示元素的个数, 但是可以是符号常数或常量表达式。
例如,
#define M 5
int a[3+2],b[7+M]; √
但是下述说明方式是错误的。
int n=5;
int a[n]; ×
6.允许在同一个类型说明中,说明多个数组和多个变量。
例如:
int a,b,c,d,k1[10],k2[20];
2024年8月11日
3.2.2 一维数组元素的引用
数组元素是组成数组的基本单元。数组元素也是一种变量, 其标识方法为数组名后跟一个下标。下标表示了元素在数组中的顺序号。
数组元素的一般形式为:
数组名[下标]
其中: 下标只能为整型常量或整型表达式。例如:
a[5]
a[i+j]
a[i++]
都是合法的数组元素。
下标从0开始,有5个元素的数组a[5]的元素为:
a[0], a[1], a[2], a[3], a[4]。
2024年8月11日
【例】 数组元素的引用
#include <stdio.h>
void main()
{
int i, a[10];
for (i=0; i<=9; i++)
a[i] = i;
for (i=9; i>=0; i--)
printf("%d ", a[i]);
}
运行结果为:
9 8 7 6 5 4 3 2 1 0
思考:能否将第二个for循环语句用语句printf("%d",a);代替?
2024年8月11日
3.2.3 一维数组的初始化
初始化赋值的一般形式为:
类型说明符 数组名[常量表达式]={值,值……值};
其中在{ }中的各数据值即为各元素的初值,各值之间用逗号间隔。
2024年8月11日
C语言对数组的初始化赋值有以下几点规定:
1. 可以只给部分元素赋初值。
当{ }中值的个数少于元素个数时,只给前面部分元素赋值。例如:
int a[10]={0,1,2,3,4};
表示只给a[0]~a[4] 5个元素赋值,而后5个元素自动赋0值。
2. 只能给元素逐个赋值,不能给数组整体赋值。
例如给十个元素全部赋1值,只能写为:
int a[10]={1,1,1,1,1,1,1,1,1,1};
而不能写为:
int a[10]=1;
2024年8月11日
3. 可以在定义数组时对数组元素赋以初值,
例如:
int a[10]={ 0,1,2,3,4,5,6,7,8,9};
相当于a[0]=0;a[1]=1...a[9]=9;
如果不给可初始化的数组赋初值,则全部元素均为0值。
如给全部元素赋值,则在数组说明中, 可以不给出数组元素的个数。
例如:
int a[5]={1,2,3,4,5};
可写为:
int a[]={1,2,3,4,5};
2024年8月11日
【例3.1】求一维数组元素的最大值并输出其所对应的下标。
#define N 10
#include "stdio.h"
void main()
{
int i,max,max_i,a[N];
for(i=0;i<N;i++)
scanf("%d",&a[i]); /* 该循环输入10个元素 */
max = a[0]; max_i=0; /* 假设第一个元素最大 */
for(i=1;i<N;i++) /* max与数组其余9个元素依次比较 */
if (a[i]> max)
{
max = a[i];
max_i = i; /* 记录较大元素的位置 */
}
printf("The Max Number is a[%d]=%d
",max_i,max);
}
3.2.4 一维数组应用举例
2024年8月11日
Fibonacci数列具有如下特点:第1、2个数均为1,从第3项开始,每一个数都是其前两项之和,即F1=1,F2=1,Fn=Fn-2+Fn-1。我们用数组f来存放Fibonacci数列,这样f[0]=f[1]=1;从f[2]以后的每一个元素f[i]=f[i-1]+f[i-2],可以用循环来实现。
【例3.2】计算Fibonacci数列前20项,要求每行输出5个数。
2024年8月11日
#include "stdio.h"
void main( )
{
int f[20]={1,1},i;
for(i=2;i<20;i++)
f[i]=f[i1]+f[i2];
printf("
------------Fibonacci-----------
");
for(i=0;i<20;i++)
{
printf("f[%2d]=%6d",i,f[i]);
if((i+1)%5==0)printf("
");
}
}
2024年8月11日
3.3 C程序调试
添加输出语句调试程序
利用VC的调试工具调试程序
2024年8月11日
3.3.1利用输出语句调试程序
#include "stdio.h"
void main()
{
int n=12345,s=0,d;
while(n)
{ n=n/10;
d=n%10;
s=s+d;
}
printf("sum=%d
",s);
}
【例3.3】求整数n的各位数字之和(如n=12345,则1+2+3+4+5=15)
出错啦!?
添加输出语句
printf("%3d",d);
2024年8月11日
#include "stdio.h"
void main()
{
int n=12345,s=0,d;
while(n)
{
d=n%10;
s=s+d;
printf("%3d",d);
n=n/10;
}
printf("sum=%d
",s);
}
结果正确,去掉输出语句
2024年8月11日
3.3.2在VC下调试C程序
VC为调试C程序提供了多种工具和多组方法,常用的方法有菜单法、工具栏法和功能键法。
在VC窗口下的菜单栏和工具栏的空白处,点右键激活快捷菜单,选择“编译”菜单项,这时VC窗口就出现了调试工具栏。
2024年8月11日
Restart 重新执行程序,功能键是 Ctrl+Shift+F5。无论C源程序处于任何状态(编辑、运行、调试),按下此按钮均可使程序从编译开始,逐步进入调试程序状态。
Stop Debugging 停止程序调试,功能键是Shift+F5。当调试过程处于跟踪程序执行的状态时,按下此按钮,将停止调试程序,返回编辑状态。编辑状态下此按钮无效。
Show Next Statement 指示当前程序运行的语句行。
Step Into 单步运行并且可进入函数内部运行,功能键是F11。程序在调试过程中,按下此按钮可单步跟踪程序运行,与Step Over按钮不同的是,该功能可进入函数内部,继续函数内部的语句行跟踪。
Step Over 单步运行程序,功能键是F10。本按钮的功能类似于F11,但它不进入函数内部,它将每一条语句看作一步,包括函数调用语句。
Step Out 从当前函数中退出,功能键是Shift+F11。当程序运行至某个函数内部时,按下此按钮后,调试状态即从函数内部退出,返回到调用该函数的主函数的当前语句。
Run to Cursor 运行到当前光标位置,功能键是Ctrl+F10。当程序处于调试状态时,为了跳过某程序段,可预先将光标定位在某语句行上,按下此按钮,即可使程序直接运行到当前光标位置,从而节省了时间,加快了调试程序的步骤。
2024年8月11日
QuickWatch窗口可以快速观察表达式的值,功能键是Shift+F9。当程序运行到某个关键语句行时,可以按下该按钮,该窗口与调试界面中的监视窗口类似,都可监视变量的值。
Watch 窗口可以设置观察点。
Variables 变量列表,简单变量只显示变量名和它的值;数组名前面有一个“ ”符号,Value列显示它的地址值。
Registers 寄存器列表,窗口中列出了所有寄存器的内容。
Memory 内存列表,用户可以在程序运行时,在“Watch”窗口中找到某个变量的地址或数组名的值(数组名本身是一个地址量),然后,将该值输出“A地址”的文本框中,在内存列表区立即就能看到它的存储值,不过该值是一个十六进制的数,并且,一个整型数占据四个字节的存储区域。
2024年8月11日
【例3.4】演示数组赋值及输出的例子。
#include "stdio.h"
void main()
{
int i,a[5];
for(i=0;i<5;i++)
{
a[i]=i;
printf("%d ",a[i]);
}
printf("
");
}
2024年8月11日
【例3.5】在有10个元素的数组中查找值为n的元素,找到则输出其下标,否则,输出“无此元素”。
#include "stdio.h"
void main()
{
int a[10]={1,3,6,0,12,9,7,15,10,20},n,i;
printf("请输入要查找的数据:");
scanf("%d",&n);
for(i=0;i<10;i++)
{
if(a[i]==n)
printf("元素%d的下标为%d
",n,i);
}
if(i>=10)
printf("无此元素");
}
2024年8月11日
3.4.1算法的概念及特征
解决某个问题或处理某个事件的方法和步骤 ,称为算法。
计算机算法:
指使用计算机去解决问题的方法和步骤 。
计算机算法可分为两大类:
数值运算算法:求解数值;
非数值运算算法:事务管理领域
3.4 算法及算法描述
27
算法就是求解问题的方法,是在有限步骤内求解某一问题所使用的一组定义明确的规则,是计算机处理问题所需要的过程。
一个算法通常由一系列求解步骤来完成,各操作步骤之间有严格的顺序关系,每一个步骤所规定的操作必须有明确的含义,不能存在二义性。计算机能够在执行有限的步骤后给出正确的结果。
同一个问题,可以有不同的解决方法,即一个问题有多种算法。
2024年8月11日
一个算法通常由一系列求解步骤来完成,各操作步骤之间有严格的顺序关系,每一个步骤所规定的操作必须有明确的含义,不能存在二义性。计算机能够在执行有限的步骤后给出正确的结果。
同一个问题,可以有不同的解决方法,即一个问题有多种算法。
2024年8月11日
算法的特性
有穷性:
一个算法应包含有限的操作步骤而不能是无限的。
确定性:
算法中每一个步骤应当是确定的,而不能应当是含糊的、模棱两可的。
有效性:
算法中每一个步骤应当能有效地执行,并得到确定的结果。
有零个或多个输入。
有一个或多个输出。
2024年8月11日
算法分析:求最大公约数的问题一般用辗转相除法。
该方法求最大公约数的具体步骤如下:
先用小的数除大的数,得第一个余数;再用第一个余数除小的数,得第二个余数;又用第二个余数除第一个余数,得第三个余数;这样逐次用后一个余数去除第一个余数,直到余数是0为止,那么最后一个除数就是所求的最大公约数。(如果最后的除数是1,那么原来两个数是互质的!)
【例3.6】给定两个正整数m和n,求它们的最大公约数。
2024年8月11日
例如
设m=18,n=12,余数用r表示。
它们的最大公约数的求法如下:
18/12商1余6,以n作m,以r作n,继续相除;12/6商2余0,当余数为零时,所得n即为两数的最大公约数。
所以18和12两数的最大公约数为6。
2024年8月11日
其算法可以描述如下:
(1)将两个正整数存放到变量m和n中。
(2)求余数:计算m除以n,将所得余数存放到变量r中。
(3)判断余数是否为0:若余数为0则执行第(5)步,否则执行第(4)步。
(4)更新被除数和余数:将n的值存放到m中,将r的值存放到n中,并转向第(2)步继续循环执行。
(5)输出n的当前值,算法结束。
2024年8月11日
用C语言实现的程序代码如下:
#include "stdio.h"
void main()
{
int m,n,r;
printf("please input m and n:");
scanf("%d%d",&m,&n);
r=m%n;
while(r!=0)
{
m=n;
n=r;
r=m%n;
}
printf("%d",n);
}
2024年8月11日
3.4.2 算法的描述
从理论上说,算法可以用任何形式的语言和符号来描述,如自然语言、程序设计语言、流程图、N-S图、PAD图和伪代码等。
2024年8月11日
1 用流程图表示算法
所谓流程图,就是对给定算法的一种图形解法。流程图又称为框图,它用规定的一系列图形、流程线及文字说明来表示算法中的基本操作和控制流程。流程图符号如右图所示。
2024年8月11日
2 用N-S流程图表示算法
N-S图是另一种算法表示法,是由美国人I.Nassi和B.Shneiderman共同提出的。其根据是:既然任何算法都可以由顺序、选择和循环3种结构组合而成,所以各基本结构之间的流程线就是多余的,因此,N-S图也是算法的一种结构化描述方法。
2024年8月11日
3种基本结构的N-S图描述如下:
顺序结构:
2024年8月11日
选择结构:
2024年8月11日
循环结构:
2024年8月11日
3 用伪代码表示算法
用传统的流程图和N-S图表示算法,直观易懂,但画起来比较费事。因此,流程图适宜表示一个算法,但在设计算法过程中使用不是很理想。为了设计算法时方便,常用一种称为伪代码(pseudo code)的工具。伪代码是用介于自然语言和计算机语言之间的文字和符号来描述算法。
2024年8月11日
4 用计算机语言表示算法
我们的任务是用计算机解题,就是用计算机实现算法;
用计算机语言表示算法必须严格遵循所用语言的语法规则。
2024年8月11日
5 结构化程序设计方法
自顶向下;
逐步细化;
模块化设计;
结构化编码。
$$