玩转C语言——数组初探

news2024/10/7 2:23:02

一、前言

        通过前面的学习,我们已了解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;
}

        结果如下:

         六、最后

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

        完!

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

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

相关文章

macOS 安装 NetLogo 6.4.0

netlogo 下载地址 NetLogo-6.4.0.dmg参考 netlogo 官网

sqllab第二十七关通关笔记

知识点&#xff1a; union select 关键字过滤 通过<> /**/进行截断处理 un<>ion sel<>ect 没效果uni/**/on sel/**/ect 被过滤了双写绕过 这关对select进行了多重过滤&#xff0c;无法进行双写绕过 大小写绕过 UNion SElect (这关可以用&am…

单片机第四季-第二课:uCos2源码-BSP

1&#xff0c;初始uCos2 文件中uC开头的为uCos相关的。 2&#xff0c;uCos2源码工程建立 建立Source Insight工程 寻找main函数 (1)RTOS其实就是一个大的裸机程序&#xff0c;也是从main开始运行的 (2)main之前也是有一个汇编的启动文件的 (3)main中调用了很多初始化函数 bsp部…

linux——进程(1)

目录 一、概念 1.1、认识进程 1.2、进程描述符&#xff08;PCB&#xff09; 1.3、进程的结构体&#xff08;task_struct&#xff09; 二、查看进程 三、获取进程的Pid和PPid 3.1、通过系统调用获取进程的PID和PPID 四、创建进程 4.1、fork() 4.2、用if进行分流 五、…

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

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

SpringCloudAlibaba系列之Seata实战

目录 环境准备 1.下载seata安装包 2.修改配置文件 3.准备seata所需配置文件 4.初始化seata所需数据库 5.运行seata 服务准备 分布式事务测试 环境准备 1.下载seata安装包 Seata-Server下载 | Apache Seata 本地环境我们选择稳定版的二进制下载。 下载之后解压到指定目录…

HTML设置语言

一、代码示例 相关代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>HTML设置语言</title> </head> <body><marquee>我爱你</marquee> <!-- …

2024年 前端JavaScript Web APIs 第三天 笔记

3.1-表单全选反选案例 <!DOCTYPE html><html><head lang"en"><meta charset"UTF-8"><title></title><style>* {margin: 0;padding: 0;}table {border-collapse: collapse;border-spacing: 0;border: 1px solid …

CentOS 7 编译安装 Git

CentOS 7 编译安装 Git 背景来源删除旧版本 Git安装依赖包下载 Git 源代码检验相关依赖&#xff0c;设置安装路径编译安装添加 Git 环境变量重新加载配置文件查看版本号参考文献 背景来源 为什么要安装新版本呢&#xff1f; 因为无聊&#xff0c;哈哈哈&#xff0c;其实也不是…

【matlab】如何批量修改图片命名

【matlab】如何批量修改图片命名 (●’◡’●)先赞后看养成习惯&#x1f60a; 假如我的图片如下&#xff0c;分别是1、2、3、4、5的命名 需求一&#xff1a;假如现在我需要在其后面统一加上_behind字符串&#xff0c;并且保留原命名&#xff0c;同时替换掉原先的图片&#xf…

论文阅读——RSGPT

RSGPT: A Remote Sensing Vision Language Model and Benchmark 贡献&#xff1a;构建了一个高质量的遥感图像描述数据集&#xff08;RSICap&#xff09;和一个名为RSIEval的基准评估数据集&#xff0c;并在新创建的RSICap数据集上开发了基于微调InstructBLIP的遥感生成预训练…

【Visual Studio】VS转换文件为UTF8格式

使用高级保存选项 更改VS的编码方案 首先需要打开高级保存选项 然后打开 文件 —> 高级保存选项 即可进行设置

Git——分支详解

目录 Git分支1、开始使用分支1.1、新增分支1.2、更改分支名称1.3、删除分支1.4、切换分支1.5、切换分支时1.6、要切换到哪个分支&#xff0c;首先要有那个分支 2、分支原理2.1、单个分支2.2、多个分支2.3、切换分支时的逻辑1、更新暂存区和工作目录2、变更HEAD的位置 2.4、如果…

微信小程序之tabBar

1、tabBar 如果小程序是一个多 tab 应用&#xff08;客户端窗口的底部或顶部有 tab 栏可以切换页面&#xff09;&#xff0c;可以通过 tabBar 配置项指定 tab 栏的表现&#xff0c;以及 tab 切换时显示的对应页面。 属性类型必填默认值描述colorHexColor是tab 上的文字默认颜色…

代码随想录day23(2)二叉树:从中序与后序遍历序列构造二叉树(leetcode106)

题目要求&#xff1a;根据一棵树的中序遍历与后序遍历构造二叉树。 思路&#xff1a;408的经典题目&#xff0c;思路和手撕的思路差不多&#xff0c;先从后序中找到根节点&#xff0c;再从中序中找到此节点&#xff0c;然后分割成左右子树&#xff0c;记录一下左右子树的节点个…

【MySQL】MySQL事务

文章目录 一、CURD不加控制&#xff0c;会有什么问题&#xff1f;二、事务的概念三、事务出现的原因四、事务的版本支持五、事务提交方式六、事务常见操作方式七、事务隔离级别1.理解隔离性12.隔离级别3.查看与设置隔离性4.读未提交【Read Uncommitted】5.读提交【Read Committ…

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

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

arm-linux实现onvif server+WS-UsernameToken令牌验证

目录 一、环境搭建 1、安装openssl 2、安装bison 3、安装flex 二、gsoap下载 三、编译x86版本gsoap 四、编译arm-linux版本gsoap 1、交叉编译openssl 1.1、下载openssl 1.2、交叉编译 2、交叉编译zlib 2.1、下载zlib 2.2、交叉编译 3、交叉编译gsoap 3.1、编译过…

C++之deque与vector、list对比分析

一.deque讲解 对于vector和list&#xff0c;前一个是顺序表&#xff0c;后一个是带头双向循环链表&#xff0c;前面我们已经实现过&#xff0c;这里就不再讲解了&#xff0c;直接上deque了。 deque&#xff1a;双端队列 常见接口大家可以查看下面链接&#xff1a; deque - …

WEB前端项目开发——(一)(2024)

目录 1 通过Git Bash安装 vue-cli 2 创建项目 3 解决Git Bash方向键失效 4 重新进行项目创建 5 浏览器输入地址查看 6 案例——简单修改v3-calendar中的内容 7 测试页面效果 本篇文章介绍通过了Git Bash创建v3-calendar项目&#xff0c;之后对v3-calendar进行简单…