单片机之从C语言基础到专家编程 - 4 C语言基础 - 4.13数组

发布于:2024-05-30 ⋅ 阅读:(59) ⋅ 点赞:(0)

C语言中,有一类数据结构,它可以存储一组相同类型的元素,并且可以通过索引访问这些元素,没错,这类数据结构就是数组。数组可以说是C语言中非常重要的数据结构之一了。使用数组可以是程序逻辑更加清晰,也更加具有可读性。

1 数组的声明和初始化
1)数组的声明

在C语言中,数组的声明方式如下:

type arrayName[arraySize];
  • type:数组中元素的数据类型
  • arrayName:数组的名字
  • arraySize:数组的大小(即数组中可以存储的元素个数)

例如,声明一个包含5个LED端口的数组:

GPIO_TypeDef* LED_PortLists[5];

声明一个包含5个LED引脚的数组

uint16_t LED_PinLists[5];
2)数组的初始化

数组可以在声明的同时进行初始化:

GPIO_TypeDef* LED_PortLists[5] = 
{
	GPIOA,
	GPIOA,
	GPIOA,
	GPIOA,
	GPIOA,
};

uint16_t LED_PinLists[5] = 
{
	GPIO_Pin_10,						 
	GPIO_Pin_11,						 
	GPIO_Pin_12,						 
	GPIO_Pin_13,						 
	GPIO_Pin_14,						 
};


也可通过索引进行初始化,[index]中index为索引值。如:

GPIO_TypeDef* LED_PortLists[5] = 
{
	[0]				= GPIOA,							 
	[1]				= GPIOA,							 
	[2]				= GPIOA,							 
	[3]				= GPIOA,							 
	[4]				= GPIOA,							 
};

uint16_t LED_PinLists[5] = 
{
	[LED_DEBUG]				= GPIO_Pin_10,						 
	[LED_FUN]				= GPIO_Pin_11,						 
	[LED_RUN]				= GPIO_Pin_12,						 
	[LED_TEMPEATATURE]		= GPIO_Pin_13,						 
	[LED_FAULT]				= GPIO_Pin_14,						 
};

如果初始化的元素个数少于数组大小,未初始化的元素会被自动赋值为0:

GPIO_TypeDef* LED_PortLists[5] = {0}; // 等价于 {0, 0, 0, 0, 0}

也可以省略数组大小,让编译器自动计算:

GPIO_TypeDef* LED_PortLists[] = {GPIOA, GPIOA, GPIOA, GPIOA, GPIOA}; 	// 数组大小自动为5
2 数组元素的访问

数组元素可以通过索引访问,索引从0开始:

 
uint16_t LED_DEBUG_PIN = LED_PinLists[0];		//访问第一个元素
uint16_t LED_FUN_PIN = LED_PinLists[1];			//访问第一个元素

可以通过索引修改数组元素的值:

LED_PinLists[0] = GPIO_Pin_9; // 将第一个元素的值修改为GPIO_Pin_9

在没有引用数组类型前,我们前面是这样来操作LED灯的。

void LED_DebugSetOn(void) 
{
	GPIO_ResetBits(LED_DEBUG_PORT , LED_DEBUG_PIN);			// 关闭
}

void LED_DebugSetOff(void) 
{
	GPIO_ResetBits(LED_DEBUG_PORT , LED_DEBUG_PIN);			// 关闭
}

void LED_DebugSet(bool value) 
{
	if(value == false)
	{
		GPIO_ResetBits(LED_DEBUG_PORT , LED_DEBUG_PIN);			// 关闭
	}	
	else
	{
		GPIO_SetBits(LED_DEBUG_PORT, LED_DEBUG_PIN);			// 点亮
	}	
}

void LED_Set(LED_t led,bool value)
{
	 switch (led)
	 {
		 case LED_DEBUG:
			
			LED_DebugSet(value);
			break;
		 
		 default:
			 break;
	 }
}

在引用了数组类型后,代码就变成了这样:

void LED_Set(LED_t led,bool value)
{
	if(value == false)
	{
		GPIO_ResetBits(LED_PortLists[led] , LED_PinLists[led] );		// 关闭
	}	
	else
	{
		GPIO_SetBits(LED_PortLists[led] , LED_PinLists[led]);			// 点亮
	}	
}
 

3 二维数组

二维数组类似于矩阵,可以用两个索引来访问元素。声明方式如下:

type arrayName[rows][columns];
  • type:数组中元素的数据类型
  • arrayName:数组的名字
  • rows:数组中行数的大小
  • columns:数组中列数的大小

例如,声明一个2行3列的二维数组:

uint16_t LED_PinMatrixs[2][3];

二维数组的初始化:

uint16_t LED_PinMatrixs[2][3] = 
{
    {GPIO_Pin_1, GPIO_Pin_2, GPIO_Pin_3},
    {GPIO_Pin_4, GPIO_Pin_5, GPIO_Pin_6},
};

可以通过两个索引访问二维数组的元素:

uint16_t LED_PinValue = LED_PinMatrixs[1][2]; 	// 访问第一行第二列的元素,GPIO_Pin_2
LED_PinMatrixs[0][0] = GPIO_Pin_0; 			// 修改第一行第一列的元素
4 常见数组操作
1) 数组遍历

通过循环遍历数组的每个元素:

for (int i = 0; i < LED_NUM; i++) 
{
    LED_Set((LED_t)i,true);				//LED灯全亮
}
2) 查找元素

遍历数组,查找特定元素的位置:

uint16_t LED_PinValue = GPIO_Pin_3;
int index = -1;
for (int i = 0; i < LED_NUM; i++) 
{
    if (LED_PinLists[i] == LED_PinValue) 
    {
        index = i;
        break;
    }
}
if (index != -1) 
{
    printf("元素 %d 在数组中的位置是 %d\n", target, index);
} 
else
{
    printf("数组中没有找到元素 %d\n", target);
}
3) 元素移位

通过循环将数组中的元素依次向前移一位

uint16_t LED_PinValue = LED_PinLists[LED_NUM - 1];

for(int i = LED_NUM - 1;i > 0;i--)
{
    LED_PinLists[i]=LED_PinLists[i-1];
}
LED_PinLists[0] = LED_PinValue;
4) 二维数组转换为一维数组
int rows = 2;
int columns = 3;

uint16_t LED_PinMatrixs[2][3] = 
{
    {GPIO_Pin_1, GPIO_Pin_2, GPIO_Pin_3},
    {GPIO_Pin_4, GPIO_Pin_5, GPIO_Pin_6},
};

uint16_t LED_PinList[rows * columns];
for (int i = 0; i < rows; i++) 
{
    for (int j = 0; j < columns; j++) 
	{
        LED_PinList[i * columns + j] = LED_PinMatrixs[i][j];
    }
}
5 数组名的本质

数组名的本质是指向该数组第一个元素的指针,关于指针,我们后面再讨论

6 使用数组的注意事项

1)在通过数组索引访问数组元素时,一定要注意数组的边界,即索引大小应小于数组元素的大小,5个数组元素,其索引值最大为4。

2)数组索引值从0开始计算。索引值应大于等于0,且小于数组元素的大小。


网站公告

今日签到

点亮在社区的每一天
去签到