[英]Is x -> y the same in c as x.y in c#/java?
->
在C中做与.
在Java / C#中?
在Java / C#中,您可以通过访问结构中的项目.
操作员。
在我看来, d_name
在dir
并且作为dir
一个项被访问
DIR *d;
struct dirent *dir;
d = opendir("."); // get current directory
if (d)
{
while ((dir = readdir(d)) != NULL)
{
// whilst item exists
printf("%s\n", dir -> d_name);
}
closedir(d);
}
如果不是这种情况,那么我会丢失一些东西,如果可能的话,我想作一个简单的解释。
从某种意义上说是的。 Java没有指针,也没有按值传递对象的概念。 本质上,所有对象都是通过引用存储和传递的,并且当未使用时,垃圾回收器会释放关联的内存。
请记住,结构与指向结构的指针之间的区别。
让我们假设一个32位编译器。
让我们创建一个结构:
struct point_i {
int x;
int y;
};
该结构具有两个int成员。 每个整数的大小为4个字节,因此结构大小的总数为8个字节。
然后使用该结构:
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的主要部分。
.NET和Java中的类类型变量均持有引用,其行为与C中的malloc指针相似,不同之处在于C允许指针和整数之间进行算术和转换,而引用不允许此类算术和转换。 如果o
在C#或Java中使用字段f
持有对C类对象的引用, of
在C#或Java中大致等效于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
,然后sf
在C#就像sf
中C.实例方法通过使“按地址”的对象实例,使得称为s.im(whatever)
等于S_im(&s, whatever);
。 请注意,对结构类型变量的操作将对变量本身进行操作,这与对类类型变量的操作(如使用C的->
标记)不同,此类操作将在变量持有引用的对象上执行。
PS-我不喜欢使用C#的决定.
而不是->
用于类字段访问或通过传递变量中包含的对象引用来调用类成员函数。 我宁愿看到foo.whatever
始终引用或修改foo
本身,以及foo->whatever
始终引用或修改foo
引用的东西。 即使使用类对象,也可以实现非虚拟方法来将byref传递给变量,例如someString.Append(x);
相当于String_Append(ref x);
并且可以更改变量someString
持有的内容(例如,使其指向String
的其他实例)。 不过,现在为时已晚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.