C语言数组操作和指针操作谁更高效

1. 数组和指针操作对比

#include <stdio.h>

int main()
{
        char *char_p, char_arr[5]={0,1,2};
        short *short_p, short_arr[5]={1,2,3};
        int *int_p, int_arr[5]={2,3,4};

        char_p=char_arr;
        short_p=short_arr;
        int_p=int_arr;

        printf("111\n");
        (*(char_p+2)) ++;
        printf("222\n");
        char_arr[2] ++;

        printf("111\n");
        (*(short_p+2)) ++;
        printf("222\n");
        short_arr[2] ++;

        printf("111\n");
        (*(int_p+2)) ++;
        printf("222\n");
        int_arr[2] ++;

        return 0;
}

横向对比:

这里可以很明显得出结论: 使用数组操作比指针高效!, 理由很简单, 编译器认为数组偏移多少成员其对于地址都是确定的, 取数组[0]和[3]没有区别就是个地址, 而指针偏移是一个独立行为,

所以要显性执行这个动作, 因此多出这部分指令!

  这个表还有其他有意思的地方, 比如用int变量比char、short高效, char要and或者movzbl屏蔽溢出, short要lsl/lsr左移右移等

  另外就是x86可以直接通过mov操作内存, 而ARM结构采用load-store, 必须先加载到寄存器, 进行操作后再回写内存

 2. 指针作为函数参数(x86编译为例)

复制代码

#include <stdio.h>

void test1(int *p)
{
    (*(p+4))++;
}

void test2(int *p)
{
    p[4]++;
}

int main()
{
    char *char_p, char_arr[5]={0,1,2};
    short *short_p, short_arr[5]={1,2,3};
    int *int_p, int_arr[5]={2,3,4};

    char_p=char_arr;
    short_p=short_arr;
    int_p=int_arr;

    /* 省略上面测试代码*/

    printf("333\n");
    test1(int_p);
    test2(int_p);
    printf("444\n");
    test1(int_arr);
    test2(int_arr);

    return 0;
}

复制代码

可以发现test1()、test2()反汇编实现是一样的, 不会因为“形式”上我用数组还是指针, 最终的本质是指针, 而调用无论传的是数组地址还是指针地址, 没有影响, 都是地址值而已

 3. 数组作为函数参数(x86编译为例)

复制代码

代码和上面一样就不贴了, 只是将参数改成数组
/*
void test1(int *p)
{
    (*(p+4))++;
}

void test2(int *p)
{
    p[4]++;
}
*/
void test1(int p[])
{
    (*(p+4))++;
}

void test2(int p[])
{
    p[4]++;
}

复制代码

 反汇编的结果发现和上面函数形参是指针的一模一样!  也就是说虽然我的参数看起来像数组, 但实际上由于没有指定成员数量实际分配内存, 所以编译器还是把参数当做指针对待!

 结论:

  a. “真实”数组操作比指针高效

  b. 有些看起来像数组, 实质是指针的, 指令走的还是指针那一套, 无论语法写的是*p++还是p[i]

发布了138 篇原创文章 · 获赞 80 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/u012308586/article/details/105536150