c语言回顾-数组(全网最详细,哈哈哈)

目录

前言,和小编一起感受数组的魅力!!!

1.数组的概念

2.一维数组的创建和初始化

2.1数组创建

2.2数组的初始化

2.3数组的类型

3.一维数组的使用

3.1数组下标

3.2数组元素的输入输出

小结:

4.一维数组在内存中的存储

5.sizeof的使用,计算数组个数

6.步入二维数组

6.1.二维数组的概念

6.2二维数组的声明和初始化

6.3二维数组元素的输入输出

6.4二维数组在内存中的存储

7.C99中的变长数组(补充)

声明变长数组

特点和注意事项

结束语


前言,和小编一起感受数组的魅力!!!

1.数组的概念

数组是一种用于存储相同类型数据元素的数据结构。它是C语言中的一种重要数据类型。数组可以包含多个元素,并通过索引(下标)来访问和操作这些元素。

从概念中发现:

数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
数组中存放的多个数据,类型是相同的。

补充了解:

在C语言中,标准并没有明确禁止定义大小为0的数组,但实际行为取决于具体的编译器和实现。在某些编译器中,定义大小为0的数组可能会导致编译错误或未定义行为。在标准C(C99及之后的标准)中,声明大小为0的数组并不是合法的。

然而,在某些情况下,特别是结构体中的灵活数组成员(flexible array member),可以使用一种类似于0大小数组的结构。

数组分为一维数组和多维数组,常见的多维数组是二维数组。

2.一维数组的创建和初始化

2.1数组创建

在C语言中,数组的声明由元素类型和数组名组成,可以指定数组的大小(元素个数)。以下是数组声明的一般形式:

type arrayName[size];

其中:

  • type 表示数组中元素的数据类型,可以是基本数据类型(如整数、浮点数、字符等)或自定义类型(如结构体)。
  • arrayName 是数组的名称,用于在程序中引用数组。
  • size 表示数组的大小,即数组中元素的个数。
比如:我们现在想存储某个班级的20人的数学成绩,那我们就可以创建一个数组,如下:
 
int math[20];
当然我们也可以根据需要创建其他类型和大小的数组:
char ch[8];
double score[10];

2.2数组的初始化

有时候,数组在创建的时候,我们需要给定一些初始值值,这种就称为初始化的。
那数组如何初始化呢?数组的初始化⼀般使用大括号,将数据放在大括号中。
//完全初始化
int arr[5] = {1,2,3,4,5};
//不完全初始化
int arr2[6] = {1};//第⼀个元素初始化为1,剩余的元素默认初始化为0
//错误的初始化 - 初始化项太多,超过了数组大小
int arr3[3] = {1, 2, 3, 4};

2.3数组的类型

数组也是有类型的,数组算是一种自定义类型,去掉数组名留下的就是数组的类型。
例如:
int arr1[10];
int arr2[12];
char ch[5];
arr1数组的类型是 int [10]
arr2数组的类型是 int[12]
ch 数组的类型是 char [5]

3.一维数组的使用

3.1数组下标

C语言规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后一个元素的下标是n-1,下标就相当于数组元素的编号,如下:
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
a7f21dbdbf6149d58a23db5f96d95ee1.png
在C语言中数组的访问提供了⼀个操作符 [ ] ,这个操作符叫:下标引用操作符。
有了下标访问操作符,我们就可以轻松的访问到数组的元素了,比如我们访问下标为7的元素,我们就 可以使用arr[7] ,想要访问下标是3的元素,就可以使用 arr[3] ,如下代码:
#include <stdio.h>
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
 printf("%d\n", arr[7]);//8
 printf("%d\n", arr[3]);//4
 return 0;
}

3.2数组元素的输入输出

输入和输出数组的元素,可以使用循环结构来遍历数组。

让数组下标显示出来再进行索引。

#include <stdio.h>

