玩转C语言——数组初探

一、前言

        通过前面的学习,我们已了解C语言的结构变量、分支结构和循环结构。今天,我们一起来认识C语言的另一知识点——数组。先赞后看,养成习惯。

二、数组概念

        学习数组,我们要明白数组是什么。在我看来:数组是⼀组相同类型元素的集合。

        从这句话中,我们可以提取到如下的信息:

  •         数组可以存放相同的数据且类型相同。
  •         数组的1元素个数不为零。

        数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。

三、一维数组

        3.1 一维数组的创建

  •         存放在数组的值被称为数组的元素,数组在创建的时候可以指定数组的⼤⼩和数组的元素类型。
  •         类型说明符就是我们常用的存储类型(如:int 、short、char......)当然也可以自定义类型。
  •         数组名就是自取的名字,要取得方便阅读。
  •         []是用来确定数组大小的,可根据需要而定。

                基本创建语法如下:

​
	int arr1[0];//0表示元素个数
	short arr2[0];
	char arr3[0];
	float arr4[0];
	double arr5[0+1];//表达式形式也可以

​

         3.2 一维数组的初始化

        在创建数组的时候,我们需要对数组进行初始化,那我们该如何进行初始化呢?且听我细细道来:

        在进行初始化时,我们一般使用大括号的形式,即把数据放入大括号中。

        初始化有分为:完全初始化和不完全初始化。

        那什么是完全初始化什么又是不完全初始化呢?可这样理解:假如你家有五口人,每个人都能分到一包饼干,这就是完全初始化;反之,则是不完全初始化。在我们写代码过程中,大多数都是用不完全初始化。

        代码如下:

        

​
	​
	int arr1[0] = { 0 };//完全初始化
	int arr2[2] = { 0 };//不完全初始化
	int arr3[3] = { 0,0 ];//不完全初始化
	int arr4[5];//错误初始化,在VS中会报错

​
	
	
​

        3.3一维数组的类型 

        数组的类型就是去除数组名就是其类型,以上述代码为例:

​
​
	​
	int arr1[0] = { 0 };//数组类型为int [0]
	int arr2[2] = { 0 };//数组类型为int [2]
	char arr3[3] = { 0,0 ];//数组类型为 char [3]
	
​
	
	
​

​

        3.4 一维数组的使用 

        在学习完基本的语法后,我们就要学习对其使用了,一维数组可以存放数据,存放数据的⽬的是对数据的操作,那我们该如何使用呢?

        3.4.1 数组下标

                C语⾔规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下 标就相当于数组元素的编号,如下:

                

         在C语⾔中数组的访问提供了⼀个操作符 [] ,这个操作符叫:下标引⽤操作符。 有了下标访问操作符,我们就可以轻松的访问到数组的元素了.

        3.4.2 数组的打印

                大家是不是现在很好奇一维数组是怎么打印的。在这里提供两种方法:

        法一:

#include <stdio.h>
int main()
{
	char arr[] = "123456";
	printf("%s", arr);
	return 0;
}

        %s可以打印字符串,因此可以采用此方法。

        法二:

#include <stdio.h>
int main()
{
	char arr[6] = { 1,2,3,4,5,6 };
	int i = 0;
	for (i = 0; i < 6; i++)
	{
		printf("%d", arr[i]);
	}
	return 0;
}

        此方法用之前学习过的for循环,运用循环的方式,逐个打印。

        3.4.3 数组的输入 

        明白了打印,自然就明白了输入,这里仍提供两种方法。

        法一:

#include <stdio.h>
int main()
{
	int arr[2] = { 1,2 };
	int i = 0;
	for (i = 0; i < 2; i++)
	{
		scanf("%d", &arr[i]);
	}
	for (i = 0; i < 2; i++)
	{
		printf("%d", arr[i]);
	}
	return 0;
}

        整体思路和上述法二一样,运用for循环进行输入及打印。

        法二:

        可借助gets()进行输入。代码如下:

        

#include <stdio.h>
int main()
{
	char arr[2] = { 0 };
	int i = 0;
	gets(arr);
	printf("%s", arr);
	return 0;
}
        3.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;
}

结果如下:

         

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

