在C中更改变量的值

时间:2017-01-16 07:38:05

标签: c pointers

  

为什么要更改主变量的 NOT 变量的COPY。

我有一个方法

url

调用此函数时,会创建一个新的堆栈框架,其中 x 副本和不是原始变量。那么这会改变这个副本的价值吗?

问:如果我想更改原始变量的值,我使用指向它的指针,然后增加一个值吗?例如:

int plusInt(int x){
 return ++x; 
}

但有什么用途/为什么有人想要改变原始变量的值而不是副本呢?

5 个答案:

答案 0 :(得分:3)

  

所以这会改变这个副本的价值吗?

确切地说,因为函数只有副本而不是原始变量,因为它是一个局部变量。

  

如果我想更改原始变量的值,我使用指向它的指针然后增加一个值吗?

再一次。使用指针的原因是将变量的 地址 传递给函数。

  

但有什么用途/为什么有人想要改变原始变量的值而不是副本呢?

原因是在您的功能结束并返回调用功能后,对副本的任何更改都将丢失。

例如,假设您要使用函数来交换两个变量的值。然后,您必须更改 原始 值。你的功能应该是这样的:

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = *temp;
}

你应该这样称呼它:

swap(&a, &b);

这样,即使返回调用函数,更改仍将保留。 如果你只是更改副本,当你返回调用函数时,变量将没有交换的值!!!

答案 1 :(得分:3)

假设您要创建一个交换两个变量的函数。然后你需要这样做:

void swap(int *a, int *b)
{
  int temp = *a;
  *a = *b;
  *b = *temp;
}
...
void swapwrong(int a, int b)  // wont work as intended
{
  int temp = a;
  a = b;
  b = temp;
}
...
int a = 1, b = 2 ;
swap(&a, &b);
printf ("after swap : a=%d b=%d\n", a,b);
swapwrong(&a, &b);
printf ("after swapwrong : a=%d b=%d\n", a,b);

这将打印

after swap : a=2 b=1
after swapwrong : a=2 b=1

答案 2 :(得分:2)

  

所以这会改变这个副本的价值吗?

是。只有plusInt

的本地副本
  

如果我想更改原始变量的值,我使用指向它的指针然后增加一个值吗?

是。要更改另一个范围中的变量,我们必须预先形成间接。这是通过传递变量地址来实现的。

  

但有什么用途/为什么有人想要改变原始变量的值而不是副本呢?

在学习编程时,最简单的用例是在尝试将节点插入链表头部时。您的添加函数必须修改调用上下文中的结构。

好吧,也许这不是最简单的。考虑这个功能

void swap_ints(int l, int r) {
  int t = l; l = r; r = t;
}

int main(void) {
  int x = 1, y = 2;
  swap_ints(x, y);
  // Were they swapped?
}

答案 3 :(得分:0)

  

但有什么用途/为什么有人想要改变它的价值   原始变量而不是副本?

您可以更改复制变量,但当您的代码退出该函数时,此变量将不可用。

另外,我们通常不会仅仅为了进行简单的增量而调用函数。代码

int plusInt(int x){
 return ++x; 
}

可以替换为

x++ 

而不是调用函数。在优化模式下,编译器可能会通过嵌入代码想要执行的更改来决定摆脱此功能

我们在许多情况下使用复制变量,例如显示变量的值或在您不想反映任何意外更改的地方

答案 4 :(得分:0)

指针将函数传递给函数有很多应用。 E.g:

当您将参数传递给函数时,如上所述,将分配堆栈中的空间,并将此类参数复制到此空间。此操作可能很昂贵,因此您可以考虑通过指针传递这些参数。然后,指向数据的指针将传递给您的函数(即,将被复制到堆栈中)。在这种情况下,您可以考虑将const放入这些参数,以防止“意外”更改其值(通常使用char*)。

有时您实际上需要更改此参数的值。请注意,这将“就地”完成。即不会有复制操作。在(修改)你的例子中,我们可以做这样的事情:

void increment(int* i)
{
  if(i)
    ++*i;
}

在此示例中,没有任何复制操作(截至输入参数,截至函数结果)。此外,正如您所看到的,我们可以将NULL作为i的值传递。您的函数的算法可以以不同的方式处理这种情况(例如,跳过此参数等)。

当你需要在一个函数中更改许多参数的值时,使用这种参数传递方法就可以了。