12. C语言 数组与指针(深入理解)

本章目录:

    • 前言
    • 1. 什么是数组?
    • 2. 数组的声明与初始化
      • 声明数组
      • 初始化数组
    • 3. 访问数组元素
      • 遍历数组
    • 4. 获取数组长度
      • 使用 `sizeof` 获取长度
      • 使用宏定义简化
    • 5. 数组与指针
      • 数组名与指针的区别
      • 使用指针操作数组
    • 6. 多维数组
      • 遍历多维数组
    • 7. 数组作为函数参数
    • 8. 高级技巧与注意事项
      • 初始化技巧
      • 常见陷阱
    • 9. 示例:统计超过平均值的学生人数
    • 总结


前言

在 C 语言中,数组是一种重要的数据结构,它可以存储一系列相同类型的数据。本文将从基础讲起,结合读者笔记和实际应用,全面解析数组的用法及其高级特性。


1. 什么是数组?

数组是一种顺序存储结构,用于存储相同数据类型的多个值。它通过连续的内存单元表示这些值。数组的索引从 0 开始,最高索引为 数组大小 - 1

例如:

int numbers[5] = {1, 2, 3, 4, 5};

这里 numbers 是一个包含 5 个整数的数组,其内存布局如下:

索引
01
12
23
34
45

2. 数组的声明与初始化

声明数组

数组声明的语法为:

type arrayName[arraySize];
  • type:元素类型,如 intdouble
  • arraySize:数组大小,必须是正整数。

示例:

double balance[10]; // 一个可以存储 10 个 double 类型数据的数组

初始化数组

数组可以在声明时初始化,方法有两种:

  1. 显式初始化
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
  1. 隐式大小推导
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

如果未显式初始化,未赋值的元素将根据数据类型被初始化为默认值,例如:

  • int0
  • float0.0
  • char'\0'

3. 访问数组元素

可以通过数组名加索引访问数组元素:

int nums[5] = {10, 20, 30, 40, 50};
int value = nums[2]; // value = 30

遍历数组

使用 for 循环:

for (int i = 0; i < 5; i++) {printf("%d ", nums[i]);
}

4. 获取数组长度

使用 sizeof 获取长度

数组总大小可以通过 sizeof(array) 获取,单个元素的大小可以通过 sizeof(array[0]) 获取。数组长度计算公式为:

int length = sizeof(array) / sizeof(array[0]);

示例:

int nums[] = {1, 2, 3, 4, 5};
int length = sizeof(nums) / sizeof(nums[0]);
printf("数组长度为: %d\n", length); // 输出 5

使用宏定义简化

#define LENGTH(array) (sizeof(array) / sizeof(array[0]))

调用示例:

int nums[] = {1, 2, 3, 4, 5};
printf("数组长度为: %d\n", LENGTH(nums));

5. 数组与指针

在 C 中,数组名可以视为指向其首元素的指针,但两者有本质区别。

数组名与指针的区别

特性数组名指针变量
表示内容首元素地址存储的地址
是否可修改不可修改可修改
用于传参表示指针可指向任意变量

例如:

int nums[5] = {1, 2, 3, 4, 5};
int *ptr = nums; // 数组名 nums 表示首元素地址

使用指针操作数组

可以通过指针遍历数组:

int nums[5] = {1, 2, 3, 4, 5};
int *ptr = nums;for (int i = 0; i < 5; i++) {printf("%d ", *(ptr + i)); // 指针运算
}

6. 多维数组

C 支持多维数组,最常见的是二维数组。其声明和初始化方式如下:

int matrix[2][3] = {{1, 2, 3},{4, 5, 6}
};

遍历多维数组

for (int i = 0; i < 2; i++) {for (int j = 0; j < 3; j++) {printf("%d ", matrix[i][j]);}printf("\n");
}

7. 数组作为函数参数

数组可以通过指针形式传递给函数:

void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}
}int main() {int nums[] = {1, 2, 3, 4, 5};printArray(nums, sizeof(nums) / sizeof(nums[0]));return 0;
}

注意:在函数中无法直接通过 sizeof 获取数组长度,因此需额外传递数组大小。


8. 高级技巧与注意事项

初始化技巧

数组可以通过 {0} 一次性初始化为零:

int nums[10] = {0};

