我对C语言中按值复制/按引用复制的理解正确吗?

我对C语言中按值复制/按引用复制的理解正确吗?,c,pointers,pass-by-reference,pass-by-value,C,Pointers,Pass By Reference,Pass By Value,以下是我认为C代码执行的工作原理: 给定代码块中使用的变量映射包含对: 标识符: 当一个块结束并且内存被自动释放时,它们被丢弃(但我们分配给自己的内存并没有被释放) 如果将其值指定给其他标识符,则始终复制它们的值。例如,下面我们在t1中有一个分配给t2的结构。值被复制,我们现在有两个精确的对象(t2存储t1的副本)。改变一个不会改变另一个。这与javascript不同,javascript中的t1=t2总是导致t1和t2指向内存中的相同位置 typedef struct _thing {

以下是我认为C代码执行的工作原理:

给定代码块中使用的变量映射包含对:

标识符:

当一个块结束并且内存被自动释放时,它们被丢弃(但我们分配给自己的内存并没有被释放)

如果将其值指定给其他标识符,则始终复制它们的值。例如,下面我们在
t1
中有一个分配给
t2
的结构。值被复制,我们现在有两个精确的对象(
t2
存储
t1
的副本)。改变一个不会改变另一个。这与javascript不同,javascript中的
t1=t2
总是导致
t1
t2
指向内存中的相同位置

typedef struct _thing 
{ 
    char item;
    char item2;
} THING;

int main (void) {
  THING t1;
  t1.item = 'a';
  t1.item2 = 'b';
  THING t2 = t1;
  t2.item = 'c';
  if (t1.item == 'a') {
    printf("t1.item is a");
  }
}
下面,我们将引用(值开始的内存位置)复制到
t2
中的
t1
。标识符
t2
映射到存储在
t1
中的对象的内存地址开始的内存地址<代码>&t1==t2但
&t1!=&t2

int main (void) {
  THING t1;
  t1.item = 'a';
  t1.item2 = 'b';
  THING* t2 = &t1;
  t2->item = 'c';
  if (t1.item == 'c') {
    printf("item is c");
  }
}
最后,最后一个示例展示了如何处理对象,其处理方式与javascript中处理对象的方式类似,在javascript中,非原语对象始终通过引用传递:

int main (void) {
  THING* t1;
  THING* t2;
  t1 = (THING *) malloc (sizeof(THING));
  t1->item = 'a';
  t1->item2 = 'b';
  t2 = t1;
  t2->item = 'c';
  if (t1->item == 'c') {
    printf("item is c");
  }
  free(t1);
}
这里我们必须明确地说
t1
t2
存储指针(
*
)。此外,我们还必须使用箭头符号(
->
)而不是点符号(
),并手动分配/释放内存

这是正确的吗

以下是我认为C代码执行的工作原理:

给定代码块中使用的变量映射包含 成对:

也许是“好像”的意思。现实世界中的C实现没有您描述的文字映射。事实上,变量的标识符在运行时根本不可用。在程序运行之前,它们在编译和/或链接时解析为地址

当一个块结束并自动释放内存时,它们将被丢弃 (但我们分配给自己的内存并没有被释放)

自动分配的对象的生命周期在其标识符超出范围时结束。这可能与您用“丢弃”一词描述的含义和含义完全相同,也可能不完全相同

如果将其值指定给其他标识符,则始终复制它们的值

是的,分配是一种复制操作。但在这个特定问题的上下文中,理解复制(分配)的值是什么很重要。特别是,指针是C中的一类对象,不同于它们所指向的对象(如果有的话)。将指针值指定给不同的指针与将一个指向对象的值指定给另一个指向对象是完全不同的操作

例如,下面我们在
t1
中有一个分配给
t2
的结构。值被复制,我们现在有两个精确的对象(
t2
存储
t1
的副本)。改变一个不会改变另一个。这与javascript不同,javascript中的
t1=t2
总是导致
t1
t2
指向内存中的相同位置

typedef struct _thing 
{ 
    char item;
    char item2;
} THING;

int main (void) {
  THING t1;
  t1.item = 'a';
  t1.item2 = 'b';
  THING t2 = t1;
  t2.item = 'c';
  if (t1.item == 'a') {
    printf("t1.item is a");
  }
}
是的,在C语言中,具有结构类型的对象可以直接访问,分配给一个对象会修改对象本身。但请注意,这样的赋值操作是肤浅的,因为当任何结构成员都是指针时,指针都会被复制,从而使该成员成为原始结构的相应成员的别名

下面,我们将引用(值开始的内存位置)复制到
t2
中的
t1
。[……]

在这一点上,我注意到C没有“引用”。它有指针,其值表示地址。这是一个非常相似的概念,但不是完全相同的概念

但是,在任何情况下,您对运算符
&
地址和指针分配的理解似乎都是正确的

最后,最后一个示例展示了如何处理对象,其处理方式与javascript中处理对象的方式类似,在javascript中,非原语对象始终通过引用传递:

您的示例显示了一种创建指向结构对象的指针的方法,而无需声明对象本身(从而自动分配对象并将其与自己的标识符关联)。但是,请注意,尽管这让人联想到在Javascript中通过引用处理对象,但它与通过引用传递(pass-by-reference)没有什么关系,这是关于调用函数/调用方法的

C(与C++不同)没有传递引用。C函数调用总是按值传递,但传递的值可以是指针。据我所知,这类似于Javascript,它也只有传递值(传递的值可以是引用)

以下是我认为C代码执行的工作原理:

给定代码块中使用的变量映射包含 成对:

也许是“好像”的意思。现实世界中的C实现没有您描述的文字映射。事实上,变量的标识符在运行时根本不可用。在程序运行之前,它们在编译和/或链接时解析为地址

当一个块结束并自动释放内存时,它们将被丢弃 (但我们分配给自己的内存并没有被释放)

自动分配的对象的生命周期在其标识符超出范围时结束。这可能与您用“丢弃”一词描述的含义和含义完全相同,也可能不完全相同

如果将其值指定给其他标识符,则始终复制它们的值

是的,分配是一种复制操作。但在这个特定问题的上下文中,理解复制(分配)的值是什么很重要。特别是指针是一流的