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

C语言:数组

文章目录

  • 前言
    • 本文旨在系统性地介绍C语言中的数组。
  • 一、数组的概念和数组类型
  • 二、一维数组
    • 2.1、一维数组的创建
    • 2.2、一维数组的初始化
      • 2.2.1、字符数组的初始化和字符串
      • 2.2.2、sizeof 和 strlen的对比
    • 2.3、一维数组的使用
      • 2.3.1、一维数组的下标
      • 2.3.2、一维数组元素的遍历
    • 2.4、一维数组在内存中的存储
  • 三、sizeof计算数组元素个数
  • 四、二维数组的创建
    • 4.1、二维数组的概念
    • 4.2、二维数组的创建
    • 4.3、二维数组的初始化
    • 4.4、二维数组的使用
      • 4.4.1、二维数组的下标
      • 4.4.2、二维数组的遍历
    • 4.5、二维数组在内存中的存储
  • 五、变长数组

前言

本文旨在系统性地介绍C语言中的数组。

一、数组的概念和数组类型

数组是相同类型元素的集合,元素个数≥1,内存连续存储。分为一维数组和多维数组(常见二维数组)。

数组类型是C语言中的一种派生类型,由元素类型和数组长度共同决定。去掉数组名后,剩下的就是数组的类型。
注:数组类型不能直接赋值,不能用赋值运算符 = 将一个数组整体赋值给另一个数组。
代码示例:

intarr1[10];//arr1 数组的类型是 int [10]intarr2[2][3];//arr2 数组的类型是 int [2][3]charch[5];//ch 数组的类型是 char [5]

二、一维数组

2.1、一维数组的创建

type:元素类型,数组中每个元素的类型(如 int、char、float)。
arr_name:数组名,标识符,见名知意。
[常量值]:数组大小,表示数组能存放多少个元素。

类型可以是内置类型也可以是自定义类型(如struct、union、enum、typedef 定义的类型别名)。
代码示例:

type arr_name[常量值];

2.2、一维数组的初始化

方式示例说明
完全初始化int arr[5] = {1, 2, 3, 4, 5};所有元素都赋值
不完全初始化int arr[5] = {1, 2};只给前几个赋值,其余自动补 0
全部初始化为0int arr[5] = {0};所有元素都为 0
省略数组大小int arr[] = {1, 2, 3};编译器自动推断大小为 3

2.2.1、字符数组的初始化和字符串

字符数组部分初始化时,未初始化的元素自动赋值为 ‘\0’。
C语言中的字符串是用双引号括起来的⼀串字符,会自动在末尾添加 \0。这个 ‘\0’ 字符是字符串的结束标志,遇到 ‘\0’ 的时候,就认为字符串结束了。
代码示例:

#include<stdio.h>intmain(){chararr[5]={'a','b'};//arr[2]、arr[3]、arr[4] 都是 \0chararr1[]={'a','b','c'};//大括号初始化chararr2[]="abc";//字符串初始化//查看大小printf("sizeof(arr1) = %zu\n",sizeof(arr1));//3(只有 a,b,c)printf("sizeof(arr2) = %zu\n",sizeof(arr2));//4(a,b,c,\0)//使用 %s 打印printf("arr1 = %s\n",arr1);//arr1 没有 \0,会继续往后找,可能打印乱码printf("arr2 = %s\n",arr2);//正常打印 "abc"//查看 \0 是否存在printf("%zu\n",strlen(arr1));//会越界访问,结果无法预测。printf("%zu\n",strlen(arr2));//3(字符串中 \0 之前的字符的个数)return0;}

2.2.2、sizeof 和 strlen的对比

sizeofstrlen
本质操作符(不是函数)库函数(需要 <string.h>)
计算内容变量/类型占用的内存字节数字符串中 \0 之前的字节数
关注点内存大小必须找到 \0,没有 \0 会越界

2.3、一维数组的使用

2.3.1、一维数组的下标

一维数组的下标从0开始的,假设数组有n个元素,最后一个元素的下标就是n-1。
[] 下标引用操作符,①读取:arr[下标] 获取该位置的值;②修改:arr[下标] = 新值 修改该位置的值。
注:不要越界访问。
代码示例:

#include<stdio.h>intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};printf("%d\n",arr[7]);//8arr[7]=0;//也可以修改这个元素的值printf("%d\n",arr[7]);//0return0;}

2.3.2、一维数组元素的遍历

给数组输入内容、打印数组内容
使用 for 循环生成 0 到 n-1 的下标,配合 [] 操作符即可依次访问并打印数组的每个元素。
代码示例:

#include<stdio.h>intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};inti=0;for(i=0;i<10;i++)//给数组输入内容{scanf("%d",&arr[i]);}for(i=0;i<10;i++)//打印数组内容{printf("%d ",arr[i]);}return0;}

2.4、一维数组在内存中的存储

数组在内存中是连续存放的,相邻元素地址之差 = 该数组元素类型所占的字节数(int → 4,char → 1,double → 8)。

三、sizeof计算数组元素个数

sizeof(arr):整个数组占用的总字节数。
sizeof(arr[0]):数组中第一个元素占用的字节数。
两者相除 = 数组的元素个数。
代码示例:

intsz=sizeof(arr)/sizeof(arr[0]);

四、二维数组的创建

4.1、二维数组的概念

二维数组:一维数组做为数组元素的数组(每一行是一个一维数组),二维数组的元素类型是一维数组(如 int [列数])。

注:三维数组:二维数组作为数组元素的数组。二维数组以上的数组统称为多维数组。

4.2、二维数组的创建

