C语言 数组.docx
- 文档编号:4464636
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:10
- 大小:26.57KB
C语言 数组.docx
《C语言 数组.docx》由会员分享,可在线阅读,更多相关《C语言 数组.docx(10页珍藏版)》请在冰豆网上搜索。
C语言数组
第九章数组
一、一维数组的定义和一维数组的引用
1、一维数组的定义
1)当数组中每个元素只带一个下标时,称这样的数组为一维数组。
2)定义一维数组一般形式如下:
类型名数组名【整型常量表达式】,……
例inta【8】
2、一维数组元素的引用
引用形式如下:
数组名[下标表达式]
例:
doublex[8];x[0],x[j],x[i+k]都是合法的。
注意:
1)一个数组元素实质上就是一个变量名,代表内存中的一个存储单元。
一个数组占一串连续的存储单元。
2)在c语言中,一个数组不能整体引用。
数组名存放的是一个地址常量,它代表整个数组的首地址。
3)引用数组元素时,下标表达式的值必须是整数,下表表达式值的下限为0。
系统不自动检验数组元素的下标是否越界,保证数组下标不越界,十分重要。
3、一维数组的初始化
数组的初始化一般形式如下:
数组类型数组名[表达式]={}
例:
inta[8]={0,1,2,3,4,5,6,7};
注意:
1)所赋初值放在等号后的一对花括号中,数值类型与所说明的类型一致,所赋初值用逗号隔开。
2)所赋初值依次给数组中的元素赋初值。
3)当所赋初值的个数少于所定义数组的元素个数时,将自动给后面的元素补初值0。
而对于字符型数组也同样补初值0,即’\0’。
4)当所赋初值多于所定义数组的元素个数时,在编译时将会给出出错信息。
例:
inta[10]={0};charc[5]={‘@’};
4、通过赋初值定义数组的大小
inta[]={0,0,0,0,0,0,0,0};等价于inta[8]={0};
二、一维数组和指针
1、一维数组和数组元素的地址
数组和指针比较记忆
1)指针变量的地址和数组名的地址值,就是该数组第一个元素的地址。
2)指针变量有基类型,相当于数组的类型名。
3)指针变量的地址值不可改变,因此不可以给数组重新赋值。
重要的是:
这个指针变量中的地址值不可改变,也就是说,不可以给数组名重新赋值!
floata[10],*p,x;
语句a=&x;或a++都是非法的!
for(k=0;k<10;k++)p=a+k;
在循环中没有改变a的值,而是通过a+k来遍历数组中的每个元素的地址。
给数组中的每个元素赋值,可以采用以下几种方法:
1)for(k=0;k<10;k++)scanf(“%d”,a+k);
2)p=a;
for(p=a,k=0;k<10;k++)p++;
3)for(p=a,k=0;k<10;k++){scanf(“%d”,p);p++;}
4)for(p=a,k=0;k<10;k++)scanf(“%d”,p++);
5)for(p=a;p-a<10;p++)scanf(“%d”,p);
2、通过数组的首地址引用数组元素
*&a[0]*(a+0)a[0]
*&a[1]*(a+1)a[1]
*&a[2]*(a+2)a[2]
通过以上表达式,数组元素可以看出可以通过*(a+i)来表示
例:
for(k=0;k<10;k++)prinf(“%4d”,*(a+k));
3、通过指针引用一维数组元素
floata[10],*p,k;p=a;
a[0]*pa[1]*(p+1)
for(p=a,k=0;k<10;k++)printf(“%d”,*(p+k));
p是可以移动的,那么就可以采用以下方法来遍历数组中的所有元素:
for(p=a;p-a<10;p++)printf(“%4d”,*p);
4、用带下标的指针变量引用一维数组
int*p,i,s[10];p=s;i>=0&&i<10
1)s[i]的地址可以用一下三种方法来表示:
&s[i]s+ip+i
2)事实上,在C语言中,一对方括号不是仅用作表示数组元素的记号,而是一种运算符。
那么数组元素s[i]可以用以下四种方法来表示:
*&s[i]*(s+i)*(p+i)p[i]
3)注意区分以下表达式的含义:
*(p++)*p++*(++p)*++p
4)在这里s和p有着明显的区别,s是不可变的,而p中的地址值却是可变的。
5)逐个输出数组中的所有元素
①for(k=0;k<10;k++)printf(“%4d”,*(a+k));
②for(k=0;k<10;k++)printf(“%4d”,a[k]);
③for(p=a;p-a<10;p++)printf(“%4d”,*p);
④for(k=0;k<10;k++)printf(“%4d”,p[k]);
三、函数之间对一维数组和数组元素的引用
1、数组名也可以作为实参传递,但数组名本身是一个地址值,因此,对应的形参应该是一个指针变量,且指针的基类型应和数组类型保持一致。
例:
#include
#defineM100
voidarrout(int*,int);
intarrin(int*);
main()
{inta[M],k;
k=arrin(a);
arrout(a,k);}
intarrin(int*a)
{inti,x;
i=0;
scanf("%d",&x);
while(x>=0)
{*(a+i)=x;
i++;
scanf("%d",&x);
}
returni;
}
voidarrout(int*a,intn)
{inti;
for(i=0;i {printf("%4d",*(a+i)); if((i+1)%5==0)printf("\n"); } } 当数组名作为实参时,对应的形参除了是指针外,还可以用另外两种形式。 1)arrin(int*a)2)arrin(inta[])3)arrin(inta[M]) 当传送数组名时,在被调用函数中也同样可用数组元素的形式来引用调用函数中对应的数组元素。 但应当注意: 这只是形式的相似,不要误以为整个数组可以传送给被调用函数。 调用函数只是把数组的首地址传送给形参指针,仍是遵循按”值”传递的机制。 2、数组元素地址作为实参 当数组元素地址作为实参时,因为是地址值,所以对应的形参也应当是基类型相同的指针变量。 3、函数的指针形参和函数体中数组的区别 #include #defineN10 int*fun(inta[N],intn) { intb[N]; renturnb; } main() { intw[N],*p; p=fun(w,N); } 1)fun中,形参a[N]会作为一个指针变量处理。 系统只是为形参a开辟一个存储单元。 2)fun中,定义了一个数组b,系统为其开辟一连串的存储单元,b是地址常量,不可以重新赋值。 3)fun执行完毕后,系统将释放a和b所占的存储单元,指针a和数组b都不存在。 四、一维数组应用举例 1、编写程序,定义一个含有15格元素的数组,并编写函数分别完成以下操作: 1)调用c库函数中的随机函数给所有元素赋以0-49的随机数。 2)输出数组元素中的值; 3)按顺序对每隔三个数字求一个和数,并传回主函数。 4)最后输出所有求出的和值。 2、将数组中的数按颠倒的顺序重新存放。 在操作时,只能借助一个临时存储单元,不得另外开辟数组。 3、已知整型数组中的值在0-9的范围内,统计每个整数的个数。 4、已知存放在a数组中的数不相重,在a数组中查找和x值相同的元素的位置。 若找到,输出该值和该值在a数组中的位置;若没找到,输出相应的信息。 5、w数组中存放了n个数据,编写函数删除下标为k的元素中的值。 6、w数组中存放了n个数据,编写函数在特定位置加入一个元素。 7、用选择法对数组中的数进行排序(由小到大)。 第二节二维数组的定义和二维数组元素的引用 一、二维数组的定义 1、定义: 当数组中每个元素带有两个下标时,称这样的数组为二维数组。 2、二维数组的定义语句形式如下: 类型名数组名【常量表达式1】【常量表达式2】…… 例: inta[3][4]; 第0列第1列第2列第3列 第0行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数组中的元素在内存中占一系列连续的存储单元。 按照“按行存放”的规则来进行存放。 在c语言中,可以把一个二维数组看成是一个一维数组,每个数组元素又是包含若干个元素的一维数组。 二、二维数组元素的引用 引用形式: 数组名[下标表达式1][下标表达式2] 考点: 1)一定要把两个下标分别放在两个方括号内。 2)下标的上限是n-1 3)如果引用m行n列的元素时,a[m-1][n-1] 三、二维数组的初始化 1、所赋初值个数与数组的个数相同 inta[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; 2、每行所赋初值个数与数组元素的个数不同 inta[4][3]={{1,2},{3,4},{7},{10}}; 3、所赋初值行数少于数组行数 inta[4][3]={{1,2},{4,5}}; 4、赋初值时省略行花括号对 inta[4][3]={1,2,3,4,5}; 四、通过赋初值定义二维数组的大小 对于二维数组,只可以缺省行下标,但不能缺省列下标 Inta[][3]={{1,2,3},{4},{5},{6}}; 等价于 Inta[4][3]={{1,2,3},{4},{5},{6}}; 当用一下形式定义数组时: Intc[][3]={1,2,3,4,5}; 第一维的大小按以下规则决定: 1)当初值的个数能被第二维的常量表达式的值除尽时,所得商数就是第一维的大小。 2)当初值个数不能被整除时: 第一维的大小=所得商数+1 以上语句等价于: c[2][3]={1,2,3,4,5}; 五、二维数组的遍历方法(双for循环) 例: 通过键盘给2*3的二维数组输入数据,第一行赋1、2、3,第二行赋10、20、30,然后按行输出此二维数组。 #include"stdio.h" main() { inta[2][3],i,j; printf("input2*3integersforarrays: \n"); for(i=0;i<2;i++) for(j=0;j<3;j++) scanf("%d",&a[i][j]); printf("outputthearraysbyline: \n"); for(i=0;i<2;i++) { for(j=0;j<3;j++) printf("%3d",a[i][j]); printf("\n"); } } 六、二维数组和指针 首先定义: int*p,a[3][4]; 1、二维数组a由若干个一维数组组成 1)C语言中定义的二维数组实际上是一个一维数组,这个一维数组的每个元素又是一个一维数组。 2)C语言中,在函数体中或在函数体外部定义的一维数组名是一个地址常量,其值为数组的第一个元素的地址,此地址的基类型就是数组元素的类型。 3)同样,在二维数组中,a[0],a[1],a[2]也是一维数组名,同样也代表一个不可变的地址常量,其值依次为二维数组每行第一个元素的地址,其基类型就是数组元素的类型。 4)p=a[i]等价于p=*(a+i) 2、二维数组名也是一个地址常量 1)二维数组名也是一个存放地址常量的指针,其值为二维数组中第一个元素的地址。 2)二维数组名应理解为一个行指针。 3)赋值语句p=a;是不合法的,因为p和a的基类型不同。 3、二维数组元素的地址 1)二维数组元素的地址可以由表达式&a[i][j]求得,也可以通过每行的首地址来表示。 2)a[i][j]的地址可以用一下五种表达式求得: 1&a[i][j]正常表示 2a[i]+j ③*(a+i)+j ④&a[0][0]+4*i+j ⑤&a[0]+4*i+j 4、通过地址引用二维数组元素 定义inta[3][4],i,j; a数组元素可用一下五种表达式来引用: ①*(&a[i][j])或a[i][j]正常表示 ②*(a[i]+j)将a[i]看成行数组名 ③*(*(a+i)+j)a[i]等价*(a+i) ④*(&a[0][0]+4*i+j) ⑤(*(a+i))[j] 5、通过建立一个指针数组引用二维数组元素 定义: int*p[3],a[3][2],i,j; for(i=0;i<3;i++)p[i]=a[i]; 1)引用形式: (1)*(p[i]+j)/*与*(a[i]+j)对应*/ (2)*(*(p+i)+j)/*与*(*(a+i)+j)对应*/ (3)(*(p+i))[j]/*与(*(a+i))[j]对应*/ (4)p[i][j]/*与a[i][j]对应*/ 6、通过建立一个行指针引用二维数组元素 inta[3][2],(*prt)[2]; 引用形式: (1)*(prt[i]+j)/*与*(a[i]+j)对应*/ (2)*(*(prt+i)+j)/*与*(*(a+i)+j)对应*/ (3)(*(prt+i))[j]/*与(*(a+i))[j]对应*/ (4)prt[i][j]/*与a[i][j]对应*/ 七、二维数组名和指针数组作为实参 1、二维数组名作为实参和形参之间的数据传递 当二维数组名作为实参时,对应的形参必须是一个指针变量 fun函数的首部可以是以下三种形式之一: 1)fun(double(*a)[N]) 2)fun(doublea[][N]) 3)fun(doublea[M][N]) 2、指针数组作为实参时实参和形参之间的数据传递 Fun函数的首部可以是以下三种形式之一: 1)fun(double*a[M]) 2)fun(double*a[]) 3)fun(double**a) 七、二维数组程序举例 例1、编写程序,通过调用随机函数给5*6的二维数组元素赋10-40范围内的整数,求出二维数组每行元素的平均值。 例2、编写程序打印出以下的杨辉三角。 例3、找出方阵中每列的最小元素及所在的行号。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C语言 数组 语言