通过指针访问数组元素?

时间:2020-07-13 09:33:37

标签: arrays c pointers

再次[]*

void func(const instance* I, const float* in, float* out)
{
    for(int i=0;i<N; i++)
    {
        // some calculation goes here
        out[i] = ... in[i] * I.something[i] ... ;
    }
}

我经常发现子函数代码的编写方式不是用[]引用数组,而是引入了额外的指针,例如:

void func(const instance* I, const float* in, float* out)
{
    const float* inp = in;
    float* outp = out;
    float* s = I->something;

    for(int i=0;i<N; i++)
    {
        // some calculation goes here
        outp++ = ... inp++ * s++ ... ;
    }
}

这样做的主要原因是:可读性,性能或其他?它对性能有影响吗?

1 个答案:

答案 0 :(得分:2)

这样做的主要原因是什么: 可读性,性能还是其他? 它对性能有影响吗?

  1. 通常,如果我们想保留原始参数以供以后在函数中使用,我们会引入新的变量。

示例:

char *mystrcpy(char *dest, const char *src)
{
    char *workdest = dest;   // temp variable to be used instead of dest.
    while((*workdest++ = *src++));
    return dest;
}
  1. 如果使用优化的编译器(并启用优化),通常对性能没有任何影响

  2. 引入新的(理论上不需要的变量)可能有助于将复杂的逻辑拆分为更易于维护的较小部分。通常,它也不会对性能产生任何影响,因为编译器通常会很好地对其进行优化。

  3. 索引和指针算术具有相同的性能,并且在大多数情况下,生成的代码是相同的。

示例:

int *reverse(int *arr, size_t size)
{
    int *end, *saved = arr;
    if(arr && size > 1)
    {
        end = arr + size - 1;
        while(end > arr)
        {
            int tmp = *arr;
            *arr++ = *end;
            *end-- = tmp;
        }
    }
    return saved;
}

int *reverse1(int *arr, size_t num)
{
    if(arr && num > 1)
    {
        for(size_t i = 0; i < num/2; i++) 
        {
            int  temp;
            temp=arr[i];
            arr[i] = arr[num-(i+1)];
            arr[num-(i+1)]=temp;
        }
    }
    return arr;
}

及其结果代码:

reverse:
        mov     r8, rdi
        test    rdi, rdi
        je      .L2
        cmp     rsi, 1
        jbe     .L2
        lea     rax, [rdi-4+rsi*4]
        cmp     rdi, rax
        jnb     .L2
        mov     rdx, rdi
.L3:
        mov     ecx, DWORD PTR [rdx]
        mov     esi, DWORD PTR [rax]
        add     rdx, 4
        sub     rax, 4
        mov     DWORD PTR [rdx-4], esi
        mov     DWORD PTR [rax+4], ecx
        cmp     rdx, rax
        jb      .L3
.L2:
        mov     rax, r8
        ret
reverse1:
        mov     r8, rdi
        test    rdi, rdi
        je      .L18
        cmp     rsi, 1
        jbe     .L18
        lea     rdx, [rdi-4+rsi*4]
        shr     rsi
        mov     rax, rdi
        lea     rdi, [rdi+rsi*4]
.L15:
        mov     esi, DWORD PTR [rdx]
        mov     ecx, DWORD PTR [rax]
        add     rax, 4
        sub     rdx, 4
        mov     DWORD PTR [rax-4], esi
        mov     DWORD PTR [rdx+4], ecx
        cmp     rax, rdi
        jne     .L15
.L18:
        mov     rax, r8
        ret

https://godbolt.org/z/qTG59h