四、二维数组 

        前⾯学习的数组被称为⼀维数组,数组的元素都是内置类型的,如果我们把⼀维数组做为数组的元 素,这时候就是⼆维数组,⼆维数组作为数组元素的数组被称为三维数组,⼆维数组以上的数组统称 为多维数组。

         4.1二维数组的创建及初始化

        我们已学习了一维数组的创建及初始化,那⼆维数组如何初始化呢?像⼀维数组⼀样,也是使⽤⼤括号初始化的。

        类比一维数组的定义,只不过二维数组第一个常量表达式表示行,第二个常量表达式表示列

         

int arr[5][5];//创建五行五列的二维数组
char arr2[3][5];//字符型二维数组
float arr3[4][5];//浮点型二维数组

        其初始化与一维数组大致一样,都分为完全初始化和不完全初始化。

        

int arr1[3][5] = {1,2};//不完全初始化
int arr2[3][5] = {0};//不完全初始化
int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};//完全初始化
int arr4[3][5] = {{1,2},{3,4},{5,6}};//按照⾏初始化
int arr5[][5] = {1,2,3};//初始化时省略⾏,但是不能省略列
        4.2 ⼆维数组的使⽤ 

                4.2.1 ⼆维数组的下标

         当我们掌握了⼆维数组的创建和初始化,那我们怎么使⽤⼆维数组呢? 其实⼆维数组访问也是使⽤下标的形式的,⼆维数组是有⾏和列的,只要锁定了⾏和列就能唯⼀锁定 数组中的⼀个元素。 C语⾔规定,⼆维数组的⾏是从0开始的,列也是从0开始的,如下所⽰:

int arr[3][5] = {1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15};

        

                4.2.2 二维数组的输入和输出

        访问⼆维数组的单个元素我们知道了,那如何访问整个⼆维数组呢? 其实我们只要能够按照⼀定的规律产⽣所有的⾏和列的数字就⾏;以上⼀段代码中的arr数组为例,⾏ 的选择范围是0~2,列的取值范围是0~4,所以我们可以借助循环实现⽣成所有的下标。 

        

