目录
- 数组的概念
- 一维数组的创建和初始化
- 一维数组的使用
- 一维数组在内存中的存储
- sizeof计算数组元素个数
- 二维数组的创建
- 二维数组的初始化
- 二维数组的使用
- 二维数组在内存中的存储
- C99中的变长数组
- 数组名
- 数组练习
1. 数组的概念
数组是一组相同元素类型的集合
- 一个或多个数据,但是元素个数不能为0
- 存放的数据类型是相同的
2. 一维数组的创建和初始化
2.1 创建
type arr_name[常量值]
存放在数组的值称为数组的元素,数组创建的时候指定数组大小和类型
例如,创建一个整数类型的容量20的数组
int ary[20]
2.2 数组的初始化
数组创建给初始值叫初始化,有两种初始化类型
//完全初始化
int arr[5]={1,2,3,4,5};
//部分初始化
int arr[5]={1,2,3}; //前三个为1,2,3,剩余没有初始化的默认为0
//错误的初始化
int arr[3]={1,2,3,4}; //初始化项太多
部分初始化,在监视窗口中未初始化的默认为0
一维数组的元素个数可以省略
数组初始化为0值时,会自动将所有元素初始化为0
int arr[5]={0};
3. 一维数组的使用
3.1 数组的下标
c语言规定数组有下标,下标从0开始,最后一个元素下标n-1,下图是int arr[4]={1,2,3,4}的下标:
3.2 数组的访问
操作符[]
,叫下标引用操作符,有了下标访问,访问下标为3的元素,就用arr[3]
3.3 数组的打印
打印数组只需要产生所有元素的下标,通过下标访问所有元素。用循环,循环次数作为元素下标
int arr[5] = { 1,2,3,4,5};
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
打印结果:
3.4 数组的输入
也可以通过下标输入值,用循环取每个元素的地址输入
int ary[5];
for(int i=0;i<5;i++){
scanf("%d",&ary[i]);
}
4. 一维数组在内存的存储
int数组的地址从小到大变化,并且每两个元素之间相差4,刚好是一个整型的大小,所以数组在内存中是连续存放的
5. sizeof计算数组元素个数
遍历数组的时候如果不知道数组的大小,可以用sizeof计算,sizeof是一个关键字,可以计算变量、类型、数组的大小
int ary[4];
printf(“%d”,sizeof(ary));
计算结果是16,单位是字节
sizeof也可以计算类型的大小,数组的每个元素类型都是相同的,只需要计算一个大小,sizeof(ary[0]),这里计算第一项的大小,为4字节
由此可以计算数组的元素个数,用数组总的大小除以每一个元素的大小,就可以算出数组有多少个元素
sizeof(ary)/sizeof(ary[0])
计算结果为4,表明数组有4个元素
6. 二维数组的创建
把一维数组作为元素,这就是二维数组,二维数组作为元素称为三维数组,二维数组以上统称为多维数组,最常用的是一维和二维数组
二维数组的创建
type arr_name[常量1][常量2]
例子:
int arr[3][5];
- 常量1即3,表示数组有3行
- 常量2即5,表示数组有5列
- type是数组类型
- arr_name是数组名
7. 二维数组的初始化
同样有两种,完全初始化和部分初始化
完全初始化
int arr[3][4]={1,2,3,4, 5,6,7,8, 9,10,11,12};
部分初始化
未初始化的部分默认为0
int ary[3][4]={1,2,3};
按行初始化
中括号表示为每一行
int ary[3][4]={{1,2},{3,4},{5,6}};
初始化时可以省略行,不可省略列
int ary[][4]={1,2,3}; √
int ary[4][]={1,2,3}; ×
给定列数,可以按顺序自动放元素,计算出需要几行。给定行数,无法得知每行几个元素
8. 二维数组的使用
二维数组也可以通过下标访问,ary[3][4],表示访问第3行第4列的元素,也就是第12个元素
二维数组的输入和输出
以ary[3][4]为例,二维数组的列范围0-3,行的取值0-2,每一行的取值都是一样的,可以用
嵌套循环生成行和列
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
int i = 0;//遍历⾏
//输⼊
for(i=0; i<3; i++) //产⽣⾏号
{
int j = 0;
for(j=0; j<5; j++) //产⽣列号
{
scanf("%d", &arr[i][j]); //输⼊数据
}
}
//输出
for(i=0; i<3; i++) //产⽣⾏号
{
int j = 0;
for(j=0; j<5; j++) //产⽣列号
{
printf("%d ", arr[i][j]); //输出数据
}
printf("\n");
}
9. 二维数组的存储
int类型二维数组元素之间相差也是4,所以二维数组也是连续存储的
10. C99中的变长数组
C99之前数组的个数只能用常量或常量表达式,也可以省略。这样的数组不灵活,使用的时候可能大了或者小了。
C99的变长数组(vla)新特性,可以用变量指定数组大小。数组长度只有在运行时才知道大小,变长数组不能初始化。数组的大小一旦确定就不能变化,不是说数组大小是可变的
可以用scanf接收变量初始化数组长度,vs中c语言无法使用该特性,gcc编译器可以
11. 数组名
数组名是数组首元素的地址
12. 数组练习
练习1:多个字符从两端移动,向中间汇聚
打印结果,放在一行内:
思路:用两个数组,一个存字符串,一个存符号,两个数组一样长。用strlen记录右边最后一个的下标,再记录左边第一个下标,左边下标不大于右边的时候循环,让符号的两边内容等于字符串的内容,两个下标不断往中间移动
char ary1[] = "welcome to msvc";
char ary2[] = "***************";
int left = 0;
int right = strlen(ary1)-1;
while (left<=right) {
printf(ary2);
ary2[left] = ary1[left];
ary2[right] = ary1[right];
printf("\r\n");
left++;
right--;
//Sleep(1000);
//system("cls");
}
printf(ary2);
练习2:二分查找
在一个升序的数组查找一个数,用遍历的话效率不高。在一个升序100的数组中猜一个数,如果50大了,就会猜中间的数字25,这就是二分查找
思路:记录左右下标,取中间下标,用中间下标的数和要找的数相比,大了就更新右下标,小了更新左下标,直到找到
int ary[10] = {1,2,3,4,5,6,7,8,9,10}; //数据数组
int n = 12; //查找的数
//设置下标
int left = 0;
int right = sizeof(ary)/sizeof(ary[0])-1;
int mid = 0;
while (left <= right) {
mid = (left + right) / 2;
if (ary[mid] == n) {
printf("已找到\r\n");
break;
}
if (ary[mid] > n) {
right = mid - 1;
}
if (ary[mid] < n) {
left = mid + 1;
}
}
if(left>right)
printf("没找到\r\n");