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

C语言:数组的介绍与使用

1. 数组的概念

数组是⼀组相同类型元素的集合;从这个概念中我们就可以发现2个有价值的信息:
数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
数组中存放的多个数据,类型是相同的。
数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。

2. ⼀维数组的创建和初始化,介绍与使用

2.1 数组创建
⼀维数组创建的基本语法如下:
data_type array_name[array_size];
  • data_type:指定数组中元素的数据类型,如 intfloatchar 等。
  • array_name:数组的名称,遵循标识符的命名规则。
  • array_size:数组的大小,即数组中元素的个数,必须是一个大于 0 的常量表达式。
  • 示例:
  • #include <stdio.h>
    
    int main() 
    {
        // 定义一个包含 5 个整数的一维数组
        int numbers[5];
        return 0;
    }
    2.2 一维数组的初始化
  • #include <stdio.h>
    
    int main()
     {
        // 完全初始化
        int arr1[5] = {1, 2, 3, 4, 5};
    
        // 部分初始化,未指定的元素自动初始化为 0
        int arr2[5] = {1, 2};
    
        // 省略数组大小,编译器会根据初始化列表的元素个数确定数组大小
        int arr3[] = {1, 2, 3, 4, 5};
    
        //错误的初始化 - 初始化项太多
        int arr4[3] = {1, 2, 3, 4};
    
        return 0;
    }
    2.3 一维数组元素的访问
  • #include <stdio.h>
    
    int main()
     {
        int arr[5] = {1, 2, 3, 4, 5};
    
        // 访问数组的第一个元素
        printf("数组的第一个元素是:%d\n", arr[0]);
    
        // 修改数组的第三个元素
        arr[2] = 10;
        printf("修改后的第三个元素是:%d\n", arr[2]);
    
        return 0;
    }
    2.4 数组的类型
    数组也是有类型的,数组算是⼀种⾃定义类型,去掉数组名留下的就是数组的类型。
    如下:
    int arr1[10];
    char ch1[5];
    
    int arr2[2][5];
    char ch2[2][5];
    
    arr1 数组的类型是 int [10]: 表示这是一个包含 10 个  int 类型元素的数组。 int 是 C 语言中用于表示整数的数据类型,在大多数系统中,一个  int 类型通常占用 4 个字节的内存空间。
    ch1 数组的类型是 char [5]:表示这是一个包含 5 个  char 类型元素的数组。 char 是 C 语言中用于表示字符的数据类型,通常占用 1 个字节的内存空间。
    arr2 数组的类型是 int [2][5]:表示的是二维数组类型。具体来说,这种类型的数组可以看作是一个具有 2 行 5 列的矩阵结构,数组中的每个元素都是  int 类型(整数类型)。在内存中,这些元素是连续存储的,先存储第一行的 5 个元素,接着存储第二行的 5 个元素。
    ch2 数组的类型是 char [2][5]:表示的是一个二维字符数组。可以将其想象成一个具有 2 行 5 列的表格,表格中的每个单元格存储一个  char 类型的数据,即一个字符。在 C 语言里, char 类型通常占用 1 个字节的内存空间,所以这个二维数组总共能存储  2 * 5 = 10 个字符。
    2.5 ⼀维数组的使⽤
    学习了⼀维数组的基本语法,⼀维数组可以存放数据,存放数据的⽬的是对数据的操作,那我们如何使⽤⼀维数组呢?
    2.6 数组下标
    C语⾔规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下标就相当于数组元素的编号,如下:
    int arr[10] = {5,6,7,8,9,10,11,12,13,14);
                                                     数组元素和下标
    在C语⾔中数组的访问提供了⼀个操作符 [] ,这个操作符叫:下标引⽤操作符。
    有了下标访问操作符,我们就可以轻松的访问到数组的元素了,⽐如我们访问下标为0的元素,我们就 可以使⽤ arr[0] ,想要访问下标是6的元素,就可以使⽤ arr[6] ,如下代码:
    #include <stdio.h>
    int main()
    {
    int arr[10] = {5,6,7,8,9,10,11,12,13,14);
     printf("%d\n", arr[0]);//5
     printf("%d\n", arr[6]);//11
    return 0;
    }
    2.7 数组元素的打印
    接下来,如果想要访问整个数组的内容,那怎么办呢?
    只要我们产⽣数组所有元素的下标就可以了,那我们使⽤for循环产⽣0~9的下标,接下来使⽤下标访 问就⾏了。
    如下代码:
    #include <stdio.h>
    int main()
    {
     int arr[10] = {5,6,7,8,9,10,11,12,13,14);
     int i = 0;
     for(i=0; i<10; i++)
     {
     printf("%d ", arr[i]);
     }
     return 0;
    }
    2.8 数组的输⼊
    明⽩了数组的访问,当然我们也根据需求,⾃⼰给数组输⼊想要的数据,如下:
    #include <stdio.h>
    int main()
    { 
       int arr[10] = {5,6,7,8,9,10,11,12,13,14);
       int i = 0;
       for(i=0; i<10; i++)
      {
         scanf("%d", &arr[i]);
      }
       for(i=0; i<10; i++)
      {
         printf("%d ", arr[i]);
      }
     return 0;
     }
    2.9 ⼀维数组在内存中的存储

    在 C 语言中,一维数组在内存中的存储是连续的,这意味着数组的各个元素在内存中依次相邻排列。以下从存储方式、内存地址计算、示例代码等方面详细介绍一维数组在内存中的存储情况。

    存储方式

    一维数组在内存中占据一段连续的内存空间,数组的元素按照其下标顺序依次存储。例如,对于一个包含 n 个元素的一维数组 arr,元素 arr[0] 存储在这段连续内存空间的起始位置,接着是 arr[1]arr[2] ,以此类推,直到 arr[n - 1]

    内存地址计算

    数组元素的内存地址可以通过数组首地址和元素的偏移量来计算。假设数组 arr 的首地址为 &arr[0](也可以用数组名 arr 表示),每个元素占用的内存字节数为 sizeof(arr[0]),计算总大小可以多少字节为sizeof(arr)。

    如:

    3. 二维数组的创建和初始化,介绍与使用

    前⾯学习的数组被称为⼀维数组,数组的元素都是内置类型的,如果我们把⼀维数组做为数组的元素,这时候就是⼆维数组,⼆维数组作为数组元素的数组被称为三维数组,⼆维数组以上的数组统称 多维数组
