C 教程

C 教程 C 语言简介 C 下载安装和环境配置 C 快速入门 C 语法 C 输出 C 注释 C 变量 C 数据类型 C 常量 C 运算符 C 布尔值 C If...Else 语句 C Switch 语句 C While 循环 C For 循环 C Break/Continue 语句 C 数组 C 字符串 C 用户输入 C 内存地址 C 指针

C 函数

C 函数 C 函数参数 C 作用域 C 函数声明 C 递归 C 数学函数

C 文件

C 创建文件 C 写入文件 C 读取文件

C 结构体

C 结构体 C 嵌套结构体 C 结构体和指针 C 联合体 C typedef

C 枚举

C 枚举

C 内存

C 内存管理

C 错误

C 错误 C 调试 C 空值 C 错误处理 C 输入验证

C 更多

C 日期 C 随机数 C 宏 C 代码组织 C 存储类 C 位运算符 C 固定宽度整数

C 项目

C 项目

C 参考资料

C 参考资料 C 关键词 C <stdio.h> C <stdlib.h> C <string.h> C <math.h> C <ctype.h> C <time.h>

C 标准库参考

C 标准库 - 参考手册 C 标准库 - <assert.h> C 标准库 - <ctype.h> C 标准库 - <errno.h> C 标准库 - <float.h> C 标准库 - <limits.h> C 标准库 - <locale.h> C 标准库 - <math.h> C 标准库 - <setjmp.h> C 标准库 - <signal.h> C 标准库 - <stdarg.h> C 标准库 - <stddef.h> C 标准库 - <stdio.h> C 标准库 - <stdlib.h> C 标准库 - <string.h> C 标准库 - <time.h>

C 实例

C 语言实例 C 经典100例 C 编译器 C 测验


C 指针与数组

指针与数组

您还可以使用指针来访问数组。

考虑以下整数数组:

示例

int myNumbers[4] = {25, 50, 75, 100};

你从数组章节中学到,可以使用for循环遍历数组元素:

示例

int myNumbers[4] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {
  printf("%d", myNumbers[i]);
}

结果:

25
50
75
100
亲自试一试 »

我们不打印每个数组元素的值,而是打印每个数组元素的内存地址:

示例

int myNumbers[4] = {25, 50, 75, 100};
int i;

for (i = 0; i < 4; i++) {
  printf("%p", &myNumbers[i]);
}

结果:

0x7ffe70f9d8f0
0x7ffe70f9d8f4
0x7ffe70f9d8f8
0x7ffe70f9d8fc
亲自试一试 »

请注意,每个元素内存地址的最后一位数字都不同,并且都加了 4。

这是因为 int 类型的大小通常为 4 个字节,请记住:

示例

// 创建一个 int 整型变量
int myInt;

// 获取 int 类型的内存大小
printf("%zu", sizeof(myInt));

结果:

4
亲自试一试 »

从上面的"内存地址示例"可以看出,编译器为每个数组元素预留了 4 字节的内存,这意味着整个数组占用 16 字节(4 * 4)的内存空间。

示例

int myNumbers[4] = {25, 50, 75, 100};

// 获取 myNumbers 数组的大小
printf("%zu", sizeof(myNumbers));

结果:

16
亲自试一试 »

指针与数组有何关系

好的,那么指针和数组之间有什么关系呢?在 C 语言中,数组的名称实际上是指向数组第一个元素的指针。

感到困惑?让我们更好地理解这一点,并再次使用上面的"内存地址示例"。

第一个元素的内存地址与数组的名称相同:

示例

int myNumbers[4] = {25, 50, 75, 100};

// 获取 myNumbers 数组的内存地址
printf("%p", myNumbers);

// 获取数组第一个元素的内存地址
printf("%p", &myNumbers[0]);

结果:

0x7ffe70f9d8f0
0x7ffe70f9d8f0
亲自试一试 »

这基本上意味着我们可以通过指针来操作数组!

如何操作?由于 myNumbers 是指向 myNumbers 中第一个元素的指针,因此您可以使用 * 运算符来访问它:

示例

int myNumbers[4] = {25, 50, 75, 100};

// 获取 myNumbers 数组中第一个元素的值
printf("%d", *myNumbers);

结果:

25
亲自试一试 »

要访问 myNumbers 中的其余元素,您可以递增指针/数组(+1、+2 等):

示例

int myNumbers[4] = {25, 50, 75, 100};

// 获取 myNumbers 数组中第二个元素的值
printf("%d", *(myNumbers + 1));

// 获取 myNumbers 数组中第三个元素的值
printf("%d", *(myNumbers + 2));

// and so on..

结果:

50
75
亲自试一试 »

或者循环遍历它:

示例

int myNumbers[4] = {25, 50, 75, 100};
int *ptr = myNumbers;
int i;

for (i = 0; i < 4; i++) {
  printf("%d", *(ptr + i));
}

结果:

25
50
75
100
亲自试一试 »

也可以使用指针来改变数组元素的值:

示例

int myNumbers[4] = {25, 50, 75, 100};

// 将第一个元素的值更改为 13
*myNumbers = 13;

// 将第二个元素的值更改为 17
*(myNumbers +1) = 17;

// 获取第一个元素的值
printf("%d", *myNumbers);

// 获取第二个元素的值
printf("%d", *(myNumbers + 1));

结果:

13
17
亲自试一试 »

这种处理数组的方式可能看起来有点繁琐,尤其对于像上面例子中那样的简单数组而言。然而,对于大型数组,使用指针访问和操作数组会更加高效。

使用指针访问二维数组也被认为更快更便捷。

由于字符串实际上是数组,您也可以使用指针来访问字符串。

目前,您已经了解了它的工作原理,这很棒。但正如我们在上一章中提到的,必须谨慎使用指针,因为指针可能会覆盖内存中存储的其他数据。