int main() {
    int numbers[5];

    // 输入数组元素
    printf("Enter 5 numbers:\n");
    for (int i = 0; i < 5; i++) {
        scanf("%d", &numbers[i]);
    }

    // 输出数组元素
    printf("The numbers are:\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }

    return 0;
}

首先声明了一个包含5个整数的数组 numbers。然后,使用循环结构来输入数组元素。在每次循环中,通过 scanf 函数将输入的值存储到数组的相应位置。接下来,使用循环结构输出数组的元素。在每次循环中,使用 printf 函数打印输出数组元素。请注意,在输入和输出数组元素时,循环的控制变量 i 表示数组的索引,从0递增到4,对应数组的五个元素。

小结:

一维数组的使用包括数组的声明和初始化、通过索引访问和操作数组元素,以及使用循环结构输入和输出数组元素。这些基本操作可以让您更灵活地处理一组相关的数据。

4.一维数组在内存中的存储

我们通过打印数组中元素的地址来观察

#include <stdio.h>
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
 int i = 0;
 for(i=0; i<10; i++)
 {
 printf("&arr[%d] = %p\n ", i, &arr[i]);
 }
 return 0;
}

b36c2c49ef414cafab5133a5f3a93248.png

从输出的结果我们分析,数组随着下标的增长,地址是由小到大变化的,并且我们发现每两个相邻的元素之间相差4(因为⼀个整型是4个字节)。所以我们得出结论:数组在内存中是连续存放的。

5.sizeof的使用,计算数组个数

sizeof 中C语言是一个关键字,是可以计算类型或者变量大小的,其实 sizeof 也可以计算数组的大小。

#include <stido.h>
int main()
{
 int arr[10] = {0};
 printf("%d\n", sizeof(arr));
 return 0;
}
这里输出的结果是40,计算的是数组所占内存空间的总大小,单位是字节。
我们又知道数组中所有元素的类型都是相同的,那只要计算出一个元素所占字节的个数,数组的元素个数就能算出来。这里我们选择第一个元素算大小就可以。
#include <stido.h>
int main()
{
 int arr[10] = {0};
 int sz = sizeof(arr)/sizeof(arr[0]);
 printf("%d\n", sz);
 return 0;
}

结果:10

小编提醒:

以后在代码中需要数组元素个数的地方就不用固定写死了,使用上面的计算,不管数组怎么变化,计算出的大小也就随着变化了。

6.步入二维数组

6.1.二维数组的概念

二维数组是C语言中的一种特殊数据类型,用于存储具有两个维度的数据。它可以看作是一个由行和列组成的表格或矩阵,其中每个元素都可以通过行索引和列索引来访问和操作。

6.2二维数组的声明和初始化

dataType arrayName[rowSize][columnSize];

  • dataType 表示数组中元素的数据类型,可以是整数、浮点数、字符或其他自定义类型。
  • arrayName 是数组的名称,用于在程序中引用数组。
  • rowSize 表示数组的行数,即矩阵的行数。
  • columnSize 表示数组的列数,即矩阵的列数。
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

这声明了一个名为 arr 的二维整数数组,它有3行和5列,总共可以存储3x5=15个整数,并进行了初始化。

二维数组的元素可以通过行索引和列索引来访问。行索引和列索引都从0开始计数,依次递增。例如,要访问二维数组 arr 的第2行第3列的元素,可以使用以下方式:

arr[1][2] = 10; // 将第2行第3列的元素赋值为10

int x = arr[0][3]; // 将第1行第4列的元素的值赋给变量x

printf("%d",arr[2][4]);//打印第2行第4列的元素的值

3e3905fbe1284f29a78cb1f6d559b7f3.png

6.3二维数组元素的输入输出

我们只要能够按照一定的规律产生所有的行和列的数字就行;以上一段代码中的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;
}

7704ccf74fdf4e41b7983c42e5a6f4f9.png

6.4二维数组在内存中的存储

像一维数组一样,我们如果想研究二维数组在内存中的存储方式,可以打印出数组所有元素的地址的。
#include <stdio.h>
int main()
{
 int arr[3][5] = { 0 };
 int i = 0;
 int j = 0;
 for (i = 0; i < 3; i++)
 {
 for (j = 0; j < 5; j++)
 {
 printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
 }
 }
 return 0;
}

输出结果:

8ef81e6c51534de78b6170c22a4b80c4.png

从输出的结果来看,每一行内部的每个元素都是相邻的,地址之间相差4个字节,跨行位置处的两个元素(如:arr[0][4]和arr[1][0])之间也是差4个字节, 所以二维数组中的每个元素都是连续存放的。
如图所示:
27342c23b9a6403fa1527e02b207b144.png

7.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];

在C语言中,变长数组(Variable Length Arrays,简称VLA)是一种特殊的数组类型,它允许数组的大小在运行时动态确定。这一特性在C99标准中引入,使得程序可以更灵活地处理数组大小不确定的情况。

