无可奈何花落去,似曾相识燕归来(第五章数组)

1. 数组的概念

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

3. ⼀维数组的使⽤

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

5. sizeof计算数组元素个数

6. ⼆维数组的创建

7. ⼆维数组的初始化

8. ⼆维数组的使⽤

9. ⼆维数组在内存中的存储

10. C99中的变⻓数组

11. 数组练习

、数组的概念

接下来,我们来学另一个新的知识,数组。
从名字上我们可以看出这是一个数的集合,在我们平常的时候 ,储存数据只能用变量并且只能储存一个数字,那如果我们想要初存多个变量呢?这里我们就需要引入数组的概念
数组就是用来储存多个相同类型的数据

数组的分类:
1 、一维数组
2.多维数组(最常见的就是二维数组)

**二、**一维数组的创建和初始化

type name [ 常量值];
给常量赋值就能够指定数组的大小,存放在数组的值被称为数组的元素

type 指的是我们创建数组的类型是 int、char、double、等等
name的命名方式和标识符一样
[常量值]是用来指定数组的大小的一般是由实际情况来确定的

比如我们要储存某组20人的成绩

float score[20];

或者其它类型的

int age [10];
char ch [15];

2.2

数组的初始话,我们在创建一个变量的时候往往需要给变量赋一个初始值,那么作为变量的集合数组在创建的时候往往也是需要给其赋其初始值.

初始化:在数组创建的过程中给定数组一些初始值

3种常见的初始化的方法2
1、//完全初始化
int arr1[5] ={1,2,3,4,5}(数组大小为5个对应5个元素)
2、// 不完全初始化
int arr2[5] ={1,2,3} (剩下没有初始化的默认为0)
3 //错误的初始化(数组大小与数组元素不匹配)
int arr[3]= {1 2,3,4,5}

2.3 数组的类型
数组也是有类型的,数组算是一种自定义类型,去掉数组名,留下的就是类型

int arr[5]; 类型:int [5]

int arr2 10]; 类型:int [10]
char arr3[7];类型:char[7]

、一维数组的使用

在上边,我们已经介绍了一维数组的基本概念,学会了基本概念我们就要学习如何使用。

3.1 数组的下标
c语言规定数组的下标是从0.开始的

int arr[5]={1,2,3,4,5}
在这里插入图片描述
所以我们不难发现数组的元素为n,那么数组的下标就为n-1,那么我们如何访问下标下标呢?
在C语言中我们引入了“[]”叫做下标引用操作符,用来访问下标

int main()
{
	int arr[5] = { 1,2,3,4,5 };
	printf("%d\n", arr[0]);//访问的就是下标为0对应的元素
	printf("%d\n", arr[3]); //访问的就是下标为3对应的元素

	return 0;
}

3.2 数组的打印
接下来如果我们要访问一个数组中所有的元素怎么办呢?
总不能一个一个打印出来吧(我们上边学的循环就要开始使用了)

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8};//不完全初始化
	int i = 0;  //作为下标
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//通过循环找到数组0到9的下标通过下标引用操作符([])来得到每一个元素并且打印
	}
	return 0;
}

在这里插入图片描述
3.3

明白了数组的打印,那么我们是否可以自己在数组中输入自己想要的元素呢?答案是当然可以的。

#include<stdio.h>
int main()
{
	int ch[10] = { 0 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		scanf("%d", &ch[i]);  //通过循环来给数组中的每个元素进行赋值
	}
	for (i = 0; i < 10; i++)
	{                              //通过循环来打印数组中的每个元素
		printf("%d ", ch[i]);
	}
	return 0;
}

在这里插入图片描述

、一维数组在内存中的存储

这里我们探究一维数组的储存主要是为了学指针与数组的关系进行铺垫的

打印数组中每个元素的地址

int main()
{
	int arr[10] = { 1,2,3,4,5 };
	for (int i = 0; i < 5; i++)
	{
		printf("%p\n", &arr[i]);//打印地址我们用的占位符是%p,通过循环我们可以把数组中
	}                         //每个元素的地址都打印出来
	return 0;
 }

由小到大,由低到高,并且来连续储存
在这里插入图片描述

、sizeof计算数组元素的个数.

在我们要想知道数组元素的个数,如果储存的元素过多我们不可能一个一个的来数。那么怎么来解决这种问题呢?
C语言提供给我们了一个关键字sizeof,sizeof可以计算类型或者变量的大小(单位是字节)

int main()
{
	int arr[10] = { 1,2,3,4,5 };
	printf("%d", sizeof(arr));  //计算数组总共的字节,可以得出是40
	return 0;
	
}
int main()
{
	int arr[10] = { 1,2,3,4,5 };
	int sum = sizeof(arr);//40元钱
	printf("%d\n", sizeof(arr));
	 //我们来举个例子:如果有40元钱,每个人提供4元,那么有多少人呢?
	int single = sizeof(arr[0]); //每个人提供4元
	printf("%d\n", sizeof(arr[0]));

	int num = sum / single;   //得到人数
	printf("%d\n", num);


	//在我们平常写的时候我们直接就可以综合的来写,我这里就是方便大家理解
	int num2 = sizeof(arr) / sizeof(arr[0]);
	printf("%d", num2);
	return 0;
}

