第四章 数组
★ 内容提要:
数组的定义说明规则数组名与数组元素的引用数组的存储结构形式数组作参数的传地址方式数组为基础的算法应用字符数组应用与编程
一维数组定义说明
数组的传地址方式
一维数组的引用
数组、算法与应用
字符数组与应用
多维数组与存储结构数组是同类型数据元素的有序集合,即数组由基本类型(整型、实型、字符、指针等变量)组合而成。
这种组合可以层层组合,但最低一级的成员必须由基本类型的元素构成,即数组元素必须是基本类型的量。
数组必须先定义后使用 。 定义形式:
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 c har str 1[30]={,z hang jia,};
static c har str 2[30]={,z hang y i,};
……
strc mp( str1,s tr2 );
……
}
strc mp(char s[],char t[] )
{
……
}
通过传地址方式实现双向传递
0
z h a n g □ j i ……
1 2 3 4 5 6 7 …… 29
a \ 0
8 9 10st r1
2000
mai n()
□ ……
……
0
z h a n g □ y i ……
1 2 3 4 5 6 7 …… 29
\ 0
8 9 10st r2
3000
□ ……
……
蓝线表示传递红蓝线表示传递红线表示指向线表示指向
st rcmp( )
s
4000
t
4004
2000 3000
⑤ 定义数组时必须指定 数组的大小:只有两种情况(场合)可以省 略一维数组长度的说明,
而用 [ ] 替代。
数组必须先定义后使用 。 定义形式:
类型表识符 数组名 [ 常量表达式 ],…… ;
二是静态 的局部数组或外部数组赋初值时,
对数组赋初值意味着对全体数组元素赋初值,
数组的长度可由初值个数确定。但当初值的个数不等于数组元素个数时长度必须显式说明。
main( ){
static c har str1[30]= {? z?,? h?,? a?,? n?,? g?,? □?,? j?,? i?,? a?,? \ 0? };
static c har 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 9st r1
2000
□
0
z h a n g □ y i
1 2 3 4 5 6 7
\ 0
8st r2
3000
□
二是静态的局部数组或外部数组赋初值时,对数组赋初值意味着对全体数组元素赋初值,数组的长度可由初值个数确定。但当初值的个数不等于数组元素个数时长度必须显式说明。
以字符形式一个一个赋初值,
则串结束符必须由程序员添加。
4,2 一维数组的引用
( 1 )以数组元素出现在变量能出现的任何地方 。数组元素为单值变量,代表相应存储单元的值,同一般变量,只是表示形式不同。
元素表示形式,数组名 [ 下标 ]
( 2 )以数组名作函数调用的参数 。数组名代表该数组的起始地址,数组名作参数,其实质是以传地址方式传递数据,实现形参和实参 共享存储空间,具有带值返回的功能。
C 规定,只能以逐个引用数组元素的方式,不能在运算中一次引用整个数组,即不能整体操作,而必须以元素作为操作数单独处理。
7,2 一维数组的引用根据数组的存储结构特征在程序设计应用领域中有许多重要应用数组应用示例介绍根据数组的存储结构特征在程序设计应用领域中有许多重要应用数组应用示例介绍例 [4 - 1] 用选择法对数组中 5 个整数按由小到大排序。
选择法排序算法描述:
① 在 n 个待排序元素中选取最小数与第一个元素交换构成:
[ 有序组( 1 ) ] [ 无序组( n - 1 ) ]) )
② 在无序组中继续选取最小值,添加到有序组中的尾部,即与无序组第一个元素交换),使得:
③ 如此重复②共 n - 1 次,即构成有序组。
[ 有序组 +1 ] [ 无序组 - 1 ]
void mai n(){
int i; static int a[5]= { 5,3,2,4,1 };
sele ctsort( a,5 );
for( i= 0; i< 5; i+ + ) printf( " % 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
arr ay
a
5 3 2 4 1
i
k
j
第二趟排序结束状态
1 5
通过中间变量 t 交换 2
t
2 3
void s el ects ort( 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=ar ray[k]; array[k] =array[ i] ; array[ i] =t;
}
}
}
执行排序算法过程的演示
(第三趟)
0 1 2 3 4
arr ay
a
5 3 2 4 1
i
k
j
第三趟排序结束状态
1 5
2
t
2 3
已经有序不再交换
3
void s el ects ort( 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=ar ray[k]; array[k] =array[ i] ; array[ i] =t;
}
}
}
执行排序算法过程的演示
(第四趟)
0 1 2 3 4
arr ay
a
5 3 2 4 1
i
k
j
第四趟排序结束状态
1 5
2
t
2 3
已经有序不再交换
4
void s el ects ort( 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=ar ray[k]; array[k] =array[ i] ; array[ i] =t;
}
}
}
# incl ude < stdio.h> // 选择排序,c 源程序
void sel ec tsort(int arr ay[],int 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]; arr ay[k]=ar ray[i ]; arr ay[i]= t;
}
}
}
void mai n(){
int i; static int a[5]= { 5,3,2,4,1 };
sele ctsort( a,5 );
for( i= 0; i< 5; i+ + ) printf( " % 6d ",a[i] );
printf( " \ n" ) ;
}
array
a
5 3 2 4 1
0 1 2 3 4
i
k
j
执行排序前的初始状态
void mai n(){
int i; static int 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 sushu(int n ){ // 源程序
int i,j;
char li ne[1000];
for(i= 0; i< =n; i ++ )
li ne[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 ) l ine[j]= 0;
}
}
}
void mai n(){
int n;
scanf(" % d",&n );
sush u( 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 mai n(){
static c har s1[80]= {" test"},s2[80]={"test2" },s3[80];
void str_c at(char s[],char t[]); // 串连接函数原型说明
int str_cmp(c har s[],char t[]); // 串比较函数原型说明
void str_c py(char s[],char t[]); // 串拷贝函数原型说明
int index (c har s[],char t[]); / / 求子串位序函数原型
str_ca t( s1,"1" ); put s(s1);
printf(" % d \ n",s tr_c mp( s1,s2 ));
str_cpy( s3,s2 ); puts( s3);
printf(" % d \ n",index ( s1,"es" )) ;
}
void mai n(){ / / 调用串连接函数,实现串连接。
…… ; str_ca t( s1,"1" ); put s(s1); ……
}
void str_c at( 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 mai n(){ / / 调用串比较函数,实现串的比较。
…… ; printf(" % d \ n",s tr_c mp( s1,s2 )); ……
}
int str_cmp( c har s[ ],char t[ ] ){
int i= 0;
w hile ( s[i]= =t[i ] ) if( s[i++ ]== ' \ 0? ) re turn( 0 );
re turn( 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 mai n(){ // 调用串复制函数,实现串的复制。
…… ; str_cpy( s3,s2 ); puts( s3); ……
}
void str_c py( char s[ ],c har 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 mai n(){
static c har s1[80]= {" test"},s2[80]={"test2" },s3[80];
void str_c at(char s[],char t[]); // 串连接函数原型说明
int str_cmp(c har s[],char t[]); // 串比较函数原型说明
void str_c py(char s[],char t[]); // 串拷贝函数原型说明
int index (c har s[],char t[]); / / 求子串位序函数原型
str_ca t( s1,"1" ); put s(s1);
printf(" % d \ n",s tr_c mp( s1,s2 ));
str_cpy( s3,s2 ); puts( s3);
printf(" % d \ n",index ( s1,"es" )) ;
}
运行结果:
test1
-1
test2
1
对两个字符串 str1[] 和 str2[] 比较不能用以下形式:
if( st r1==st r2 ) p rintf( "yes!");
只能采用字符串比较函数逐位比较确定,如下所示:
if( st r_cmp( str1,str2 ) == 0 )p rintf( "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;
}
}
li ne
0 1 2 3 4 5 6 7 8 9 10 …
…
k
s
p \ 0\ ntnir ……
输入,print ↙
输出,print
li ne
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;
}
}
li ne
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 rodu ct(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 () {
stat ic i nt a[3] [3] ={{1,1,1},{2,2,2},{3,3,3}};
stat ic i nt b[ 3][ 2]= {{4,4},{5,5},{6,6}};
int c[3 ][ 2],i,j;
mat prod uct( a,b,c,3,3,2) ;
for(i=0; i<3; i++ )
for(j =0; j< 2;j ++ )
print f( "%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));The end
培 育 英 才 钻 研 科 学书山有径勤为路学海无边苦作舟书山有径勤为路书山有径勤为路学海无边苦作舟学海无边苦作舟