声明变长数组

变长数组的声明与普通数组相似,但它的大小不是一个常量表达式,而是一个变量或表达式的结果。以下是一个变长数组的声明示例:

#include <stdio.h>

int main() {
    int n;
    printf("Enter the size of the array: ");
    scanf("%d", &n);  // 读取数组大小

    int arr[n];  // 声明变长数组

    // 输入数组元素
    printf("Enter %d elements:\n", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }

    // 输出数组元素
    printf("The elements are:\n");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }

    return 0;
}

在这个示例中,数组 arr 的大小由变量 n 的值决定。用户输入数组大小 n 后,程序动态创建一个大小为 n 的数组,并读取和输出 n 个元素。

特点和注意事项

  1. 作用域和生命周期:

    变长数组的作用域和生命周期与其所在的块作用域相同。它在声明的块作用域内有效,块作用域结束时变长数组也随之销毁。
  2. 运行时确定大小:

    变长数组的大小在运行时确定,使得程序可以处理大小不确定的数据结构。
  3. 不支持全局或静态变长数组:

    变长数组不能声明为全局变量或静态变量,只能在函数内使用。
  4. 内存分配:

    变长数组的内存分配在栈上,因此不能使用太大的数组以防止栈溢出。

结束语

本节内容到此结束,内容有点多,感谢友友们到看到最后。

支持小编的点个赞,留个评论吧!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python中的__init__方法:为何它如此重要

目录 一、__init__方法的基本概念 1.1 定义与作用 1.2 调用时机 1.3 参数传递 二、__init__方法的工作原理 2.1 初始化属性 2.2 执行其他操作 2.3 继承与多态 三、__init__方法的使用技巧 3.1 参数传递与默认值 3.2 链式初始化 3.3 继承与超类初始化 3.4 初始化方…

常见锁策略之可重入锁VS不可重入锁

可重入锁VS不可重入锁 有一个线程,针对同一把锁,连续加锁两次,如果产生了死锁,那就是不可重入锁,如果没有产生死锁,那就是可重入锁. 死锁 我们之前引入多线程的时候不是讲了一个加数字的案例么,我们今天以它来举例 当我们这样写的时候会出现什么问题? 分析:第一个synchron…

Zookeeper:Zookeeper集群角色

文章目录 一、Leader选举二、Zookeeper集群角色 一、Leader选举 Serverid&#xff1a;服务器ID&#xff1b;比如有三台服务器&#xff0c;编号越大在选择算法中的权重越大。Zxid&#xff1a;数据ID&#xff1b;服务器中存放的最大数据ID&#xff0c;值越大说明数据越新&#x…

【创作纪念日】我的CSDN1024创作纪念

机缘 注册CSDN是很长时间了&#xff0c;但是上学时因为专业是电气工程&#xff0c;与编程打交道比较少&#xff0c;一直都是寻求帮助&#xff0c;而非内容输出。直到考研后专业改变&#xff0c;成为了主要跟软件编程、计算机知识相关的研究后&#xff0c;才逐步开启自己的CSDN…

模拟布局:为什么井、抽头和保护环至关重要

其中的关键示例是井、抽头和保护环。这些结构对于任何 MOSFET 电路的工作都至关重要。 这就是为什么了解衬底在 MOSFET 电路中的作用对于创建有效的模拟设计至关重要。要做到这一点&#xff0c;首先必须了解 MOSFET 晶体管的工作原理。 让我们来看看一种类型的 MOSFET&#x…

归并排序-MergeSort (C语言详解)

目录 前言归并排序的思想归并排序的递归法归并排序的非递归法归并排序的时间复杂度与适用场景总结 前言 好久不见, 前面我们了解到了快速排序, 那么本篇旨在介绍另外一种排序, 它和快速排序的思想雷同, 但又有区别, 这就是归并排序, 如下图, 我们对比快速排序与归并排序. 本…

编译器的控制流图分析

1&#xff0c;建立感性认识 1.1 源码 hello.c int x 10; int y 11; int main(){int z 12;for (int i 0;i < 10;i){z * x * y;}if(z>7.0)z1.0f;elsez 2.0f;return 0; }1.2 编译 2005 sudo apt-get install -y graphviz-doc libgraphviz-dev graphviz2034 ../ex_…

Java学习高级一

