如何旋转数组,以便无论我指向哪个索引,我总能得到最后两个元素? 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 时对 STM32DMA 数组取差。 DMA 数组中的前两个值包含一个 timercounter 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.

之前

请注意,运行 以上代码的输出与您的不匹配,因为您的代码没有表现出您所描述的行为。