• 对定义局部变量位置的思考


        C89规定,在任何执行语句之前,在块的开头声明所有局部变量。在C99以及C++中则没有这个限制,即在首次使用之前,可在块的任何位置都可以声明变量。另一方面,编译器不同也不同,gcc编译器有很多扩展的功能,可完美支持C99标准。

        所以在gcc编译下局部变量并不是一定要定义在代码块的开始位置,可以如下进行定义。

    1. #include <stdio.h>
    2. void test(void *arg)
    3. {
    4. printf("ssssss ");
    5. }
    6. int main(int argc, char *argv[])
    7. {
    8. char tmp[32]="ssssss ";
    9. test(tmp);
    10. printf("zhang ");
    11. int c = 0;//
    12. printf("zhangcf ");
    13. {
    14. int dd = 5;//代码块中
    15. int c=20;
    16. }
    17. int ss = 6;
    18. return 0;
    19. }

        今天经过实践发现,其实在代码块中定义的局部变量除非不可避免,否则尽量不要使用这种方式,原因如下:

    在代码执行到main中的时候dd和c的内存空间是没有进行分配的,之后当进入到第17行才会进行分配。所以在执行第17行的时候会对栈进行一次操作,如果,这个代码块是在一个循环中的话,对栈的操作就更加频繁了。虽说不会严重影响性能,但是能快一分是一分嘛。

        使用gdb调试的 info locals命令可以清楚的看到这个现象。

    就使用上面的例子来看,在main入口处打一个断点,然后可以看到如下的现象


        可以看到这个函数块中的所有变量的内存都已经在栈内存里分配出来了,但是并没有进行赋值,应该是执行到具体的代码位置时才进行具体数值的赋值操作。现在要注意16行到19行的dd和c的两个变量是没有任何显示的。

        当程序运行到17行的时候再看一下当前所有局部变量的信息如下:


       可以找到代码块中dd和c了。因为局部变量肯定是在栈中分配内存,所有这个过程就涉及到了栈内存与变量的映射关系,其实就是对栈进行了操作。



  • 相关阅读:
    Spring注解@Component、@Repository、@Service、@Controller @Resource、@Autowired、@Qualifier 解析
    Oracle Instant Client 安装配置
    Android Studio配置文件路径修改
    Java压缩技术(三) ZIP解压缩——Java原生实现
    Java压缩技术(二) ZIP压缩——Java原生实现
    Java压缩技术(一) ZLib
    [JavaEE] JBoss主要版本下载链接一览
    EL表达式
    如何实现hibernate的缓存机制
    如何理解hibernate当中的锁机制
  • 原文地址:https://www.cnblogs.com/cfzhang/p/c6511ffccd228b1aabc0f68b2e0811cd.html
Copyright © 2020-2023  润新知