【问题标题】:Copy of address in C?C中的地址副本?
【发布时间】:2017-06-01 03:16:08
【问题描述】:

我知道这段代码:

void incVar(int i){
  i++; 
}

我们知道这将创建一个整数的副本,然后增加该值,但不是实际值。

本质上: C 中的方法在其堆栈框架中创建参数的副本,而不是原始变量。

但是:

 void incVar(int *i){
      (*i)++; 
    }

应该通过指针解引用来增加整数的实际值

但是,C 为什么不直接创建指针*i 的副本呢?如果这是常规整数的正常行为,那么为什么指针不会发生同样的事情呢?

【问题讨论】:

  • 你没有改变i,所以这个结论不知从何而来。
  • 将指针声明int *i 与指针取消引用运算符*i 混淆是一个常见的错误。愚蠢的是,C 语言将* 符号用于许多完全不同的事物。

标签: c


【解决方案1】:

指针也是如此。 C 中的所有变量都是按值传递的,甚至是指针。

您将存储在函数外部指针中的地址复制到其参数中。

但是您可以使用该地址来引用一个可以在任何地方分配的变量。所以在下面的代码中:

int j = 0;
incVar(&j);

incVar 接收通过复制j 的地址。但它可以使用该地址直接读取或修改j (in)。

【讨论】:

  • 我明白了。谢谢!所以如果我有我的第一种方法,复制的x的地址和我定义的全局x不一样?
  • @Amad27 - 你是说i?是的,它的地址与复制到其中的变量的地址不同。事实上,C 中的所有有效对象在任何给定时间都有唯一的地址。
【解决方案2】:

事实上,与值相同的事情发生在指针上。只要确保正确理解语法即可。您没有将整数*i 通过复制传递给incVar,但是您通过复制传递int* 类型的指针i。无论您多久将指针复制到一个地址,它总是指向同一个地址。所以i 在你的第二个incVar 示例中指向调用者获取地址的整数。因此,通过取消引用指针的副本(在 (*i)++ 中),您正在访问调用者的整数。

【讨论】:

    【解决方案3】:

    最好将int *i; 看作一个名为ipointer-to-int 类型的变量,而不是一个名为*i 的指针。

    在你的例子中:

     void incVar(int *i) {
          (*i)++; 
        }
    

    我们可能在 main 函数中这样使用它:

    int a = 5;
    incVar(&a); //After this line, a is now 6.
    

    incVar(..) 发生的事情是这样的:

    1. 创建了一个变量i,类型为pointer-to-int
    2. 它保存了&a 值的副本
    3. 虽然i是一个副本,但是它的值和&a的值是一样的,而且还是指向同一个整数a
    4. 因此,通过取消引用i,我引用了整数a
    5. 递增整数a,显然是i指向的地址。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 2010-12-23
      • 1970-01-01
      • 2018-09-02
      • 1970-01-01
      • 2012-05-08
      • 1970-01-01
      相关资源
      最近更新 更多