type:元素类型,数组中每个元素的类型(如 int、char、float)。
arr_name:数组名,标识符,见名知意。
[常量值1]:行数,第一维大小,表示有多少个一维数组。
[常量值2]:列数,第二维大小,表示每个一维数组有多少个元素。

代码示例:

type arr_name[常量值1][常量值2]

4.3、二维数组的初始化

方式示例说明
不完全初始化int arr[3][5] = {1, 2};只给前两个元素赋值,其余自动补 0
完全初始化int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};所有元素都赋值,按行连续存放
按行初始化int arr[3][5] = {{1,2},{3,4},{5,6}};用 {} 明确分行,每行未赋值的补 0
省略行int arr[][5] = {1,2,3,4,5,6,7};编译器根据初始化数据自动推断行数

4.4、二维数组的使用

4.4.1、二维数组的下标

二维数组的行和列下标都从 0 开始。用 arr[行下标][列下标] 访问元素,行下标范围 0 ~ 行数-1,列下标范围 0 ~ 列数-1。
字符型二维数组可以直接用 %s 输出整行(字符串),其他类型必须用循环遍历整行。访问单个元素时,所有类型都用 arr[行下标][列下标]。
代码示例:

#include<stdio.h>intmain(){charstudents[3][10]={"张三","李四","王五"};printf("第0行:%s\n",students[0]);//张三printf("第1行:%s\n",students[1]);//李四printf("第2行:%s\n",students[2]);//王五return0;}

4.4.2、二维数组的遍历

遍历二维数组用双重循环:外层循环控制行(i),内层循环控制列(j),通过 arr[i][j] 访问每个元素。行和列的下标都从 0 开始,到 长度-1 结束。
代码示例:

#include<stdio.h>intmain(){intarr[3][5]={0};inti,j;//输入数据printf("请输入 3×5 个整数:\n");for(i=0;i<3;i++){for(j=0;j<5;j++){scanf("%d",&arr[i][j]);}}//输出数据printf("\n二维数组内容:\n");for(i=0;i<3;i++){for(j=0;j<5;j++){printf("%d ",arr[i][j]);}printf("\n");// 每行结束换行}return0;}

4.5、二维数组在内存中的存储

二维数组在内存中是连续存放的(按行优先),同一行相邻元素地址相差 sizeof(type),跨行相邻元素同样相差 sizeof(type)。整个数组是一块连续的内存空间。

五、变长数组

变长数组(Variable-Length Array,VLA) 是 C99 标准引入的特性,允许使用变量来指定数组的大小,数组的大小在运行时才确定。
代码示例:

#include<stdio.h>intmain(){intn=0;scanf("%d",&n);//根据输⼊数值确定数组的⼤⼩intarr[n];inti=0;for(i=0;i<n;i++){scanf("%d",&arr[i]);}for(i=0;i<n;i++){printf("%d ",arr[i]);}return0;}
http://www.jsqmd.com/news/1332781/

相关文章:

  • DLSS Swapper:3分钟掌握游戏性能调校的艺术
  • 从文件管理器到云存储工作流中枢:重新定义OSS Browser的技术架构与生态价值
  • 告别滚动拼接:3分钟学会用Chrome插件一键保存完整网页
  • AI时代程序员不用慌!七条靠谱发展出路,普通人直接抄
  • Airflow Dockerfile优化与生产部署实践
  • 密云区海绵城市厂家推荐PP模块厂家哪家好?2026避坑攻略:4个坑+5条硬标准,帮你绕开90%的雷区 - geo88
  • 【RustyML入门】2.2. 逻辑回归
  • 说一些变化,关于豆包,公众号,搜一搜,小红书点点,GEO优化,媒体信源名单等
  • 如何用3分钟找出占用你Windows快捷键的“元凶“:Hotkey Detective深度解析
  • 终极窗口大小调整工具:轻松掌控Windows窗口尺寸的免费解决方案
  • 哈希表与动态规划:算法面试高频考点解析
  • Unity版本升级命名空间报错排查指南:从API废弃到程序集依赖的全面修复
  • 构建第三方服务替代方案:从核心能力评估到生产部署全流程指南
  • 如何彻底掌控你的微信聊天记录?WeChatMsg数据管理终极方案
  • ZEV OBD(零排放车辆车载诊断)详解及举例
  • WCPulse 第 066 个开关:图库自动勾选原图的位置、验证方法与风险边界
  • Vue3应用打包:Ionic Framework移动端开发指南
  • 粉丝空间站搭建指南:从概念到落地的全流程解析
  • Android Coil 3为什么没有沿用Glide那种BitmapPool体系?是偷懒、退化,还是一次正确的架构取舍?
  • 完全掌控Windows桌面:Window Resizer让你的每个窗口都服服帖帖
  • 5分钟快速上手:免费在普通电脑上运行macOS虚拟机的终极指南
  • UDP协议深度解析:从极简设计到实时应用实战
  • 思源宋体TTF:7种字重免费商用中文字体终极指南
  • Meshroom:从照片到3D模型的智能转换,开源节点式可视化编程完全指南
  • 如何高效获取城通网盘直连地址:免费开源完整技术方案
  • 企业级AI部署实战:从零搭建本地Codex服务与运营集成指南
  • 别只把 CTF 当比赛!网络安全的黄金赛道,打通你的职业发展捷径
  • LinkSwift:九大网盘直链提取神器,解锁高效下载新体验
  • PraisonAI安全策略失效解析:如何强制沙箱执行Agent权限控制
  • 5分钟掌握NCM解密:解决网易云音乐格式限制的终极方案