5.3 指针与数组
5.3.1 数组的几个概念
什么是数组?数组是组织数据的一种方式。
如何创建一个数组?
int numbers[5]; // 定义一个包含 5 个整数的数组为什么要定义数组?
组织数据:数组允许你将一组相关的数据元素组织在一起,从而更容易管理和访问这些数据。
节省内存:数组在内存中是连续存储的,这意味着它们占用的内存空间相对较小,因为它们没有额外的开销用于存储数据之间的链接信息。
快速访问:通过索引,你可以快速访问数组中的任何元素,而不必遍历整个数据集。
生活中的例子:
/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 存在一个问题:只支持整数输入。 │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
#include <stdio.h>
int main()
{
// 定义一个整数数组来存储一周中每天的温度
int temperatures[7];
// 输入每天的温度数据
for (int i = 0; i < 7; i++)
{
printf("Enter temperature for day %d: ", i + 1);
scanf("%d", &temperatures[i]);
}
// 打印一周中每天的温度
printf("Weekly temperatures:\n");
for (int i = 0; i < 7; i++)
{
printf("Day %d: %d degrees\n", i + 1, temperatures[i]);
}
return 0;
}5.3.2 数组下标

数组的索引通常从 0 开始为什么?数组索引从 0 开始的设计是历史上的一种约定,起初是为了更有效地实现数组的内部表示和访问。这个设计选择有一些历史原因和技术因素:
直接内存访问:在底层的内存管理中,数组的元素是按照连续的内存地址排列的。通过从零开始的索引,可以更容易地计算出每个元素的内存地址。例如,第一个元素的地址就是数组的起始地址,第二个元素的地址是第一个元素地址加上一个固定的偏移量,以此类推。这种设计使得数组的元素可以通过简单的数学运算来直接访问,而无需复杂的指针计算。
历史原因:早期的编程语言,特别是汇编语言和低级语言,通常使用从 0 开始的索引。C语言在设计时受到了这些语言的影响,因此也采用了从 0 开始的索引。这种约定的延续使得C语言的设计更具一致性和可预测性。
方便性:从 0 开始的索引也具有一些方便之处。例如,数组的长度就是最后一个元素的索引加1,这使得计算数组的长度更加直观和方便。
尽管从 0 开始的索引在历史上有一些技术原因,但它已经成为了一种编程的标准约定。这种约定在C语言中被广泛采用,也在许多其他编程语言中得到了继承和延续,因此程序员通常期望数组的索引从0开始。虽然它可能在某些情况下导致初学者困惑,但一旦习惯了,它可以提供更加一致和方便的编程体验。在定义数组的时候,其实已经申请了一个内存空间,数组在内存中有也自己的一个“序号”=“数组下标”。
5.3.3 数组的初始化
数组可以进行完全初始化、不完全初始化。

还可,进行指定初始化:
5.3.4 数组长度计算
求一个未知长度的数组的长度,并进行遍历打印:
打印数组占用字节数:
5.3.5 二维数组(矩阵)及其初始化
注意:作为一个 idiom 记忆,内存花括号的省略会是很危险的。
二维数组初始化 SOL1:

二维数组初始化 SOL2 不够补零 :


5.3.6 二维数组、指针与冒泡排序
数组作为函数的参数,并以指针的形式出现。
略
5.3.7 数组名作为指针
指针与数组更为关键的联系:可以用数组的名字作为指向数组第一个元素的指针。
注意:虽然能把数组名用作指针,但是不能给数组名赋新的值。如果要更改,采取下列先复制再更改的方法:
代码解释:
5.3.8 指针与数组的神奇公式
把数组取下标和指针算术运算关联起来的神奇公式:
通常情况下,a+i等价于 &a[i],也就是两者都表示指向数组 a 中元素 i 的指针。并且,*(a+i) 等价于 a[i] 两者都表示元素 i 本身。换句话说,可以把数组的取下标看成是指针算术运算的一种形式。
Last updated
Was this helpful?