目录
1. 数组的定义
数组是一组具有相同数据类型的元素的集合,这些元素在内存中是连续存储的。也是一种容器,可以用来存储同种数据类型的多个值。
2. 数组的格式
①定义数组的一般格式为:数据类型(int) 数组名(arr) [数组大小/长度] ;
-
数据类型:指定数组中每个元素的数据类型,如
int
、float
、char
等。 -
数组名:是用户为数组取的名称,遵循标识符命名规则。
-
数组大小/长度:表示数组中元素的个数,必须是一个常量表达式。
②特点:连续的空间;一旦定义,长度不可变。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[80];//定义数组存储全班80位同学年龄
double arr2[50];//定义数组存储全班50位同学身高
double arr3[3];//定义数组存储全身每件衣服价格
return 0;
}
3. 数组的初始化
①完全初始化:在定义数组时,为数组的每个元素提供初始值。
int arr[5] = {1, 2, 3, 4, 5};
② 部分初始化:只对数组的部分元素提供初始值,未初始化的元素会被自动初始化为 0。
int arr[5] = {1, 2}; // 等价于 {1, 2, 0, 0, 0}
③省略数组大小:如果在初始化时提供了所有元素的值,可以省略数组大小,编译器会根据初始化列表的元素个数来确定数组的大小。
int arr[ ] = {1, 2, 3, 4, 5}; // 数组大小为 5
④注意:
(1)长度省略:数据值的个数就是数组长度。如:int arr [ ]={1,2,3}
(2)长度未省略:数据值的个数≤长度。如:int arr [ 5 ]={1,2,3} ——还有2个空位没有数字,用默认值0表示!
4. 数组的索引
数组的一个编号,也叫作:角标,下标,编号。数组的索引是从 0 开始的整数,用于访问数组中的元素。例如,对于一个包含 n
个元素的数组,其索引范围是从 0 到 n - 1
。
特点:从0开始,连续+1,不间断。
5. 元素访问
(1)定义:通过数组名和索引来访问数组中的元素。
(2)获取:
变量 = 数组名 [ 索引 ] 或 printf( “ 占位符 ” ,数组名 [ 索引 ]);
int num = arr [ 5 ] 或 printf( “ 占位符 ” ,arr [ 5 ]);
(3)修改:
数组名 [ 索引 ] = 数据值;
arr [ 5 ] = 10;
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//定义一个长度为5的数组,并进行初始化:1,2,3,4,5
//要求:①获取索引为0,2,4并求和
// ②把最后一个索引元素修改为10
int main()
{
int arr[] = { 1,2,3,4,5 };
int num1 = arr[0];
int num2 = arr[2];
int num3 = arr[4];
int sum = num1 + num2 + num3;
printf("%d\n", sum);//9
printf("修改前:%d\n", arr[4]);//修改前:5
arr[4] = 10;
printf("修改后:%d\n", arr[4]);//修改后:10
return 0;
}
6.遍历
依次获取数组中的每一个元素
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//定义一个长度为5的数组,并进行初始化:1,2,3,4,5
//要求:遍历数组,并且把每一个元素打印到控制台
int main()
{
int arr[5] = { 1,2,3,4,5 };
//利用循环遍历数组
for (int i = 0; i < 5; i++)
{
//i:依次表示数组里面的每一个索引
printf("%d\n", arr[i]);//1 2 3 4 5
}
return 0;
}
7.内存和内存地址
(1)定义
①内存:软件在运行时,用来临时存储数据的
②内存地址:编号(1格子=1字节)。作用是快速管理内存空间
规则:
Ⅰ:32位操作系统,内存地址以32位的二进制表示。地址范围共计429496.7296个=4GB
Ⅱ:64位操作系统,内存地址以64位的二进制表示。地址范围共计0~2^64=17179TB=17.592.186GB
(2)C语言中的内存地址
int类型→4个字节 1个索引4个格子,1个格子8个0
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//获取变量的内存地址
int main()
{
int a = 10;
printf("%p\n", &a);//00000052AAB4F684
return 0;
}
(3)通过变量的首地址,就可以确定变量中存储的数据
(4)数组长度=总长度 / 数据类型占用的字节个数
(5)数组作为函数的形参,实际上传送是数组的首地址,如果要在函数中对数组进行遍历的话,记得一定要把数组的长度一起传送过去
(6)数组的索引越界:最小索引:0; 最大索引:长度-1
8.数组练习
①写出10个数,找出最大值
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int numbers[10] = { 23, 45, 12, 67, 89, 34, 56, 78, 90, 11 };
int max = numbers[0];
for (int i = 1; i < 10; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
}
printf("这 10 个数中的最大值是: %d\n", max);//这 10 个数中的最大值是: 90
return 0;
}
②生成10个1-100之间的随机数存入数组并且求和
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int arr[10];
int sum = 0;
srand(time(NULL));
for (int i = 0; i < 10; i++) {
arr[i] = rand() % 100 + 1;
sum += arr[i];
}
printf("生成的 10 个 1 - 100 之间的随机数为: ");//生成的 10 个 1 - 100 之间的随机数为: 10 87 61 14 70 80 40 82 44 31
for (int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
printf("\n");
printf("这 10 个随机数的和为: %d\n", sum);//这 10 个随机数的和为: 519
return 0;
}
-
srand(time(NULL));
利用当前时间初始化随机数种子,保证每次运行生成的随机数不同。 -
rand() % 100 + 1
生成 1 到 100 之间的随机数。
③定义一个数组,存入1-10,要求打乱数组中的所有数据顺序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int arr[10];
srand(time(NULL));
for (int i = 0; i < 10; i++) {
arr[i] = i + 1;
}
for (int i = 9; i > 0; i--) {
int j = rand() % (i + 1);
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
printf("打乱顺序后的数组为: ");//打乱顺序后的数组为: 9 1 6 2 10 8 7 4 5 3
for (int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
- 先把数组初始化为 1 到 10。
- 采用 Fisher - Yates 洗牌算法打乱数组顺序,从数组末尾开始,随机选取前面的元素与当前元素交换。
④遍历数组比较最大值
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define ARRAY_SIZE 10
int main() {
int arr[ARRAY_SIZE] = { 34, 7, 23, 32, 5, 62, 15, 54, 90, 8 };
int max = arr[0];
for (int i = 1; i < ARRAY_SIZE; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
printf("数组中的最大值是: %d\n", max);//数组中的最大值是: 90
return 0;
}
- 数组定义:借助
#define
宏定义数组的大小ARRAY_SIZE
,接着定义了一个包含ARRAY_SIZE
个元素的整数数组arr
,并且对其进行了初始化。 - 最大值初始化:把数组的首个元素
arr[0]
赋值给变量max
,将其当作当前的最大值。 - 数组遍历:利用
for
循环从数组的第二个元素(索引为 1)开始遍历整个数组。 - 比较更新:在循环中,运用
if
语句比较当前元素arr[i]
和max
的大小,若当前元素大于max
,就把当前元素的值赋给max
。 - 输出结果:循环结束后,
max
中存储的就是数组中的最大值,使用printf
函数输出该值。
9.数组常见算法
①查找算法
(1)基本查找/顺序查找
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 顺序查找函数
int sequentialSearch(int arr[], int n, int target) {
for (int i = 0; i < n; i++) {
if (arr[i] == target) {
return i; // 找到目标元素,返回其索引
}
}
return -1; // 未找到目标元素,返回 -1
}
int main() {
int arr[] = { 12, 34, 56, 78, 90, 23, 45, 67 };
int n = sizeof(arr) / sizeof(arr[0]);
int target = 45;
int result = sequentialSearch(arr, n, target);
if (result != -1) {
printf("元素 %d 在数组中的索引是 %d\n", target, result);//元素 45 在数组中的索引是 6
}
else {
printf("元素 %d 未在数组中找到\n", target);
}
return 0;
}
-
int sequentialSearch(int arr[], int n, int target)
:这是一个自定义函数,用于在数组里进行顺序查找。-
int arr[]
:表示要查找的数组。 -
int n
:代表数组的元素个数。 -
int target
:指的是要查找的目标元素。
-
-
for (int i = 0; i < n; i++)
:运用for
循环逐个遍历数组元素。 -
if (arr[i] == target)
:在遍历过程中,若当前元素和目标元素相等,就返回该元素的索引i
。 -
return -1
:若遍历完整个数组都没找到目标元素,就返回 -1 以表明未找到。 -
int main()
:程序的入口函数,程序从这里开始执行。 -
int arr[] = { 12, 34, 56, 78, 90, 23, 45, 67 };
:定义并初始化一个整数数组arr
。 -
int n = sizeof(arr) / sizeof(arr[0]);
:计算数组arr
的元素个数。sizeof(arr)
得到数组的总字节数,sizeof(arr[0])
得到数组单个元素的字节数,二者相除便得到元素个数。 -
int target = 45;
:定义要查找的目标元素为 45。 -
int result = sequentialSearch(arr, n, target);
:调用sequentialSearch
函数在数组arr
里查找目标元素target
,并把查找结果存于变量result
中。 -
if (result != -1)
:对查找结果进行判断。若result
不等于 -1,就意味着找到了目标元素,输出目标元素及其索引;反之,则输出未找到目标元素的信息。 -
return 0;
:表示程序正常结束。
(2)二分查找/折半查找
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 二分查找函数
int binarySearch(int arr[], int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid; // 找到目标元素,返回其索引
}
else if (arr[mid] < target) {
left = mid + 1; // 目标元素在右半部分
}
else {
right = mid - 1; // 目标元素在左半部分
}
}
return -1; // 未找到目标元素,返回 -1
}
int main() {
int arr[] = { 10, 20, 30, 40, 50, 60, 70, 80 };
int n = sizeof(arr) / sizeof(arr[0]);
int target = 40;
int result = binarySearch(arr, 0, n - 1, target);
if (result != -1) {
printf("元素 %d 在数组中的索引是 %d\n", target, result);//元素 40 在数组中的索引是 3
}
else {
printf("元素 %d 未在数组中找到\n", target);
}
return 0;
}
(3)插值查找
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 插值查找函数
int interpolationSearch(int arr[], int n, int target) {
int left = 0, right = n - 1;
while (left <= right && target >= arr[left] && target <= arr[right]) {
if (left == right) {
if (arr[left] == target) return left;
return -1;
}
// 计算插值位置
int pos = left + (((double)(target - arr[left]) / (arr[right] - arr[left])) * (right - left));
if (arr[pos] == target) {
return pos; // 找到目标元素,返回其索引
}
else if (arr[pos] < target) {
left = pos + 1; // 目标元素在右半部分
}
else {
right = pos - 1; // 目标元素在左半部分
}
}
return -1; // 未找到目标元素,返回 -1
}
int main() {
int arr[] = { 10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47 };
int n = sizeof(arr) / sizeof(arr[0]);
int target = 18;
int result = interpolationSearch(arr, n, target);
if (result != -1) {
printf("元素 %d 在数组中的索引是 %d\n", target, result);//元素 18 在数组中的索引是 4
}
else {
printf("元素 %d 未在数组中找到\n", target);
}
return 0;
}
②排序算法
(1)冒泡排序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 冒泡排序函数
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// 交换 arr[j] 和 arr[j+1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
int arr[] = { 64, 34, 25, 12, 22, 11, 90 };
int n = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, n);
printf("排序后的数组: ");//排序后的数组: 11 12 22 25 34 64 90
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
(2)选择排序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 选择排序函数
void selectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
} // 交换 arr[i] 和 arr[minIndex]
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
int main() {
int arr[] = { 64, 25, 12, 22, 11 };
int n = sizeof(arr) / sizeof(arr[0]);
selectionSort(arr, n);
printf("排序后的数组: ");//排序后的数组: 11 12 22 25 64
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}