理解C的工作方式的最佳方法是将其视为高级汇编语言。变量只是内存中的位置,将值分配给变量会将值存储到该位置。从高级语言的角度来看,这将是最纯粹形式的变异。
在C中,声明/定义如
int x;
告诉编译器为该
int变量保留一些内存
x。(在函数内部,内存将来自堆栈。在全局范围内,它将来自数据段。)
像这样的作业
x = 7;
只需生成代码即可将值7复制到该内存位置。同样,类似
x = y;
生成代码以将
int存储在
y的存储位置的值复制到
x的存储位置。(假设
y是另一个
int。)
同样的逻辑也适用于比
ints 更复杂的类型。
在Java中,变量是引用(反正是非原始类型),并且可以在不同时间引用不同的对象。为了获得类似于C中引用的内容,您必须显式定义一个 指针
变量(一个保存地址的变量),并在不同的时间将其指向不同对象的地址(为其分配地址)。
(为方便起见,我提供了以下示例。)
的
&操作者用来得到在C变量的地址,以便
&x将地址
x例如。
*当应用于指针时,运算符将提供指向的对象。这是一个如何在不同时间使用指针来引用不同变量的示例:
int x;int y;int *ptr;ptr = &x; // Store the address of 'x' in 'ptr'.*ptr = 1; // Store 1 into the memory 'ptr' points to ('x').ptr = &y; // Store the address of 'y' in 'ptr'.*ptr = 2; // Store 2 into the memory 'ptr' points to ('y').上面代码的最终结果将设置
x为1和
y2。这当然是一个愚蠢的示例,但希望它能使您理解。
(
//顺便说一下,C99和更高版本支持样式注释。)
问题的答案
(注意:我的Java有点生锈,因此我必须做一些阅读。希望细节应该正确。请随时纠正我。)
第1期
那作业
x = "Goodbye World";
将具有
x引用
String值为“再见世界” 的对象的效果。确切地说
,
String创建此对象的时间不应该有所不同,只要在分配给对象
x(或任何其他变量)之前创建该对象即可。
它可能是在执行分配之前或程序启动时创建的。通常,您将无法分辨出差异。
第2期
听起来您已经掌握了高级概念,并且您的C代码是正确的。
(尽管说“
ptr是一个指针”比说“
*ptr是一个指针”
更正确。C中存在一些语法上的晦涩之处,这使得
*在声明(IMO)中放置下一个名称更为自然,但是您可以也要像这样写声明
int*ptr;。只有在同一行中声明许多变量时,事情才开始变得怪异。)
在讨论Java的实现方式时,引用可能必须比仅是底层对象的指针要先进一些。例如,JVM可能会在内存中移动对象(这将更改它们的地址)以减少内存碎片,但是引用仍必须保持有效。一种方法是在移动对象时“固定”指针,另一种方法是使引用成为指针表的索引。不管它在JVM实现中是如何完成的,
指针 至少都是正确的想法。
由于Java中的每个引用都有一个指针字段(在高层,完全忽略了实现的方式),并且由于原始类型不需要此字段,因此一种可能性是重用指针字段并将值存储在其中而不是原始类型。
例如,类似
x = 1;
可能将值1直接存储到引用的指针字段中
x。这样的技术很普遍。
附带说明一下,a
union可以用于在C中将两种不同类型(例如,an
int和指针)存储在内存中的同一位置,以便它们重叠。当然,分配给其中一种类型也会改变另一种类型的值。