常见陷阱

  • 字符串数组与字符串指针的区别

    char str[] = "Hello";  // 自动追加 '\0'
    char *ptr = "Hello";   // 指向常量字符串
    
  • 数组变量不可赋值

    int nums1[5], nums2[5];
    nums1 = nums2; // 错误,数组名是常量指针
    

9. 示例:统计超过平均值的学生人数

以下代码示例展示了数组的一个实际应用场景:

#include <stdio.h>int main() {int scores[100], n, count = 0;double sum = 0;printf("输入学生人数: ");scanf("%d", &n);printf("输入每位学生的成绩:\n");for (int i = 0; i < n; i++) {scanf("%d", &scores[i]);sum += scores[i];}double avg = sum / n;for (int i = 0; i < n; i++) {if (scores[i] > avg) {count++;}}printf("平均分为: %.2f\n", avg);printf("超过平均分的人数: %d\n", count);return 0;
}

总结

数组是 C 语言中的基础而重要的结构。通过掌握数组的声明、初始化、操作以及与指针的关系,您可以更高效地处理多数据存储和计算的需求。希望本文能够帮助您对 C 数组有更深入的理解!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/66769.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode 120. 三角形最小路径和 动态规划

原题链接&#xff1a;Leetcode 120. 三角形最小路径和 class Solution { public:int minimumTotal(vector<vector<int>>& triangle) {int n triangle.size();if (n 1)return triangle[0][0];int dp[n][n];dp[0][0] triangle[0][0];int res INT_MAX;for (in…

网络安全概论

网络安全概论--网络基础知识--防火墙技术--身份识别技术--虚拟专用网络--入侵检测技术--病毒和恶意代码 --业务连续性计划--安全管理--信息系统安全方案设计方法 一、网络安全面临的威胁 物理安全威胁、操作系统的安全缺陷、网络协议的安全缺陷、应用软件的实现缺陷、用户使…

设计模式 行为型 状态模式(State Pattern)与 常见技术框架应用 解析

状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许对象在内部状态改变时改变其行为&#xff0c;使得对象看起来好像修改了它的类。这种设计模式的核心思想是将对象的状态和行为封装成不同的状态类&#xff0c;通过状态对象的行为改变来避免…

Java 线程池 ThreadPoolExecutor 底层原理与源码分析

引言 我们探讨了 ThreadPoolExecutor 的基本概念、内部机制以及部分源码实现。本文将继续深入研究该类的更多细节&#xff0c;并结合提供的文档内容&#xff0c;进一步解析线程池的工作流程、任务提交和执行的具体过程&#xff0c;以及如何通过自定义配置来优化性能。 一、线…

Mysql--基础篇--视图,存储过程,触发器

1、视图 MySQL视图&#xff08;View&#xff09;是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。但是&#xff0c;视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表&#…

某团 mtgsig1.2 | sdkVersion: 3.0.0 签名算法分析记录(2025/1/9)

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#…

(二)最长公共子序列、最长上升子序列、最大子段和、三角形最小路径和、矩阵连乘、0-1背包

最近刚考完算法设计分析课的考试&#xff0c;复习总结一下期末考试的几道算法题吧 目录 LCR 095. 最长公共子序列 300. 最长递增子序列 53. 最大子数组和 LCR 100. 三角形最小路径和 矩阵连乘问题 0-1背包 LCR 095. 最长公共子序列 给定两个字符串 text1 和 text2&#xff…

聚类系列 (二)——HDBSCAN算法详解

在进行组会汇报的时候&#xff0c;为了引出本研究动机&#xff08;论文尚未发表&#xff0c;暂不介绍&#xff09;&#xff0c;需要对DBSCAN、OPTICS、和HDBSCAN算法等进行详细介绍。在查询相关资料的时候&#xff0c;发现网络上对于DBSCAN算法的介绍非常多与细致&#xff0c;但…

通义灵码在跨领域应用拓展之物联网篇

目录 一.引言 二.通义灵码简介 三.通义灵码在物联网领域的设备端应用 1.传感器数据采集 (1).不同类型传感器的数据读取 (2).数据转换与预处理 2.设备控制指令接收和执行 (1).指令解析与处理 (2).设备动作执行 四.通义灵码在物联网领域的云端平台应用 1.数据存储和管…

python_excel列表单元格字符合并、填充、复制操作

