C语言—数组的介绍

数组的概念

数组是一组相同类型元素的集合
1.数组中存放的元素是一个或者多个,但是数组的元素不能为0;
2.数组中存放的多个元素,类型是相同的,例如int ,char

而我们所说的变量中就只有一个元素,
例如 int a = 0;char b =’ f '。

一维数组的创建和初始化

数组创建

一维数组创建的基本语法是:
type arr_name [常量值];

存放在数组中的值被叫做数组的元素,数组在创建时可以指定数组的大小(元素的个数)数组元素的类型

type 是指数组中存放的值的类型,可以是char int short float double,也可以是自定义的类型;

arr_name 是指数组的名字,这个名字根据实际情况设置,起的有意义就可以了;

[ ] 中的常量值是用来指定数组的大小的,根据实际情况来设定。

下面创建几个数组:

int arr[20];
char ch[8];

数组的初始化

在数组创建时,我们需要给定一些初始数值,这种就被称为初始化。
数组的初始化一般使用大括号,将选定的类型的数据放在大括号中。
在这里插入图片描述

数组的类型

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

int arr1[10];
int arr2[8];

char ch[10];

arr1的类型为 int [10]
arr2的类型为 int [8]
ch的类型为 char [10]

数组元素的类型就是type的类型。

一维数组的使用

数组下标

C语言规定数组是有下标的,下标是从0开始的,
也就是说如果数组有n个元素,那么最后一个数组的下标为n-1
下标就相当于数组元素的编号

int arr [10]={1,2,3,4,5,6,7,8,9,10};
数组下标
10
21
32
43
54
65
76
87
98
109

在C语言中数组的访问提供了一个操作符**[ ],叫做下标引用操作符**。

有了这个操作符,我们能够轻松的访问到数组的元素
例如:我们访问下标为7的元素,我们就可以使用arr[7],想要访问下标是3的元素,就可以使用arr[3],如下代码:

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	printf("%d\n", arr[7]);
	printf("%d\n", arr[3]);
	return 0;
}

输出的结果为
在这里插入图片描述

数组元素的输入与输出

如果我们想要访问整个数组的内容,就需要产生所有的元素的下标即可,我们只需要运用for循环就可以了,代码如下:

int main()
{
	int arr[10] = { 0 };
	int n = 0;
	
	//输入
	for (n = 0; n < 10; n++)
	{
		scanf("%d", &arr[n]);
	}

	//输出
	for (n = 0; n < 10; n++)
	{
		printf("%d ", arr[n]);
	}
	return 0;
}

输入数据的结果:
在这里插入图片描述

一维数组在内存中的存储

1.内存:
电脑的内存分为多种,有4G,8G,16G,32G,64G(计算机处理的数据。都要加载到内存中处理)
内存会被划分为1一个个的内存单元(大小为1个字节),然后给每个内存单元都编上号
编号地址C语言中的指针

2.为了了解数组在内存中的存储,我们就要知道数组元素的地址:

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int n = 0;

	for (n = 0; n < 10; n++)
	{
		printf("&arr[%d]=%p\n", n, &arr[n]);
		// &--取地址操作符 %p--打印地址的数据类型 (&&--并且)
	}
	return 0;
}

其中 &–取地址操作符 (&&–并且) %p–打印地址的数据类型

输出的结果为:
在这里插入图片描述
从输出的结果可以看出:
1.数组随着下标的增长,地址是由小到大变化的;
2.每相邻的两个元素之间相差为4(因为一个整型是4个字节);

得出的最后结论就是:数组在内存中是连续存放的

sizeof计算数组元素的个数

sizeof是C语言中的一个关键字,是可以计算类型或者变量大小/长度的,单位是字节,其实sizeof也可以计算数组的大小
比如:

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

这里输出的结果为40(10x4),计算的是数组所占的空间的总大小。

我们又知道数组所有元素的类型都是相同的,那只要计算出一个元素所占字节的个数,数组的元素个数就能算出来。我们选择第一个元素算大小就可以。

int main()
{
	int arr[10] = { 0 };
	printf("%d\n", sizeof(arr[0]));//计算一个元素的大小,单位是字节
	return 0;
}

最后我们就能计算数组的元素个数:

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

这里的结果是:10,表达数组有10个元素。

数组的元素个数计算公式:sizeof(arr) / sizeof(arr[0])

二维数组的创建与初始化

二维数组的概念

如果我们把一维数组做为数组的元素,这时候就叫二维数组,
二维数组作为数组元素的数组称为三维数组,
二维数组以上的数组统称为多维数组
在这里插入图片描述

二维数组的创建

二位数组的语法如下:
type arr_name[常量值1][常量值2]

前面的内容与一维数组一致,
而[常量值1]—行数 [常量值2]—列数

二维数组的初始化

在创建变量或者数组时,给定一定的初始值,被称为初始化。
像一维数组一样,也是使用大括号来初始化的

1.不完全初始化

依次初始化每一行,当不够的时候,剩余的元素初始化为0

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

在这里插入图片描述

2.完全初始化

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

在这里插入图片描述

3.按照行初始化
如果想要几个数据在同一行,则可以在{}下再添加{}

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

在这里插入图片描述
4.初始化时省略行,但是不能省略列

