目录
1.数组的概念
数组是一组相同类型元素的集合。由此我们可以可知:
- 数组中存放的是一个或者多个数据,但数组元素个数不能为0.
- 数组中存放的多个数据,类型是相同的。
数组分为一维数组和多维数组。多为数组常见的是二维数组。
2.一维数组的创建和初始化
2.1创建数组
一维数组的基本语法如下:
type arr_name[常量值];
放在数组中的值被称为数组的元素。数组在创建时可以指定数组大小和数组元素类型。
- type指定的是数组中存放数据的类型,可以使char、short、int、float、等,也可以是自定义的类型。
- arr_name指的是数组的名字。
- [] 中的常量值是用来指定数组的大小的。
创建数组示例如下:
int a[20];
char name[10];
float fl[5]
2.1 数组的初始化
在创建数组时,我们需要给定一些初始值,这样被称为初始化。一般将数据放在大括号中。初始化示例如下:
//完全初始化
int n1[5] = { 1 , 2 , 3 , 4 ,5 };
int n2[5] = { 0 }; //数组中的元素都为0
//不完全初始化
int n3[5] = { 1 }; //第一个元素初始值为1,剩余的元素初始值为0
//错误的初始化 初始化项太多
int n4[5]={ 0 , 1 , 2 , 3 , 4 , 5 , 6 };
2.3 数组的类型
数组是一种自定义类型,去掉数组名留下的就是数组的类型
int a[20];
char name[10];
float fl[5]
a 数组的类型是 int [20];
name 数组的类型是 char [10];
fl 数组的类型是 float [5];
3.一维数组的使用
3.1数组下标
C语言规定数组是有下标的,下标是从 0 开始。假设数组有 n 个元素,那么最后一个元素的下标就是 n-1。下标就相当于数组的编号。
访问数组提供了一个操作符 [] ,叫做:下标引用操作符。
有一个数组 arr ,数组中共有5个元素。当我们要访问下标为 0 的元素时,就可以使用 arr[0] ,在这个数组中,下标最大为4。代码如下:
3.2 数组元素的打印
如果想要访问整个数组的内容,那么我们就可以使用 for 循环,产生并打印数组所有的下标就好了。
3..3 数组的输入
数组的输入也是需要对应到下标,也可使用 for 循环对数组进行输入。示例如下:
4.一维数组在内存中的存储
依次打印数组每个元素的地址
从输出的结果分析,数组随着下标的增长,地址是由小到大变化的,并且相邻的两个元素之间相差 4 (是因为一个整型是4个字节),综上得出:数组在内存中时连续存放的。
5.sizeof 计算数组元素个数
C语言中有什么办法可以通过程序来计算数组元素个数吗? 可以使用 sizeof
sizeof 是C语言中的一个关键字,是可以计算类型或者变量大小的。
如何计算一个数组所占内存空间总大小,单位是字节。示例如下:
而且数组中的各个元素的类型都是相同的,我们就可以计算一个元素的大小,这样就可算出数组中元素的个数。示例如下:
6.二维数组的创建
6.1二维数组的概念
如果把一维数组看做整体,作为数组的元素,这就是二维数组;如果把二维数组看做整体,作为数组的元素,这就是三维数组。二维以上的数组统称为多维数组。
6.2 二维数组的创建
二维数组语法如下:
type arr_name[常量值1][常量值2];
例如:
int arr1[3][5];
double arr2[5][5];
- int 表示数组的每个元素是整型
- arr是数组的名字
- 3(常量值1)表示数组有三行
- 5(常量值2)表示数组有五列
7.二维数组的初始化
7.1不完全初始化
int arr1[3][5]={1,2};
int arr2[3][5]={0};
7.2 完全初始化
int arr3[3][5]={1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15}
7.3 按照行初始化
int arr[3][5]={{1,2},{3,4},{5,6}};
7.4初始化时可以省略行,但不能省略列
int arr5[][5]={1,2,3};
int arr6[][5]={1,2,3,4,5,6,7};
int arr7[][5]={{1,2},{3,4},{5,6};
8.二维数组的使用
8.1 二维数组的下标
二维数组行和列的下标都是从 0 开始的,只要有了行和列的下标就能锁定一个元素。以下面这个二维数组为例:
int arr[3][5]={1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15};
左边蓝色的数字表示行号,上面红色的数字表示列号。当我们访问 行下标为1,列下标为2,就能定位到八。
代码示例如下:
9.二维数组在内存中的存储
将二维数组中所有元素的地址打印出来。
从输出的结果来看,每一行内部的每个元素都是相邻的,地址之间相差4个字节,跨行位置除的两个元素也是相差4个字节。所以二维数组中的每个元素都是连续存放的。
10.数组练习
10.1 练习1
练习1:多个字符从两端移动,向中间汇聚。
给一个 arr1 和 arr2 ,让这两个数组元素数量相同。再给一个 left 和 right 的变量,作为 arr1 和 arr2 的下标。再通过循环,将arr1 中的内容替换 arr2 中的内容,让 left 进行自增1,让 right 进行自减1 ,替换内容向中间靠拢。这样就基本完成了这个代码。
为了让这个代码更加炫酷,这里使用了 sleep() 休眠 和 system(“cls”)清空屏幕的内容,从而达到下面这样的效果。
字符从两端移动,向中间汇聚
参考代码如下:
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main()
{
char arr1[] = "This is a code!!";
char arr2[] = "****************";
int left = 0;
int right = strlen(arr1) - 1;
while (left <= right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
left++;
right--;
printf("%s\n",arr2);
Sleep(1000); //休眠,单位是毫秒
system("cls"); //用来执行系统命令,进行清理屏幕
}
printf("%s\n",arr2);
return 0;
}
10.2 二分查找
在一个升序的数组中找到指定的数字n,很容易想到的就是遍历数组的方法,但是这种方法效率较低。比如在猜数字1-100中,不可能会从1开始一个一个猜,会猜一个50,来获取大了或者小了的信息,这就是二分查找,也叫折半查找。
分析:
- 刚开始 left 左下标为0,right 右下标为9。进入循环,mid 中间下标为4,arr 中下标为4的元素为 5 ,小于查找的数字,于是 left=4+1.
- left 左下标为5,right 右下标为9。进入循环,mid 中间下标为7,arr 中下标为7的元素为 8 ,大于查找的数字,于是 right=7-1.
- left 左下标为5,right 右下标为6。进入循环,mid 中间下标为5,arr 中下标为6的元素为 6 ,小于查找的值,于是 left=5+1
- left 左下标为6,right 右下标为6。进入循环,mid 中间下标为6,arr 中下标为6的元素为 7,等于查找的值,于是给 find 赋值 1.
- 最后对 find 进行判断,因为 find 等于 1,所以打印找到了。
代码示例如下:
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int left = 0;
int right = sizeof(arr) / sizeof(arr[0]) -1;
int key = 7; //查找的数字
int mid = 0; //记录中间元素的下标
int find = 0; //默认0 为找不到,当找到时,将find值改为1
while (left <= right)
{
mid = (left + right) / 2;
if (arr[mid] < key) // 当中间值小于查找的数字时,left在mid基础上+1
{
left = mid + 1;
}
else if (arr[mid] > key)// 当中间值大于查找的数字时,right在mid基础上-1
{
right = mid - 1;
}
else //默认 0 为找不到,当找到时,将find值改为1
{
find = 1;
break;
}
}
if (find == 1) //判断是否找到了
printf("找到了,下标是:%d\n", mid);
else
printf("没有找到\n");
return 0;
}