->
在C中与{/ 1}中的{/ 1}}做同样的事情吗?
在Java / C#中,您可以通过.
运算符访问结构中的项目。
在我看来,.
位于d_name
内,其作为dir
内的项目进行访问
dir
如果情况并非如此,那么我错过了一些内容,如果可能的话,我想要一个简单的解释。
答案 0 :(得分:4)
含糊不清,是的。 Java没有指针,也没有按值传递的对象的概念;本质上,所有对象都是通过引用存储和传递的,并且在未使用时,垃圾收集器会释放相关的内存。
答案 1 :(得分:1)
请记住struct和指向struct的指针之间的区别。
让我们假设一个32位编译器。
让我们创建一个结构:
struct point_i {
int x;
int y;
};
此结构有两个int成员。每个整数的大小为4个字节,因此结构大小总共为8个字节。
然后使用struct:
strut point_i my_point; // 8 bytes allocated, lets assume that they
// are located at address 0x10000000.
my_point.y = 10;
执行此操作时,编译器会知道my_point的位置及其大小,并且还知道成员y
相对于结构的位置。因此它(非常粗略地)编译为:
MOV [0x10000004], 10 ;; Notice that its 0x10000000 + 4.
;; The first four bytes are X so we skip them
;; to get to Y and put 10 in that memory address.
另一方面,当你有一个指针时:
strut point_i *another_point; // 4 bytes allocated, the pointer size.
// Let's assume in 0x20000000.
another_point = get_random_point(); // Get an address to some random point.
another_point->y = 10; // You have to use -> to reference the member
// because you are not dealing with an struct
// anymore but a *pointer* to said struct.
由于编译器不知道你要在该指针中放入什么地址,因此它必须生成稍有不同的代码。
MOV EBX, [0x20000000] ;; 0x20000000 has your pointer. So we fetch it.
MOV [EBX+4], 10 ;; Dereference the pointer and put 10 in Y.
;; You can see that we now have two memory references,
;; one to get the pointer and another to get where it
;; points to. So it is a layer of indirection.
请注意,这是一个非常简化的世界观。编译器/链接器和操作系统解析程序上的内存地址。但它应该澄清这些背后发生的事情。指针解除引用是C的主要部分。
答案 2 :(得分:0)
.NET和Java中类类型的变量保存引用,其行为类似于C中malloc指定的行为,除了C允许指针和整数之间的算术和转换,而引用不允许这样的算法和转换。如果o
包含对带有字段f
的C类对象的引用,则C#或Java中的o.f
大致相当于C中的o->f
。
实例方法采用隐含参数,该参数保证包含对相应类型的实例的引用。如果im
是o
的非虚方法,则o.im(whatever)
相当于C_im(o, whatever);
。如果vm
是虚拟成员,系统将定义一个内部方法,该方法返回适用于给定实例的实现的地址。因此,o.vm(whatever)
相当于C_get_vm(o)(o, whatever);
C#中的结构更像C中的结构。结构字段访问使用与类字段访问相同的.
标记,但如果s
是带有字段{S
的结构f
{1}},然后C#中的s.f
与C中的s.f
类似。通过将“byref”传递给对象实例来调用实例方法,这样s.im(whatever)
将等同于S_im(&s, whatever);
{1}}。请注意,对结构类型变量的操作将对变量本身进行操作,不像对类型变量的操作(与C的->
标记一样)将对变量保存引用的内容执行。 / p>
PS - 我不喜欢决定让C#使用.
而不是->
来进行类字段访问,或者通过传递变量中包含的对象引用来调用类成员函数。我宁愿看到foo.whatever
始终引用或修改foo
本身,而foo->whatever
始终引用或修改foo
拥有引用的内容。即使使用类对象,也可以实现非虚方法以将byref传递给变量,例如, someString.Append(x);
等同于String_Append(ref x);
,可以更改变量someString
的含义(例如,使其指向String
的不同实例)。但现在太迟了。