版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
9数组在C语言中,除了前面介绍的基本类型之外,还有另外一些数据类型---构造类型。数组就属于构造类型中的一种。数组是有序数据的集合。数组中的每一个元素都属于同一个数据类型。用一个的数组名和下标来唯一的确定数组中的元素。可以用来解决所论数据不仅与其取值状况有关,还与其所在位置有关(有序性)的问题。数组特点:排列有序、取名同源、彼此 、联
组1为什么用数组成绩例:要输入班上60位同学的数定义变量:int
math_1,
math_2,
math_3,
math_4,…,math_60;intEng_1,Eng_2,….,Eng_59,Eng_60;采用数组:int
math[60];intEng[60];如果要输出第一位同学的数学成绩printf(“%d”,math[0]);2一维数组的定义和33一维数组的定义一般形式:类型说明符数组名[常量表达式];例如:int
a[10];说明:数组名定名规则和变量名相同,遵循标识符定名规则;数组名后面是用方括号括起来的常量表达式;定义表达式的常量表达式表示元素的个数,即数组长度;定义表达式中的常量表达式可以是常量和符号常量,但不能是变量,即不允许进行动态定义。下面定义是错的:int n;scanf(“%d”,
&n);inta[n];a[0]
a[1]a[2]
a[3]
a[4]
a[5]a[6]
a[7]
a[8]
a[9]120460939801150一维数组元素的数组元素的
形式:
数组名[下标]以int
a[n]定义的数组的下标从0开始,n-1结束整个数组的元素每次可
一个数组元素,不能一次一个数组元素就如同一个简单变量下标可以是整型常量或整型表达式常量和表达式作下标变量作下标数组元素做下标a[0]=
a[5]
+
a[7]
-
a[2*3];a[i]=
a[i]
+1;a[
a[0]
]
=
a[1]55一维数组元素的[例]
#include
<stdio.h>main(){int
i,a[10];for(i=0;i<=9;i++)a[i]=i;for
(i=9;
i>=0;i--)printf("%d",a[i]);}987654321066一维数组元素的说明:一个数组元素实质是一个变量名,代表一个内存单元,一个数单元组占有一串连续的如:int
arr[4]={5};arr[0]=arr[1]+2;数组不能整体如:int
arr[10]=0,arry[10];arry=arr;单元下标表达式的值必须是整数,下标表达值的下限为0编译时不会检查下标越界,一旦越界可能会破坏其他中的数据,甚至程序代码7一维数组的初始化8定义数组时,系统开辟一串连续的内存单元,但无确定值。因此在使用前必须赋值初始化:在定义时给各个元素赋值方法:从数组的第一个元素开始依次给出初始值表;表中各值之间用逗号分开,并用一对大括号括起来。例:int
a[10]={0,1,2,3,4,5,6,7,8,9};只给一部分元素赋初值,后面的元素自动补0int
a[10]={0,1,2,3,4};等价于
int
a[10]={0,1,2,3,4,0,0,0,0,0,0};9一维数据的初始化欲使一个数组中全部元素初值为0,可写成:int a[10]={0,0,0,0,0,0,0,0,0,0};或
int a[10]={0};char
c[5]={‘\0’};在对全部数组元素赋初值时,可以不指定数组长度int a[]={0,1,2,3,4,5};等价于
inta[6]={0,1,2,3,4,5};例:inta[10]={1*10};printf(“%d”,a[2]);结果为?一维数组的初始化如果在定义时没有赋值,那在后面的程序段只能依次为每个元素赋值a[10]={0};[例]
#include
<stdio.h>main(){int
i,a[10];printf(“%d”,a[0]);}for(i=
0;i
<=
9;i++)scanf("%d",&a[i]);[例]
#include
<stdio.h>main(){int
i,a[10];printf(“%d”,a[0]);}10程序举例编写程序,定义一个含有10元素的int类型数组,依次给数组元素赋偶数2,4,6,8….,然后逆序输出119.2
一维数组和指针1.一维数组元素的地址和一维数组名a[0]a[1]a[2]a[3]a[9]整型指针p...&a[0]p12例:int
a[10];数组元素a[0]----a[9],都是整型变量,因此都有一个地址:&
a[i](0<=i<=9)例:inta[10];数组名是表示数组首地址的地址常量p=a;
等价于:p=&a[0];9.1
一维数组和指针1.一维数组元素的地址和一维数组名a[0]a[1]a[2]a[3]a[9]整型指针p...****a设:inta[10],*p;数组名是表示数组首地址的地址常量对于一维数组a,数组名a是数组元素
a[0]的地址,即&a[0]与a是等值的。属性也相同,都是int
的地址。&a[1]是数组元素的地址;
&a[2]是数组元素的地址;&a[i](0<=i<=9有效)是数组元素的地址;a++;
a=&a[3];13设有:int
i,a[10],*p,
*p1,
*p2;则:p=&i;p=a;(将变量i地址p)(将数组a首地址p)p1=&a
[i]; (将数组元素地址p1)p1=p2; (指针变量p2值p1)不能把一个整数p,也不能把p的值整型变量如
int
i,
*p;p=1000;i=p;()()指针变量所指的变量的数据类型只能是它的基类型1415指针变量与一维数组的关系设有:int
*p
与
int
a[10]数组名是指针(地址)常量若已有p=a;
即已使p指向了a[0];则p+i
是a[i]的地址数组元素的表示方法:下标法和指针法,
即若:
p=a;则
p[i]
a[i]
*(p+i)
*(a+i)形参数组实质上是指针变量,即int a[
]
int*a在定义指针变量(不是形参)时,不能把int
*p
写成intp[];系统只给p分配能保存一个指针值的内存区(4字节);而给a分配4*10字节的内存区a[0]a[1]a[2]a[3]a[9]整型指针p...&a[0]pa+1是数组元素a[1]的地址;即:&a[1]a+i是数组元素a[i]的地址;即:&a[i]a(即a+0)是a[0]的地址;即:&a[0]通过数组的首地址设:inta[10],*p=a;数据元素for
(k=0;k<10;k++
)printf(“%4d”, *(a+k)
);等价于:printf(“%4d”,
a[k]);16a[0]a[1]a[2]a[3]a[9]整型指针p...&a[0]pp=a;p指向a数据的首地址*p
*(&a[0])
a[0]*(p+1)
*(&a[0]+1)
a[1]通过指针 一维数据元素设:inta[10],*p=a;for
(k=0;k<10;k++
)printf(“%4d”, *(p+k));等价于:printf(“%4d”,
a[k]);17a[0]a[1]a[2]a[3]a[9]...aa+1a+2a+9元素下标法
指针法a[0]a[1]a[2]a[3]a[9]...地址 地址元素*p*(p+1)*(p+2)*(p+9)(3)数组元素表示方法[]
变址运算符18a[i]
*(a+i)a[0]
*a
pa[1]
*(a+1)
p+1a[2]
*(a+2)
p+2a[9]
*(a+9)
p+9a[i]
p[i]
*(p+i)
*(a+i)p[0]p[1]p[2]p[9]要注意的几点是:指针和数组名是有区别的:指针是一个变量,其值是地址,指针可以自减或自加,表示指针前后移动;数组名是一个地址它是在系统为数组分配存贮单元时确定的,是一个常量所以数组名不能自增自减,也不能在赋值语句中作左值。如:int
a[4];a=3;a++;都是错误的19a[0]a[1]a[2]a[3]a[9]整型指针p...&a[0]p例:已定义如右图的数组,程序运行后输出结果分别为int
a[10]={0};int
i;for(i=0;i<10;i++)
a[i]=i;)p=a;
printf(“%d\n”,*p++);p=a; printf(“%d\n”,*a++);
(p=a; printf(“%d\n”,
(p++)>=a);p=a; printf(“%d\n”,
*(a+3)
);p=a; printf(“%d\n”,
*(p+5)
);p=a; printf(“%d\n”,
(p++)-a
);209.3
函数之间对一维数组和数组元素的应用9.3.1
数组元素作实参数组元素和普通的变量一样,在函数中只能对该变量进行操作,不能直接对应的数组元素,更不能再函数内改变对应数组的值。219.3
函数之间对一维数组和数组元素的应用9.3.1
数组名作实参数组名是地址,对应形参应当是一个指针变量。可以通过指针变量、操作调用函数中对应数组元素。#define
M
10f(int
x[
],int
n){…}main(
){int
a[M];…f(a,M);…}对应的形参可以是x[],x[M],或者*x。都是把实参的首地址传递给形参。传递的不是整个数组被调用函数中,并没有为对应的形参另外开辟一串存储单元,而只是开辟了一个指针变量的
单元。2223例:输出数组中的值#include<stdio.h>void
print(int
x[10],int
n){int
i;for(i=0;i<n;i++)printf((i+1)%5==0?“%4d\n”:”%4d”,x[i]
);}main(){int
a[10];int
i;for(i=0;i<10;i++)
scanf(“%d”,&a[i]);print(a,10);}249.3函数之间对一维数组和数组元素的应用9.3.2
数组元素地址作实参和数组名作实参情况相同。f(int
x[
],int
n){…}main(
){int
a[10];…f(&a[4],10);…}把实参的首地址(&a[4])传递给形参。25#include<stdio.h>void
print(int
*x,int
n){int
i;for(i=0;i<n;i++)printf((i+1)%5==0?“%4d\n”:”%4d”,x[i]
);}main(){int
a[10];int
i;for(i=0;i<10;i++)
scanf(“%d”,&a[i]);print(&a[1],8);}9.3函数之间对一维数组和数组元素的应用9.3.3
函数的指针形参和函数体中的数组的区别#define
N
10int
*
f(int
x[N],int
n){int
b[N];…return
b;}main(
){int
a[10],*p;…p=
f(a,10);…}形参在形式上写x[],x[M],或者*x。x都被当做一个指针变量处理。可进行x++等操作。f函数中的b数组,b是一个地址常量,不可以重新赋值。f函数被调用结束, 内存,p不指向任何对象成为“无向指针”2627例求学生的平均成绩#include
<stdio.h>float
average(int
stu[10],
int
n);void
main(){int
score[10],
i;float
aver;printf("Input
10
scores:\n");for(
i=0;
i<10;
i++
)scanf("%d",
&score[i]);aver=average(score,10);printf("Average is:%.2f",
av);}float average(float
stu[10],
int
n){
int
i;float
aver,sum=0;for(
i=1;
i<n;
i++
)sum
+=
stu[i];aver
=
sum/n;retur
;}实参用数组名012..9score122356….….88stu例数组元素与数组名作函数参数比较#include
<stdio.h>void
swap2(int
x,int
y){ int
z;z=x;
x=y;
y=z;}main(){ int
a[2]={1,2};swap2(a[0],a[1]);printf("a[0]=%d\na[1]=%d\n",a[0],a[1]);}值传递28例数组元素与数组名作函数参数比较#include
<stdio.h>void
swap2(int
x
[]){ int
z;z=x[0];
x[0]=x[1];x[1]=z;}main(){ int
a[2]={1,2};swap2(a);printf("a[0]=%d\na[1]=%d\n",a[0],a[1]);}地址传递29309.5
二维数组的定义(1)1、一般形式:类型说明符
数组名[常量表达式][常量表达式]例如:int
a[3][4];包含:a[0][0],a[0][1],a[0][2],a[0][3]a[1][0],a[1][1],a[1][2],a[1][3]a[2][0],a[2][1],a[2][2],a[2][3]定义了一个3*4(3行4列)的数组.注意:
不能写成
int
a[3,4];二维数组的定义(2)可以把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组.例如:inta[3][4];/*定义了一个3*4(3行4列)的数组.*/我们可以将a看成一个一维数组:a[0]、a[1]、a[2],每个元素又是包含4个元素的一维数组。a[0]a[1]a[2]---------a[0][0]31a[0][1]a[0][2]a[0][3]---------a[1][0]a[1][1]a[1][2]a[1][3]---------a[2][0]a[2][1]a[2][2]a[2][3]a二维数组的存放2、存放顺序:按行存放,即在内存中先顺序存放第一行的元素,再存放第二行的元素。int
a[3][4];a[0][0]
a[0][1]
a[0][2]
a[0][3]a[1][0]
a[1][1]
a[1][2]
a[1][3]a[2][0]
a[2][1]
a[2][2]
a[2][3]321、数组元素的表示形式:数组名[下标][下标]例如:a[3][4]区分在定义数组时用的a[3][4]和下标可以是整型表达式例如:a[2-1][2*2-1]二维数组的元素a[3][4]数组元素可以出现在表达式中,也可以被赋值。例如:b[1][2]=a[2][3]/2;2、注意:使用数组元素时,下标值应该在定义的数组大小的范围内。不要出现这样的错误:例如:int
a[3][4];a[3][4]=3;33二维数组的初始化(1)1、分行给二维数组赋初值。例如:int
a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};1234567891011122、可以将所有数据写在一个花括弧内,按数组排列的顺序对各元素赋初值。例如:int
a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};12345678910111234二维数组的初始化(2)3、可以对部分数据赋初值。例如:int
a[3][4]={{1},{5},{9}};100050009000例如:int
a[3][4]={{1},{5,6}};100056000000例如:int
a[3][4]={{1},{},{0,0,11}};100000000011035二维数组的初始化(3)4、如果对全部元素赋初值(即提供全部初始数据),则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。例如:
int
a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};等价于:int
a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};1234567891011120030000001000定义时也可以赋值部分元素而省略第一维的长度,但应分行赋初值。
第1维长度由以下规则确定:a当初值个数能被第二维的常量表达式整除时,商就是第一维的大小。b不能整除时:第一维的大小=商+1例如:int
a[][4]={{0,0,3},{},{0,10}};36(4)打印3*4的矩阵main(){int
i,j,row=0,colum=0,max;int
a[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};max=a[0][0];for(i=0;i<=2;i++){for(j=0;j<=3;j++)printf(“%4d”,a[i][j]);printf(“\n”);}}运行结果为:371
2
3
4<CR>9
8
7
6<CR>-10
10 -5
2<CR>(4)38例有一个3*4的矩阵,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号.main(){int
i,j,row=0,colum=0,max=0;int
a[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};for(i=0;i<3;i++){for(j=0;j<4;j++)if(a[i][j]>max)
{max=a[i][j];
row=i;colum=j;}}printf(“max=%d,row=%d,colum=%d\n”,max,row,
colum);}9.6
二维数组和指针a[0]---------a[0][0]a[0][1]a[0][2]a[0][3]a[1]---------a[1][0]a[1][1]a[1][2]a[1][3]a[2]---------a[2][0]a[2][1]a[2][2]a[2][3]可以把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组.例如:int
a[3][4];/*定义了一个3*4(3行4列)的数组.*/int
*p=a[i];我们可以将a看成一个一维数组:a[0]、a[1]、a[2],每个元素又是包含4个元素的一维数组。aa[0],a[1],a[2]都是一维数组名,同样也代表一个不可变的地址常量。其值为二维数组每行第一个元素的地址。若表达式a[0]+1,表达式中1应该是4个单位(VC)。若有p=a[i],合法。因为a[i]=*(a+i),所以与p=*(a+i)等价39二维数组名也是一个地址值常量例如:int
a[3][4];int
*
p;二维数组名也是一个地址常量,其值为二维数组中第一个元素的地址。a的值与a[0],a+1的值与a[1],相同,a+2的值与a[2]相同,分别表示a数组的第一、第二、第三行的首地址。所以二维数组名是一个行指针。p=a;p=a[i];合法int
a[3][4];a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]aa+140int
a[3][4];a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]二维数组元素表示形式:(1)a[1][2](2)*(a[1]+2)(3)*(*(a+1)+2)(4)*(&a[0][0]+1*4+2)地址表示:a+1&a[1][0]a[1]*(a+1)属性为行指针属性为元素指针地址表示:&a[1][2]a[1]+2*(a+1)+2(4)&a[0][0]+1*4+241二维数组元素的地址42则:a[i][j];*(a[i]+j)*(*(a+i)+j)*(&a[0][0]+4*i+j)int
a[3][4];a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]9.6.3指针数组(多个指针)指针型变量的每个元素是地址性的。指针数组中每一个变量是指针可以指向一行。定义:int
*p[3];int
a[3][4];p[i]=a[i]p[3]就是指针数组,p[0],p[1],p[2]中各可存放三个地址值指向目标:int
*pa[]={a[0],
a[1],a[2]};pa[0]
是数组a第一行的行地址a[0],pa[1]
是数组a第二行的行地址a[1],pa[2]
是数组a第三行的行地址a[2]。43可见,通过指针数组的元素,可以得到每一行的行地址a[i],通过行指针a[i],可以找到该行的第j列的元素,所以,用指针数组表示数组的任一个元素a[i][j]的方式如下:*(pa[i]+j),
pa[i][j]449.6.4
行指针变量(一个指针)定义形式:数据类型(*指针名)[一维数组维数];int
(*p)[4]与int
*p[4]不同首地址,p是行指针可让p指向二维数组某一行如(i)nt不能a[3少][4],(*p)[4]=a;int
a[3][4];a[0][0]a[0][1]a[1][0]a[1][1]a[2][0]a[2][1]a[0][2]a[0][3]a[1][2]a[1][3]a[2][2]a[2][3]例
int (*p)[4];
int
a[3][4];
p=a;aa+2pp+1p的值是一维数组p[0的]+1或*p+1*(*p+1)或(*p)[1]p[1]+2或*(p+1)+2*(*(p+1)+2)p+245一维数组指针变量维数和a+1二维数组列数必须相同469.7
二维数组名和指针数组作为参数9.7.1
二维数组名作为实参时二维数组名作为实参时,对应的形参必须是一个行指针变量。int
fun(int
(*x)[N]){…}main(
){int
a[M][N],;…f(a);…}fun函数的形参可以是以下三种之一:fun(int(*x)[N])fun(intx[][N])fun(intx[M][N])列下标不可缺把x处理成一个行指针。并没有开辟一串
单元,而只是开辟了一个指针变量的 单元。voidfun(int x[][3],
int
row,
int
col){ int
i,j,result;for(i=0;i<col;i++){
result=0;for(j=0;j<row;j++)result+=x[j][i];x[0][i]=result;}}main(){ int
a[2][3]={3,6,9,1,4,7};int
row=2,col=3,i;fun(a,row,col);for(i=0;i<col;i++)printf(“a[0][%d]=%d\n”,i,a[0][i]);}运行结果为:a[0][0]=4a[0][1]=10a[0][2]=1647489.7
二维数组名和指针数组作为参数9.7.2
指针数组名作为实参时指针数组名作为实参时,对应形参必须是一个的指针数组形式int
fun(int
*x[N]){…}main(
){int
a[M][N],*ps[M];…for(i=0;i<M;i++)
ps[i]=s[i];f(ps);…}fun函数的形参可以是以下三种之一:
fun(int*x[N])fun(int*x[])fun(int**x)传递的是一维指针数组名493.
二维数组的指针作函数参数用指向数组元素的指针变量作参数用指向二维数组“行”的指针变量作参数用二维数组名作参数实参形参数组名a数组int
x[][4]数组名a指针变量int
(*q)[4]指针变量p1数组int
x[][4]指针变量p1指针变量int(*q)[4]指针变量p2指针变量int
*q若有定义:int
a[3][4];
int
(*p1)[4]=a;int
*p2=a[0];例
:
求二维数组中最大元素值j57683412j57683412iji13241517max=11
32
415
17max=7int
max_value(int array[][4]){ int
i,j,k,max;max=array[0][0];for(i=0;i<3;i++)if(array[i][j]>max)max=array[i][j];return(max);}main(){inta[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}};printf("max
value
is%d\n",max_value(a));}形参数组第一维维数可省略,第二维必须相同for(j=0;j<4;j++)
intarray[][4]50例:
求二维数组中各行元
和get_sum_row(int x[][3],
int result[]
,int
row,
int
col){ int
i,j;for(i=0;i<row;i++){
result[i]=0;for(j=0;j<col;j++)result[i]+=x[i][j];}}main(){ int
a[2][3]={3,6,9,1,4,7};intsum_row[2],row=2,col=3,i;get_sum_row(a,sum_row,row,col);for(i=0;i<row;i++)printf("The
sum
of
row[%d]=%d\n",i+1,sum_row[i]);}369147axresultsum_row181251例:
3个学生各学4门课计算总平均分,并输出第n个学生成绩main(){
void
average(float
*p,int
n);void
search(float
(*p)[4],int
n);float
score[3][4]={{65,52,79,60},{80,87,90,81},{90,99,100,98}};average(*score,12);search(score,2);}void
average(float
*p,int
n){ float
*p_end,
sum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}void
search(float
(*q)[4],
int
n){ int
i;printf("
No.%d
:\n",n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《装饰施工图范例》课件
- 2023年水处理剂项目筹资方案
- 危险废物相关法律法规及规范化管理培训 课件
- 机械制图测试题及参考答案
- 东莞市长安实验中学2023-2024学年八年级上学期期末考试数学试卷
- 养老院老人生活娱乐设施管理制度
- 养老院老人健康监测服务质量管理制度
- 投资养殖合同(2篇)
- 2024年版:临时建设设施买卖合同规范
- 2025年阿克苏货运车从业考试题
- 完整版场记单模板
- 实木家具工艺标准(全流程)
- 高一语文必修一4篇古文 词类活用(课堂PPT)
- 商业发票Commercial Invoice模板2
- OPERA系统培训ppt课件
- 电镀工艺-电镀镍
- 幼小衔接中幼儿园与小学合作的国内外研究现状分析
- 110Kv输变电工程电气安装技术交底
- 录屏软件Camtasia_Studio使用教程
- 工厂常用英语
- 海上平台场址工程地质勘察规范
评论
0/150
提交评论