【C语言初阶】C语言数组基础:从定义到遍历的全面指南

news2024/12/24 8:30:10

📝个人主页🌹:Eternity._
⏩收录专栏⏪:C语言 “ 登神长阶 ”
🤡往期回顾🤡:C语言函数
🌹🌹期待您的关注 🌹🌹

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

❀数组

  • 📒1. 什么是数组?
    • 🌸数组的特点
    • 🌺数组的应用
  • 📜2. 一维数组
    • 🌈数组的创建
    • 🌞数组的初始化
    • 🌙数组的使用
    • ⭐数组在内存中的存储
  • 📚3. 二维数组
    • 🌈数组的创建
    • 🌞数组的初始化
    • 🌙数组的使用
    • ⭐数组在内存中的存储
  • 📙4. 数组越界
  • 📝5. 数组作为函数参数
    • ⛰️数组作为函数参数错误设计
    • 🏞️数组名
    • 🌄正确设计
  • 📖6. 总结


🔍前言: 在编程的世界里,数据结构是构建复杂应用程序的基石,而数组则是这些基石中最基础且最不可或缺的一种。C语言,作为一门历史悠久且广泛应用于系统编程、嵌入式开发等领域的编程语言,其数组的概念与操作更是每一位C语言学习者必须掌握的核心技能

数组,简而言之,是一种连续存储相同类型数据的集合。它允许我们通过索引(或下标)快速访问其中的元素,无论是读取还是修改,都极为高效。C语言中的数组不仅支持一维形式,还可以轻松扩展到多维,为处理复杂数据提供了极大的便利

本文旨在全面而深入地介绍C语言数组的基本概念、声明与初始化、访问与遍历、以及多维数组的应用等关键内容。通过理论讲解与实例演示相结合的方式,我们将逐步揭开C语言数组的神秘面纱,帮助读者建立扎实的数组知识基础,并掌握在实际编程中灵活应用数组的技巧

让我们一同踏上这段充满挑战与收获的C语言数组之旅吧!


📒1. 什么是数组?

数组(Array)是一种基础的数据结构,用于在计算机内存中连续存储相同类型的数据。它允许通过索引(或下标)来访问这些数据元素,索引通常是从0开始的。数组中的每个元素可以通过计算偏移量来快速定位,这使得数组在访问元素时非常高效


🌸数组的特点

  • 类型一致性: 数组中的所有元素都必须是相同的数据类型。这意味着,如果你有一个整型数组,那么数组中的所有元素都必须是整数
  • 固定大小: 在大多数编程语言中,数组的大小在声明时就必须确定,并且之后不能改变(尽管有些语言支持动态数组或类似的数据结构,如C++的std::vector或Python的列表,它们提供了动态大小的数组功能)。然而,在C99标准中,C语言引入了变长数组(VLA),其大小可以在运行时确定,但这仍然受到栈大小等限制
  • 索引访问: 数组中的元素可以通过索引来访问,索引通常是从0开始的。例如,在C语言中,如果你有一个名为arr的数组,并且你想要访问它的第一个元素,你可以使用arr[0]
  • 内存连续性: 数组中的元素在内存中是连续存储的。这意味着,如果你知道数组中某个元素的地址,你可以很容易地计算出数组中其他元素的地址

🌺数组的应用

  • 存储和处理一系列的数据,如学生的成绩、商品的库存量等
  • 作为函数参数传递数据集合
  • 实现算法,如排序、搜索等
  • 字符串处理,因为字符串在C语言中是通过字符数组来实现的
  • 表示多维数据结构,如矩阵和表格

尽管数组是编程中非常基础且强大的工具,但它们也有一些局限性,比如大小固定(对于传统数组而言)和类型单一。因此,在需要更灵活的数据结构时,程序员可能会选择使用其他数据结构,如链表、树或图等。然而,对于许多常见的编程任务来说,数组仍然是首选的数据结构之一


📜2. 一维数组

数组是一组相同类型元素的集合


🌈数组的创建

数组的创建方式:

type_t arr_name [const_n];
// type_t 是指数组的元素类型
// const_n 是一个常量表达式,用来指定数组的大小

数组创建代码示例 (C语言):

//代码1
int arr1[10];

//代码2
int count = 10;
int arr2[count];

//代码3
char arr3[10];
float arr4[1];
double arr5[20];

注意:我们来看一下代码二,数组创建,在C99标准之前, [ ] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念,数组的大小可以使用变量指定,但是数组不能初始化


🌞数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)


数组的初始化:

int arr1[10] = { 1,2,3 };
int arr2[] = { 1,2,3,4 };
int arr3[5] = { 12345 }char arr4[3] = { 'a',98, 'c' };
char arr5[] = { 'a','b','c' };
char arr6[] = "abcdef";

