Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 传递值和引用之间的混淆?_C - Fatal编程技术网

C 传递值和引用之间的混淆?

C 传递值和引用之间的混淆?,c,C,有人能解释为什么这不起作用吗 int main() { float* x; float a, b; int num_vals = 10; fill_in_x(&x, num_vals); // malloc is called and x is populated with values a = x[0]; b = x[1] - x[0]; printf("%f\n", a); printf("%f\n", b);

有人能解释为什么这不起作用吗

int main()
{
    float* x;
    float a, b;
    int num_vals = 10;

    fill_in_x(&x, num_vals); // malloc is called and x is populated with values

    a = x[0];
    b = x[1] - x[0];

    printf("%f\n", a);
    printf("%f\n", b);

    function_using_a_and_b(a, b); // The values of a and b used in this function 
                                  // don't match those calculated in main 
}

void fill_in_x(float** x, int num_vals)
{
    *x = (float*)malloc(num_vals * sizeof(float));

    // Fill in values for x
}

void function_using_a_and_b(float a, float b)
{
    printf("%f\n", a);
    printf("%f\n", b);
}
为了重申注释中所说的内容,当我在一个单独的函数中动态地为malloc中的x分配内存,然后尝试将几个值传递到另一个函数中时,这些值传递不正确。这感觉像是一个指向性问题,但我认为我传递的是a和b的值,而不是地址。为了记录在案,我甚至尝试使用memcpy将值放入a和b中,但这也没有奏效

我确实是通过传递a和b的地址,然后使用函数a和b在函数u中取消引用它们来实现的,但是为什么上面的方法不起作用呢


提前感谢。

为了让malloc在fill_in_x()函数中工作,您需要将指针传递给函数,而不是指针的引用。关于传递引用和传递值之间的问题,传递值涉及生成变量的本地副本的函数,而传递引用是一种更具体的传递指针类型,最好通过以下内容进行解释。忽略它是C++的,因为它对C的工作方式和你的问题一样。

很可能你在FILIZIN X中做了一些不正确的事情。既然定义不在帖子中,我不能说是什么,但应该是这样的:

void fill_in_x(float** array) {
      *array = (float*) malloc(10*sizeof(float));
}
(虽然返回分配的内存是一种不好的形式,因为它经常导致内存泄漏,就像代码中的泄漏一样。)


(响应fill-in-x):在visual studio上编译并运行此代码将生成预期的输出

#include <stdio.h>
#include <stdlib.h>

void fill_in_x(float** x, int num_vals)
{
    *x = (float*)malloc(num_vals * sizeof(float));

    for(int i = 0; i < num_vals; ++i)
        (*x)[i] = (i*2)+3;
}

void function_using_a_and_b(float a, float b)
{
    printf("%f\n", a);
    printf("%f\n", b);
}

int main()
{
    float* x;
    float a, b;
    int num_vals = 10;

    fill_in_x(&x, num_vals); // malloc is called and x is populated with values

    a = x[0];
    b = x[1] - x[0];

    printf("%f\n", a);
    printf("%f\n", b);

    function_using_a_and_b(a, b); // The values of a and b used in this function 
                                  // don't match those calculated in main 
}

所以我还是不知道你的意思。我怀疑文章中仍然缺少有问题的代码。

如果函数需要修改给定参数的值,则需要为其提供一个地址。否则,它将创建a和b中值的新本地副本并修改这些值。

您可以尝试调试函数fill_X,并查看main和函数内部的f地址

另一种方法是将fill_x函数更改为

float* fill_x(){

  float* f = malloc(...);

  //do stuff with f.

  return f;

}
那你就得释放那些记忆

 float *f = fill_x();

  //do stuff with f.
  free(f);

你所做的看起来是正确的,虽然有点奇怪

唯一让我担心的是,您没有显示足够的代码来填充,我们无法看到您是如何填充的

 // Fill in values for x
这里有一种可能是你做错了——很简单,因为你要考虑两个解引用(float**x)

确保你正在做:-

(*x)[0] = 0;
(*x)[1] = 100;
... etc...
。。。而不是

x[0] = 0; // compiles, but overwrites the pointer with NULL...
…或

…或


至于a和b,当你用a和b调用函数时会发生变化,这很奇怪。您按值传递它们是正确的。您在这里使用什么编译器?

为什么不在main中使用malloc x,这样您就不会忘记稍后释放x,从而造成内存泄漏。我建议避免使用float**,这太令人困惑了

嘿,这个谜语真好。:-)

