我头脑中有一点结。我只是想向某人解释,为什么一个小程序会按照它的方式使用指针,然后她问我一个不同的方式,应该(据我所知)工作,但不是。 以下是有效的代码:
#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;
}
我知道这很简单,但为了上帝的爱,我无法弄明白。谢谢你们:))
答案 0 :(得分:2)
您的代码中发生了两个函数调用,需要能够修改调用者中的数据:
inputNums(...)
和scanf(...)
inputNums(...)
来电
为了使scanf
的嵌套调用能够修改main
中的数据,scanf
需要指向main
中的数据:这是C函数可以修改其调用者内部的局部变量的唯一方法。
在你的第一个例子中,inputNums
有一个指向main
内部变量的指针,所以修改工作正常,而在第二个例子中,它没有指向main
变量的指针,因为你按值传递参数。这就是打破第二次实施的原因。
以下是正在发生的事情的说明:
在第一种情况下,指向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。
在第一个示例中,您将变量numOne
和numTwo
的地址传递给函数inputNums
,并且该函数的参数是指针。这意味着这两个指针valOne
和secVal
包含numOne
和numTwo
中变量的地址。因此,修改*valOne
和*secVal
(存储在两个指针所包含的地址中的值)将修改main
中的变量值({{1 }和numOne
)。
在第二个示例中,您将numTwo
和numOne
的值传递给函数numTwo
,因此会生成变量的副本,并将初始值存储在{{ 1}}和inputNums
被复制到函数numOne
中的变量numTwo
和valOne
。修改这些变量将不会修改secVal
和inputNums
的值,因为所有这些变量都存储在不同的内存位置。
答案 4 :(得分:0)
在第二种情况下,inputNums
按值获取其参数。因此,所做的更改不会影响main
中的变量。 valOne
中的inputNums
是numOne
的副本。 OTOH,在第一个例子中,由于inputNums
有指针参数,你所做的改变是他们指向的变量。在这种情况下,valOne
指向numOne
,scanf
调用已修改为numOne
。