当前位置: 首页 > news >正文

C 语言指针完全指南:创建、解除引用、指针与数组关系解析

C 语言中的指针

创建指针

我们可以使用引用运算符&获取变量的内存地址:

代码语言:c

AI代码解释

int myAge = 43; // 一个 int 变量 printf("%d", myAge); // 输出 myAge 的值 (43) printf("%p", &myAge); // 输出 myAge 的内存地址 (0x7ffe5367e044)

指针是一个将另一个变量的内存地址作为其值的变量。

指针变量指向一个数据类型(如int)的相同类型,并使用*运算符创建。您正在使用的变量的地址被分配给指针:

代码语言:c

AI代码解释

int myAge = 43; // 一个 int 变量 int* ptr = &myAge; // 一个名为 ptr 的指针变量,存储 myAge 的地址 // 输出 myAge 的值 (43) printf("%d\n", myAge); // 输出 myAge 的内存地址 (0x7ffe5367e044) printf("%p\n", &myAge); // 使用指针输出 myAge 的内存地址 (0x7ffe5367e044) printf("%p\n", ptr);

示例解释:

  • 创建一个名为ptr的指针变量,指向一个int变量 (myAge)。请注意,指针的类型必须与您正在使用的变量的类型匹配(本例中为int)。
  • 使用&运算符将myAge变量的内存地址存储并分配给指针。
  • 现在,ptr存储了myAge的内存地址值。
解除引用

在上面的示例中,我们使用指针变量来获取变量的内存地址(与&引用运算符一起使用)。

您还可以通过使用*运算符(取消引用运算符)获取指针指向的变量的值:

代码语言:c

AI代码解释

int myAge = 43; // 变量声明 int* ptr = &myAge; // 指针声明 // 引用:使用指针输出 myAge 的内存地址 (0x7ffe5367e044) printf("%p\n", ptr); // 解除引用:使用指针输出 myAge 的值 (43) printf("%d\n", *ptr);

请注意,*符号在这里可能会让人困惑,因为它在我们的代码中做了两件事:

  • 当用于声明 (int* ptr) 时,它会创建一个指针变量。
  • 当不用于声明时,它充当取消引用运算符。

值得注意:在 C 语言中声明指针变量有两种方法:

代码语言:c

AI代码解释

int* myNum; int *myNum;

关于指针的注意事项:

  • 指针是 C 语言区别于其他编程语言(如 Python 和 Java)的一大特点。
  • 它们在 C 语言中很重要,因为它们允许我们操作计算机内存中的数据。这可以减少代码量并提高性能。如果您熟悉像列表、树和图这样的数据结构,您应该知道指针对于实现它们特别有用。有时您甚至必须使用指针,例如在处理文件时。
  • 但是要小心; 指针必须谨慎处理,因为有可能损坏存储在其他内存地址的数据。

C 语言中的指针和数组

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

考虑以下整数数组

代码语言:c

AI代码解释

int myNumbers[4] = {25, 50, 75, 100}; int i; for (i = 0; i < 4; i++) { printf("%d\n", myNumbers[i]); }

结果:

代码语言:c

AI代码解释

25 50 75 100

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

代码语言:c

AI代码解释

int myNumbers[4] = {25, 50, 75, 100}; int i; for (i = 0; i < 4; i++) { printf("%p\n", &myNumbers[i]); }

结果:

代码语言:c

AI代码解释

0x7ffe70f9d8f0 0x7ffe70f9d8f4 0x7ffe70f9d8f8 0x7ffe70f9d8fc

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

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

代码语言:c

AI代码解释

// 创建一个 int 变量 int myInt; // 获取一个 int 的内存大小 printf("%lu", sizeof(myInt));

结果:4

因此,从上面的“内存地址示例”中,

您可以看到编译器为每个数组元素预留了 4 个字节的内存,这意味着整个数组占用 16 个字节(4 * 4)的内存存储空间:

代码语言:c

AI代码解释

int myNumbers[4] = {25, 50, 75, 100}; // 获取 myNumbers 数组的大小 printf("%lu", sizeof(myNumbers));

结果:16

指针与数组的关系

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

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

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

代码语言:c

AI代码解释

int myNumbers[4] = {25, 50, 75, 100}; // 获取 myNumbers 数组的内存地址 printf("%p\n", myNumbers); // 获取第一个数组元素的内存地址 printf("%p\n", &myNumbers[0]);