int main()
{
	int arr[3][5] = { 1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15 };
	int i = 0;
	for(i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

        结果如下:

         

        4.2.3 ⼆维数组在内存中的存储 

        像⼀维数组⼀样,我们如果想研究⼆维数组在内存中的存储⽅式,我们也是可以打印出数组所有元素 的地址的。代码如下:

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

        结果如下:

        

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

        

 五、数组练习

        多个字符从两端移动,向中间汇聚 编写代码,演⽰多个字符从两端移动,向中间汇聚

        分析:

        若要完成此题,需要借个操作符:strlen和函数:Sleep。

        一下是解释:

         

 C语言中的 sleep 函数可以让当前线程暂停执行一段时间,通常用于模拟实际运行环境下的等待或延时操作。在 Windows 和 Linux 等主流操作系统中,sleep 函数的实现方式略有不同,但其基本原理都是通过让线程进入睡眠状态来实现等待或延时的效果。

其中,seconds 参数表示线程需要暂停的秒数。sleep 函数返回值为 0,表示线程成功地暂停了指定的秒数,如果 sleep 函数被其他信号打断,则返回值为剩余需要暂停的秒数。

需要注意的是,sleep 函数的参数类型为 unsigned int,而不是浮点数类型。如果需要暂停小于 1 秒的时间,可以使用 usleep 函数,它的参数类型为微秒(unsigned int),可以精确地控制线程的等待时间。

        在每次输出之后,使用 sleep 函数暂停 1 秒,模拟实际运行环境下的延时操作。需要注意的是,在使用 sleep 函数时,应该将输出立即刷新到控制台上,否则可能会出现输出延迟的情况。

另外,需要注意的是,sleep 函数会让当前线程进入睡眠状态,因此在调用 sleep 函数时,应该确保当前线程已经完成了所有需要执行的操作,否则可能会导致程序出现不可预测的结果。同时,需要注意不要在循环中频繁地调用 sleep 函数,否则可能会降低程序的性能,影响程序的正常运行。

需要注意的是,在不同的操作系统中,sleep 函数的精度和可靠性可能会有所不同。在一些嵌入式系统中,sleep 函数的精度可能会受到系统时钟精度的限制,导致实际暂停的时间可能会比预期的时间短。因此,在使用 sleep 函数时,应该根据实际需要选择合适的等待时间,并且在代码中添加必要的异常处理机制,以确保程序的稳定性和可靠性。

        总的来说:strlen是计算长度的,sleep是延迟打印。 

        可参考如下代码: 

#define _CRT_SECURE_NO_WARNINGS 1​
#include <stdio.h>
int main()
{
	char arr1[] = "hello,world" ;
	char arr2[] = "###########" ;
	int left = 0;
	int right = strlen(arr2) - 1;
	while (left <= right)
	{
		Sleep(1000);
		arr2[right] = arr1[right];
		arr2[left] = arr1[left];
		left++;
		right--;
		printf("%s\n", arr2);
	}
	return 0;
}

        结果如下:

         六、最后

        今天的学习到这里就结束了,如果有什么问题可以留言,我会尽我所能为你解答。

        完!

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

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

相关文章

Linux提权!!

本来是想更新PTH的&#xff0c;但我鸽了&#xff0c;那就来讲讲Linux的提权吧&#xff01;&#xff01;主要是下周我就要学免杀了啦&#xff01;&#xff01;&#xff01; 对于内网&#xff0c;什么难学&#xff1f;&#xff1f;&#xff1f; 是的&#xff0c;确实呢&#xff0…

ISIS默认层级实验简述

ISIS被划分为三个层级&#xff1a;Level 1、Level 2和Level 1-2。 默认情况下&#xff0c;ISIS路由器属于level 1-2,是指同时支持Level 1和Level 2的路由器。路由器既可以在同一个自治系统内部进行路由选择&#xff0c;也可以将路由信息传递到其他自治系统。 实验拓扑图&#…

Redis实战——优惠券秒杀:超卖问题一人一单问题

目录 优惠券秒杀Redis实现全局唯一ID业务场景代码实现&#xff1a; 添加优惠券业务场景新增普通券新增秒杀券测试添加秒杀券 实现秒杀下单业务分析流程代码编写 超卖问题超买场景分析解决方案使用乐观锁 一人一单业务场景解决步骤 集群环境下的并发问题 优惠券秒杀 Redis实现全…

AntV L7深圳智慧城市

本案例使用L7库和Mapbox GL JS构建深圳智慧城市。 文章目录 1. 引入 CDN 链接2. 引入组件3. 创建地图4. 创建场景5. 获取数据6. 创建面图层7. 演示效果8. 代码实现 1. 引入 CDN 链接 <!-- 1.引入CDN链接 --> <script src"https://unpkg.com/antv/l7"><…

Transformer的前世今生 day02(神经网络语言模型

神经网络语言模型 使用神经网络的方法&#xff0c;去完成语言模型的两个问题&#xff0c;下图为两层感知机的神经网络语言模型&#xff1a; 以下为预备概念 感知机 线性模型可以用下图来表示&#xff1a;输入经过线性层得到输出 线性层 / 全连接层 / 稠密层&#xff1a;假…

odoo17开发教程(8):设置界面UI的字段属性

目录 添加字段 给字段设置只读和不可拷贝 给字段添加默认值 保留字段 本节目标&#xff1a;在本文末尾&#xff0c;售价(selling price)应为只读值&#xff0c;卧室数量(bedrooms)和可用日期(availability date)应为默认值。此外&#xff0c;在复制记录时&#xff0c;售价和…

Langchain-chatchat+ChatGlm3-6b部署

我的环境 台式机 内存&#xff1a;16GB 显卡&#xff1a;GTX1060-6G 1. 基础环境准备 1.1. 安装anaconda&#xff0c;创建环境python版本3.11 conda create -n chatglm3 python3.11 conda activate chatglm3 1.2. 搭建cuda环境 # 查看cuda版本&#xff0c;版本是CUDA V…

cmd常用指令

cmd全称Command Prompt&#xff0c;中文译为命令提示符。 命令提示符是在操作系统中&#xff0c;提示进行命令输入的一种工作提示符。 在不同的操作系统环境下&#xff0c;命令提示符各不相同。 在windows环境下&#xff0c;命令行程序为cmd.exe&#xff0c;是一个32位的命令…

sqlite 常见命令 表结构

在 SQLite 中&#xff0c;将表结构保存为 SQL 具有一定的便捷性和重要性&#xff0c;原因如下 便捷性&#xff1a; 备份和恢复&#xff1a;将表结构保存为 SQL 可以方便地进行备份。如果需要还原或迁移数据库&#xff0c;只需执行保存的 SQL 脚本&#xff0c;就可以重新创建表…

Mybatis-xml映射文件与动态SQL

xml映射文件 动态SQL <where><if test"name!null">name like concat(%,#{name},%)</if><if test"username!null">and username#{username}</if></where> <!-- collection&#xff1a;遍历的集合--> <!-- …

问题解决:关于tomcat无法连接问题的解决

安装tomcat并配置环境变量 下载tomcat并安装 首先去tomcat官方网站,下载tomcat 进入tomcat官方网站之后&#xff0c;查看jdk应该对应的tomcat版本&#xff0c;点击图示的按钮 点击完毕之后&#xff0c;可以看到下述的页面 图中的表格可以看到对应的jdk版本与tomcat的版本之…

基于sortablejs实现拖拽element-ui el-table表格行进行排序

可以用原生的dragstart、drag、dragend、dragover、drop、dragleave实现这个效果&#xff0c;但是有现成的轮子就不要重复造了&#xff0c;看效果&#xff1a; <template><el-table :class"$options.name" :data"tableData" ref"table"…

【数据结构入门】顺序表详解(增删查改)

目录 顺序表的基本概念 动态顺序表的实现 初始化 插入 尾插法 头插法 指定位置之前插入 删除 尾删法 头删法 指定位置删除 查找 销毁 顺序表的基本概念 什么是顺序表&#xff1f; 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般…

树与二叉树(数据结构)

本篇博客讲解 树与二叉树&#xff0c;后续会继续讲解堆 —————————————————————— 1.树概念及结构 1.1树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看…

浅谈C++的函数重载

今天我们来谈谈C的函数重载&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;对于函数重载&#xff0c;我们首先需要理解几个问题&#xff1a; 1、什么是函数重载 &#xff1f;2、函数重载需要注意什么 &#xff1f;3、为什么C语言不支持函数重载&#xff0c;而C支持 &…

Unity在UGUI上通过绘制网格顶点自由画线

该插件的实现是使用UI组件的绘图API来动态生成和修改几何形状&#xff0c;可自由动态更改画线的粗细、拐角圆滑度、颜色&#xff0c;自由增减节点&#xff0c;不额外增加gameobject&#xff0c;并且在原生的UGUI上以ScreenSpace-Overlay的状态下&#xff0c;显示效果如下所示 …

【PyTorch】基础学习:一文详细介绍 load_state_dict() 的用法和应用

【PyTorch】基础学习&#xff1a;一文详细介绍 load_state_dict() 的用法和应用 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#…

【AI】Ubuntu系统深度学习框架的神经网络图绘制

一、Graphviz 在Ubuntu上安装Graphviz&#xff0c;可以使用命令行工具apt进行安装。 安装Graphviz的步骤相对简单。打开终端&#xff0c;输入以下命令更新软件包列表&#xff1a;sudo apt update。之后&#xff0c;使用命令sudo apt install graphviz来安装Graphviz软件包。为…

使用 GitHub Actions 通过 CI/CD 简化 Flutter 应用程序开发

在快节奏的移动应用程序开发世界中&#xff0c;速度、可靠性和效率是决定项目成功或失败的关键因素。持续集成和持续部署 (CI/CD) 实践已成为确保满足这些方面的强大工具。当与流行的跨平台框架 Flutter 和 GitHub Actions 的自动化功能相结合时&#xff0c;开发人员可以创建无…

网络安全实训Day5

写在前面 昨天忘更新了......讲的内容不多&#xff0c;就一个NAT。 之前记的NAT的内容&#xff1a;blog.csdn.net/Yisitelz/article/details/131840119 网络安全实训-网络工程 NAT 公网地址与私网地址 公网地址 可以在互联网上被寻址&#xff0c;由运营商统一分配全球唯一的I…