代码之家  ›  专栏  ›  技术社区  ›  marzelin

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

  •  0
  • marzelin  · 技术社区  · 6 年前

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

    在给定的代码块中有一个变量映射,其中包含对:

    identifier: <address in memory where the value of a given type is located (its first byte)>

    如果分配给其他标识符,则始终复制它们的值。例如,下面我们有一个 t1 t2 . 值被复制,我们现在有两个精确的对象( 存储的副本 t1级 ). 改变一个不会改变另一个。这与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级 开始。 &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);
    }
    

    这里我们必须明确地说 存储指针( * -> )而不是点符号( . )手动分配/释放内存。

    是这样吗?

    1 回复  |  直到 6 年前
        1
  •  3
  •   John Bollinger    6 年前

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

    对:

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

    (但我们分配给自己的内存不会被释放)。

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

    如果分配给其他标识符,则始终复制它们的值。

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

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

    是的,在C中,具有结构类型的对象是可以直接访问的,将其指定给一个对象会修改对象本身。但请注意,这样的赋值操作是肤浅的,因为当任何结构成员都是指针时, 指示者 复制,将该成员保留为原始结构的相应成员的别名。

    t1级 在里面 t2级 . [...]

    指针 ,其值表示地址。这是一个非常相似的概念,但不是一个完全相同的概念。

    无论如何,你对接线员地址的理解, & ,指针赋值的和似乎是正确的。

    最后,最后一个示例演示了如何处理对象,就像在javascript中处理对象一样,在javascript中,非原语对象总是通过引用传递:

    您的示例演示了一种创建指向结构对象的指针的方法,而无需声明对象本身(从而使其自动分配并与自己的标识符相关联)。不过,请注意,尽管这让人想起在Javascript中通过引用处理对象,但它与 通过引用传递