数组如果初始化了,也可以省略掉数组的行,编译器会根据数组的初始化内容来确定数组的大小

int arr4[][5]={1,2,3};//一行
int arr5[][5]={1,2,3,4,5,6,7};//二行
int arr6[][5]={{1,2}{3,4}{5,6}};//三行

在这里插入图片描述

二维数组的使用

二维数组的下标

二维数组访问也是使用下标的形式的,二维数组是有行和列的,只要锁定了行和列就能唯一锁定数组中的一个元素。
C语言规定,二维数组的行是从0开始的,列也是从0开始的 如下所示:

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

在这里插入图片描述
图中最右侧绿色的数字表示行号,第一行蓝色的数字表示列号,都是从0开始的。
比如:我们说:第二行,第四列,快速能定位出7。

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

输出的结果为:
在这里插入图片描述

二维数组的输入与输出

int main()
{
	int arr[3][5] = { 0 };
	int a = 0;
	int b = 0;
	
	//输入
	for (a = 0; a < 3; a++)//产生行号
	{
		for (b = 0; b < 5; b++)//产生列号
		{
			scanf("%d", &arr[a][b]);//输入数据
		}
	}

	//输出
	for (a = 0; a < 3; a++)//产生行号
	{
		for (b = 0; b < 5; b++)//产生列号
		{
			printf("%d ", arr[a][b]);//输出数据
		}
		printf("\n");
	}
	return 0;
}

输入和输出的结果:
在这里插入图片描述

二位数组在内存中的存储

跟一维数组一样,我们为了研究二维数据在内存中的存储方式,我们也可以打印出数组所有元素的地址。

int main()
{
	int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
	int a = 0;
	int b = 0;

	for (a = 0; a < 3; a++)
	{
		for (b = 0; b < 5; b++)
		{
			printf("&arr[%d][%d]=%p\n", a, b, &arr[a][b]);
		}
	}
	return 0;
}

输出的结果:
在这里插入图片描述
从输出的结果可以得出:
1.每一行内部的各个元素都是相邻的,地址之间相差四个字节
2.跨行位置处的两个元素(如:arr[0][4]和arr[1][0])之间也差四个字节

所以二维数组的每个元素都是连续存放的

如下图所示:
在这里插入图片描述

arr[0]为第一行数组名——arr[0][b]
arr[1]为第二行数组名——arr[1][b]
arr[2]为第三行数组名——arr[2][b]

C99的变长数组

在C99标准之前,C语言在创建数组的时候,数组大小的指定只能使用常量,常量表达式,或者如果我们初始化数据的话,可以省略数组大小。

在C99中给一个变长数组的新特征,允许我们可以使用变量指定数组大小

int n = a+b;
int arr[n];

上面代码中,数组arr就是变长数组,因为它的长度取决于变量n的值。

变长数组的根本特征,就是数组长度只有运行时才能确定,所以变长数组不能初始化。它的好处是程序员不必在开发时,随意为数组指定一个估计的长度,程序员可以在运行时为数组分配精确的长度。但变长数组的意思是数组的大小可以使用变量来指定的,在程序运行的时候,根据变量的大小来指定数组的元素个数,而不是说数组的大小是可变的。数组的大小一旦确认就不能再变化的。

数组练习

多个字符由两边向中间汇聚

1.strlen和sizeof的区别:

char ch = 'a b c'//a,b,c,/0

strlen–求字符串长度(/0之前的元素个数) 为3 使用时要包含头文件#include<string.h>
sizeof–求字符串占空间的大小(包含/0) 为4

2.代码:

#include<windows.h>
#include<string.h>
#include<stdlib.h>

int main()
{
	char arr1[] = "welcome to YueYang!!!";
	char arr2[] = "*********************";
	int left = 0;
	int right = strlen(arr1) - 1;
	printf("%s\n", arr2);
	while (left <= right)
	{
	    Sleep(1000);
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		left++;
		right--;
		system("cls");
		printf("%s\n", arr2);

	}
	return 0;
}

3.函数介绍:
Sleep(常数值)–睡眠,表示代码运行暂停,常量值表示睡眠的时间,单位是毫秒;使用时要包含头文件#include<windows.h>
system–system是库函数,执行系统指令,例如:“cls”-清理控制台屏幕信息;使用时要包含头文件#include<stdlib.h>

二分查找

1.使用限制:在一个**升序(按顺序)**的数组中查找指定的数字n;

2.代码:

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int key = 0;
	scanf("%d", &key);
	int left = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int right = sz - 1;
	int mid = 0;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (key == arr[mid])
		{
			printf("找到了,下标为%d\n", mid);
			break;
		}
		else if (key > arr[mid])
		{
			left = mid + 1;
		}
		else
		{
			right = mid - 1;
		}
	if (left > right)
	{
			printf("找不到\n");
	}
	}
	return 0;
}

一次折半的过程包含下面几个步骤:
①确定被查找的范围:
②确定被查找范围的左右下标:
③根据左右下标来确定中间的下标:
④然后将中间下标所对应的数组的元素和要找的元素进行比较:
⑴找到了:结束循环
⑵找不到:根据大小关系,确定新的查找范围

3.如果left和right比较大的时候可能存在空间问题,所以使用下面的方式来书写会更好:
mid = left+ (right - left) / 2

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值