简体   繁体   English

C 中的赋值混淆

[英]Assignment confusion in C

I am new in C so I need some help.我是 C 新手,所以我需要一些帮助。

for example I have this struct object例如我有这个结构对象

struct Frac {
   int num; 
   int dec
}

which i do this in c:我在 c 中这样做:

struct Frac fract1 = {1, 2};
struct Frac temp; 
temp = fract1;

Is temp point to a copy of fract1 or is it pointing to the actual fract1? temp 是指向 fract1 的副本还是指向实际的 fract1? I tried it on computer by printing the address and it is pointing to a copy of fract1.我通过打印地址在计算机上进行了尝试,它指向 fract1 的副本。 If this is in Java, it will be pointing to the actual fract1.如果这是在 Java 中,它将指向实际的 fract1。 Do correct me if I am wrong.如果我错了,请纠正我。 Can I ask why temp is pointing to a copy of fract1 in C instead of the actual object itself thanks!我能问一下为什么 temp 指向 C 中 fract1 的副本而不是实际对象本身,谢谢!

Nothing is pointing to anything.没有任何东西指向任何东西。 Assignment copies values.赋值复制值。 Assignment always copies values.赋值总是复制值。 Sometimes those values are pointers, but if you don't see a pointer, there isn't a pointer.有时这些值是指针,但如果您没有看到指针,则说明没有指针。 C doesn't have Java's dichotomy between simple types with value semantics and everything-else with reference semantics. C 没有 Java 在具有值语义的简单类型和具有引用语义的所有其他类型之间的二分法。

" Is temp point to a copy of fract1 or is it pointing to the actual fract1 "? temp是指向fract1的副本还是指向实际的fract1 ”?

First of all, temp and fract1 are not pointers.首先, tempfract1不是指针。 There are object types of the structures.有结构的对象类型。

The content of frac1 is copied to temp but temp is a different object. frac1的内容被复制到temptemp是一个不同的对象。

Is temp point to a copy of fract1 or is it pointing to the actual fract1? temp 是指向 fract1 的副本还是指向实际的 fract1? I tried it on computer by printing the address and it is pointing to a copy of fract1.我通过打印地址在计算机上进行了尝试,它指向 fract1 的副本。

You're correct.你是对的。 It would point to a copy of fract1.它将指向 fract1 的副本。

If this is in Java, it will be pointing to the actual fract1.如果这是在 Java 中,它将指向实际的 fract1。

You're correct, in Java there would be two references to the same object.你是对的,在 Java 中会有两个对同一个对象的引用。

Can I ask why temp is pointing to a copy of fract1 in C instead of the actual object itself我可以问为什么 temp 指向 C 中 fract1 的副本而不是实际对象本身

C doesn't automatically allocate objects on the heap unless you ask it to. C 不会自动在堆上分配对象,除非你要求它。 You could reproduce something similar to Java by using pointers and heap allocations.您可以通过使用指针和堆分配来重现类似于 Java 的内容。 But note that you are required to free objects explicitly unlike in Java.但请注意,与 Java 不同,您需要明确地释放对象。

struct Fraction *frac1 = malloc(sizeof(struct Fraction));
frac1->num = 1;
frac1->dec = 2;

struct Fraction *temp; 
temp = frac1;

// Both frac1 and temp point to the same object
...

// Make sure you free the object eventually
free(frac1);

Yes, the assignment operator always creates a copy.是的,赋值运算符总是创建一个副本。 This is what you would normally expect.这是您通常所期望的。 The Java behaviour is actually the deviant one. Java 行为实际上是异常行为。

For example in C or Java,例如在 C 或 Java 中,

int a = 3;
int b = a;

Would you expect b to point to the 'actual' a or would b be a copy of a containing the same value 3 ?你会想到b ,以点到“实际” a或将b是副本a包含相同的值3 This is exactly what C does, even for structures, unlike Java.与 Java 不同,这正是 C 所做的,即使对于结构也是如此。 For all non-trivial objects, Java implicitly allocates memory on the heap and creates a reference (equivalent to a pointer).对于所有非平凡对象,Java 会在堆上隐式分配内存并创建一个引用(相当于一个指针)。 What you call 'object' in Java is actually a reference to an object and when you copy it using the assignment operator, you are actually copying this reference.您在 Java 中所说的“对象”实际上是对对象的引用,当您使用赋值运算符复制它时,您实际上是在复制此引用。 Allocation of composite objects on the stack that is possible in C is not possible in a language like Java.在 C 中可以在堆栈上分配复合对象在 Java 等语言中是不可能的。

If you want to create a reference, you can still do that using pointers in C. You will have to 'dereference' this pointer to actually retrieve the object behind it.如果你想创建一个引用,你仍然可以使用 C 中的指针来做到这一点。你必须“取消引用”这个指针才能实际检索它后面的对象。

Modifying your original example:修改您的原始示例:

struct Frac fract1 = {1, 2};
struct Frac *temp;
struct Frac *temp2; 
temp = &fract1; // Now temp points to the original fract1
temp2 = temp;   // Copying a reference: temp2 is a copy of temp but both point to the same fract1

temp->num = 3;  // This modifies fract1 indirectly

Both frac1 and temp are variables. frac1temp都是变量。 These variables occupy two different spaces in memory.这些变量在内存中占据两个不同的空间。

What is going on in C, is that temp = frac1 is copying the contents of the memory named frac1 into the memory named temp . C 中发生的事情是temp = frac1正在将名为frac1的内存的内容复制到名为temp的内存中。

If you are dealing with a pointer, these ideas of spaces in memory and copying the contents still applies.如果您正在处理指针,则内存中的空间和复制内容的这些想法仍然适用。

For example:例如:

int *p; - there is a space in memory named p; - 内存中有一个名为 p 的空间; however, the contents of this space in memory contain an address.然而,内存中这个空间的内容包含一个地址。 This address in turn (likely) refers to a different space in memory.该地址又(可能)指代内存中的不同空间。 Thus p = ... will update the contents of p (which is a pointer) so that it will point to someplace new.因此p = ...将更新 p (它是一个指针)的内容,使其指向某个新的地方。 Meanwhile *p = ... changes the contents of the memory to which the contents of p pointed.同时*p = ...更改p的内容指向的内存的内容。

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

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