数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定

注意:要区分以下这两种数组初始化

char arr1[] = "abc";
char arr2[3] = { 'a','b','c' };

🌙数组的使用

对于数组的使用我们之前介绍了一个操作符: [] ,下标引用操作符。它其实就数组访问的操作符


数组的使用:

int main()
{
	int arr[10] = { 0 };//数组的不完全初始化
	//计算数组的元素个数
	int sz = sizeof(arr) / sizeof(arr[0]);
	//对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
	int i = 0;//做下标
	// for循环遍历数组
	for (i = 0; i < sz; i++)
	{
		arr[i] = i;
	}
	//输出数组的内容
	i = 0;
	// while循环遍历数组
	while (i < sz)
	{
		printf("%d ", arr[i]);
		i++;
	}
	return 0;
}

通过示例:

  • 数组是使用下标来访问的,下标是从0开始
  • 数组的大小可以通过计算得到
int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);

在这里插入图片描述


⭐数组在内存中的存储

代码示例 (C语言):

int main()
{
	int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; ++i)
	{
		printf("&arr[%d] = %p\n", i, &arr[i]);
	}
	return 0;
}

在这里插入图片描述

注意:仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增

由此可以得出结论:数组在内存中是连续存放的
在这里插入图片描述


📚3. 二维数组

二维数组(也称为矩阵)是计算机科学中常用的数据结构,用于存储具有两个维度的数据集合。简单来说,它是一个数组的数组,即每个元素本身也是一个数组。二维数组在图像处理、游戏开发、数据分析、科学计算等领域有广泛应用


🌈数组的创建

数组的创建方式:

type_t arr_name [const_n][const_m];
// type_t 是指数组的元素类型
// const_n 表示行的大小
// const_m 表示列的大小

//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];

🌞数组的初始化

数组的初始化方式:

//数组初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};
// 二维数组如果有初始化,行可以省略,列不能省略

🌙数组的使用

二维数组的使用也是通过下标的方式

数组的遍历:

int main()
{
	int arr[3][4] = { 0 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			arr[i][j] = i * 4 + j;
		}
	}
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述


⭐数组在内存中的存储

我们来打印以下二维数组的地址看看

内存中的存储:

int main()
{
	int arr[3][4];
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
		}
	}
	return 0;
}

在这里插入图片描述
我们可以看出来,其实二维数组在内存中也是连续存储的

在这里插入图片描述


📙4. 数组越界

数组越界(Array Bounds Violation 或 Index Out of Bounds)是编程中常见的一个错误,主要发生在尝试访问数组时,使用的索引超出了数组的有效范围。在大多数编程语言中,数组索引是从0开始的,因此,对于一个长度为n的数组,有效的索引范围是0到n-1。如果尝试访问索引为n或更大的元素,就会发生数组越界错误


数组的下标是有范围限制的
数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1

所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,

所以程序员写代码时,最好自己做越界的检查

数组越界:

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("%d\n", arr[i]);//当i等于10的时候,越界访问了
	}
	return 0;
}

注意:二维数组的行和列也可能存在越界


数组越界的影响

  • 程序崩溃: 在许多编程语言中,如C/C++、Java,数组越界通常会导致程序崩溃或抛出异常,因为系统不允许访问未分配的内存区域。
  • 数据损坏: 在某些情况下,如果数组越界没有被系统捕获,可能会覆盖或损坏内存中的其他数据,导致难以跟踪的错误。
  • 安全漏洞: 在安全敏感的应用程序中,数组越界可能被恶意用户利用来执行未授权的操作或访问敏感数据

📝5. 数组作为函数参数

数组作为函数参数在C或C++等编程语言中是一个常见的操作。然而,当数组作为函数参数传递时,它并不直接传递整个数组的内容,而是传递了数组的首地址(即数组第一个元素的地址)。这意味着函数内部对数组的任何非本地(即不在函数内部定义的)修改都会影响到原始数组


⛰️数组作为函数参数错误设计

代码示例 (C语言):

