• 【转】变量的声明和定义,从C到编译原理到C++,再到Java


    基础学了太久,时间一长有些东西就可能记得不太清楚,俗话说得好,"好记性不如烂笔头",所以把基础中的基础-变量的声明和定义,从C到编译原理到C++,再到Java用烂笔头记录下来

        最早在编程语言中认识声明和定义是在学C语言的时候...

        C语言中:如extern User user;extern int a;就是声明,变量的声明就是仅仅告诉编译器,声明的变量的存在,要预留一点空间,但并不为其分配内存.定义就是声明这个变量并真正在内存(堆或栈中)为此变量分配空间.

        从编译原理上来说,声明就是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存.而定义就是不仅知道某类型的变量会被使用,并且已经为其分配了内存.

         因为 在编译的时候,编译器先处理一些特殊数据(宏定义,函数的声明,变量的声明),在这个过程中,编译器 通过声明 可以预测整个定义需要的内存大小,并且 把这些大小预留起来,留给定义的时候使用(因为虽然定义,但是在 main函数里面没有调用,一样的不分配内存)。   如果不事先声明,直接定义,有可能会造成系统崩溃,出现内存不足,不能分配。 然而现在内存都是1G左右了,所以一般空间都足够,所以你也可以不声明直接定义函数。     但是一旦内存紧张,就会出错,而且程序简洁性就很低。(不看到定义,还不知道原来还定义了这么一个函数!!!)

        在C++中,如short a;int b;这些是定义,也就是说在栈上分配了内存,而对于对象,比如自定义的类:User user;也就是说在栈上分配了引用或句柄,没有具体分配对象的内存,而User *puser就需要puser=new User(),才会真正为对象在堆上分配空间.

        在C和C++中,extern User user就是声明,并没有分配内存空间

        在Java中,如果在方法中的局部变量,如使用short a;int b;也只是声明,因为没有初始化时,要想使用这个变量时编译器要会求初始化这个变量,如果不使用这个变量,那单是声明这个变量是没有问题的,如果要使用的 话就要初始化这个变量,即是要给这个变量分配内存并赋值,也就是定义.如果在类中声明一个成员变量,如short a;int b; 在方法中要使用这两个变量时,编译器没有要求初始化这变量,因为当系统加载类或创建该类的实例时,系统自动为成员变量分配内存空间,并在分配内存空间后, 自动为成员变量指定初始值,所以,a 和b的值都会被初始化为0.而这个0是在堆内存中的

        

        下面我们来看看Java中局部变量的初始化和在内存中的运行机制:局部变量声明后,必须经过显式初始化后才能使用,系统不会为局部变量执行初始化,这意味着声明局部变量后,系统并未为这个变量分配内存空间,只是在栈中分配了一个内存保存这个变量名,并没有为变量的值分配内存.直到等到程序为这个变量赋初始值时,系统才会为这个局部变量分配内存,并将初始化值保存到这块内存中.

        与成员变量不同,局部变量不属于任何类或实例,因此它总是保存在其所在方法的栈内存中的.如果局部变量是基本类型的变量,则直接把这个变量的值保 存在该变量对应内存中;如果局部变量是一个引用类型的变量,这个变量里存放的是地址,通过该地址引用到该变量实际引用的对象或数组.因为局部变量只保存基 本类型的值或者对象的引用,所以局部变量所占的内存区通常比较小.

       

        如果有误,请斧正!

  • 相关阅读:
    Android 创建Library Project(库项目)与引用操作
    Android插件化(二):使用DexClassLoader动态载入assets中的apk
    洛谷P3388 【模板】割点(割顶)(tarjan求割点)
    BZOJ 1179: [Apio2009]Atm(tarjan+SPFA)
    洛谷P1067 多项式输出(模拟)
    洛谷P2118 比例简化(暴力)
    BZOJ 3714: [PA2014]Kuglarz(最小生成树)
    BZOJ 4289: PA2012 Tax(最短路)
    BZOJ 4152: [AMPPZ2014]The Captain(最短路)
    洛谷P2939 [USACO09FEB]改造路Revamping Trails(最短路)
  • 原文地址:https://www.cnblogs.com/dirgo/p/4896048.html
Copyright © 2020-2023  润新知