数组在程序设计中是一个十分重要的概念,在许多语言中都有涉及到,今天我们要学习的是跟C语言有关的数组知识。
1. 数组概念
数组是一组相同类型元素的集合。从这个概念中我们可以观察到俩点有价值的信息:
1.数组中存放的是一个或多个数据,但是数组元素个数不能为零。
2.数组中存放的每个数据类型必须是相同的。
数组分为一维数组和多维数组,今天我们要学习的是一维数组和二维数组。这也是最常见的俩种数组。
2. 一维数组
2.1 一维数组的创建
存放在数组的值被称为数组的元素,数组在创建的时候可以指定数组的⼤⼩和数组的元素类型。 一维数组的基本语法如下:
type arr_name[常量值];
1.type 指定的是数组中存放数据的类型,可以是: char、short、int、float 等,也可以是⾃定义的类型2.arr_name 指的是数组名的名字,这个名字根据实际情况,起的有意义就⾏。3.[] 中的常量值是⽤来指定数组的⼤⼩的,这个数组的⼤⼩是根据实际的需求指定就⾏
数组创建实例:
//存放班级里二十个人的数学成绩,可以创建一个整型数组
int math[20];
//存放一个人的性别,我们可以用字符数组
char ch[5];
//在实际操作中,我们要根据需要创造出适合的数组。
2.2 一维数组的初始化
创建出一个数组后,我们需要往里面填入元素,这个过程称为数组的初始化。那我们应该如何初始化数组呢,这就需要使用到大括号了。
初始化示例:
//完全初始化
int arr1[5] = { 1,2,3,4,5 };
//不完全初始化
int arr2[5] = { 1 };//第⼀个元素初始化为1,剩余的元素默认初始化为0
//错误的初始化
int arr3[2] = {1,2,3,4};//该数组只能放进俩个元素,现在却放了四个元素,初始化项太多
通过vs的调试,我们可以观察到以上结果。
2.3 数组的类型
int arr1[10]; arr1的类型为 int [10];double arr2[10];arr2的类型为double [10];char arr3[10]; arr3的类型为 char [10];
2.4 一维数组的使用
学习了一维数组的基本语法,我们知道了它可以存放数据,那么我们要如何操作这些数据来解决问题呢。
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
学习了数组下标和下标引⽤操作符之后,我们就可以用来输入数组和打印数组。代码如下:
int main()
{
int arr[10] = { 0 };
for (int i = 0; i < 10; i++)
{
scanf("%d", &arr[i]);
}
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
2.5 一维数组在内存中的存储
我们要深入了解数组,就要了解数组在内存中的存储。下面有一个代码,打印数组元素的地址:
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
for (i = 0; i < 10; i++)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
}
return 0;
}
2.6 sizeof计算数组元素个数
sizeof 在C语⾔是⼀个关键字,计算的是数组所占内存空间的总⼤⼩,单位是字节。
3. 二维数组
3.1 二维数组的创建
二维数组的基本语法如下:
type arr_name[常量值1][常量值2];
例如:
int arr[3][5];
double data[2][8];
3表⽰数组有3⾏,5表⽰每⼀⾏有5个元素
int 表⽰数组的每个元素是整型类型,arr 是数组名,可以根据⾃⼰的需要指定名字,data数组意思基本一致。
3.2 二维数组的初始化
3.2.1 不完全初始化
二维数组跟一维数组一样,也是使用大括号进行初始化的。
int arr1[3][5] = {1,2};
int arr2[3][5] = {0};
3.2.2 完全初始化
int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7}
3.2.3 按照行初始化
int arr4 = {{1,2},{3,4},{5,6}};
3.2.4 初始化时省略行,但是不能省略列
int arr5[][5] = {1,2,3};
int arr6[][5] = {1,2,3,4,5,6};
int arr7[][5] = {{1,2},{3,4},{5,6}};
3.3 二维数组的使用
3.3.1 二维数组的下标
二维数组的使用我们可以参考一维数组,访问二维数组也是使用下标的形式,二维数组是有行和列的,只要锁定行和列就能唯一锁定数组中的一个元素。C语⾔规定,⼆维数组的⾏是从0开始的,列也是从0开始的,如下所⽰:
int arr[3][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };
根据下标,我们就可以快速找出数组中的每一个元素。
利用VS的调试,我们可以观察到:
3.3.2 二维数组的输入和打印
3.4 二维数组在内存中的存储
int main()
{
int arr[3][5] = { 0 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
return 0;
}
4. C99中的变长数组
1. int arr1[10];2. int arr2[3+5];
3. double arr3[] = {1.0,2.0,3.0};
int arr[n];
上⾯⽰例中,数组 arr 就是变⻓数组,因为它的⻓度取决于变量 n 的值,编译器没法事先确定,只有运⾏时才能知道 n 是多少。
int main()
{
int n = 0;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
输入和输出:
5.Sleep函数
sleep函数
- 头文件:#include<windows.h>
- 功能:使计算机程序(进程、任务或线程)进入休眠状态,在一段时间内处于非活动状态。当函数设定的计时器到期,或接收到信号、程序发生中断时,程序会继续执行。
- 单位:sleep函数的计时单位在不同的系统和编译器下有所不同。在Windows系统中,Sleep函数的单位是毫秒。在Unix类操作系统中,sleep函数的单位是秒。
- 用法:在Windows系统中,Sleep函数需要一个以毫秒为单位的参数,表示程序挂起时长,且Sleep函数中的S应大写。
- 总的来说,sleep函数是一个在编程中常用的控制程序执行速度的工具,它可以让程序在指定的时间间隔内暂停执行,使系统的处理器资源得到休息,或实现等待、延时等操作。
#include<stdio.h>
#include<windows.h>
int main()
{
int arr[5] = { 1,2,3,4,5 };
for (int i = 0; i < 5; i++)
{
Sleep(1000);
printf("%d ", arr[i]);
}
return 0;
}
该代码会在屏幕上打印1,2,3,4,5,但是打印完一个数之后会过一秒再打印另外一个数。
6. 数组练习
练习1:多个字符从两端移动,向中间汇聚
int main()
{
char ch1[] = "helloworld";
char ch2[] = "**********";
int left = 0;
int right = strlen(ch1) - 1;
printf("%s\n", ch2);
while (left <= right)
{
Sleep(1000);
ch2[left] = ch1[left];
ch2[right] = ch1[right];
left++;
right--;
printf("%s\n", ch2);
}
return 0;
}
练习2:⼆分查找
二分查找(Binary Search)是一种在 有序数组中查找特定元素的高效算法。其核心思想是不断将搜索范围对半分割,直到找到目标元素或确定元素不存在。 二分查找的时间复杂度为O(log n),这是基于每次迭代都将搜索范围减半的事实。算法的步骤包括:
- 确定搜索范围,即数组的起始和结束位置。
- 计算中间元素的索引。
- 比较中间元素与目标值:
- 如果中间元素等于目标值,返回中间元素的索引。
- 如果中间元素小于目标值,目标值可能在中间元素的右侧,更新搜索范围的开始位置为中间元素的索引加一。
- 如果中间元素大于目标值,目标值可能在中间元素的左侧,更新搜索范围的结束位置为中间元素的索引减一。
- 重复以上步骤,直到找到目标值或搜索范围为空。
二分查找要求输入的数据必须是有序的,这样可以保证每次都可以将搜索范围减半。
示例代码如下:
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10, };
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
int key = 0;
scanf("%d", &key);
int mid = 0;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (key > arr[mid])
{
left = mid + 1;
}
else if (key < arr[mid])
{
right = mid - 1;
}
else
{
printf("找到了key,该数下标为%d\n", mid);
return 0;
}
}
printf("没有找到该数\n");
return 0;
}