这样我们就可以在使用数组元素的时候就不用写的那么死板了,不管数组怎么变换我们都可以通过该计算得到数组元素的大小

、二维数组的创建

学会了一维数组,那么我们接下来来学二维数组
我们知道一维数组是相同类型数据的集合,那么我们不妨理解,一维数组的****集合不就是二维数组,依次类推…二维数组以上的数组统称为多维数组

在这里插入图片描述
6.2
二维数组的创建

我们上边知道了一维数组的创建,那么接下来我们来介绍如何创建二维数组
如下:
type name [常量值1] [常量值2] ;
例子:1.int arr1[5][3] —(三行五列)
2.char arr2 [3] [5] (五行三列)
这里我们来解读三点
1 type 指的是 我们所需要创建的变量的类型
2 常量值1指的是 行数
3常量值 2指的是列数

七、二维数组的初始化
在创建变量的时候,我们总会给变量赋一些值,这种叫做初始化。

二维数组和一维数组的一样,在初始化的时候也是需要用大括号来初始化的。
接下来我们来介绍几种初始化

7.1 不完全初始化

int arr1[3][5]={1,2}
int arr2[3][5]={0}

在这里插入图片描述
在这里插入图片描述
7.2,完全初始化

int arr3[3][5]={1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7}

在这里插入图片描述

7.3 按照行初始化

int arr4[3][5]={{1,2},{3,4},{5,6}}

在这里插入图片描述

7.4 在初始化的时候,可以省略行,不能省略列
在这里插入图片描述

、二维数组的使用

在上边我们介绍了如何创建二维数组,以及二维数组的初始化,那么接下来我们介绍如何使用二维数组。
我们在一维数组中通过数组的下标来访问元素,那么我们在二维数组也可以通过下标来访问二维数组的元素。
c语言中规定 行的元素从0开始,列的元素也从0开始6

int Arr[3][5] ={1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7}
在这里插入图片描述

int main()
{
	int arr1[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
	printf("%d\n", arr1[2][4]);
	printf("%d\n", arr1[0][0]);
	printf("%d\n", arr1[2][3]);
	return 0;
}

8.2 二维数组的输入和输出

通过上边我们可以访问一个元素,那么我们要访问所有的元素呢
行是到0到2,列是0到4,那么通过嵌套循环可以打印出来了
在这里插入图片描述

int main()
{
	int arr[5][3] = { 0 };
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		int j = 0;
		for (j = 0; j < 3; j++)
		{
			scanf("%d",&arr[i][j]);  //这个嵌套循环是用来给数组来输入值的
		}
	}


	for (i = 0; i < 5; i++)
	{
		int j = 0;
		for (j = 0; j < 3; j++)
		{
			printf("%d ", arr[i][j]);  //这个嵌套循环是用来给数组来打印值的
		}
		printf("\n");   //打印完内层第一个循环后就换行
	}
	return 0;
}

在这里插入图片描述
九、二维数组在内存中的存储



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

在这里插入图片描述
这里我们也可以发现二维数组在内存中的存储也是连续的,内存地址也是由低到高,也是相差四个字节。
在这里插入图片描述
了解其储存的本质,对我们之后学习指针有很大的作用的。

、c99中的变长数组

在c99之前我们没有引入边长数组,此时数组指定大小只能用常量。而在c99之后引入了变长数组,此时我们就可以创建变量来命名,根据我们所需要的大小来创建变量这样就使其更加灵活。

c99之前

int arr[5]={1,2,3,4,5};
char arr2[]={0};

c99
变⻓数组(variable-lengtharray,简称VLA)的新特性,允许我们可以使⽤变量指定数组的大小。

int a = 0 ; a=10;
int arr3[a]={0};
上述代码我们要知道的是虽然是变长数组,但是并不是在使用中它就会自动根据数组存放的大小来变的,只要我们在创建变量的时候变量赋了值,那么其大小就已经确定了。

但是我们需要知道的是vs中并不支持变长数组,而gcc编译器是支持的

接下来我们来练习两个常见的数组题目
十一 、

练习1:多个字符从两端移动,向中间汇聚

#include<stdio.h>
#include<string.h>

int main()
{
	char arr1[] = "wly sgdsd" ;
	char arr2[] = "*********";
	int right = strlen(arr1)-1; //拿出的是右边得最后一个下标
	int left = 0;   //拿出的首个元素的下标
	while (left <= right)    //条件,左边下标的值永远是小于或者等于右边下标的
	{
		Sleep(1000);   //延迟的库函数,目的是为了看的更清楚
		arr2[left] = arr1[left];  //arr1的数组首个元素赋给arr2(从左边开始)
		arr2[right] = arr1[right];//arr1的数组末尾元素赋给arr2(从右边开始)
		left++;   //开始循环访问
		right--;
		printf("%s\n", arr2);
	}

	return 0;
}

