简体   繁体   English

x-> y在c中是否与c#/ java中的xy相同?

[英]Is x -> y the same in c as x.y in c#/java?

Is -> doing the same thing in C as . ->在C中做与. in Java/C#? 在Java / C#中?

In Java/C# you access items inside a struct via the . 在Java / C#中,您可以通过访问结构中的项目. operator. 操作员。

It seems to me that d_name is inside dir and its being accessed as an item inside dir 在我看来, d_namedir并且作为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);
}

If this is not the case then I am missing something and I would like a simple explanation if possible. 如果不是这种情况,那么我会丢失一些东西,如果可能的话,我想作一个简单的解释。

In a vague sense, yes. 从某种意义上说是的。 Java does not have pointers, nor the concept of objects being passed by value; Java没有指针,也没有按值传递对象的概念。 in essence, all objects are stored and passed by reference and the associated memory is freed by the garbage collector when unused. 本质上,所有对象都是通过引用存储和传递的,并且当未使用时,垃圾回收器会释放关联的内存。

Keep in mind the difference between an struct, and a pointer to an struct. 请记住,结构与指向结构的指针之间的区别。

Let's assume a 32 bit compiler. 让我们假设一个32位编译器。

Let's create an struct: 让我们创建一个结构:

struct point_i {
    int x; 
    int y; 
};

This struct has two int members. 该结构具有两个int成员。 Each integer is four bytes in size so the struct size in total is eight bytes. 每个整数的大小为4个字节,因此结构大小的总数为8个字节。

Then use the struct: 然后使用该结构:

strut point_i my_point;        // 8 bytes allocated, lets assume that they  
                               // are located at address 0x10000000.
my_point.y = 10;              

When you do this, the compiler knows where my_point is located and its size and it also knows where the member y is with respect to the struct. 执行此操作时,编译器会知道my_point的位置及其大小,并且还知道成员y相对于该结构的位置。 So it compiles (very roughly) to something like: 因此,它可以(大致)编译为:

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.

On the other hand, when you have a pointer: 另一方面,当您有一个指针时:

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.

And since the compiler has no idea what address you are going to put in that pointer it has to generate code that is a bit different. 而且由于编译器不知道您要在该指针中放置什么地址,因此它必须生成略有不同的代码。

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.

Notice that this is a very simplified view of the world. 请注意,这是一个非常简化的视图。 The compiler/linker and the operating system resolve memory addresses on your programs. 编译器/链接器和操作系统解析程序上的内存地址。 But it should clarify what's going on behind the courtains. 但是它应该弄清后宫发生了什么。 Pointer dereferencing is a major part of C. 指针解引用是C的主要部分。

Variables of class type in both .NET and Java hold references, whose behavior is similar to that of a malloc'ed pointer in C, except that C allows arithmetic and conversions between pointers and integers, whereas references allow no such arithmetic nor conversions. .NET和Java中的类类型变量均持有引用,其行为与C中的malloc指针相似,不同之处在于C允许指针和整数之间进行算术和转换,而引用不允许此类算术和转换。 If o holds a reference to an object of class C with a field f , of in C# or Java is roughly equivalent to o->f in C. 如果o在C#或Java中使用字段f持有对C类对象的引用, of在C#或Java中大致等效于C中的o->f

Instance methods take an implied parameter, which is guaranteed to hold a reference to an instance of the appropriate type. 实例方法采用隐式参数,该参数可确保保留对适当类型的实例的引用。 If im is a non-virtual method of o , then o.im(whatever) is equivalent to C_im(o, whatever); 如果imo的非虚拟方法,则o.im(whatever)等效于C_im(o, whatever); . If vm is a virtual member, the system will define an internal method which returns the address of the implementation applicable to a given instance. 如果vm是虚拟成员,则系统将定义一个内部方法,该方法返回适用于给定实例的实现的地址。 Thus, o.vm(whatever) is equivalent to C_get_vm(o)(o, whatever); 因此, o.vm(whatever)等同于C_get_vm(o)(o, whatever);

Structures in C# behave more like structures in C. Structure field access uses the same . C#中的结构在行为上更像C中的结构。结构字段访问使用相同的. token as class field access, but if s is a structure of type S with field f , then sf in C# is like sf in C. Instance methods are called by passing a "byref" to the object instance, such that s.im(whatever) would be equivalent to S_im(&s, whatever); 令牌作为类字段访问,但如果s是类型的结构S与现场f ,然后sf在C#就像sf中C.实例方法通过使“按地址”的对象实例,使得称为s.im(whatever)等于S_im(&s, whatever); . Note that operations on a structure-type variable will operate on the variable itself, unlike operations on a class-type variable which (as with C's -> token) will be performed upon something to which the variable holds a reference. 请注意,对结构类型变量的操作将对变量本身进行操作,这与对类类型变量的操作(如使用C的->标记)不同,此类操作将在变量持有引用的对象上执行。

PS--I dislike the decision to have C# use . PS-我不喜欢使用C#的决定. rather than -> for class field access or for the invocation of class member functions by passing the object reference contained in a variable. 而不是->用于类字段访问或通过传递变量中包含的对象引用来调用类成员函数。 I would rather have seen foo.whatever consistently refer to or modify foo itself, and foo->whatever consistently refer to or modify a thing to which foo holds a reference. 我宁愿看到foo.whatever始终引用或修改foo本身,以及foo->whatever始终引用或修改foo引用的东西。 Even with class objects, non-virtual methods could have been implemented to pass a byref to the variable, such that eg someString.Append(x); 即使使用类对象,也可以实现非虚拟方法来将byref传递给变量,例如someString.Append(x); would have been equivalent to String_Append(ref x); 相当于String_Append(ref x); and could change what the variable someString holds (eg making it point to a different instance of String ). 并且可以更改变量someString持有的内容(例如,使其指向String的其他实例)。 Too late now, though. 不过,现在为时已晚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM