如何动态申请python 全局变量量

动态或静态的的全局变量问题_百度知道
动态或静态的的全局变量问题
而静态全局变量的作用域是定义了该变量的源文件,动态全局变量作用域是整个源程序,那么如果多个文件使用了static修饰了同名变量,还是定义的同时赋值?(因为我看到有程序将定义好的变量赋值叫初始化?还有怎样才算是变量的初始化呢在网上看到全局变量分动态和静态?定义在源文件函数体制外的变量算什么呢,难道就因为是第一次赋值所以叫初始化?用了extern声明了的不就是动态全局变量吗,那么怎样才算是动态全局变量呢?先定义后赋值,还说明?为什么作用域只限定在存在全局变量梁声明的源文件当中使用,在全局变量定义之前冠以static即为静态全局变量。对于动态的全局变量,那么他们是不是共用一个变量
提问者采纳
但是这时不可用因为没有初始化(这时x的值是不可预料的);%d&quot,你申请了一个变量(分配内存);,就是不能直接定义然后直接就使用(例如in x,相当于源文件隐藏这个静态全局变量(只自己能看见)。所以你后面使用时赋值也是可以的;),并不是共用一个变量,也就是该源文件是独享自己的静态全局变量的;(我们一般都习惯初始化为零;不然B模块你再用直接int a。但是全局变量因为没有static,作用域范围内使用完了就释放内存(不断申请内存而不释放内存是很恐怖的,局部变量都有自己的作用域呀,毕竟内存有限),楼主去看看static在变量前和函数前的作用吧?)没懂,所以不影响的。)
本人也是菜鸟,B文件就不能声明同名的全局变量。文件之间互不能看到对方的静态全局变量;会报错(认为你再次声明同名了);B模块要使用就用extern int a。你自己说了(静态全局变量的作用域是定义了该变量的源文件)。你也可以定义的同时直接初始化。这句(为什么作用域只限定在存在全局变量声明的源文件当中使用,即例如A文件声明了一个全局变量,所以其他文件也是可以看见的,作用域就是使用范围,x),反正后面使用时会给x赋值。extern的作用你也应该去了解下,个人认为不为零没什么关系,例如你在A模块声明了全局变量int a多个文件使用了static修饰的同名变量; printf(&quot。 变量先是声明比如int x,例如int x=0,辛苦这么久给点财富值吧
提问者评价
其他类似问题
表示为静态变量,随程序出栈入栈而产生和消失的,全局变量,只要是函数体外的都是全局变量。。
extern声明的是我用的变量,在堆栈中。
自动变量。
我写ARM移植程序,具体怎么用你自己安排。
全局变量都是静态的哪里有动态全局变量,想弄明白这个可以研究计算机原理。。。。。。,啥叫堆栈, 程序使用过程中向系统申请的新存储空间,谁都能用,用于函数体内的变量。这些完成之后才轮到调用main函数。你别看全局变量写的靠前,数据从flash导入内存,所以碰到extern不能申请内存,随程序导入内存,用malloc申请的,生存期和程序代码一样,生存期和程序代码一样。,随程序一起导入内存。。。,也可以没有)。。,非自动变量,编译器在外部文件查找函数时会跳过有static的同名函数和变量,而是连接时从其他文件中找该函数或变量的地址。动态变量就是动态变量,在程序导入内存的时候就导入内存了。
动态变量。,再全局(静态)。
静态变量。,自动变量使用的存储区,是别的文件里的,所以叫动态变量。,也随时可以让系统收回。,相当于自动变量,全局变量都是静态的,只要,步奏就是先代码,再预留内存(这个区没有定义变量。,导入内存所有全局变量都在函数代码的后面,最后是堆栈区。,static只是声明该函数或变量为内部的。
为您推荐:
其他1条回答
h文件用#include 包含到一起的算一个文件)编译的时候 external 和 static 才有意义,只有external global object(外部全局对象)只有把一个程序分成多个源文件(多个.c或,多个.cpp文件没有“动态全局变量”之说
那就叫非静态全局变量好了,书上是说非静态全局变量的作用域是整个源程序,如果在a.c中有定义,那么在b.c中就不能再出现相同的定义,但是b.c中如果要使用的话必须用extern声明或static声明,那么非静态变量的作用域为整个源程序算不算是多此一举呢?
写C代码大概不是很容易体现,C++程序员大概都会用到cin和cout,二者都是外部对象
全局变量的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁程序的局部变量全局变量动态申请数据分别存储在什么地方?-中国学网-中国IT综合门户网站
> 程序的局部变量全局变量动态申请数据分别存储在什么地方?
程序的局部变量全局变量动态申请数据分别存储在什么地方?
转载 编辑:李强
为了帮助网友解决“程序的局部变量全局变量动态申请数据分别存”相关的问题,中国学网通过互联网对“程序的局部变量全局变量动态申请数据分别存”相关的解决方案进行了整理,用户详细问题包括:RT,我想知道:程序的局部变量全局变量动态申请数据分别存储在什么地方?,具体解决方案如下:解决方案1: 局部变量-----栈stack全局变量,静态变量-----初始化的存在数据段,未初始化的存在bss段,上电后统一清0,我们一般都说存在全局静态数据区常量----常量数据区动态申请的---堆通过对数据库的索引,我们还为您准备了:答:静态存储方式是指在程序运行期间分配固定的存储空间的方式,动态存储方式是在程序运行期间根据需要进行动态的分配存储空间的方式。 每一个变量均有作用域和存储类别两个属性,这些属性共同用于描述一个变量,这些不同类型的变量与存储位置的关系===========================================答:静态存储方式是指在程序运行期间分配固定的存储空间的方式,动态存储方式是在程序运行期间根据需要进行动态的分配存储空间的方式。 每一个变量均有作用域和存储类别两个属性,这些属性共同用于描述一个变量,这些不同类型的变量与存储位置的关系...===========================================答:局部变量-----栈 stack 全局变量,静态变量-----初始化的存在数据段,未初始化的存在bss段,上电后统一清0,我们一般都说存在全局静态数据区 常量----常量数据区 动态申请的---堆===========================================答:程序的局部变量 全局变量 动态申请数据分别存储在什么地方? 量的类别: 根据作用域可分为全局变量和局部变量。 根据生存周期可分为静态存储方式和动态存储方式,具体地又分为自动的(auto)、静态的(static)、寄存器的(register)、外部的(e...===========================================答:简单来说,静态变量就是一个变量名称前有static标注的 比如说 全局变量等于静态变量,他们的差别你可以简单理解成在作用域上的差别,静态变量是在一个函数中的作用域(主函数就是主函数作用域,局部函数就是局部函数的作用域),...===========================================答:在C语言里面,局部变量,全局变量都是存贮在栈(stack)里面的, 而所有用malloc和new这种操作符动态分配的空间则都是存贮在堆(dump)里面的, 举个简单的例子: int * ptr =(int*)malloc(100*sizeof(int)); 这两句中,ptr这个指针变量是存...===========================================问:看到别人的回答: “所有的程序都是在运行阶段分配内存,所有变量的逻辑...答:局部变量是堆栈 例如 { } 进入{ } 就push a入栈 就有了a这个变量 出了{ } 就pop a出栈 a这个变量就消失了 所有局部变量的生命周期就就在{ }内 全局变量 在程序运行期间一直存在没错,放在数据区 可是具体装在哪个位置是系统为你分配的 而...===========================================问:一道填空题,答案众多,问一问高人答:五大内存分区 在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。 堆,就是那些由n...===========================================问:陈正冲的《C语言深度解剖》中说 局部变量和全局变量都存储在内存的静态...答:全局变量和局部静态变量在内存静态区; 局部变量在栈区。===========================================程序的局部变量 全局变量 动态申请数据分别存储在什么地方? 量的类别: 根据作用域可分为全局变量和局部变量。 根据生存周期可分为静态存储方式和动态存储方式,具体地...===========================================局部变量-----栈 stack 全局变量,静态变量-----初始化的存在数据段,未初始化的存在bss段... 上电后统一清0,我们一般都说存在全局静态数据区 常量----常量数据区 动态申请的---堆===========================================在C语言里面,局部变量,全局变量都是存贮在栈(stack)里面的, 而所有用malloc和new这种操作符动态分配的空间则都是存贮在堆(dump)里面的, 举个简单的例子: int * ptr =...===========================================在C语言里面,局部变量,全局变量都是存贮在栈(stack)里面的, 而所有用malloc和new这种操作符动态分配的空间则都是存贮在堆(dump)里面的, 举个简单的例子: int * ptr =(i...===========================================这个要看你程序运行的吧,你程序用到的时候就分配了。你是不是对这些还根本不懂啊===========================================局部变量仅在一个函数内有效,如果你需要在此函数内使用全局变量,可以使用与全局变量不同名的变量 但是如果是在定义局部变量的函数外,全局变量是不受影响的。=========================================== 根据作用域可分为全局变量和局部变量。 根据生存周期可分为静态存储方式和动态存... 通过这种方式可提升对某些局部变量频繁调用的程序的性能。(寄存器运算速度远高于内...===========================================最好写两个不同的变量若是把全局变量覆盖了,是用不了全局变量的。===========================================静态局部变量始终存在着,也就是说它的生存期为整个源程序。 (2)静态局部变量的生存... ,因此仍以采用局部静态变量为宜。 简单的说静态局部变量与全局变量最明显的区别就...===========================================局部变量是指在函数内部定义的变量,作用域为定义局部变量的函数,也就是说他只能在... 而全局变量则是在整个程序执行的过程中一直有效,除非整个程序退出才会消失. 例子: O...===========================================
本文欢迎转载,转载请注明:转载自中国学网: []
用户还关注
可能有帮助怎么把动态数组变成全局变量?_百度知道
怎么把动态数组变成全局变量?
}我想在别的函数中调用;m在一个函数中声明了一个二维动态数组int **a;for (int i=0;i&a=new int [m],请问怎么办;i++){a[i]=new int[n]
提问者采纳
动态数组int main(){/i&/i++){a[i]=new int[n];动态数组单元分配a=new int [m]; 全局量;m.}。return 0。;。;
for (int i=0;
其他类似问题
为您推荐:
其他4条回答
全局变量也称为外部变量,它是在函数外部定义的变量。 它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。 只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。 但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。 例如:
int a,b; /*外部变量*/
void f1() /*函数f1*/
float x,y; /*外部变量*/
int fz() /*函数fz*/
main() /*主函数*/
}/*全局变量x,y作用域 全局变量a,b作用域*/
从上例可以看出a、b、x、y 都是在函数外部定义的外部变量,都是全局变量。但x,y 定义在函数f1之后,而在f1内又无对x,y的说明,所以它们在f1内无效。 a,b定义在源程序最前面,...
定义为全局变量
楼上那个是VB吧。。。
你可以尝试一下用ArrayList看看行不行.
1.数组的定义与声明
数组的定义语法如下:
Dim 数组名( [[下标下界 To ] 下标上界] ) [As 数据类型]
例如(假设在当前模块中 数组的缺省下界为0)):
① Dim A(10) As Integer
表示数组名为A,此数组下标下界为缺省值0,下标上界为10,有11个Integer类型的元素,从A(0)、A(1)到A(10)。
② Dim B(1 To 20) As Integer
表示数组名为B,此数组下标下界为1,下标上界为20,有20个Integer类型的元素,从B(1)到B(20)。
③Dim DayArray(50)
表示DayArray 是一个有 51 个索引(从 0 到 50)元素的 Variant 数组。
④Dim Matrix(3, 4) As Integer
表示Matrix 是一个二维 Integer 数组。
⑤Dim MyMatrix(1 To 5, 4 To 9, 3 To 5) As Double...
全局变量的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁关于java里面的全局变量的内存分配 - 高级语言虚拟机 - ITeye群组
今天突然想到一些问题,关于java内存分配的问题,基本类型在栈上分配。new出来的对象引用分配在栈上,对象分配在堆上,一直以来都是记住了,从来没仔细思考过,在栈上到底怎么分配,在堆上到底具体怎么分配的。举个例子:
class Test{
private int i=9;
private int j=9;
public static void main(String args[]){
Test t=new Test();
System.out.println(t.i==t.j);//true
System.out.println(t.i==w);//true
}
很明显t的引用在栈上,也就是指针,对象分配在堆上,在程序中我是故意让他们的值都相等,我就是想看他们是怎么分配的。w毫无疑问在栈上。但是对象的属性i,j在哪里分配,通过运行的结果貌似也在栈上,因为栈上有优化。i,j,w都指向了存贮9这个值的地址。我今天看到一句话是这么说的,
 & 1)方法本身是指令的操作码部分,保存在Stack中;
  2)方法内部变量作为指令的操作数部分,跟在指令的操作码之后,保存在Stack中(实际上是简单类型保存在Stack中,对象类型在Stack中保存地址,在Heap 中保存值);上述的指令操作码和指令操作数构成了完整的Java 指令。
  3)对象实例包括其属性值作为数据,保存在数据区Heap 中。
  非静态的对象属性作为对象实例的一部分保存在Heap 中,而对象实例必须通过Stack中保存的地址指针才能访问到。因此能否访问到对象实例以及它的非静态属性值完全取决于能否获得对象实例在Stack中的地址指针。
也就是说数据放在堆上,在此我有疑问,到底怎么分配?
最近项目周期很紧所以暂时回复不了什么,下下周应该能稍微解脱一两天吧,到时候画些图来说明这个。大家有兴趣讨论的请先踊跃发表见解哦~
先简单写几句:
1、一定要留意,JVM规范所规定的“概念中的JVM”与实际的JVM实现是可以有差异的。所以请区分清楚“堆”、“栈”在概念中与实际实现中的不同。我猜多数Java程序员更关心(或者说更有用)的是概念中的JVM的状况,但请千万不要想当然的认为实际上也必须要那样实现。
不过,作为一种现象,我们可以观察到用解释器实现的JVM会比用JIT编译器/混合模式方式实现的JVM要更接近于概念中的JVM。
2、请留意,“地址”、“指针”、“引用”等是不同抽象层次的概念,并不等价。
·引用可以用指针来实现,也可以用handle(一般翻译为“句柄”?总之很怪)来实现;
·指针里可以直接包含地址,也可以包含地址的某种映射关系(例如HotSpot中的compressedOop);
·地址可以是不同意义上的地址,在常见的Linux、Windows等现代操作系统上一般有虚拟内存系统,因而所谓“地址”在这里一般指虚拟内存的地址而不是所谓的“物理内存地址”。“物理内存”是一个经常被滥用、误用的词,也要注意判断。
后面几点没有特别说明的话都是针对概念上的JVM而言的。
3、Java是一种静态与动态类型相结合的强类型语言,表现在:
·Java的变量有类型,值也有类型,而且变量与值的类型并不需要精确一致,只要满足赋值匹配的约束即可;
·Java变量的类型可以是原始类型或引用类型的,其中引用类型又包括类类型、接口类型与数组类型;
·Java值的类型也可以是原始类型或引用类型的,其中引用类型的值包括指向类的实例的引用或者指向数组实例的引用;
·Java的类型系统中,所有与原始类型相关的操作都可以在Java源码编译时完成类型检查,并且在运行时不需要做额外的检查来保证类型安全;而引用类型的相关操作中有部分带有运行时检查的必要,例如强制向下类型转换、对元素为引用类型的数组的元素赋值,等等;
·Java中虚方法的实际调用目标在Java源码编译时无法确定,概念上需要在运行时根据值的实际类型来分派,与上一条提到的动态类型检查一起表现了Java的动态性。
4、原始类型的变量如果是成员变量,那么它的存储空间就正好是其所在对象中的一部分,是在Java堆上的。引用类型的变量……嗯回头有空画图了再详细说。
5、原始类型变量之间的==与!=所做的是相等性比较——值是否相等,而引用类型变量之间的==与!=做的是同一性比较——是否指向同一对象。其实如果可以理解“引用”的本质就是多了一个间接层的话,这个非常好理解,因为引用间的比较实质上也是值比较。这跟“Java中方法调用的参数传递全部是按值传递”底下的道理是一样的。
6、如果把方法的代码看作它的“静态”部分,而把一次方法调用需要记录的临时数据看做它的“动态”部分,那么每个方法的代码是只有一份的,存储于JVM的方法区中;每次某方法被调用,则在该调用所在的线程的的Java栈上新分配一个栈帧,用于存放临时数据,在方法返回时栈帧自动撤销;
7、Java程序中没有全局变量的概念。相似的概念只有“静态变量”。概念上它也是存储在方法区里的。
于是……等我回头画图吧,呵呵 ^_^
这么说吧,应该区分这些东西:
1.JVM的内存组成
JVM是一个进程,它的内存有进程Heap构成。这个进程Heap,又可以分成Java Object Heap和非Java Object Heap。
Java Object Heap,我们知道是放置Java的对象,它是分代的。
而非Java Object Heap,它主要放置:
& a)Permanent Generation,就是永久代
& 在JVM启动时候,可能设置这个东东 -XX:PermSize 和-XX:MaxPermSize
& b)Code Generation
& 用于将字节码转化成Native Code
& c)Socket Buffers
& d)Thread Stacks
& e)Direct Memory Space
& f)JNI Code
& g)Garbage Collection
& h)JNI Allocated Memory
这些解释,我可能会写一篇文章说明吧。
其中Thread Stacks,这就是线程栈,JVM通过main方法启动main thread来做的(在一定程度上Process和Thread区别),那么每个线程都有一定的栈空间大小,可以通过启动参数–Xss来设置大小。自然它是有限的,因此当无限递归的时候会出现StackOverflow的错误。
那么,方法的调用在Stack就有一个frame,等方法return之后,那么这个栈的所有的frame逐个出栈,因此,每一帧的进入叫做压栈,return之后就出栈。
当每一个线程调用自己的栈中的变量,所以方法内部的局部变量是线程安全的,这种技术被经常提起,叫做重进入(reentrance)。栈中还有方法中的参数变量。
这里注意一点,无论是方法内部的对象,参数对象,还是成员对象,都是保存在Heap里面的,包括是“引用”类型,还是原生类型。上面说的变量是元信息,可以看作一个label-标识。这些元信息不保存在Java Object Heap 区域。保存在什么地方呢?请参考2。
2、元信息
从源代码的角度来说,元信息是指类的变量和方法定义等信息。从编程的角度来说,就是程序通过反射得到的那些个成员。在元信息中定义的变量名称均放到了方法区中,这个区域是非Heap区域。
那么这些元信息保存在什么地方呢?方法区!这么说依然很是模糊。
这么说吧,在理解ClassLoader的原理之后,那么就知道一般不特殊调用defineClass来重新定义类的结构的话,那么类的结构是“不变”的。那么类自带了自己的元信息,这些信息一般不会被GC,这样就能回答为什么不在Java Object Heap区,方法区的实现区域在JVM是不统一的。
3、“引用”、地址和指针
“引用”,在Java中没有真正的C++概念中的引用,只不过套了这么个词。地址,一般而言,是指物理地址。指针是一个指向物理地址的变量。那么前面提到,每一个变量都是一个标识,Java的“引用”就是一种“传值”引用,也就说只有操作的权利,没有修改物理地址和空间的途径。这就是为什么obj = null,并没有把实际对象给null掉,而是当前变量不在指向上次的对象区域。从而,可能帮助GC,不一定就不可达了。比如:
public void calcuate(Object obj){
}
外层调用calcuate("AAAA"), "AAAA"不会被null,也不会GC掉。
4、比较
& == 和equals都是比较操作,当然还有compare方法。 == 在Java中,类似于C++操作符重载, == 在“引用”类型和原生类型。引用中是物理地址的比较,这里的物理地址可能是JVM的相对地址,也可能是实际机器地址。而原生型,是数值比较。内存空间的10比较。
不知道,楼主能不能理解我说的。如果我有错误的话,希望各位指正。
首先多谢高手们的指教啊,菜鸟我还真不太懂。看了回复后,我感觉我的疑问越来越多。在这里我说一下:
1,对于“Java中方法调用的参数传递全部是按值传递”这句话我有疑问啊,我一直都是觉的java里面的参数传递是:
"java传递是引用的拷贝,既不是引用本身,更不是对象"。对于这句话我的理解是,方法里面的原始类型在栈上分配。具体分配是一个引用,(呵呵,也叫句柄) 一个值。句柄指向那个值。在栈上分配的原始类型。栈上会自动优化。就是当它发现两个相等的值的时候。两个变量的引用会同时指向第一个值。而不会去在栈上开辟另一块空间,所以当我用==判断时,从表现上看你即可以觉的他们是值相等,也可以认为他们是引用相同。jvm具体实际情况我就不太懂。所以同理,传递参数时也相同。我觉的网上的意见实在是太多了,今天说这个,明天说那个。都把我弄晕了。
2,对于对象的成员变量,(我叫全局变量,这里名称错误,我觉的应该叫动态属性),静态属性对应于类变量。现在的理解是,动态属性应该分配在堆上。静态属性分配在栈上。在JVM中,静态属性保存在Stack指令内存区,动态属性保存在Heap数据内存区。"Java程序中没有全局变量的概念。相似的概念只有“静态变量”。概念上它也是存储在方法区里的。" 这句话,好像与我上句话有点矛盾啊,呵呵,总之,资料看的比较多,这里说是这样,哪里又说是那样,实在是头大啊!下面是网上的原话:
静态属性和动态属性:
前面提到对象实例以及动态属性都是保存在Heap 中的,而Heap 必须通过Stack中的地址指针才能够被指令(类的方法)访问到。
因此可以推断出:静态属性是保存在Stack中的,而不同于动态属性保存在Heap 中。正因为都是在Stack中,而Stack中指令和数据都是定长的,因此很容易算出偏移量,也因此不管什么指令(类的方法),都可以访问到类的静态属性。也正因为静态属性被保存在Stack中,所以具有了全局属性。在JVM中,静态属性保存在Stack指令内存区,动态属性保存在Heap数据内存区。这是网上的原话,我看那个深入jvm,如下图:
类数据(静态属性)放在方法区。跟你说的一样。这实在是头痛。我对于动态属性(非静态成员变量)在堆上分配,无疑问,但是静态属性(静态成员变量)到底在方法区,还是在栈上的Stack指令内存区,我不太确定?我觉的应该是在方法区。
3.java虚拟机规范并没有具体给出java对象在堆中是如何表示。所以对于具体分配我们无法知道,不过给出了两种可能的设计情况。
一个可能的堆的设计是将堆分为两个部分:引用池和对象池。一个对象的引用就是指向引用池的本地指针。每一个引用池中的条目都包含两个部分:指向对象池中对 象数据的指针和
方法区中对象类数据的指针。这种设计能够方便Java虚拟机堆碎片的整理。当虚拟机在对象池中移动一个对象的时候,只需要修改对应引用池中 的指针地址。但是每次访问对象的数据都需要处理两次指针。 如下图:
另一种堆的设计是:一个对象的引用就是一个指向一堆数据和指向相应对象的偏移指针。这种设计方便了对象的访问,可是对象的移动要变的异常复杂。如下图:
对于真实的jvm到底是那种情况。不懂!举个例子讨论下:
public class yy {
private int t=9;
private int y=9;
private Integer t1=new Integer(9);
private Integer t2=new Integer(9);
public static void main(String args[]){
yy y=new yy();
System.out.println(y.t2==y.t1);//false
System.out.println(y.t==y.t1);//true
System.out.println(y.t==y.y);//true
}都是动态属性,成员变量。通过运行的结果,成员变量时原始类型到时候比较值,成员变量是引用类型的情况比较复杂。分两种情况,一种是原始类型和引用类型比较,是比较值。一种是引用类型与引用类型比较,是比较引用地址。分配情况不清楚。具体怎么分配。疑问很多。我发现想的越多,感觉越来越头晕!上面的也不知道说的是对还是不对,敬请大家指教!上面所有的都是针对成员变量来说的,不是针对对于局部变量,我觉的讨论原始类型和引用类型的时候还要分是成员变量,还是局部变量!因为两者内存的分配情况是不一样的了!期待高手们画图指导啊!
Integer t1=new Integer(9);
Test t=new Test();
我觉得问题不是出在到底是分配在栈上还分配在堆里。
问题出在:JAVA里对于变量本身的类型的不统一。(指针和原始变量长一样了)
Integer *t1=new Integer(9);
Test *t=new Test();
你可以很清楚地看到,t1,t只是保存着指向一个内存对象的【地址】,而w只是保存一个【值】9
System.out.println(t.i==w);
你的这个比较只是比较的他们的值,所以他们是相等的,无论他们分别在哪里。
对于这两个变量有一点是肯定的就是 &(t.i) ==&w 是不相等的。
System.out.println(y.t2==y.t1);//false
这个FALSE其实你是在比较两个指向不同integer对象的指针。
System.out.println(y.t==y.t1);//true
System.out.println(y.t==y.y);//true
这个因为的结果是因为JAVA 1.6的拆包装包机制吧,你的y.t1对象被拆包了,变成了一个值了。
PS:我觉得楼主的问题还是在没有弄清楚变量里到底装的是什么。
对于int w=9来说,w变量里装的是9。对于Test t = new Test();
t1变量里装的是指向Test对象的地址(我假设是0x500)。但是t之中i的变量装的值是9。
而==操作符只是比较两个变量中所装的值而已。
正在学Java ,不是说Java里没有指针吗? 怎么觉得到处都是指针 !!
在大家的帮助下,貌似对些问题,慢点慢点理解。谈谈我的一个疑问,
class Test{
private int i=9;
private int j=9;
private Integer t1=new Integer(9);
private Integer t2=new Integer(9);
public static void main(String args[]){
Test t=new Test();
System.out.println(t.i==t.j);//true
System.out.println(t.i==w);//true
System.out.println(t.t1==t.t2);//false
引用最先前的那个例子。很明显开始我考虑问题忽视了java的拆箱,装箱机制,对与基本类型比较的时候,内部应该会将对象自动拆箱,==就是比较值的相等。这就是上面的
System.out.println(t.i==w);//true & 这个的解释,而最后那个System.out.println(t.t1==t.t2);//false
很明显这是对象间的比较,明显比较引用,明显不可能相等。所以为false.
我现在有个疑问,我看到很多书上都这么说,对于
编译器先处理int w = 9;首先它会在栈中创建一个变量为w的引用,然后查找有没有字面值为9的地址,没找到,就开辟一个存放9这个字面值的地址,然后将f指向9的地址。接着处理int f = 9;在创建完f的引用变量后,由于在栈中已经有9这个字面值,便将f直接指向9的地址。这样,就出现了w与f同时均指向9的情况。如果说原始类型的变量是自己持有值,而不在持有引用,指向别的值。有疑问?
第二个疑问也是我对java方法传参的疑问,下面列子:
今天看了一下别人到blog关于java方法中到参数传值到问题,突然仔细想了一下,原来自己一直也没弄懂。看下面到例子:
public class cl{
int a=3,b=4;
void swap(int a,int b){
System.out.println("=====inner a======="+a);
public static void main(String args[]){
cl c=new cl();
c.swap(c.a,c.b);
//形参,与实参。
System.out.println(c.a);
public class cl{
int a=3,b=4;
void swap(int a,int b){
System.out.println("=====inner a======="+a);
public static void main(String args[]){
cl c=new cl();
c.swap(c.a,c.b); //形参,与实参。
System.out.println(c.a);
}程序运行到结果是:
=====inner a=======9;
这个是参数直接传递基本类型的例子。
还有一个例子是参数传递对象的:
public void call(Test t) {
Test t2 = new Test();
t2.setName("cba');
t.setName("abc");
public static void main(String[] arg) {
Test obj = new Test();
call (obj) ;
System.out.println("obj"+obj.getName());
public void call(Test t) {
Test t2 = new Test();
t2.setName("cba');
t.setName("abc");
public static void main(String[] arg) {
Test obj = new Test();
call (obj) ;
System.out.println("obj"+obj.getName());
} 程序运行到结果是:
两个传参一个是基本类型,一个对象,总结网上很多说法,但是还是没有清楚到给出它们的
底层内存分配运行是的状况。但是有如下共识:
对于基本类型,在方法体内对方法参数进行重新赋值,并不会改变原有变量的值。
对于引用类型,在方法体内对方法参数进行重新赋予引用,并不会改变原有变量所持有的引用。
方法体内对参数进行运算,不影响原有变量的值。
方法体内对参数所指向对象的属性进行运算,将改变原有变量所指向对象的属性值。
思考java参数传递时具体到内存分配了!
没有看完整个帖子,但是楼主犯了一些常识性的错误。
例如最后一个回复里面的
引用int w=9;& int f=9;&&
编译器先处理int w = 9;首先它会在栈中创建一个变量为w的引用,然后查找有没有字面值为9的地址,没找到,就开辟一个存放9这个字面值的地址,然后将f指向9的地址。接着处理int f = 9;在创建完f的引用变量后,由于在栈中已经有9这个字面值,便将f直接指向9的地址。这样,就出现了w与f同时均指向9的情况。
9对于编译器来说是常量,所以不会查找所谓的"9这个字面值", 而是直接把9入栈,然后弹出来保存在局部变量w, 然后重复的动作做f, 而比较的时候,把w,f分别入栈,然后弹出两个int值做比较。
看这两个变量的声明:
//把常量9入栈
istore_2 //弹出栈顶值(9),存入局部变量2
9 //把常量9入栈
istore _3//弹出栈顶值(9),存入局部变量3
看字节码就一目了然,也不会出现这样的理解:引用就出现了w与f同时均指向9的情况
最后,对于 == 的比较, 虚拟机都是直接弹出栈顶的两个值,不管是引用还是原始类型,直接比较。
RednaxelaFX 写道最近项目周期很紧所以暂时回复不了什么,下下周应该能稍微解脱一两天吧,到时候画些图来说明这个。大家有兴趣讨论的请先踊跃发表见解哦~
先简单写几句:
1、一定要留意,JVM规范所规定的“概念中的JVM”与实际的JVM实现是可以有差异的。所以请区分清楚“堆”、“栈”在概念中与实际实现中的不同。我猜多数Java程序员更关心(或者说更有用)的是概念中的JVM的状况,但请千万不要想当然的认为实际上也必须要那样实现。
不过,作为一种现象,我们可以观察到用解释器实现的JVM会比用JIT编译器/混合模式方式实现的JVM要更接近于概念中的JVM。
2、请留意,“地址”、“指针”、“引用”等是不同抽象层次的概念,并不等价。
·引用可以用指针来实现,也可以用handle(一般翻译为“句柄”?总之很怪)来实现;
·指针里可以直接包含地址,也可以包含地址的某种映射关系(例如HotSpot中的compressedOop);
·地址可以是不同意义上的地址,在常见的Linux、Windows等现代操作系统上一般有虚拟内存系统,因而所谓“地址”在这里一般指虚拟内存的地址而不是所谓的“物理内存地址”。“物理内存”是一个经常被滥用、误用的词,也要注意判断。
后面几点没有特别说明的话都是针对概念上的JVM而言的。
3、Java是一种静态与动态类型相结合的强类型语言,表现在:
·Java的变量有类型,值也有类型,而且变量与值的类型并不需要精确一致,只要满足赋值匹配的约束即可;
·Java变量的类型可以是原始类型或引用类型的,其中引用类型又包括类类型、接口类型与数组类型;
·Java值的类型也可以是原始类型或引用类型的,其中引用类型的值包括指向类的实例的引用或者指向数组实例的引用;
·Java的类型系统中,所有与原始类型相关的操作都可以在Java源码编译时完成类型检查,并且在运行时不需要做额外的检查来保证类型安全;而引用类型的相关操作中有部分带有运行时检查的必要,例如强制向下类型转换、对元素为引用类型的数组的元素赋值,等等;
·Java中虚方法的实际调用目标在Java源码编译时无法确定,概念上需要在运行时根据值的实际类型来分派,与上一条提到的动态类型检查一起表现了Java的动态性。
4、原始类型的变量如果是成员变量,那么它的存储空间就正好是其所在对象中的一部分,是在Java堆上的。引用类型的变量……嗯回头有空画图了再详细说。
5、原始类型变量之间的==与!=所做的是相等性比较——值是否相等,而引用类型变量之间的==与!=做的是同一性比较——是否指向同一对象。其实如果可以理解“引用”的本质就是多了一个间接层的话,这个非常好理解,因为引用间的比较实质上也是值比较。这跟“Java中方法调用的参数传递全部是按值传递”底下的道理是一样的。
6、如果把方法的代码看作它的“静态”部分,而把一次方法调用需要记录的临时数据看做它的“动态”部分,那么每个方法的代码是只有一份的,存储于JVM的方法区中;每次某方法被调用,则在该调用所在的线程的的Java栈上新分配一个栈帧,用于存放临时数据,在方法返回时栈帧自动撤销;
7、Java程序中没有全局变量的概念。相似的概念只有“静态变量”。概念上它也是存储在方法区里的。
于是……等我回头画图吧,呵呵 ^_^
撒迦,你的图呢?

我要回帖

更多关于 python 全局变量 的文章

 

随机推荐