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 个整数的数组,其内存布局如下:
索引 | 值 |
---|---|
0 | 1 |
1 | 2 |
2 | 3 |
3 | 4 |
4 | 5 |
2. 数组的声明与初始化
声明数组
数组声明的语法为:
type arrayName[arraySize];
type
:元素类型,如int
、double
。arraySize
:数组大小,必须是正整数。
示例:
double balance[10]; // 一个可以存储 10 个 double 类型数据的数组
初始化数组
数组可以在声明时初始化,方法有两种:
- 显式初始化:
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
- 隐式大小推导:
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
如果未显式初始化,未赋值的元素将根据数据类型被初始化为默认值,例如:
int
:0
float
:0.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 数组有更深入的理解!
相关文章:
12. C语言 数组与指针(深入理解)
本章目录: 前言1. 什么是数组?2. 数组的声明与初始化声明数组初始化数组 3. 访问数组元素遍历数组 4. 获取数组长度使用 sizeof 获取长度使用宏定义简化 5. 数组与指针数组名与指针的区别使用指针操作数组 6. 多维数组遍历多维数组 7. 数组作为函数参数8. 高级技巧与…...

Postman接口测试基本操作
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 Postman-获取验证码 需求:使用Postman访问验证码接口,并查看响应结果。 地址:http://kdtx-test.itheima.net/api/captchaIm…...

MySQL--2.1MySQL的六种日志文件
大家好,我们来说一下MySQL的6中日志文件。 1.查询日志 查询日志主要记录mysql的select查询的,改配置是默认关闭的。不推荐开启,因为会导致大量查询日志文件储存占用你的空间。 举例查询一下 select * from class; 开启查询日志的命…...
spring task使用
Spring Task 简介 Spring Task 是 Spring 框架原生自带的任务调度框架,它犹如一把瑞士军刀,为开发者提供了丰富多样的功能,助力轻松创建和管理定时任务。相较于其他一些第三方任务调度框架,Spring Task 最大的优势在于其与 Sprin…...

【FPGA】时序约束与分析
设计约束 设计约束所处环节: 约束输入 分析实现结果 设计优化 设计约束分类: 物理约束:I/O接口约束(例如引脚分配、电平标准设定等物理属性的约束)、布局约束、布线约束以及配置约束 时序约束:设计FP…...
LLM的MoE由什么构成:门控网络,专家网络
LLM的MoE由什么构成:门控网络,专家网络 目录 LLM的MoE由什么构成:门控网络,专家网络专家网络门控网络MoE在联邦学习中的使用及原理专家网络 定义与特点:是一组独立的模型,每个模型都负责处理某个特定的子任务或学习输入空间的特定部分。这些专家可以是简单的线性回归模型…...
HTML-多媒体标签
除了图像,网页还可以放置视频和音频。 1.<video> <video>标签是一个块级元素,用于放置视频。如果浏览器支持加载的视频格式,就会显示一个播放器,否则显示<video>内部的子元素。 <video src"example.…...

MySQL笔记大总结20250108
Day2 1.where (1)关系运算符 select * from info where id>1; select * from info where id1; select * from info where id>1; select * from info where id!1;(2)逻辑运算符 select * from info where name"吴佩奇" and age19; select * from info wh…...

stm32week3
stm32学习 二.外设 8.TIM输出比较 OC(output compare)输出比较 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0、翻转操作,用于输出一定频率和占空比的PWM波形 每个高级定时器和通用定时器都拥有4个输出比较通道 高级定时器的…...

uniapp 的uni.getRecorderManager() 录音功能小记
官网上明确说的是全局唯一并且只是获取对象,所以会导致一个问题就是,当你多个页面要用到这个对象的时候,会发现 onStop 方法会被覆盖,导致调用结果不是自己想要的 解决办法也简单粗暴,在需要用到的界面重新覆盖onStop…...

【面试题】技术场景 4、负责项目时遇到的棘手问题及解决方法
工作经验一年以上程序员必问问题 面试题概述 问题为在负责项目时遇到的棘手问题及解决方法,主要考察开发经验与技术水平,回答不佳会影响面试印象。提供四个回答方向,准备其中一个方向即可。 1、设计模式应用方向 以登录为例,未…...

RT-DETR代码详解(官方pytorch版)——参数配置(1)
前言 RT-DETR虽然是DETR系列,但是它的代码结构和之前的DETR系列代码不一样。 它是通过很多的yaml文件进行参数配置,和之前在train.py的parser argparse.ArgumentParser()去配置所有参数不同,所以刚开始不熟悉代码的时候可能不知道在哪儿修…...

腾讯云AI代码助手编程挑战赛-凯撒密码解码编码器
作品简介 在CTFer选手比赛做crypto的题目时,一些题目需要自己去解密,但是解密的工具大部分在线上,而在比赛过程中大部分又是无网环境,所以根据要求做了这个工具 技术架构 python语言的tk库来完成的GUI页面设计,通过…...

搭建docker私有化仓库Harbor
Docker私有仓库概述 Docker私有仓库介绍 Docker私有仓库是个人、组织或企业内部用于存储和管理Docker镜像的存储库。Docker默认会有一个公共的仓库Docker Hub,而与Docker Hub不同,私有仓库是受限访问的,只有授权用户才能够上传、下载和管理其中的镜像。这种私有仓库可以部…...

【Vim Masterclass 笔记09】S06L22:Vim 核心操作训练之 —— 文本的搜索、查找与替换操作(第一部分)
文章目录 S06L22 Search, Find, and Replace - Part One1 从光标位置起,正向定位到当前行的首个字符 b2 从光标位置起,反向查找某个字符3 重复上一次字符查找操作4 定位到目标字符的前一个字符5 单字符查找与 Vim 命令的组合6 跨行查找某字符串7 Vim 的增…...
GIC中断分组介绍(IMX6ull为例)
一、Cortex-A7内核中断 Cortex-A7内核具有多个中断类型,但其中最重要的是复位中断和IRQ(普通中断请求)中断。对于IMX6ULL而言,主要关注的是IRQ中断,因为外部设备和内部事件通常都会触发这类中断。 从左到右 中断控制…...

计算机网络期末复习(知识点)
概念题 在实际复习之前,可以看一下这个视频将网络知识串一下,以便更好地复习:【你管这破玩意叫网络?】 网络规模的分类 PAN(个人区域网络):用于个人设备间的连接,如手机与蓝牙耳机…...

Apache XMLBeans 一个强大的 XML 数据处理框架
Apache XMLBeans 是一个用于处理 XML 数据的 Java 框架,它提供了一种方式将 XML Schema (XSD) 映射到 Java 类,从而使得开发者可以通过强类型化的 Java 对象来访问和操作 XML 文档。下面将以一个简单的案例说明如何使用 Apache XMLBeans 来解析、生成和验…...

飞凌嵌入式i.MX8M Mini核心板已支持Linux6.1
飞凌嵌入式FETMX8MM-C核心板现已支持Linux6.1系统,此次升级不仅使系统功能更加丰富,还通过全新BSP实现了内存性能的显著提升。 基于NXP i.MX8M Mini处理器设计开发的飞凌嵌入式FETMX8MM-C核心板,拥有4个Cortex-A53高性能核和1个Cortex-M4实时…...
【数据链电台】洛克希德·马丁(Lockheed Martin)
洛克希德马丁公司(Lockheed Martin)是全球领先的航空航天、国防、先进技术和安全领域的供应商之一。 公司为美军及盟国军队提供了广泛的通信系统,包括数据链电台和相关的通信系统。 洛克希德马丁的许多产品用于战术通信、卫星通信、电子战、…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...