读取指定sheet页&#xff0c;根据规则合并指定列&#xff0c;填充特定字符&#xff0c;删除多余的列&#xff0c;每行复制四次&#xff0c;最后写入新的文件中。 import pandas as pd""" 读取指定sheet页&#xff0c;根据规则合并指定列&#xff0c;填充特定字…

C++ STL 中的 vector 总结

1. 什么是 std::vector&#xff1f; std::vector 是 C STL 提供的动态数组容器&#xff0c;可以动态调整大小并存储任意类型的元素。 与普通数组相比&#xff0c;std::vector 更加灵活&#xff0c;提供了丰富的操作接口。 2. 基本特性 动态大小&#xff1a;支持在运行时动态增…

DolphinScheduler自身容错导致的服务器持续崩溃重大问题的排查与解决

01 问题复现 在DolphinScheduler中有如下一个Shell任务&#xff1a; current_timestamp() { date "%Y-%m-%d %H:%M:%S" }TIMESTAMP$(current_timestamp) echo $TIMESTAMP sleep 60 在DolphinScheduler将工作流执行策略设置为并行&#xff1a; 定时周期调度设置…

【stm32+K210项目】基于K210与STM32协同工作的智能垃圾分类系统设计与实现(完整工程资料源码)

视频效果演示: 基于K210与STM32协同工作的智能垃圾分类系统设计与实现 目录: 目录 视频效果演示: 目录:

CISAW-ES应急服务方向信息安全事件分级

网络安全事件事件分级 网络安全事件分为四级&#xff1a;特别重大网络安全事件、重大网络安全事大网络安全事件、一般网络安全事件。 1&#xff0e;特别重大网络安全事件 符合下列情形之一的&#xff0c;为特别重大网络安全事件。 &#xff08;1&#xff09;重要网络和信息系…

油猴支持阿里云自动登陆插件

遇到的以下问题,都已在脚本中解决: 获取到的元素赋值在页面显示,但是底层的value并没有改写,导致请求就是获取不到数据元素的加载时机不定,尤其是弱网情况下,只靠延迟还是有可能获取不到,且登陆不丝滑,通过元素发现机制,解决此问题并做到丝滑登陆根据密钥计算校验码之…

简聊MySQL的顺序读写和随机读写

在MySQL数据库中&#xff0c;顺序读写和随机读写的应用区别主要体现在以下几个方面&#xff1a; 一、定义回顾 顺序读写&#xff1a;数据按照物理地址的连续性进行读写操作&#xff0c;通常用于处理大型文件或连续的数据块。随机读写&#xff1a;数据分散在磁盘的不同位置进行…

[Git] git reset --hard / git reset --soft

git reset --hard 功能&#xff1a;重置索引&#xff08;暂存区&#xff09;和工作目录到指定的提交状态。这意味着它会丢弃所有未提交的更改和已暂存的更改。 适用场景&#xff1a;当你想要完全放弃当前工作目录中的所有更改并回退到某个特定提交状态时&#xff0c;可以使用这…

C语言基本知识复习浓缩版:scanf函数

C语言基本知识复习浓缩版&#xff1a;scanf函数 1 scanf()函数用于读取用户的键盘输入 2 scanf()函数的基本形式&#xff1a;scanf("参数列表1",参数列表2): 参数列表1&#xff1a;用户键盘输入的数据的类型&#xff0c;用占位符表示。 参数列表2&#xff1a;用户键…

Ubuntu 24.04 LTS系统安装Docker踩的坑

一开始我跟着Docker给出的官网文档 Ubuntu | Docker Docs 流程走&#xff0c;倒腾了两个多小时&#xff0c;遇到了各种坑&#xff0c;最后放弃了。在我们使用脚本安装Docker命令前&#xff0c;我们先把已经安装的Docker全部卸载掉。 卸载Docker 1.删除docker及安装时自动安装…

B树与B+树:数据库索引的秘密武器

想象一下&#xff0c;你正在构建一个超级大的图书馆&#xff0c;里面摆满了各种各样的书籍。B树和B树就像是两种不同的图书分类和摆放方式&#xff0c;它们都能帮助你快速找到想要的书籍&#xff0c;但各有特点。 B树就像是一个传统的图书馆摆放方式&#xff1a; 1. 书籍摆放&…