练习2;二分查找
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int left = 0;
int right = sizeof(arr) / sizeof(arr[0]) - 1;
int mid = 0;
int find = 0;
printf(“请输入要查找的1到10的数\n”);
scanf(“%d”, &find);
while (left <= right)
{
mid = (left + right) / 2;
if (arr[mid] > find) //如果取的元素比我们要找的元素大的时候,就需要把mid下标-1给right
{
right = mid - 1;
}
else if (arr[mid] < find)
{
left = mid + 1;//如果取的元素比我们要找的元素小的时候,就需要把mid下标+1给left
}
else
{
break;
}

}
printf("找到的数为%d 下标为%d\n",arr[mid],mid);

return 0;

}

本研究利用Sen+MK方法分析了特定区域内的ET(蒸散发)趋势,重点评估了使用遥感数据的ET空间变化。该方法结合了Sen斜率估算器和Mann-Kendall(MK)检验,为评估长期趋势提供了稳健的框架,同时考虑了时间变化和统计显著性。 主要过程与结果: 1.ET趋势可视化:研究利用ET数据,通过ET-MK和ET趋势图展示了蒸散发在不同区域的空间和时间变化。这些图通过颜色渐变表示不同的ET水平及其趋势。 2.Mann-Kendall检验:应用MK检验来评估ET趋势的统计显著性。检验结果以二元分类图呈现,标明ET变化的显著性,帮助识别出有显著变化的区域。 3.重分类结果:通过重分类处理,将区域根据ET变化的显著性进行分类,从而聚焦于具有显著变化的区域。这一过程确保分析集中在具有实际意义的发现上。 4.最终输出:最终结果以栅格图和png图的形式呈现,支持各种应用,包括政策规划、水资源管理和土地利用变化分析,这些都是基于详细的时空分析。 ------------------------------------------------------------------- 文件夹构造: data文件夹:原始数据,支持分析的基础数据(MOD16A2H ET数据 宁夏部分)。 results文件夹:分析结果与可视化,展示研究成果。 Sen+MK_optimized.py:主分析脚本,适合批量数据处理和自动化分析。 Sen+MK.ipynb:Jupyter Notebook,复现可视化地图。
### 解决服务器或系统中CPU占用100%的问题 当服务器或系统的CPU使用率达到100%,通常会严重影响性能并可能导致服务中断。以下是针对该问题的具体分析和解决方案: #### 一、初步诊断 通过工具定位高CPU消耗的进程是解决问题的第一步。对于Linux环境,可以运行`top`命令来查看当前所有进程按CPU资源使用的排序情况[^3]。如果发现某个特定进程(如Java进程)始终位于前列,则可能是此进程存在异常。 #### 二、深入排查 一旦确认了具体的高负载进程,下一步是对该进程内部的行为做更细致的研究。例如,在涉及Java应用的情况下,可以通过附加参数调用`top -H -p <PID>`命令获取线程级别的详情数据[^4]。这有助于识别具体哪个线程正在过度消耗计算能力。 #### 三、优化措施 - **软件层面**: 如果是由恶意脚本或者病毒引起的持续性高负荷现象, 应及时更新防病毒定义库并对整个磁盘进行全面扫描清除潜在威胁源[^1]。 - **硬件扩展**: 当现有设备无法满足日益增长的工作需求时,考虑增加物理内存容量或是更换更快处理器型号成为必要选项之一;另外还可以部署额外主机分担原有单机上的工作量从而缓解压力状况[^2]。 ```bash # 示例:查找占用 CPU 过高的 Java 线程 top -b -n 1 | grep java # 找到对应的 PID top -H -p <PID> # 查看线程级 CPU 占用 ``` #### 四、预防机制建立 为了防止未来再次发生类似的事件,建议定期监控关键指标变化趋势图谱,并设置合理的阈值报警通知相关人员采取行动前预警提示功能启用状态良好与否检查清单项目列表如下所示: 1. 实施实时日志记录与错误追踪体系结构设计原则; 2. 定期审查应用程序逻辑是否存在死循环等问题区域改进计划书撰写完成时间表安排合理分配任务职责分工明细表制定流程标准化文档编写指南手册编制进度跟踪甘特图表绘制草稿版本初审意见汇总反馈修改完善最终定稿发布实施效果评估报告总结经验教训吸取改进建议提交领导审批签字盖章存档备案留作日后参考依据资料保存期限规定说明白纸黑字写清楚明白无误以免引起不必要的争议纠纷矛盾冲突激化恶化事态发展不可收拾局面出现造成严重后果损失难以挽回弥补后悔莫及追悔不及徒呼奈何无可奈何花落去似曾相识归来往事已成空还如一梦中千金难买早知道万事皆休一场空罢了罢了罢了……
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值