3.1 ⼆维数组的创建 
数据类型 数组名[行数][列数];
  • 数据类型:指定数组中每个元素的数据类型,例如 intfloatchar 等。
  • 数组名:是用户自定义的标识符,用于标识这个二维数组。
  • 行数:表示二维数组有多少行,必须是一个大于 0 的整数常量表达式。
  • 列数:表示二维数组每行有多少列,同样必须是一个大于 0 的整数常量表达式。
#include <stdio.h>

int main() 
{
    // 创建一个 3 行 4 列的二维整数数组
    int matrix[3][4];
    return 0;
}

在这个例子中,matrix 是一个包含 3 行 4 列的二维数组,总共可以存储 3 * 4 = 12 个 int 类型的元素

3.2 ⼆维数组的初始化
#include<stdio.h>
int main()
{    //完全初始化
	int arr[2][3] = { 1,2,3,4,5,6 };
	int arr[2][3] = { {1,2,3},{4,5,6} };

	//部分初始化
	int arr[2][3] = { 1,2,3,4};
	int arr[2][3] = { {1,2,3},{4}};

	//省略行数初始化,但是不能省略列
	int arr[][3] = { 1,2,3,4,5,6 };//省略行数它会根据总大小除于列数计算出行数:6/3=2行
	int arr[][3] = { {1,2,3},{4,5,6} };
	return 0;
}
3.3 ⼆维数组的下标
当我们掌握了⼆维数组的创建和初始化,那我们怎么使⽤⼆维数组呢?
其实⼆维数组访问也是使⽤下标的形式的,⼆维数组是有⾏和列的,只要锁定了⾏和列就能唯⼀锁定数组中的⼀个元素。
C语⾔规定,⼆维数组的⾏是从0开始的,列也是从0开始的,如下所⽰:
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
图中最右侧绿⾊的数字表⽰⾏号,第⼀⾏蓝⾊的数字表⽰列号,都是从0开始的,⽐如,我们说:第2⾏,第4列,快速就能定位出7。

 

#include <stdio.h>
int main()
{
 int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
 printf("%d\n", arr[2][4]);
return 0;
}
3.4 ⼆维数组的输⼊和输出
访问⼆维数组的单个元素我们知道了,那如何访问整个⼆维数组呢?
其实我们只要能够按照⼀定的规律产⽣所有的⾏和列的数字就⾏;以上⼀段代码中的arr数组为例,⾏的选择范围是0~2,列的取值范围是0~4,所以我们可以借助循环实现⽣成所有的下标。
#include <stdio.h>
int main()
{
 int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
 int i = 0;//遍历⾏
 //输⼊
 for(i=0; i<3; i++) //产⽣⾏号
 {
 int j = 0;
 for(j=0; j<5; j++) //产⽣列号
 {
 scanf("%d", &arr[i][j]); //输⼊数据
 }
 }
 //输出
 for(i=0; i<3; i++) //产⽣⾏号
 {
 int j = 0;
 for(j=0; j<5; j++) //产⽣列号
 {
 printf("%d ", arr[i][j]); //输出数据
 }
 printf("\n");
 }
 return 0;
}
3.5 ⼆维数组在内存中的存储

存储方式:按行连续存储

二维数组在内存中是按行连续存储的。也就是说,二维数组先将第一行的所有元素依次存储在内存中,接着存储第二行的元素,以此类推,直到存储完所有行的元素。这种存储方式使得二维数组在内存中实际上是一个线性的连续内存块。

