第四章 数组
★ 内容提要:
数组的定义说明规则
数组名与数组元素的引用
数组的存储结构形式
数组作参数的传地址方式
数组为基础的算法应用
字符数组应用与编程
? 一维数组定义说明
? 数组的传地址方式
? 一维数组的引用
? 数组、算法与应用
? 字符数组与应用
? 多维数组与存储结构
数组是同类型数据元素的有序集
合, 即数组由基本类型(整型、实
型、字符、指针等变量)组合而成。
这种组合可以层层组合,但最低一
级的成员必须由基本类型的元素构
成,即数组元素必须是基本类型的
量。
数组必须先定义后使用 。 定义形式:
4, 1 一维数组的定义与说明
类型表识符 数组名 [ 常量表达式 ], …… ;
说明:
① [ ],为数组下标运算符;在此表示定义一个指定
名称的数组并为其开辟由常量表达式确定大小的连续
的存储空间;
② 数组名,代表该数组存储空间的起始地址,取名规
则同变量;
④ 数组的下标,从 0 开始,最后一个元素的下标应为
,数组长度 - 1, 。
例:设有 i nt a [ 1 0 ] ; 则数组的大小为 10,其元素有:
a[0],a[1],a[2],a[3],??, a[9]
③ 常量表达式,其值作为所定义数组的长度(大小)。
定义数组时必须指定数组的大小,不能包含变量,且
必须是正的整型常量表达式。
数组必须先定义后使用 。 定义形式:
类型表识符 数组名 [ 常量表达式 ], …… ;
⑤ 定义数组时必须指定 数组的大小:只有两
种情况(场合)可以省略数组 长度的说明,而
用 [ ] 替代。
? 一是数组名作为被调函数的参数,其存储空
间和大小由主调函数的实参数组传递确定。
数组必须先定义后使用 。 定义形式:
类型表识符 数组名 [ 常量表达式 ], …… ;
main( ){
static char str1[30]={, zhang jia, };
static char str2[30]={, zhang yi, };
……
strcmp( str1,str2 );
……
}
int strcmp(char s[ ],char t[ ] ){ …… }
数组名代表数组存储单元的起始地址,数组名
作为函数的参数,其数据传递方式属传地址方式
。其实质是形参和实参共享存储空间。以达到数
据双向传递的目的。
? 一是数组名
作为被调函数
的参数,其存
储空间和大小
由主调函数的
实参数组传递
确定。
main( ){
static char str1[30]={, z hang jia, };
static char str2[30]={, z hang y i, };
……
strcmp( str1,str 2 );
……
}
strcmp(char s[],char t[] )
{
……
}
通过传地址方式实现
双向传递
0
z h a n g □ j i ……
1 2 3 4 5 6 7 …… 29
a \ 0
8 9 10str1
2000
mai n()
□
……
0
z h a n g □ y i ……
1 2 3 4 5 6 7 …… 29
\ 0
8 9 10str2
3000
□
蓝线表示传递红蓝线表示传递红
线表示指向线表示指向
strcm p()
s
4000
t
4004
2000 3000
⑤ 定义数组时必须指定 数组的大小:只有两
种情况(场合)可以省 略一维数组长度的说明,
而用 [ ] 替代。
数组必须先定义后使用 。 定义形式:
类型表识符 数组名 [ 常量表达式 ], …… ;
? 二是静态 的局部数组或外部数组赋初值时,
对数组赋初值意味着对全体数组元素赋初值,
数组的长度可由初值个数确定。但当初值的个
数不等于数组元素个数时长度必须显式说明。
main( ){
static char str1[30]= { ? z ?,? h ?,? a ?,? n ?,? g ?,? □ ?,? j ?,? i ?,? a ?,? \ 0 ? };
static char str2[30]= { ? z ?,? h ?,? a ?,? n ?,? g ?,? □ ?,? y ?,? i ?,? \ 0 ? };
……
} 0
z h a n g □ j i
1 2 3 4 5 6 7
a \ 0
8 9str1
2000
□
0
z h a n g □ y i
1 2 3 4 5 6 7
\ 0
8str2
3000
□
? 二是静态的局部数组或外部数组赋初值时,对数组
赋初值意味着对全体数组元素赋初值,数组的长度可
由初值个数确定。但当初值的个数不等于数组元素个
数时长度必须显式说明。
以字符形式一
个一个赋初值,
则串结束符必须
由程序员添加。
4, 2 一维数组的引用
( 1 )以数组元素出现在变量能出现的任何地方 。数组
元素为单值变量,代表相应存储单元的值,同一般变
量,只是表示形式不同。
元素表示形式,数组名 [ 下标 ]
( 2 )以数组名作函数调用的参数 。数组名代表该数组
的起始地址,数组名作参数,其实质是以传地址方式
传递数据,实现形参和实参 共享存储空间,具有带值
返回的功能。
C 规定,只能以逐个引用数组元素
的方式,不能在运算中一次引用整个
数组,即不能整体操作,而必须以元
素作为操作数单独处理。
7, 2 一维数组的引用
根据数组的存储结构特征在程序
设计应用领域中有许多重要应用
数组应用示例介绍
根据数组的存储结构特征在程序
设计应用领域中有许多重要应用
数组应用示例介绍
例 [4 - 1] 用选择法对数组中 5 个整数按由小到大排序。
选择法排序算法描述:
① 在 n 个待排序元素中选取最小数与第一个元素交换
构成:
[ 有序组( 1 ) ] [ 无序组( n - 1 ) ]) )
② 在无序组中继续选取最小值,添加到有序组中的尾
部,即与无序组第一个元素交换),使得:
③ 如此重复②共 n - 1 次,即构成有序组。
[ 有序组 +1] [ 无序组 - 1 ]
void main(){
int i; static i nt a[5]={ 5,3,2,4,1 } ;
selec tsort( a,5 );
for( i= 0; i< 5; i+ + ) pri ntf( " % 6d ",a[i] );
printf( " \ n" );
}
array
a
5 3 2 4 1
0 1 2 3 4
i
k
j
执行排序前的初始状态
执行排序算法
过程的演示
(第二趟)
0 1 2 3 4
array
a
5 3 2 4 1
i
k
j
第二趟排序结束状态
1 5
通过中间变量 t 交换 2
t
2 3
void sel ectsort( int array[],i nt n){
int i,j,k,t;
for(i =0; i <n - 1; i ++){
k=i;
for(j=i +1; j<n; j ++)
if (array[j]<array[k]) k=j; / /k 标记最小值的下标
if (k!=i ){
t=array[k]; array[k]=array[i]; array[i]= t;
}
}
}
执行排序算法
过程的演示
(第三趟)
0 1 2 3 4
array
a
5 3 2 4 1
i
k
j
第三趟排序结束状态
1 5
2
t
2 3
已经有序不再交换
void sel ectsort( int array[],i nt n){
int i,j,k,t;
for(i =0; i <n - 1; i ++){
k=i;
for(j=i +1; j<n; j ++)
if (array[j]<array[k]) k=j; / /k 标记最小值的下标
if (k!=i ){
t=array[k]; array[k]=array[i]; array[i]= t;
}
}
}
执行排序算法
过程的演示
(第四趟)
0 1 2 3 4
array
a
5 3 2 4 1
i
k
j
第四趟排序结束状态
1 5
2
t
2 3
已经有序不再交换
4
void sel ectsort( int array[],i nt n){
int i,j,k,t;
for(i =0; i <n - 1; i ++){
k=i;
for(j=i +1; j<n; j ++)
if (array[j]<array[k]) k=j; / /k 标记最小值的下标
if (k!=i ){
t=array[k]; array[k]=array[i]; array[i]= t;
}
}
}
# include < stdio.h> // 选择排序, c 源程序
void selec tsort(int array[],i nt n){
int i,j,k,t;
for(i= 0; i< n - 1; i+ +){
k=i;
for(j= i+ 1; j<n; j+ +)
if(arr ay[j]<ar ray[k]) k=j; //k 标记最小值的下标
if(k!=i ){
t=ar ray[k]; array[k]= array[i ]; array[i ]=t;
}
}
}
void main(){
int i; static i nt a[5]={ 5,3,2,4,1 } ;
selec tsort( a,5 );
for( i= 0; i< 5; i+ + ) pri ntf( " % 6d ",a[i] );
printf( " \ n" );
}
array
a
5 3 2 4 1
0 1 2 3 4
i
k
j
执行排序前的初始状态
void main(){
int i; static i nt a[5]={ 5,3,2,4,1 } ; ……
}
? 对数组初始化时,初值的个数不能多于数组元素的
个数,但允许初值的个数 少于数组元素的个数。当初
值的个数少于数组元素个 数时,就以出现在初值表中
的初值的顺序对数组元素 从头开始依次赋值,而其余
的数组元素隐含用 0 赋初值。
若有 static int a[5]={ 5,3,2 };
则 a[0] ~ a[2] 分别被赋予 5,3,2 。而 a[3] ~ a[4]
隐含用 0 赋初值。
数组初始化时应注意问题,
例 [4 - 2] 数组筛选法求 1 ~指定数之间的素数。
数组初始状态与数据 关系, 所求数据与下标对应;
设指定 n 值内的所有数都为素数置 1 。
数组筛选法算法描述:
① 2 是素数,打印并去除指定范围内的该素数的倍数;
② 下一个不为 0 的元素是素数,打印并去除指定范围
内的该素数的倍数;
③ 如此依次进行下去,直至完成。
li ne
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 …
1 1111111111 1 …1111
输出,2
li ne
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 …
1 0101010111 1 …1010
输出,2输出,2 3
数组筛选法算法描述:
① 2 是素数,打印并去除指定范围内的该素数的倍数;
② 下一个不为 0 的元素是素数,打印并去除指定范围
内的该素数的倍数;
③ 如此依次进行下去,直至完成。
例 [4 - 2] 数组筛选法求 1 ~指定数之间的素数。
数组初始状态与数据 关系, 所求数据与下标对应;
设指定 n 值内的所有数都为素数置 1 。
li ne
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 …
1 0001010111 1 …0010
输出,2输出,2 3输出,2 3 5
数组筛选法算法描述:
① 2 是素数,打印并去除指定范围内的该素数的倍数;
② 下一个不为 0 的元素是素数,打印并去除指定范围
内的该素数的倍数;
③ 如此依次进行下去,直至完成。
例 [4 - 2] 数组筛选法求 1 ~指定数之间的素数。
数组初始状态与数据 关系, 所求数据与下标对应;
设指定 n 值内的所有数都为素数置 1 。
li ne
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 …
1 0001010111 1 …0010
输出,2输出,2 3输出,2 3 5输出,2 3 5 72 3 5 7 11 …
数组筛选法算法描述:
① 2 是素数,打印并去除指定范围内的该素数的倍数;
② 下一个不为 0 的元素是素数,打印并去除指定范围
内的该素数的倍数;
③ 如此依次进行下去,直至完成。
例 [4 - 2] 数组筛选法求 1 ~指定数之间的素数。
数组初始状态与数据 关系, 所求数据与下标对应;
设指定 n 值内的所有数都为素数置 1 。
void sus hu(int n ){ // 源程序
int i,j;
char li ne[1000];
for(i= 0; i< =n; i+ + )
line[i ]=1; // 设指定值 n 内的数都为素数
for(i= 2; i< =n; i+ +){
if( li ne[i] ){ // 不为 0 的元素为素数
printf(" % 6d",i); // 打印素数 i
for(j= i+ 1; j<= n;j++ ) // 去除当前素数的倍数
if(j % i= =0) line[j]=0;
}
}
}
void main(){
int n;
scanf(" % d",&n);
sus hu( n );
}
运行结果
输入,100
输出,2 3 5 7 11 13 17 19
23 29 31 37 41 43 47 53
59 61 67 71 73 79 83 89
97
例 [4 - 3] 折半查找编程。 折半查找又称二分查找,要
求待查记录数据排列有序
查找过程, 先确定待查记录数据 key 所在范围(区间),
然后逐步缩小范围,直到找到或找不到为止。
查找方法,
1) 查找从数组的中间元素开始,求中间元素的下标;
2) 将 key 与中间元素比较,得到三种结果并分别处理:
< key, 待查记录在数组 r 的右半部》
r[mid] ==key, 查找成功》
> key, 待查记录在数组 r 的左半部》
《
《
《
// 折半查找 功能函数
int binarysearch(int r[ ],int n,int key){
int low,mid,high;
low=0; high=n - 1;
while(low<=high){
mid=(low+high)/2;
if(key>r[mid])low=mid+1;
else if(key==r[mid]) return(mid);
else high=mid - 1;
}
return - 1;
}
void main(){
static int a[11]={ 5,13,19,21,37,56,64,
75,80,88,92};
int i,k;
scanf("%d",&k);
i=binarysearch( a,11,k );
if(i!= - 1)
printf("a[%d]=%d \ n",i,a[i]);
else
printf("not found!");
}
运行结果,
输入,19
输出,a[2]=19
4, 3 字符数组
在 C 语言中,字符串可通过 字符数组
表示,具体操作通过字符数组元素的运
算实现。
一、字符数组定义说明
char 数组名 [ 常量表达式 ], ?? ;
例,ch a r n a m e [ 2 0 ] ;
注意:
scanf("%s",name);
① 用, % s " 输入串遇空格结束(即不能包 含空格),
因此输入串的中间不能出现空格,否则将作为串输入
结束处理;
② 数组名代表该数组存储单元的起始地址,故作为输
入参数不用 ' & ' 取地址符;
③ 用, % s, 输入串,系统将自动在串尾加 ' \ 0 ' 结束符;
③ 正确区分:字符串长度与数组长度两个不同的概念。
注意:
printf("%s %c",name, name[0] );
与, % s, 对应的输出参数要求为字符数组名
(地址常量)或字符串的起始地址,系统从第
一个字符起依次输出串内容,直至遇 ‘ \ 0 ’ 串
结束符结束。
与, % c, 对应的输出参数要求为字符型量。
功能:
gets(name); puts(name);
gets( 存放字符串的起始地址 ),从键盘读入一
个字符串到指定存储空间。函数的返回值是:
若读取成功则是存放字符串的起始地址;
否则若遇文件结束标志或出错则返回 NULL ;
puts( 存放字符串的起始地址 ), 将一个字符串
输出到显示屏,并输出后自动换行。
例 [4 - 4] 介绍一个字符串比较程序
两个串是相等的,当且仅当它们的长度相
等并且各个对应位置上的字符都相同,若对应
位置上的字符逐个比较中一旦出现不同,则就
根据这两个对应字符在 ASCII 码表中的位序确
定两串的大小。两串相比可得三种结果:
1) 前串大于后串,返回大于 0 的正数;
2) 两串相等,返回 0 ;
3) 前串小于后串,返回小于 0 的负数。
# define N 30
int compst(char s[],char t[]){
int i=0;
while(s[i]==t[i] && s[i]!=' \ 0')
++i;
return(s[i] - t[i]);
}
void main(){
char str1[N],str2[N];
gets(str1); gets(str2);
puts(str1); puts(str2);
printf("%d \ n",compst( str1,str2 ));
}
数组名代表该
数组存储空间的
起始地址,数组
名作为函数参数
,其数据传递方
式属传地址方式
,其实质是形实
数组共享存储空
间 ( 双向传递 ) 。
# define N 30
int compst(char s[],char t[]){
int i=0;
while(s[i]==t[i] && s[i]!=' \ 0')
++i;
return(s[i] - t[i]);
}
void main(){
char str1[N],str2[N];
gets(str1); gets(str2);
puts(str1); puts(str2);
printf("%d \ n",compst( str1,str2 ));
}
输入:
Z h ang jia ↙
z hang yi ↙
输出:
z hang jia
z hang yi
- 15
// 使用 scanf(, %s %s,,str1,str2) 输入串的源程序
# include <stdio.h>
#define N 30
int compst(char s[],char t[]){
int i=0;
while(s[i]==t[i] && s[i]!=' \ 0')
++i;
return(s[i] - t[i]);
}
void main(){
char str1[N],str2[N];
scanf("%s%s",str1,str2);
printf("%s \ n%s \ n",str1,str2);
printf("%d \ n",compst( str1,str2 ));
}
注意, 用 " % s " 输入
串遇空格结束(即
不能包含空格),
因此输入串的中间
不能出现空格,否
则将作为串输入结
束处理;
输入,zhang jia
输出,zhang
jia
16
注意,以字符串常数形式赋初值时,系统在存
储时自动为串加串结束符 ‘ \ 0 ’,若以单字符
形式为数组赋初值,则串结束符 ‘ \ 0 ’ 必须由
程序员显式添加。字符数组定 义本身并不一定
要 ‘ \ 0 ’,但为了求字符串的长度、字符串比
较、字符串拷贝、打印等处理,及与系统为字
符串常数自动附加 ' \ 0 ' 这一规定匹配,因此以
单字符形式为数组赋初值时应显式添加 ' \ 0 ' 。
char name[20]={ 'c','h','i','n','a',' \ 0'};
main(){ …… }
例 [4 - 5] 介绍几个字符串处理函数的编程。
void main(){
static char s1[80]= {" test"},s2[80]={" test2"},s3[80];
void str_cat(char s[],char t[]); // 串连接函数原型说明
int str_cmp(char s[],char t[]); // 串比较函数原型说明
void str_cpy(char s[],char t[]); // 串拷贝函数原型说明
int index (c har s[],char t[]); // 求子串位序函数原型
str_cat( s1,"1" ); puts (s1);
printf(" % d \ n",str_cmp( s1,s 2 ));
str_cpy( s3,s2 ); p uts(s 3);
printf(" % d \ n",index ( s1," es" ));
}
void main(){ // 调用串连接函数,实现串连接。
…… ; str_cat( s1,"1" ); puts (s1); ……
}
void str_cat( char s[ ],char t[ ] ){
int i,j;
for( i= 0; s[i]!=' \ 0'; i+ + ) ;
for( j= 0; (s[i++ ]=t[j+ +])!= ' \ 0'; ) ;
}
s1
0 1 2 3 4 5 6 7 8 9 10 …
t \ 0tse …
…
…
i
地址
0 1
1 \ 0
j
s
t
1 \ 0
注意, 字 符 串
常 数 作 为 实 参
时, 数 据 传 递
方 式 为 传 地 址
方式。
② 连接串 s[]
的存储空间必
须足够的大。
void main(){ // 调用串比较函数,实现串的比较。
…… ; printf(" % d \ n",s tr_cmp( s1,s2 )); ……
}
int str_cmp( char s[ ],char t[ ] ){
int i= 0;
w hile( s[i]==t[i ] ) if( s[i+ +]= =' \ 0 ? ) return( 0 );
return( s[i] - t[i] );
}
s1
0 1 2 3 4 5 6 7 8 9 10 …
t 1tse …
…
…
i
s
\ 0
s2
0 1 2 3 4 5 6 7 8 9 10 …
t \ 02tse …
…
…
t
依次逐位比较,相应位不同
或遇串结束符则比较结束!
void main(){ // 调用串复制函数,实现串的复制。
…… ; str_cpy( s3,s2 ); p uts(s 3); ……
}
void str_cpy( char s[ ],char t[ ] ){
int i= 0;
w hile(( s[i] =t[i ] )!=' \ 0 ? ) i+ +;
}
s3
0 1 2 3 4 5 6 7 8 9 10 …
…
…
…
i
s
s2
0 1 2 3 4 5 6 7 8 9 10 …
t \ 02tse …
…
…
t
依次逐位复制,直至
到字符串结束符结束!
t e s t 2 \ 0
void main(){
static char s1[80]= {" test"},s2[80]={" test2"},s3[80];
void str_cat(char s[],char t[]); // 串连接函数原型说明
int str_cmp(char s[],char t[]); // 串比较函数原型说明
void str_cpy(char s[],char t[]); // 串拷贝函数原型说明
int index (c har s[],char t[]); // 求子串位序函数原型
str_cat( s1,"1" ); puts (s1);
printf(" % d \ n",str_cmp( s1,s 2 ));
str_cpy( s3,s2 ); p uts(s 3);
printf(" % d \ n",index ( s1," es" ));
}
运行结果:
test1
-1
test2
1
对两个字符串 str1[] 和 str2[] 比较不能用以下形式:
if( str1== str2 ) print f( "yes !");
只能采用字符串比较函数逐位比较确定,如下所示:
if( str_cmp( str1,str2 )==0 )p ri nt f( "yes !");
特别提示:
程序调试技巧,采用 分段插入打印语句,打印
跟踪数据变化,定位错误发生区间与位置,分
析数据确定错误原因,是一种有效的调试程序
方法。
void main(){
char str[20]; float atof(char s[ ]);
gets(str); printf("%f \ n",atof(str));
}
str
0 1 2 3 4 5 6 7 8 9 10 …
□ \ 054.321-□ …
i
=(0*10)+10
1
= 1*10
=((0*10)+1)*10+2= (((0*10)+1)*10+2)*10+3=((((0*10)+1)*10+2)*10+3)*10+4=(((((0*10)+1)*10+2)*10+3)*10+4)*10+5
(1*10)*10
s
val
pow
112123123412345
10100
结果:符号× val ÷ pow=123.45
输入:, □□ - 123.45, 输出,- 123.34
float atof(char s[ ]){
float val,power; int i,sign=1;
for(i=0;s[i]==' '||s[i]==' \ n'||s[i]==' \ t';i++);
sign=1;
if(s[i]=='+'||s[i]==' - ')
sign=(s[i++]=='+')? 1, - 1;
for(val=0; s[i]>='0'&&s[i]<='9'; i++)
val=10*val+s[i] - '0';
if(s[i]=='.') i++;
for(power=1; s[i]>='0'&&s[i]<='9'; i++){
val=10*val+s[i] - '0'; power*=10;
}
return( sign*val/power );
}
输入,-123.45
输出,-123.450000
对 atof(str) 函数的功能进行扩充,
使它能处理 - 123.45 e - 6 那样的指数表示
形式,其中指数以 E 或 e 表示,指数值可
正可负,C 规定指数部分占 4 位。
思考题:
例 [4 - 7] 打印输入正文中所 有含有字母 ‘ p ’ 和 ‘ P ’
的行;结合介绍一个自定义输入字符串的函数。 int
getline(char s[],int lim) 功能是读入一个字符串,
并返回该串的长度。
算法描述:
while( 当读入一行且长度不为 0 ){
循环判断该行是否有 ‘ p ’ 或 ' P ' ;
若有就打印;
}
void main(){
char line[500]; int k;
int getline(char s[],int lim);// 函数原型说明
while( getline(line,500)>0 )
for(k=0; line[k]!=' \ 0'; k++)
if(line[k]=='p'||line[k]=='P'){
printf("%s",line); break;
}
}
line
0 1 2 3 4 5 6 7 8 9 10 …
…
k
s
p \ 0\ ntnir ……
输入,print ↙
输出,print
line
0 1 2 3 4 5 6 7 8 9 10 …
…
k
s
w \ 0\ netir ……
输入,write ↙
输出:
输入,^ D
void main(){
char line[500]; int k;
int getline(char s[],int lim);// 函数原型说明
while( getline(line,500)>0 )
for(k=0; line[k]!=' \ 0'; k++)
if(line[k]=='p'||line[k]=='P'){
printf("%s",line); break;
}
}
line
0 1 2 3 4 5 6 7 8 9 10 …
…
k
s
w \ 0\ netir ……
输入,write ↙
输出:
输入,^ D
void main(){
char line[500]; int k;
int getline(char s[],int lim);// 函数原型说明
while( getline(line,500)>0 )
for(k=0; line[k]!=' \ 0'; k++)
if(line[k]=='p'||line[k]=='P'){
printf("%s",line); break;
}
}
说明:
① 字符串应该以 '\0'结束;
② ‘ \n?也是字符,也可作为
字符串的一部分;
③ EOF文件结束标志:
UNIX按 CTRL-D
Turbo C等按 CTRL-Z
4, 4 多维数组
一、定义形式
类型 数组名 [ 常量表达式 1][ 常量表达式 2] …… ;
例,
定 义,float a[3][4],b[10][40];
元素表示,a[i][j],b[i][j]
意 义,分别代表 a 和 b 数组中第 i 行第 j 列的元素
行 列 行 列
说明:
① 数组的维数没有限止;
② 在内存中按行优先存储。
以 a 数组为例:
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]
a[2]
A,a[0]
a[1]
a[ 0] [ 1]
a[ 0] [ 0]
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 数组可看
成是由 a[0], a[1], a[2] 三个元素组成,
而每一个元素又是由一 个一维数组组成的,
因此,可以把 a[0], a[1], a[2] 看成是一
维数组名,各代表一维数组的起始地址。
a[0]
a[1]
a[2]
a[2]
a
a[0]
a[1]
a[0] [ 1]
a[0] [ 0]
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
( 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] )
以此类推,当一个多维数组的元素(作为操
作数)出现时,各部分可理解为:
a[i][j][k] 是 元素代表值是 元素代表值
a[i][j] 一维数组名,代表一维数组的起始地址一维数组名,代表一维数组的起始地址
a[i] 二维数组名,代表二维数组的起始地址二维数组名,代表二维数组的起始地址
a 三维数组名,代表三维数组的起始地址三维数组名,代表三维数组的起始地址
层 行 列
④ 数组的引用(存取访问)只能以元素的形
式一个一个地进行。(除数组名作为函数的参
数及字符数组名可与 ‘ % s ’ 匹配作为输入输出
参数外)
for(i=0; i<3; i++)
for(j=0; j<4; j++)
scanf("%d",&a[i][j]);
??
for(i=0; i<3; i++)
for(j=0; j<4; j++)
printf("%4d",a[i][j]);
例 [4 - 8] 设有两个矩阵为:
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
6
5
4
6
5
4
333
222
111
BA
求乘积矩阵 C=AB 。 要求通过编制矩阵乘法的函
数 m a t p r o du c t ( ) 实现:
若 则计算公式为:pnnm
BAC
??
??
1,...,0,1,...,0
1
0
??????
?
?
?
pjmiBAC
n
k
kjikij
// 源程序文件如下:
void m atp roduct( int a [ ] [3],int b[ ][ 2],in t c[ ][ 2],
int n,int m,in t p ){
int i,j,k,s;
for(i=0; i<n; i++)
for(j= 0; j <p ; j ++ ){
for(k=s=0; k< m; k++)
s+=a[ i][k]*b [ k][j] ;
c[i][j] =s;
}
}
main () {
static int a[ 3][ 3]= {{1,1,1},{2,2,2},{3,3,3 }};
static int b [3] [2] ={{4,4},{5,5},{6,6}};
int c[3] [2],i,j;
mat produ ct(a,b,c,3,3,2);
for(i=0; i<3; i++ )
for(j= 0; j <2; j+ +)
printf ("%6d %c",
c[i][j],(( j+ 1)%2= =0)? ' \ n ?, ' ');
}
结果:
15 15
30 30
45 45
# include <stdio.h>
#include <math.h>
#define EPS 1e - 7
void main(){
double udf_sin(double x); // 用户自定义函数原型说明
double a; scanf("%lf",&a);
printf("%f %f \ n",udf_sin(a),sin(a));
}
double udf_sin( double x ){ // 用户自定义函数
double sum,term,n=1; sum=term=x;
while( fabs(term) > EPS ){
n=n+1;
term=term*( - x*x)/((2*n - 2)*(2*n - 1));Th e end
培 育 英 才 钻 研 科 学
书山有径勤为路
学海无边苦作舟
书山有径勤为路书山有径勤为路
学海无边苦作舟学海无边苦作舟