我猜您的函数声明如下所示:

void fill_in_x(float* x);
void fill_in_x(float** x);
当它看起来像这样时:

void fill_in_x(float* x);
void fill_in_x(float** x);
使用您的声明,函数期望获得一个浮点指针,但您将浮点指针x的地址传递给它-它就在堆栈的某个地方,因为这是分配局部变量的地方


这意味着您正在自己的调用堆栈上分配空间,结果显然很可怕。:)

这似乎和我预期的一样有效:

#include <stdlib.h>
#include <stdio.h>

void fill_in_x(float** x, int num_vals)
{
    float* res = (float*)malloc(num_vals * sizeof(float));
    *x = res;

    // Fill in values for x
    res[0] = 1.0;
    res[1] = 4.0;
}

void function_using_a_and_b(float a, float b)
{
    printf("%f\n", a);
    printf("%f\n", b);
}

int main()
{
    float* x;
    float a, b;
    int num_vals = 10;

    fill_in_x(&x, num_vals); // malloc is called and x is populated with values

    a = x[0];
    b = x[1] - x[0];

    function_using_a_and_b(a, b); // The values of a and b used in this function 
                                  // don't match those calculated in main 
}
#包括
#包括
空白填充(浮动**x,整数)
{
float*res=(float*)malloc(num_vals*sizeof(float));
*x=分辨率;
//填写x的值
res[0]=1.0;
res[1]=4.0;
}
使用_a_和_b的无效函数_(浮点a,浮点b)
{
printf(“%f\n”,a);
printf(“%f\n”,b);
}
int main()
{
浮动*x;
浮子a、b;
int num_vals=10;
fill_in_x(&x,num_vals);//调用malloc并用值填充x
a=x[0];
b=x[1]-x[0];
函数_使用_a_和_b(a,b);//此函数中使用的a和b的值
//与主数据中计算的不匹配
}
您可能正在使用

*x[0]=3.0

中,当您实际需要使用

(*x)[0]

编辑:顺便说一下,C没有通过引用,它只是一个教学功能。您只需按值传递变量地址,然后取消对该值的引用即可获得原始变量。

void fill\u in\u x(float**x,int num\u vals)
void fill_in_x(float** x, int num_vals)
{
    *x = (float*)malloc(num_vals * sizeof(float));

    for (int i = 0; i < num_vals; ++i) {
        (*x)[i] = (float)i;
    }
}
{ *x=(浮点*)malloc(num_vals*sizeof(浮点)); 对于(整数i=0;i

这也行得通。让我想知道你的填充是什么样的。代码本身没有问题。

正如最初编写的那样,调用
函数时,在作用域中没有使用_a_和_b()
函数原型,因此编译器必须在传递它们之前将
float
值提升为
double
。然后,该函数用原型表示法编写,因此编译器可能不会注意到该函数已被双精度调用,即使原型表示法允许将其以浮点形式传递。这将导致打印时出现奇怪的值


我不相信编译器不会发现这个问题,但它可以解释您看到的问题。当然,如果函数在单独的源文件中,那么编译器就没有机会发现不匹配的地方。

请在函数中显示fill\u请我们也需要使用函数a\u和函数b来查看函数u的定义。我在上面添加了一些精简版本的函数。基本上,如果在使用a和b调用函数之前先打印a和b的值,然后在使用a和b调用函数内部打印F,则值不匹配。很抱歉,我无法提供有关这些函数的更多详细信息。这不是我最初的代码-有人把这个问题带给我,我无法找到它,除了注意到糟糕的设计。由于某些原因,a和b在主要方面是正确的,然后在使用a和b的函数中是错误的
void fill_in_x(float** x, int num_vals)
{
    *x = (float*)malloc(num_vals * sizeof(float));

    for (int i = 0; i < num_vals; ++i) {
        (*x)[i] = (float)i;
    }
}