地址计算

二维数组元素的内存地址可以通过数组首地址和元素的偏移量来计算。假设二维数组  arr[m][n] 的首地址为  &arr[0][0](也可以用数组名  arr 表示),每个元素占用的内存字节数为  sizeof(arr[0][0]),那么数组中第  i 行第  j 列的元素  arr[i][j] 的内存地址可以通过以下公式计算:
&arr[i][j] = &arr[0][0] + (i * n + j) * sizeof(arr[0][0])

其中,i * n 表示前面 i 行元素的总数,再加上 j 就是从数组首元素到 arr[i][j] 的偏移量。

注意事项
  • 内存连续性:二维数组元素的内存连续性使得可以通过指针运算来访问数组元素,但同时也要求在操作数组时要注意避免越界访问,否则可能会访问到相邻的其他变量或数据,导致未定义行为。
  • 列数的重要性:在进行地址计算和指针操作时,列数是一个关键因素,因为编译器需要根据列数来正确计算元素的偏移量。
  • 与多维数组的关系:二维数组的存储方式可以推广到更高维的数组,多维数组同样是按行优先的顺序在内存中连续存储。

4. C99中的变⻓数组

在C99标准之前,C语⾔在创建数组的时候,数组⼤⼩的指定只能使⽤常量、常量表达式,或者如果我们初始化数据的话,可以省略数组⼤⼩。
int arr1[10];
int arr2[3+5];
int arr3[] = {1,2,3};
这样的语法限制,让我们创建数组就不够灵活,有时候数组⼤了浪费空间,有时候数组⼜⼩了不够⽤的。
C99中给⼀个变⻓数组(variable-length array,简称 VLA)的新特性,允许我们可以使⽤变量指定
数组⼤⼩。
请看下⾯的代码:
int n = a+b;
int arr[n];
上⾯⽰例中,数组 arr 就是变⻓数组,因为它的⻓度取决于变量 n 的值,编译器没法事先确定,只
有运⾏时才能知道 n 是多少。
变⻓数组的根本特征,就是数组⻓度只有运⾏时才能确定,所以 变⻓数组不能初始化 。它的好处是程序员不必在开发时,随意为数组指定⼀个估计的⻓度,程序可以在运⾏时为数组分配精确的⻓度。有 ⼀个⽐较迷惑的点,变⻓数组的意思是数组的⼤⼩是可以使⽤变量来指定的,在程序运⾏的时候,根 据变量的⼤⼩来指定数组的元素个数,⽽不是说数组的⼤⼩是可变的数组的⼤⼩⼀旦确定就不能再 变化了(在程序运行时确定,就不能修改,直到程序结束)
遗憾的是在VS2022上,虽然⽀持⼤部分C99的语法,没有⽀持C99中的变⻓数组,没法测试;下⾯是 我在gcc编译器上测试,可以看⼀下
如:
#include <stdio.h>
int main()
{
 int n = 0;
 scanf("%d", &n);//通过键盘输⼊数值确定数组的⼤⼩
 int arr[n];
 int i = 0;
 for (i = 0; i < n; i++)
 {
 scanf("%d", &arr[i]);
 }
 for (i = 0; i < n; i++)
 {
 printf("%d ", arr[i]);
 }
 return 0;
}

以上就是数组的全部介绍了。


http://www.kler.cn/a/528380.html

相关文章:

  • 前端知识速记—JS篇:null 与 undefined
  • 华硕笔记本装win10哪个版本好用分析_华硕笔记本装win10专业版图文教程
  • 使用 Ollama 和 Kibana 在本地为 RAG 测试 DeepSeek R1
  • ROS应用之SwarmSim在ROS 中的协同路径规划
  • FreeRTOS从入门到精通 第十五章(事件标志组)
  • Elasticsearch:如何搜索含有复合词的语言
  • Excel 技巧23 - 在Excel中用切片器做出查询效果(★★★)
  • 4 [危机13小时追踪一场GitHub投毒事件]
  • javaEE-6.网络原理-http
  • Arduino可以做哪些有意思的项目
  • Java泛型深度解析(JDK23)
  • 牛客网第k小(详解)c++
  • 分布式微服务系统架构第90集:现代化金融核心系统
  • 深度学习之“缺失数据处理”
  • 青少年编程与数学 02-008 Pyhon语言编程基础 11课题、字典与循环语句
  • nginx目录结构和配置文件
  • 交错定理和切比雪夫节点的联系与区别
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.27 线性代数王国:矩阵分解实战指南
  • XML DOM 解析器
  • MCU内部ADC模块误差如何校准
  • AI-System 学习
  • list的使用,及部分功能的模拟实现(C++)
  • 青少年编程与数学 02-008 Pyhon语言编程基础 13课题、数据类型相关函数
  • tf.Keras (tf-1.15)使用记录2-基于tf.keras.layers创建层
  • 【JavaEE】Spring(7):统一功能处理
  • mac连接linux服务器