修饰符 static 类变量的应用场景 成员方法的分类 成员变量的执行原理 成员方法的执行原理 Java之 main 方法 类方法的常见应用场景 代码块 设计模式 单例设计模式 饿汉式单例设计模式 懒汉式单例设计模式 继承 权限修饰符

LeetCode题练习与总结:二叉树的后序遍历--145

一、题目描述 给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[3,2,1]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a…

以太坊DApp交易量激增83%的背后原因解析

引言 最近&#xff0c;以太坊网络上的去中心化应用程序&#xff08;DApp&#xff09;交易量激增83%&#xff0c;引发了广泛关注和讨论。尽管交易费用高达2.4美元&#xff0c;但以太坊仍在DApp交易量方面遥遥领先于其他区块链网络。本文将深入探讨导致这一现象的主要原因&#…

颅内感染性疾病患者就诊指南

颅内感染性疾病&#xff0c;即病原体侵入中枢神经系统&#xff0c;导致脑部或脑膜发生炎症的疾病。这些病原体可能是细菌、病毒、真菌或寄生虫等。颅内感染不仅会对脑组织造成损害&#xff0c;还可能引发一系列严重的并发症&#xff0c;如癫痫发作、意识障碍等 颅内感染性疾病的…

国产软件号称Windows系统的天花板,却被误认为是外国佬研发

说起国产软件&#xff0c;大家总是容易给它们贴上“流氓、捆绑、满满的都是套路”这样的标签。 其实挺冤枉的&#xff0c;有些软件真的挺好用&#xff0c;也挺良心的&#xff0c;但就是因为这些刻板印象&#xff0c;老是被误以为是外国工程师搞出来的。 VeryCapture 之前小编…

JavaScript之深入对象,详细讲讲构造函数与常见内置构造函数

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;我是前端菜鸟的自我修养&#xff01;今天给大家详细讲讲构造函数与常见内置构造函数&#xff0c;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;原创不易&#xff0c;如果能帮助到带大家&#xff0c;欢迎…

达梦数据库的系统视图v$deadlock_history

达梦数据库的系统视图v$deadlock_history 在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;V$DEADLOCK_HISTORY 视图记录了数据库中发生的死锁信息。通过查询这个视图&#xff0c;数据库管理员可以监控和诊断数据库中的死锁问题&#xff0c;从而采取相应的措施…

鸿蒙认证值得考吗?

鸿蒙认证值得考吗&#xff1f; 鸿蒙认证&#xff08;HarmonyOS Certification&#xff09;是华为为了培养和认证开发者在鸿蒙操作系统&#xff08;HarmonyOS&#xff09;领域的专业技能而设立的一系列认证项目。这些认证旨在帮助开发者和企业工程师提升在鸿蒙生态中的专业技能…

小故事——半个世纪的爱情

半个世纪的爱情 故事的开端永远是在那个情窦初开的年纪&#xff0c;那富有蓬勃朝气的少年时代&#xff0c;眼神中青涩未尽&#xff0c;正是这个时间&#xff0c;才真正的让人难以忘怀。她不过是那班级里面普普通通的小孩&#xff0c;故事的男主角同样也是简简单单的存在&#…

激光SLAM如何动态管理关键帧和地图

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…

Activity、Window、DecorView的关系

目录 一、Activity、Window、DecorView的层级关系如下图所示&#xff1a; 1、Activity 2、Window 3、DecorView 二、DecorView初始化相关源码 三、DecorView显示时机 前言&#xff1a; 不同的Android版本有差异&#xff0c;以下基于Android 11进行讲解。 一、Activi…

音乐发行平台无加密开源源码

适用于唱片公司&#xff0c;用于接收物料&#xff0c;下载物料功能&#xff1a;个人或机构认证&#xff0c;上传专辑和歌曲&#xff0c;版税结算环境要求php7.4Nginx 1、导入数据库 2、/inc/conn.php里填写数据库密码等后台路径/admin&#xff08;可自行修改任意入口名称&…

Meta 3D Gen:文生 3D 模型

是由 Meta 公布的一个利用 Meta AssetGen&#xff08;模型生成&#xff09;和 TextureGen&#xff08;贴图材质生成&#xff09;的组合 AI 系统&#xff0c;可以在分分钟内生成高质量 3D 模型和高分辨率贴图纹理。 视频演示的效果非常好&#xff0c;目前只有论文&#xff0c;期…