如何旋转数组,以便无论我指向哪个索引,我总能得到最后两个元素? C代码
How to rotate an array so I always got the last two elements, no matter what index I'm pointing at? C code
如果我说我正在计算需要插入多少个值才能完全填充数组,我如何才能找到数组中前两个值之间的差异?假设我们有一个包含 5
个元素的数组。如果我指定索引 0
,那么我需要取 index 4 - index 3
,因为它们是前两个元素。如果我指定索引1
,那么我需要取index 0 - index 4
。如果我指定索引4
,那么我需要再次取index 4 - index 3
。
我已经为此编写了 C 代码,我的问题是...是否有更好的方法来最小化此 C 代码?
#include <stdio.h>
#include <stdint.h>
#define LEN 10
uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};
int main()
{
for(int i = LEN; i >= 0; i--){
int i0, i1;
int left = i;
if(LEN == left){
i0 = LEN - 2;
i1 = LEN - 1;
}else if(0 == left){
i0 = LEN - 2;
i1 = LEN - 1;
}else if(1 == LEN - left){
i0 = LEN - 1;
i1 = 0;
}else{
i0 = LEN - left - 2;
i1 = LEN - left - 1;
}
printf("i0 = %i, i1 = %i. Difference = %i\n", i0, i1, myArray[i1] - myArray[i0]);
}
return 0;
}
模拟:https://onlinegdb.com/QuIt-vRLR
输出:
i0 = 8, i1 = 9. Difference = 6
i0 = 9, i1 = 0. Difference = -2
i0 = 0, i1 = 1. Difference = -3
i0 = 1, i1 = 2. Difference = 5
i0 = 2, i1 = 3. Difference = 2
i0 = 3, i1 = 4. Difference = -5
i0 = 4, i1 = 5. Difference = 1
i0 = 5, i1 = 6. Difference = 2
i0 = 6, i1 = 7. Difference = 2
i0 = 7, i1 = 8. Difference = -8
i0 = 8, i1 = 9. Difference = 6
我问的原因是因为我想在使用 Input Capture
时对 STM32
的 DMA
数组取差。 DMA
数组中的前两个值包含一个 timer
的 counter periods
,我想要它们之间的差异。
举例说明我现在的表现。但由于索引错误,它对我来说效果不佳。
#define LENGTH_ARRAY 5
static uint16_t input_capture0[LENGTH_ARRAY] = {0};
static uint16_t input_capture1[LENGTH_ARRAY] = {0};
static TIM_HandleTypeDef* handler_tim17;
static TIM_HandleTypeDef* handler_tim16;
void STM32_PLC_Input_Capture(TIM_HandleTypeDef* htim17, TIM_HandleTypeDef* htim16) {
/*
* Input capture for measuring frequency
* For TIM17 and TIM16
* Timer clock: 48 Mhz
* Prescaler: 4799
* Counter: 65535 (0xffff)
* Update frequency: 0.1526 Hz (1/0.1526 = 6.5535 seconds)
* Example: For every second, it will count 10000
* Lowest frequency measurement: 1/(0xFFFF*0.0001) = 0.1526 Hz
* Highest frequency measurement: 1/(1*0.0001) = 10000 Hz
*/
if(HAL_TIM_IC_Start_DMA(htim16, TIM_CHANNEL_1, (uint32_t*)input_capture1, LENGTH_ARRAY) != HAL_OK)
Error_Handler();
if(HAL_TIM_IC_Start_DMA(htim17, TIM_CHANNEL_1, (uint32_t*)input_capture0, LENGTH_ARRAY) != HAL_OK)
Error_Handler();
/* Save */
handler_tim17 = htim17;
handler_tim16 = htim16;
}
static uint16_t compute_period(uint16_t input_capture[], uint8_t elements_left_to_write_in_array) {
uint8_t index0, index1;
switch(elements_left_to_write_in_array){
case 5:
/* When the whole array has been filled by DMA and we stand at index 0, then we need to use the 2 past indexes */
index0 = 3;
index1 = 4;
case 4:
index0 = 4;
index1 = 0;
case 3:
index0 = 0;
index1 = 1;
case 2:
index0 = 1;
index1 = 2;
case 1:
index0 = 2;
index1 = 3;
default:
index0 = 0;
index1 = 1;
break;
}
return input_capture[index1] - input_capture[index0];
}
uint16_t STM32_PLC_Input_Capture_Get_Raw(uint8_t i){
if(i == 0)
return compute_period((uint16_t*)input_capture0, (uint8_t)handler_tim17->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
else
return compute_period((uint16_t*)input_capture1, (uint8_t)handler_tim16->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
}
myArray
是一个循环数组。你想要包装索引,这是我们可以使用 %
operator:
获得的行为
#include <stdio.h>
#include <stdint.h>
#define LEN 10
uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};
int main()
{
for(int i = LEN; i >= 0; i--){
int i0 = ((i + LEN) - 2) % LEN;
int i1 = ((i + LEN) - 1) % LEN;
printf("i0 = %i, i1 = %i, i = %i Difference = %i\n",
i0, i1, i, myArray[i1] - myArray[i0]);
}
return 0;
}
输出
i0 = 8, i1 = 9, i = 10 Difference = 6
i0 = 7, i1 = 8, i = 9 Difference = -8
i0 = 6, i1 = 7, i = 8 Difference = 2
i0 = 5, i1 = 6, i = 7 Difference = 2
i0 = 4, i1 = 5, i = 6 Difference = 1
i0 = 3, i1 = 4, i = 5 Difference = -5
i0 = 2, i1 = 3, i = 4 Difference = 2
i0 = 1, i1 = 2, i = 3 Difference = 5
i0 = 0, i1 = 1, i = 2 Difference = -3
i0 = 9, i1 = 0, i = 1 Difference = -2
i0 = 8, i1 = 9, i = 0 Difference = 6
如您所见,i
始终在 i1
之前,而 i1
本身又在 i0
.
之前
请注意,运行 以上代码的输出与您的不匹配,因为您的代码没有表现出您所描述的行为。
如果我说我正在计算需要插入多少个值才能完全填充数组,我如何才能找到数组中前两个值之间的差异?假设我们有一个包含 5
个元素的数组。如果我指定索引 0
,那么我需要取 index 4 - index 3
,因为它们是前两个元素。如果我指定索引1
,那么我需要取index 0 - index 4
。如果我指定索引4
,那么我需要再次取index 4 - index 3
。
我已经为此编写了 C 代码,我的问题是...是否有更好的方法来最小化此 C 代码?
#include <stdio.h>
#include <stdint.h>
#define LEN 10
uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};
int main()
{
for(int i = LEN; i >= 0; i--){
int i0, i1;
int left = i;
if(LEN == left){
i0 = LEN - 2;
i1 = LEN - 1;
}else if(0 == left){
i0 = LEN - 2;
i1 = LEN - 1;
}else if(1 == LEN - left){
i0 = LEN - 1;
i1 = 0;
}else{
i0 = LEN - left - 2;
i1 = LEN - left - 1;
}
printf("i0 = %i, i1 = %i. Difference = %i\n", i0, i1, myArray[i1] - myArray[i0]);
}
return 0;
}
模拟:https://onlinegdb.com/QuIt-vRLR
输出:
i0 = 8, i1 = 9. Difference = 6
i0 = 9, i1 = 0. Difference = -2
i0 = 0, i1 = 1. Difference = -3
i0 = 1, i1 = 2. Difference = 5
i0 = 2, i1 = 3. Difference = 2
i0 = 3, i1 = 4. Difference = -5
i0 = 4, i1 = 5. Difference = 1
i0 = 5, i1 = 6. Difference = 2
i0 = 6, i1 = 7. Difference = 2
i0 = 7, i1 = 8. Difference = -8
i0 = 8, i1 = 9. Difference = 6
我问的原因是因为我想在使用 Input Capture
时对 STM32
的 DMA
数组取差。 DMA
数组中的前两个值包含一个 timer
的 counter periods
,我想要它们之间的差异。
举例说明我现在的表现。但由于索引错误,它对我来说效果不佳。
#define LENGTH_ARRAY 5
static uint16_t input_capture0[LENGTH_ARRAY] = {0};
static uint16_t input_capture1[LENGTH_ARRAY] = {0};
static TIM_HandleTypeDef* handler_tim17;
static TIM_HandleTypeDef* handler_tim16;
void STM32_PLC_Input_Capture(TIM_HandleTypeDef* htim17, TIM_HandleTypeDef* htim16) {
/*
* Input capture for measuring frequency
* For TIM17 and TIM16
* Timer clock: 48 Mhz
* Prescaler: 4799
* Counter: 65535 (0xffff)
* Update frequency: 0.1526 Hz (1/0.1526 = 6.5535 seconds)
* Example: For every second, it will count 10000
* Lowest frequency measurement: 1/(0xFFFF*0.0001) = 0.1526 Hz
* Highest frequency measurement: 1/(1*0.0001) = 10000 Hz
*/
if(HAL_TIM_IC_Start_DMA(htim16, TIM_CHANNEL_1, (uint32_t*)input_capture1, LENGTH_ARRAY) != HAL_OK)
Error_Handler();
if(HAL_TIM_IC_Start_DMA(htim17, TIM_CHANNEL_1, (uint32_t*)input_capture0, LENGTH_ARRAY) != HAL_OK)
Error_Handler();
/* Save */
handler_tim17 = htim17;
handler_tim16 = htim16;
}
static uint16_t compute_period(uint16_t input_capture[], uint8_t elements_left_to_write_in_array) {
uint8_t index0, index1;
switch(elements_left_to_write_in_array){
case 5:
/* When the whole array has been filled by DMA and we stand at index 0, then we need to use the 2 past indexes */
index0 = 3;
index1 = 4;
case 4:
index0 = 4;
index1 = 0;
case 3:
index0 = 0;
index1 = 1;
case 2:
index0 = 1;
index1 = 2;
case 1:
index0 = 2;
index1 = 3;
default:
index0 = 0;
index1 = 1;
break;
}
return input_capture[index1] - input_capture[index0];
}
uint16_t STM32_PLC_Input_Capture_Get_Raw(uint8_t i){
if(i == 0)
return compute_period((uint16_t*)input_capture0, (uint8_t)handler_tim17->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
else
return compute_period((uint16_t*)input_capture1, (uint8_t)handler_tim16->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
}
myArray
是一个循环数组。你想要包装索引,这是我们可以使用 %
operator:
#include <stdio.h>
#include <stdint.h>
#define LEN 10
uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};
int main()
{
for(int i = LEN; i >= 0; i--){
int i0 = ((i + LEN) - 2) % LEN;
int i1 = ((i + LEN) - 1) % LEN;
printf("i0 = %i, i1 = %i, i = %i Difference = %i\n",
i0, i1, i, myArray[i1] - myArray[i0]);
}
return 0;
}
输出
i0 = 8, i1 = 9, i = 10 Difference = 6
i0 = 7, i1 = 8, i = 9 Difference = -8
i0 = 6, i1 = 7, i = 8 Difference = 2
i0 = 5, i1 = 6, i = 7 Difference = 2
i0 = 4, i1 = 5, i = 6 Difference = 1
i0 = 3, i1 = 4, i = 5 Difference = -5
i0 = 2, i1 = 3, i = 4 Difference = 2
i0 = 1, i1 = 2, i = 3 Difference = 5
i0 = 0, i1 = 1, i = 2 Difference = -3
i0 = 9, i1 = 0, i = 1 Difference = -2
i0 = 8, i1 = 9, i = 0 Difference = 6
如您所见,i
始终在 i1
之前,而 i1
本身又在 i0
.
请注意,运行 以上代码的输出与您的不匹配,因为您的代码没有表现出您所描述的行为。