Scanf - 每个参考的每个参考VS参数的变量

时间:2014-12-28 10:09:31

标签: c pointers pass-by-reference scanf pass-by-value

我头脑中有一点结。我只是想向某人解释,为什么一个小程序会按照它的方式使用指针,然后她问我一个不同的方式,应该(据我所知)工作,但不是。 以下是有效的代码:

#include <stdio.h>

void inputNums(double *valOne, double *secVal)
{
    printf("Enter your first number: ");
    scanf("%lf", valOne);

    printf("Enter your second number: ");
    scanf("%lf", secVal);
}

void sum(double valOne, double secVal )
{
    double result = valOne + secVal;
    printf("The sum is: %.2f\n", result);
}


int main()
{
    double numOne;
    double numTwo;

    inputNums(&numOne, &numTwo);
    sum(numOne, numTwo);
    return 0;
}

这里的代码不是,但我不明白为什么:

#include <stdio.h>

void inputNums(double valOne, double secVal)
{
    printf("Enter your first number: ");
    scanf("%lf", &valOne);

    printf("Enter your second number: ");
    scanf("%lf", &secVal);
}

void sum(double valOne, double secVal )
{
    double result = valOne + secVal;
    printf("The sum is: %.2f\n", result);
}


int main()
{
    double numOne;
    double numTwo;

    inputNums(numOne, numTwo);
    sum(numOne, numTwo);
    return 0;
}

我知道这很简单,但为了上帝的爱,我无法弄明白。谢谢你们:))

5 个答案:

答案 0 :(得分:2)

您的代码中发生了两个函数调用,需要能够修改调用者中的数据:

  • 致电inputNums(...)
  • 来自scanf(...)
  • 内部的inputNums(...)来电

为了使scanf的嵌套调用能够修改main中的数据,scanf需要指向main中的数据:这是C函数可以修改其调用者内部的局部变量的唯一方法。

在你的第一个例子中,inputNums有一个指向main内部变量的指针,所以修改工作正常,而在第二个例子中,它没有指向main变量的指针,因为你按值传递参数。这就是打破第二次实施的原因。

以下是正在发生的事情的说明:

Passing by pointer vs. passing by value

在第一种情况下,指向numOne的{​​{1}}和numTwo的指针一直传递到main,而在第二种情况下,scanf会看到指针scanf的{​​{1}}和valOne的本地secVal,这是它修改的内容,而不触及inputNums的变量。

答案 1 :(得分:1)

非常简单,默认情况下,C中的所有值都按值传递。

这使得您的inputNums仅修改变量的副本。

在该示例中,您的变量是numOne和numTwo的地址

有了这个说法     inputNums(&numOne, &numTwo);

您只发送numOne和numTwo地址的副本     这将是你主堆栈上的一些地址。

答案 2 :(得分:1)

它不起作用,因为C是按值传递。在第二个代码块中,

void inputNums(double valOne, double secVal)
{

传入valOne和secVal的,然后它们成为局部变量。你的指针代码正在正确地改变那些变量,但是当函数返回时它们仍然被删除,因为变量是本地的。

在第一个区块中,

void inputNums(double *valOne, double *secVal)
{

传入的唯一值是main方法范围内的两个变量的地址(即变量numOne和numTwo);跟随这些指针会导致这些变量,并且当函数返回时更改会保持不变。

答案 3 :(得分:1)

在第一个示例中,您正在执行pass-by-reference,而在第二个示例中,它是pass-by-value

在第一个示例中,您将变量numOnenumTwo的地址传递给函数inputNums,并且该函数的参数是指针。这意味着这两个指针valOnesecVal包含numOnenumTwo中变量的地址。因此,修改*valOne*secVal(存储在两个指针所包含的地址中的值)修改main中的变量值({{1 }和numOne)。

在第二个示例中,您将numTwonumOne的值传递给函数numTwo,因此会生成变量的副本,并将初始值存储在{{ 1}}和inputNums被复制到函数numOne中的变量numTwovalOne。修改这些变量将不会修改secValinputNums的值,因为所有这些变量都存储在不同的内存位置。

答案 4 :(得分:0)

在第二种情况下,inputNums按值获取其参数。因此,所做的更改不会影响main中的变量。 valOne中的inputNumsnumOne的副本。 OTOH,在第一个例子中,由于inputNums有指针参数,你所做的改变是他们指向的变量。在这种情况下,valOne指向numOnescanf调用已修改为numOne