结果:

代码语言:c

AI代码解释

0x7ffe70f9d8f0 0x7ffe70f9d8f0

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

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

代码语言:c

AI代码解释

int myNumbers[4] = {25, 50, 75, 100}; // 获取 myNumbers 中第一个元素的值 printf("%d", *myNumbers);

结果:25

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

代码语言:c

AI代码解释

int myNumbers[4] = {25, 50, 75, 100}; // 获取 myNumbers 中的第二个元素的值 printf("%d\n", *(myNumbers + 1)); // 获取 myNumbers 中的第三个元素的值 printf("%d", *(myNumbers + 2)); // 等等..

结果:

代码语言:c

AI代码解释

50 75

或者循环遍历它:

代码语言:c

AI代码解释

int myNumbers[4] = {25, 50, 75, 100}; int *ptr = myNumbers; int i; for (i = 0; i < 4; i++) { printf("%d\n", *(ptr + i)); }

结果:

代码语言:c

AI代码解释

25 50 75 100

您也可以使用指针更改数组元素的值:

代码语言:c

AI代码解释

int myNumbers[4] = {25, 50, 75, 100}; // 将第一个元素的值改为 13 *myNumbers = 13; // 将第二个元素的值改为 17

最后

为了方便其他设备和平台的小伙伴观看往期文章

http://www.jsqmd.com/news/511113/

相关文章:

  • Floyd-Warshall算法在社交网络分析中的5个实际应用案例
  • 三菱FX3U源码在V10.5的基础上增加了禁止上传功能,介于三菱的密码没啥用特意做了这个功能
  • Arduino 10位软件PWM与CIE1931人眼亮度校准库
  • Qwen3-ASR-0.6B多场景落地:跨境电商直播语音→商品名识别+用户提问聚类分析
  • MSPM0L系列MCU的ADC高精度采集设计与实现
  • 紧急预警:新国标GB/T 15969.3-2023实施倒计时90天!你的梯形图-C转换工具是否通过安全相关代码静态分析认证?
  • GPEN效果展示:修复前后可商用级别对比——满足印刷/展板输出要求
  • SolidWorks宏录制不生成C++代码?手把手教你手动转换VB/C#示例到C++
  • GetQzonehistory:守护数字记忆的QQ空间数据备份工具
  • 从电影到代码:用Python手把手实现RSA加密(附完整密钥生成步骤)
  • 示波器安全测量:共模电压陷阱与三层防护策略
  • AVR单片机实现轻量级Modbus TCP从站(ENC28J60)
  • SpringBoot整合Easypoi实现Excel模板导出(附完整代码示例)
  • Flutter 状态管理为什么总是“选型焦虑”?
  • Phi-3-mini-4k-instruct在.NET开发中的应用
  • 5分钟搭建时间序列预测工具:时空波动仪FlowState Lab新手入门全攻略
  • 探讨2026年靠谱入伙活动策划公司,深圳信雅文化经验丰富 - 工业品牌热点
  • 千问图像生成16Bit在电商设计中的应用:1024px海报秒级生成落地案例
  • IQuest-Coder-V1-40B效果实测:生成代码准确率高,开发效率翻倍
  • RMBG-2.0应用案例:AI绘画工作流中LoRA训练前图像预处理环节
  • Pixel Dimension Fissioner入门教程:理解‘文本种子→裂变炉→维度手稿’工作流
  • GLM-4-9B-Chat-1M应用场景:生物医药——临床试验报告长文本终点指标提取与解读
  • 驾驭OpenCore:OCAT工具让黑苹果配置化繁为简
  • OpenClaw多模型切换:Qwen3-32B与Llama3任务分工方案
  • 告别玄学调参!S32K144时钟配置保姆级教程:从Clock Manager到代码生成
  • 2026年深圳靠谱奠基活动策划公司排名,专业方案助力项目启航 - 工业推荐榜
  • REX-UniNLU在UI/UX设计文档分析中的应用
  • PCB表意层设计:从丝印铭文到功能性图形的工程实践
  • 电位器式双轴摇杆模块原理与嵌入式驱动实现
  • OpenBCI Cyton SD卡驱动库深度解析:PIC32嵌入式FAT32实现