C语言开发里指针到底快还是不快?(底层汇编解释)

C语言开发里指针到底快还是不快?

答:不快,甚至比一般变量要慢!

近日我能看到网上很多人说指针快,我非常纳闷,因为我在学习汇编和cpu底层架构时去翻译过c语言的一些指针代码,给我的答案是:指针从来不快于变量,它比普通变量调用慢一拍。

同时为了验证我是正确的,我去找了许多资料,c语言之父:丹尼斯·里奇也没有说过指针快于普通变量,人家只是说指针更灵活,更便捷。

今天看到很多人在说指针快于普通变量这一点,我感到这样非常误人子弟,说这些话的人可能自己都没有去研究过指针,对指针的理解不是很透彻。

很多人说指针就是地址,这是错误的,首先指针存在于栈中,它自己本身就是变量!指针本身就是一个变量,它跟别的变量的区别在于别的变量是表示值,它是表示地址,编译器在对它进行翻译时会多一层解引用的步骤,也就是这个步骤,注定让它会比别的变量更慢。

这里来说一下变量与指针取值的时候的区别:

1.普通变量

获取变量栈地址->到内存里将值取出

2.指针

获取指针变量栈地址->到内存里将指针变量指向的地址取出->到取出的地址里去将值取出

显而易见,指针很明显更慢!

那些说指针更快的我不清楚为什么这样说,但是有一点,当在c++里,你的类参数是指针或引用时,传递参数不会发生构造函数的深拷贝,这一点的确比普通类更快。

但是在c语言里,这是不可能的!

这里我给大家贴出我在linux环境下使用GCC编译出的代码,代码分别是对变量取值与对指针取值:

如,如下代码:

我们使用GCC翻译成汇编:

gcc -S _test.c -o _test.s

在使用cat命令查看一下:

cat _test.s

有许多gcc自动生成的一些初始化的汇编代码,这里我们先跳过,这里我把与main函数里对应的汇编代码提取出来并加上注释:

        //分配4字节的栈空间,并初始化为0
        movl    $0, -4(%rbp)
        //这里就是取变量a的值了
        //将变量a的地址放入eax寄存器,相当于传值给printf
        movl    -4(%rbp), %eax
        //调用printf
        call    printf@PLT

在看看指针的

汇编:

这里我在取出一些相关的汇编

        //分配变量a,初始化为0
        movl    $0, -12(%rbp)
        //将变量a的地址放入rax中
        leaq    -12(%rbp), %rax
        //将rax放入存入指针p中
        movq    %rax, -8(%rbp)
        /*
            这里就是取指针p的值了
        */
        //将指针p指向的地址放入rax中
        movq    -8(%rbp), %rax
        //在将rax中的地址值取到eax中
        movl    (%rax), %eax
        //调用printf
        call    printf@PLT

这里可以看到,指针确实是多了一个步骤,先将指针指向的地址放入到rax地址中,在将rax地址里的值取出到eax寄存器里供printf作为参数

而普通变量则直接取值

注意上面是at&t汇编,由gcc编译而成,与asm汇编不同。

这样看会更仔细

普通变量:

  movl    -4(%rbp), %eax
  call    printf@PLT

指针

 movq    -8(%rbp), %rax
 movl    (%rax), %eax
 call    printf@PLT

 

指针会更加灵活,同时指针可以指向堆区,用于处理更大的内存。

但是从来没有说指针更快这一说法,只有更灵活,可以指向任意地址

最初开发指针的目的,就是为了能够在单片机中操作任意地址,而不是加快普通变量的访问

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

17岁boy想当攻城狮

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值