1.数组的概念
数组是相同类型元素的集合——存放>=1个数据;数据类型相同。
数组分为一维数组和多维数组,多维数组中较常见的是二维数组。
2.
2.1一维数组创建
基本语法:type arr_name[常量值];
type 指数组中存放数据的类型;
arr_name 指数组名;
[] 中的常量值用来指定数组大小。
数组大小可不写,编译器会自动计算数组元素个数。如int arr[] = { 1,2,3,4,5 }; char arr[]=“hello world”
2.2一维数组初始化
数组的初始化一般使用大括号,将数据放在大括号中。
int arr[5] = { 1,2,3,4,5 };
char arr[5] = { ‘a’,‘b’,‘c’,‘d’,‘e’ }; //完全初始化
int arr[5] = { 1 }; //不完全初始化,第一个元素初始化为1,剩余的元素默认初始化为0
int arr[3] = {1, 2, 3, 4};//错误的初始化——初始化项太多
2.3 数组的类型
数组算是一种自定义类型,去掉数组名留下的就是数组的类型。
如:int arr[10]; 该数组的类型是 int [10]
3.
3.1一维数组下标
C语言规定数组是有下标的,下标从0开始,若数组有n个元素,则最后一个元素下标是n-1。下标相当于数组元素的编号。
如int arr[10] = {1,2,3,4,5,6,7,8,9,10};
数组元素 1 2 3 4 5 6 7 8 9 10
下标 0 1 2 3 4 5 6 7 8 9
C语言中数组的访问用到操作符 [ ]—— 下标引用操作符。
若要访问arr数组中下标为7的元素 ,则使用arr[7]
3.2 一维数组元素的打印
要访问整个数组的元素,用for循环产生数组所有元素的下标即可。
打印数组中奇数位次的元素:
3.3一维数组的输入
4. 一维数组在内存中的存储
依次打印数组元素的地址:
上述地址是16进制整型。16进制用0~9、a(/A)、b(/B)、c(/C)、d(/D)、e(/E)、f(/F)分别表示数字0至15。
C表示12,12-8=4;12+4=16,逢16(一个位达16向前一位)进1,得30…则随着下标增大,地址由小到大变化,相邻元素地址间相差4——因为一个整型占4个字节(Byte)
由以上可得:一维数组中元素在内存中连续存放。
5. sizeof 计算数组元素个数
sizeof 是C语言中一个关键字,可以计算类型或变量或数组的大小。
sizeof(类型/变量/数组)
数组中所有元素的类型相同,那只要计算出一个元素所占字节,数组的元素个数就能算出。
6.
6.1二维数组的概念
一维数组作为数组的元素,得到二维数组。
二维数组作为数组的元素,得到三维数组。
二维数组以上的数组统称为多维数组。
6.2 二维数组的创建
定义二维数组的语法如下:
type arr_name[常量值1][常量值2];
如:int arr[3][5]; ——该数组有3行5列
7. 二维数组初始化
7.1 不完全初始化
int arr[3][5]={1,2};——第一行第1、2个元素分别初始化为1,2,余下元素默认初始化为0
int arr[3][5]={{1,4},{7,8},{5,2}};——第一行第1、2个元素 第二行第1、2个元素 第三行第1、2个元素分别初始化
7.2 完全初始化
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
7.3按照行初始化
int arr[3][5]={{1,4},{7,8},{5,2}};也叫按照行初始化。
7.4初始化时可省行数,不能省列数
int arr1[][5] = {1,2,3};
int arr2[][5] = {1,2,3,4,5,6,7};
int arr3[][5] = {{1,2}, {3,4}, {5,6}};
8. 二维数组的使用
8.1 二维数组的下标
⼆维数组下标,行从0开始,列也是从0开始。
8.2 二维数组的输入和输出
如何访问整个二维数组呢?
9. 二维数组在内存中的存储
所以二维数组中的元素在内存中连续存放。
如图所示:
10. C99中的变长数组
C99标准制定之前,C语言创建数组时,数组大小的指定只能用常量、常量表达式,或者初始化数据时可省略数组大小。
如:int arr[10]; int arr[3+5]; int arr[] = {1,2,3};
这样的语法限制,让我们创建数组不够灵活,数组大了浪费空间,数组小了不够用。
C99中的变长数组(variable-length array,简称 VLA),允许我们使用变量指定数组大小。
变长数组的根本特征,是数组长度只有运行时才能确定。所以变长数组不能初始化。好处是程序员不必在开发时为数组指定一个估计的长度,可在运行时为数组分配精确的长度。
值得注意的是,在程序运行时,根据变量大小来指定数组的元素个数,而非数组的大小可变。数组的大小⼀旦确定就不能再变。
VS2022不支持C99中的变长数组,无法测试。
在gcc编译器上测试,
第一次测试,给n输入5,然后在数组中输入5个元素,输出;
第二次测试,给n输入10,然后在数组中输入10个元素,输出。
11. 数组练习
11.1多个字符从两端移动,向中间汇聚
如打印:
h#############!
he###########!!
hel#########!!!
hell#######!!!
hello#####!!!
hellow###d!!!
hellowo#ld!!!
helloworld!!!
假如我们希望打印速度变慢,打印一行后停顿一会再打印下一行,可使用Sleep()函数。
假如我们希望打印完后清空屏幕,可使用system(“cls”);
假如我们希望最终屏幕上保留最后一行,
11.2二分查找
在一个升序数组中查找指定的数字,遍历数组效率较低。我们可以猜中间数字,然后看大了还是小了,再往两边找。这就是二分查找,也叫折半查找。如:求某升序数组中是否含有7,
元素1 2 3 4 5 6 7 8 9 10
下标0 1 2 3 4 5 6 7 8 9
mid=(0+9)/2=4,arr[4]=5<7,则去掉1~5,最左端元素下标变为mid+1=5;
mid=(5+9)/2=7,arr[7]=8>7,则去掉8~10,最右端下标变为mid-1=6;
mid=(5+6)/2=5,arr[5]=6<7,则去掉6,最左端元素下标变为mid+1=6;
mid=6,arr[6]=7。
12.求两个数的平均值
因为2147483647+2147483647的结果超过了TNT_MAX(2147483647),即数值溢出。
为防数值溢出,可用avg=a+(b-a)/2——a,b谁大皆可——大+(小-大)=小+(大-小)。