void bubble_sort(int arr[])
{
	int sz = sizeof(arr) / sizeof(arr[0]);//这样对吗?
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
	bubble_sort(arr);//是否可以正常排序?
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

此处冒泡排序并不能发挥作用
在这里插入图片描述

在这里插入图片描述

注意:数组作为函数参数的时候,并不是把整个数组的传递过去,而是传的是首元素的地址


🏞️数组名

数组名的含义代码示例 (C语言):

int main()
{
	int arr[10] = { 1,2,3,4,5 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%d\n", *arr);
	//输出结果
	return 0;
}

在这里插入图片描述

结论: 数组名是数组首元素的地址(有两个例外)

数组名是首元素地址,但是计算大小不适用

int arr[10] = {0};
printf("%d\n", sizeof(arr)); // 40

两个例外:

  • sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组
  • &数组名,取出的是数组的地址。&数组名,数组名表示整个数组

🌄正确设计

void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = {3,1,7,5,8,9,0,2,4,6};
	int sz = sizeof(arr)/sizeof(arr[0]);
	// 我们先计算好数组的大小
	bubble_sort(arr, sz);
	for(int i=0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

📖6. 总结

在探索C语言数组的旅程即将结束之际,我们不禁要回顾这一路上所见的风景与收获。数组,作为C语言乃至众多编程语言中的基石之一,其重要性不言而喻。它不仅是我们存储和操作一系列相同类型数据的高效工具,更是构建复杂数据结构(如矩阵、字符串等)的基础

通过本文的介绍,我们深入了解了C语言数组的定义、初始化、访问以及通过循环遍历数组的方法。我们见证了数组如何帮助解决一系列实际问题,从简单的数学计算到复杂的数据处理,数组都以其独特的方式展现出了其强大的功能性和灵活性

然而,正如任何强大的工具一样,数组的使用也需要谨慎。越界访问、内存泄漏等问题是我们在使用数组时不得不面对的挑战。因此,掌握良好的编程习惯,如在使用前检查数组边界、合理管理内存等,对于避免潜在的问题至关重要

让我们在掌握C语言函数的基础上,继续保持对编程的热情与好奇心,勇于探索未知,不断挑战自我!!!

在这里插入图片描述
希望本文能够为你提供有益的参考和启示,让我们一起在编程的道路上不断前行!
谢谢大家支持本篇到这里就结束了,祝大家天天开心!

在这里插入图片描述

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

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

相关文章

【医学影像】X86+FPGA:支持AI医学影像设备应用的工控主板,赋能CT、MRI、X线、超声等医学影像设备

支持AI医学影像设备应用的工控主板 在我国人口老龄化问题不断加剧&#xff0c;对影像诊断需求持续增长&#xff0c;和国家利好高端医学影像市场发展的系列法规和政策接连出台的大环境下&#xff0c;AI医学影像设备产业迎来发展黄金期。紧跟发展大势&#xff0c;基于12/13代 In…

天途无人机林业应用解决方案

林业应用现状分析 森林环境较为复杂&#xff0c;人员无法快速到达现场&#xff0c;工作人员通常会面临监控盲区&#xff0c;林区爬山涉水困难多&#xff1b;森林防火重要性不可忽视&#xff0c;2019年全国共发生森林火灾2345起&#xff0c;森林防火仍为重中之重&#xff1b;环…

SAPUI5基础知识16 - 深入理解MVC架构

1. 背景 经过一系列的练习&#xff0c;相信大家对于SAPUI5的应用程序已经有了直观的认识&#xff0c;我们在练习中介绍了视图、控制器、模型的概念和用法。在本篇博客中&#xff0c;让我们回顾总结下这些知识点&#xff0c;更深入地理解SAPUI5的MVC架构。 首先&#xff0c;让…

Jvm基础(一)

目录 JVM是什么运行时数据区域线程私有1.程序计数器2.虚拟机栈3.本地方法栈 线程共享1.方法区2.堆 二、对象创建1.给对象分配空间(1)指针碰撞(2)空闲列表 2.对象的内存布局对象的组成Mark Word类型指针实例数据&#xff1a;对齐填充 对象的访问定位句柄法 三、垃圾收集器和内存…

React基础学习-Day04

React基础学习-Day04 常见的钩子函数及基础使用方式 1.useState useState 是 React 的一个 Hook&#xff0c;用于在函数组件中添加状态。它返回一个状态变量和一个更新该状态的函数。与类组件的 this.state 和 this.setState 相对应&#xff0c;useState 让函数组件也能拥有…

【第10章】Spring Cloud之Nacos动态配置

文章目录 前言一、上下文1. 新增配置2. 启动类3. 效果 二、注解 ( 推荐 ) \color{#00FF00}{(推荐)} (推荐)1. 获取配置2. 测试2.1 未配置2.2 配置值2.3 修改值 总结 前言 这一章我们通过两个案例来学习Nacos动态配置&#xff0c;通过在控制台修改服务端配置文件值&#xff0c;…

linux环境交叉编译openssl库,以使Qt支持https

一.前言 Qt若需要支持https&#xff0c;则需要openssl的支撑,并且要注意&#xff0c;Qt不同版本会指定对应的openssl版本库&#xff0c;比方我用的Qt5.15.10他要求用的openssl版本是1.1.1&#xff0c;你就不能用其他版本&#xff0c;不然基本就是失败报错。 如何查看Qt对应ope…

TK秘籍:深度剖析机房IP与住宅IP的利与弊

大家好&#xff0c;今天我们来聊聊TikTok运营中的一个重要环节——IP地址的选择。 想象一下&#xff0c;你在TikTok上发布视频&#xff0c;就像是在一个热闹的市集上摆摊&#xff0c;而IP地址就是你的摊位位置。选对了位置&#xff0c;你的摊位就能吸引更多顾客&#xff0c;也…

浪漫情怀:红酒中的诗意与情感

在生活的点滴细节中&#xff0c;总有些元素能触动我们内心较柔软的地方&#xff0c;唤起那份深深的浪漫情怀。而红酒&#xff0c;便是这其中的一种神奇媒介。它以其不同的色泽、香气和口感&#xff0c;让人沉醉其中&#xff0c;感受那份诗意与情感的交织。今天&#xff0c;就让…

使用Kotlin Flow和协程开发高性能Android应用

使用Kotlin Flow和协程开发高性能Android应用:以电影业务为例 引言 在当今移动互联网快速发展的时代,用户对应用的性能和响应速度有了更高的要求。作为开发者,我们需要不断探索和采用新的技术来提升应用的性能和用户体验。Kotlin作为Android开发的首选语言,其协程和Flow特…

抖音/腾讯/百度ocpm深度回传如何操作?广告投放双出价的投放技巧?

要实现抖音、腾讯和百度的OCPM&#xff08;Optimized Cost Per Mille&#xff09;深度回传&#xff0c;可以通过借助第三方平台&#xff0c;例如&#xff08;转化宝&#xff09;实现广告数据精准回传&#xff0c;如此之外&#xff0c;在广告投放过程中还需要注重这些方面。 转化…

Python+Django+MySQL的新闻发布管理系统【附源码,运行简单】

PythonDjangoMySQL的新闻发布管理系统【附源码&#xff0c;运行简单】 总览 1、《新闻发布管理系统》1.1 方案设计说明书设计目标工具列表 2、详细设计2.1 登录2.2 程序主页面2.3 新闻新增界面2.4 文章编辑界面2.5 新闻详情页2.7 其他功能贴图 3、下载 总览 自己做的项目&…

云计算实训06——find、stat、touch、tree、scp、crontab指令相关应用

一、find命令 1.find的作用&#xff1a;对文件进行搜索 2. 基本语法&#xff1a; find [文件路径] [选项 选项的值 ] 3.常见的选项 -name 根据文件的名称搜索文件&#xff0c;支持通配符 * -type f 代表普通文件&#xff0c;-type d 代表目录 4.* 通配符 在 linux 系统…

QT--多页面、定时器和日期时间数据

多页面 widget.ui 负责实现一个页面; mian.cpp创建窗体对象,并监控上面的事件 窗口的显示和隐藏: 一个窗体,比如logpage widget,继承QWidget QWidget::show(); 显示该窗体 QWidget::hide(); 隐藏该窗体 页面间通信采用在main.cpp中创建connect槽函数。 代码如下 //main.c…

socket 收发TCP/UDP

一、c 个人测试记录&#xff0c;有问题还请指出&#xff0c;谢谢 参考&#xff1a;C开发基础之网络编程WinSock库使用详解TCP/UDP Socket开发_c udp使用什么库-CSDN博客 代码中Logger测试见文章&#xff1a; c中spdlog的使用/python中logger的使用-CSDN博客 1、main.cpp 收…

PE安装系统

前些天客户的电脑坏了,需要重装系统,我们的恢复光盘安装的时候,由于主板的原因,导致进入windows安装界面,鼠标键盘没有响应,自然也就无法正常安装了. 那我们只能换个方法,PE安装试试看,那么我们需要做哪些准备工作呢? 1.制作PE启动盘,网上很多制作工具,如""U启动,…

贪心算法总结(1)

一、贪心算法简介 常用方法&#xff1a;交换论证法、数学归纳法、反证法、分类讨论 二、柠檬水找零&#xff08;交换论证法&#xff09; . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool lemonadeChange(vector<int>& bills) {int five0,t…

蜂窝物联云平台:一站式服务,智能生活从此开始!

蜂窝云平台 一、PC端展示与管理 GIS地图整合 在GIS地图上精确展示地块&#xff0c;轻松点选查看详细设备信息、实时监控和控制功能&#xff0c;以及基地的全方位介绍。 个性化定制界面 界面布局与功能展示均可按需求定制&#xff0c;打造独一无二的用户体验。 数据集中看板 将…

html网页使用tesseract实现OCR文字识别

即在前端实现OCR文字识别 1.前端代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>OCR文字识别…