将指针/数组从函数传递给main()

Rey*_*eyL 9 c pointers dynamic-arrays

我正在学习函数/指针,并且遇到了一些问题.我需要写的是一个C程序main()和另外两个函数.

要求:

  1. read_funct()必须分配足够的内存malloc()用于存储数据.

  2. 函数原型read_funct 必须是:

    int read_funct(int *data_num, double **data_vals, char *filename)
    
    Run Code Online (Sandbox Code Playgroud)

它是如何工作的:

  1. main() 调用第一个函数: read_funct()

  2. read_num()从文件中读取二进制数据.必须提取两个值:no.值(前4个字节),然后是值本身(每个8个字节,因此包含在下一个8*值的值中).这些对应于data_numdata_vals.他们必须打印,程序然后返回main().

  3. main() 执行操作以编辑第一个文件中的数据.

  4. main()调用第二个函数:write_funct(),它将编辑后的数据写入新文件.

我在哪里:

第一个函数data_num正确读取,并读取/打印data_vals.这一切都正常.但是,我正在尝试打印这些main()以验证我正在对正确的数据执行操作,但我无法使其正常工作.

注意:我现在不是试图让它一起工作write_funct(),只是一步一步地进行.

这是我目前的代码main():

int read_funct(int *data_num, double **data_vals, char *filename);
int main()
{
  int data_num;
  double **data_vals;

  //Reads file using read_funct()
  read_funct(&data_num, data_vals, filename);

  //Check: print data_num
  printf("\nCheck No. of Values: %d\n", data_num);

  //Check: print data_vals
  for(int i = 0; i<data_num; i++)
  {
        printf("%0.3lf\t", data_vals[i]);
  }
  return(0);
}
Run Code Online (Sandbox Code Playgroud)

这是read_funct()

int read_funct (int *data_num, double **data_vals, char *filename)
{
    FILE * fp = fopen(filename, "rb");                          //Opening file      
   //There's code here to check valid file open

   //There's code here to determine size and check valid length

  //Proceed with reading data_num if file is large enough
  char buffer_n[4];
  fread(buffer_n, 4, 1, fp);
  int res = buffer_n[0]|(buffer_n[1] << 8)|(buffer_n[2] << 16)|(buffer_n[3] << 24);     //Convert endian

  data_num = &res;          //Passes results back to data_num
  printf("Number of Data Values: %d \n", *data_num);    //Printing results

  //Proceeds with calculating data_vals
  data_vals = malloc(8*res);                //Allocating memory
  fread(data_vals, 8, res, fp); 

    //Prints data_vals
    for(int i=0; i<res; i++)
    {
        printf("%0.3f\t", data_vals[i]);
    }
    printf("\nEnd of File Read.\n\n");
    fclose(fp); 
    free(data_vals);                //Free allocated memory
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

期望的输出:

基本上,我希望它从内部打印出值read_file()然后打印签入main(),所以输出将是这样的:

No. of values: 3            //From printf in read_file()
2 4 6

Check No. of values: 3      //From printf in main()
2 4 6
Run Code Online (Sandbox Code Playgroud)

在哪里,我认为我错了:

  1. 相当肯定的是,主要问题是我搞砸了我的指针以及我是如何初始化的main().我一直在努力解决这个问题,但我认为我需要一些更有经验的帮助来解决这个问题.

  2. 我知道每次malloc()通话都必须有一个后续的free(),但是我担心通过这样做我的方式,也许我已经做到了这样我无法取回它main().是否需要有一个分配内存的中间缓冲区?

将非常感谢帮助使此代码正常工作.谢谢!

lin*_*fan 6

除了过早释放数据外,您还有另一个问题:

double **data_vals;
read_funct(&data_num, data_vals, filename);
Run Code Online (Sandbox Code Playgroud)

如果您希望data_vals通过函数填充(写入,修改),则必须完全按照您的方式传递其地址data_num.

这是另一个略有不同的解释.你看,你声明data_vals但你没有给它赋值 - 它包含垃圾.因此,传递data_vals给任何函数或在任何表达式中使用它都是无意义的.它有一个感觉,而不是到指定的东西给它,无论是通过直接转让或通过它的地址给一个函数,该函数来填充变量.

然后,您的用法data_vals描绘了一个向量或一个数组.所以你真的需要声明一个数组[],或者可能是一个指针(指针和数组在C中非常相关/可互换).main()函数的逻辑需要指针,而不是指向指针的指针.因此,这是合适的:

double *data_vals;
Run Code Online (Sandbox Code Playgroud)

相反,写入指针变量的函数需要写入变量的地址; 换句话说:指向指针的指针.这就是您的函数具有此(正确)签名的原因:

read_funct(..., double **data_vals, ...)
Run Code Online (Sandbox Code Playgroud)

要轻松理解,请查看您正确编写的其他(更简单)的内容:

int data_num;
read_funct(&data_num, ...);  // declaration: read_funct(int *data_num, ...)
Run Code Online (Sandbox Code Playgroud)

data_num在main()中声明为整数; 你使用指向整数指针的形式参数声明read_funct(),然后调用read_funct()传递变量的地址data_num.完善.现在,对其他变量做同样的事情data_vals.你将它声明为double的指针,使用表示法将其地址传递给read_funct()&data_vals,并且你的函数read_funct()将该参数声明为指向double的指针(并使用它写入它*data_vals = ....你可以看到两者之间的并行性变量吧?

可能是我太迂腐了,但你的问题非常清楚,形成得很好,所以我也尝试过这样做.