前言:
如今我们对“编写程序求一维整型数组中数据的最小值”大致比较关注,大家都需要剖析一些“编写程序求一维整型数组中数据的最小值”的相关内容。那么小编也在网络上收集了一些对于“编写程序求一维整型数组中数据的最小值””的相关资讯,希望我们能喜欢,咱们快快来学习一下吧!7.1 一维数组
前面几章介绍了程序设计的四种基本结构、数据类型和表达式的基本概念。从本章起我们将聚焦在数据的存储和应用上,并通过实际应用展示不同数据结构的使用方法。本讲先介绍数组的定义、赋初值及使用。
前面我们学习了普通变量的定义和使用方法。定义变量后,我们可以通过变量名使用对应的内存空间。如对三个变量进行排序,程序可以如下编写:
int a,b,c;int t;scanf("%d%d%d",&a,&b,&c);if(a>b){t=a;a=b;b=t;}if(a>c){t=a;a=c;c=t;}if(b>c){t=b;b=c;c=b;}printf("%d,%d,%d\n",a,b,c);
以上程序定义了三个变量,并通过键盘给每个变量赋值,然后通过if语句比较变量大小并进行变量值的交换。前两个if语句分别比较a>b与a>c,如果条件为真则交换a、b或a、c,目的是把a、b、c三个变量的最小值放在a中。第三个if语句是把b和c两个变量中找最小值交换到b中。此时,c中的值肯定是三个中最大的。可见,三个变量的排序需要3次比较和交换才能实现。
那么,如果要实现对四个变量的排序,程序怎么写?首先当然要定义四个变量a、b、c、d,然后给这四个变量赋值,为了使a得到最小值,要用3个if语句分别对a>b、a>c、a>d等进行比较,然后通过交换使最小数放在a中。然后用前述方法继续对剩下的b、c、d三个变量排序,需要3次if的比较。所以四个变变量的排序总共需要连续写6个if语句。然而,如果要对100个变量进行排序,我们要怎么做呢?当然要定义100个变量,要输入100个数给变量赋值,要做99+98+...+3+2+1次(4950)比较和交换。按三个变量排序的思路,想象一下我们的程序需要多少行?除了4950行if语句外,光100个变量的定义、输入和输出的行数少则几十行,多则上百行。显然,当处理的数据量很大的时侯,数据存储和程序带来了问题。
解决之道是使用数组。通过引入数组可以解决变量太多时命名、定义和输出等一系列问题,使程序编写更加简单。
数组是具有相同名字、相同数据类型的一组变量的集合。数组定义好后,会在内存中开辟一块连续的存储空间依次作为数组的每个元素。如图:
地址
内空空间
编号
xxx14
9
xxx12
8
xxx0F
7
xxx0D
6
xxx0B
5
xxx09
120
4
xxx07
3
xxx05
2
xxx03
1
xxx01
0
上图是一块具有20个字节的连续存储空间,可以用来分配给10个不同名字的short变量,每个变量占2字节。如10个变量定义如下:
short int a,b,c,d,e,f,g,h,i,j;
10个变量的定义我们还可对付,但100个变量的定义就太花时间了。好在我们可以把10个变量定义成数组,只需要在原来普通变量的后面加一对括号并指明变量的个数即可,如;
short int a[10];
定义了一个名为a的数组,a中的每个变量都共享同一个名字a,且具有相同的数据类型。如果要定义100个变量,只需要把“[]”中的10改为100就好了。一维数组定义的格式如下:
数据类型 数组名[整型常量表达式]
数组的数据类型可以是前面学习几种简单类型,也可以是未来要学到的指针、结构体等自定义类型。数组名的命名与变量名的命名方法一样的。整型常量表达式用以说明数组的元素个数,因此只能是整型且是非负整数,由于数组是在编译时完成内存空间的分配,所以表达式的值必须在程序运行前确定,数组定义时期括号内的整型表达式只能是常量。以下定义是正确的:
double x[10],y[10+20];
以下定义是错误的,也是编程是要避免的:
int n;float a[n]; //元素个数不确定float b[]; //没有元素
数组在函数内定义时,默认的存储类型是自动类型auto,因此数组放在栈中,数组元素个数受到栈空间大小限制。因为数组在程序执行时才自动生成,所以数组中的每一个元素存放的都是垃圾数据。在定义数组时,可以给数组每个元素赋初值,有两种方式实现。
一是把数组定义为静态的存储类,如:
static int a[100];
这样数组会在程序编译成二进制代码时定义,并且每个元素会自动被赋0值 。静态数组在程序结束前一直存在,并且只能被定义它的函数使用。
不管static或auto的数组都可以在定义的时侯赋初值,格式如:
数据类型 数组名[变量表达式]={初值列表};
以下代码定义了两个数组a和b:
int a[5]={1,2,3,4,5};int b[5]={1,2};
其中,a数组中的a[0]至a[4]分别被赋了1至5的值;b数组中初值列表中的数的个数少于数组元素,此时依次把括号中的数给前面的数组元素b[0]、b[1]赋初值,后面的数组元素b[2]至b[4]自动被赋予了0值。
还可以这样给数组赋初值:
int c[]={1,2,3,4};int d[]={};
其中,c数组没有指定整型表达式,但计算机会按初值列表的数据的个数给c自动分配4个数组元素的内存空间,并把1至4依次给数组c中的每个元素赋初值。数组d的后面括号中一个元素没有,此时会自动生成元素个数为0的数组,这个数组仅表示一个地址,无实际意义。
C语言数组定义好后,不能想当然地使用数组,初学者经常会写出代码:
int a[10],b[10];scanf("%d",a);printf("%d",a);
以上代码试图用scanf函数给整个数组a赋值,并用printf输出整个数组a。想法很好,但这不可能实现。数组名不是一个变量,而是表示第一个数组元素的首地址(&a[0])的常量,也称首元地址。因此,上述代码虽然不会提示错误,但scanf只能完成给a的第1个变量(即a[0])赋值,printf只能以整数形式输出数组首元地址(&a[0])。因为数组名是常量,想把一个数组的所有元素赋给另一个数组也行不能,以下赋值也是错误的:
int a[10],b[10];....b=a; (X)
那么,如何使用数组呢?即数组必先定义后使用,且只有通过逐个使用数组中变量来实现。数组中的一个变量用数组名和下标共同表示,称为下标变量或数组元素,格式如下:
数组名[下标表达式]
数组名是已定义了的数组。下标表达式可以是常量、变量或任何整型表达式,表达式的取值范围一般从0至数组元素个数减1。值得注意的是当数组下标在此范围之外时,有的C编译器不会提示错误。
如果有定义:
int a[10];
则a数组元素分别是a[0]、a[1]、a[2]、....、a[9],分别表示数组中第1个变量(数组元素),第2个变量,....,第10个变量。下标的取值范围只能是0至9的数或表达式,其它下标会产生越界错误!由于数组元素本质上是变量,因此,凡是变量可以使用的场景,数组元素都可以使用,如前面的三个变量的排序问题可以写成:
int a[3],t;scanf("%d%d%d",&a[0],&a[1],&a[2]);if(a[0]>a[1]){t=a[0];a[0]=a[1];a[1]=t;}if(a[0]>a[2]){t=a[0];a[0]=a[2];a[2]=t;}if(a[1]>a[2]){t=a[1];a[1]=a[2];a[2]=t;}printf("%d,%d,%d\n",a[0],a[1],a[2]);
可见对数组元素的输入、使用和输出和变量a、b、c都一样。
因为数组的下标可以是变量或合法的整型表达式,这给数组的使用带来了方便,如:
a[i] 或 a[i+1];
“[]”是取数组元素运算符。当i为5时,表示取数组的第5个元素,即a[5]。当i取6即表示取a的第6个元素。而a[i+1]表示取i元素紧挨着的后面元素。所以,对数组a的输入和输出就可以用for循环来实现了。因为n个元素的数组的下标从0至n-1,可设循环控制变量i来表示下标,其初值为0,终值为n-1,步长变化为1。给数组每个元素输入赋值的代码为:
for(i=0;i<10;i++) //设数组有10个元素 scanf("%d",a[i]);
同样要输出数组的每个元素,也用一个for循环就可以了,如:
for(i=0;i<10;i++) //设数组有10个元素 printf("%d",a[i]);
现在我们来看一个实例。
例:从键盘上输入10个数,然后输出每个数及这些数中所有偶数和。
利用上述数组的输入与输出循环代码,然后任意一个循环中增加对数组元素求和的语句就可以了,程序如下:
#include<stdio.h>int main( ){ int a[10],sum,i; sum=0; for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<10;i++){ if(a[i]%2==0) sum=sum+a[i]; printf("%d ",a[i]); } printf("sum=%d\n",sum);}
本节通过三个变量排序引入了数组的概念,并介绍了一维数组的使用场景、定义、占用的内存空间和赋初值的方法,以及数组元素的使用、输入和输出等。本节就讲到这里,下次再见。