【问题标题】:Pointer to array of struct in function指向函数中结构数组的指针
【发布时间】:2015-01-16 19:50:01
【问题描述】:

我的指针有问题。我想用一个函数读取一个二进制文件,然后在主文件中使用读取的数据。问题是我必须传递一个指向结构数组的指针才能使用 main 中的数据。

代码是:

#define TMOLDEO 8
#define TAM 41


struct fichpiezas{
    int codPieza;
    float dimPieza;
    float costePieza[TMOLDEO];
};

int leer_fichero(struct fichpiezas *vpiezas[]);

int main(int argc, const char * argv[]) {

    struct fichpiezas vpiezas[TAM];

    leer_fichero(&vpiezas);

    for(int i = 0; sizeof(vpiezas)/sizeof(struct fichpiezas); i++){
        printf("Codigo pieza : %d\n", vpiezas[i].codPieza);
    }

    return 0;
}


int leer_fichero (struct fichpiezas *vpiezas[]){

    FILE *fich;
    struct fichpiezas pieza;
    int error_dev = 0, i = 0;
    if ((fich = fopen("piezas.bin", "rb")) == NULL){
        printf ( "Error en apertura del fichero para lectura \n " );
        error_dev = 1;
    } else{
        //Bucle mientras no sea fin de fichero
        while (! feof(fich)){
            fread (&pieza, sizeof(pieza), 1, fich);
            vpiezas[i] = &pieza;
            i++;
        }

        fclose (fich);
    }

    return error_dev;
}

【问题讨论】:

  • 英文的代码/cmets 通常会更容易阅读,但leer_fichero 中的pieza 具有本地存储,您只需将一个地址放入您的数组中,该对象将是函数结束后超出范围。
  • 这一行:'for(int i = 0; sizeof(vpiezas)/sizeof(struct fichpiezas); i++){' in main() 有问题。它永远不会退出 for 循环,因为计算总是相同的。建议:'for(int i = 0; i
  • 这一行:'while (!feof(fich)){' 将无法按预期工作,因为 feof() 直到从 fich 文件读取操作后才定义。建议使用:'while ( fread (&pieza, sizeof(pieza), 1, fich) ) ' fread 将在成功时返回第三个参数,并且(在这种情况下)在失败/EOF 发生时返回 0。
  • 这一行:'vpiezas[i] = &pieza;每次通过相同的地址。建议:'memcpy( &(vpiezas[i]), &pieza, sizeof(struct fichpiezas) ); ''
  • 这一行:'int leer_fichero (struct fichpiezas *vpiezas[]){' 表示传递一个指针数组,而实际上只涉及一个指向结构数组的指针。建议:'int leer_fichero (struct fichpiezas *vpiezas){'

标签: c arrays pointers struct


【解决方案1】:

改一下

int leer_fichero (struct fichpiezas *vpiezas[])

int leer_fichero (struct fichpiezas *vpiezas)

在你的main()

leer_fichero(&vpiezas);

leer_fichero(vpiezas);

数组在传递给函数时会自动衰减为指针。所以你不需要将它的地址传递给函数。

你还有一个问题,这个作业

vpiezas[i] = &pieza;

是个问题,因为你把局部变量pieza的地址存放在数组中,这个函数返回时数据就没有了。

此外,pieza 的值在每次迭代 bu fread() 中都会被覆盖,并且由于您存储的是 pieza 的地址而不是它的值,因此如果成功,数组的所有元素都将具有相同的值方式。

您需要将结构复制到数组元素中,如果您按照我上面的建议,这行应该更改为

vpiezas[i] = pieza;

否则程序编译失败,因为&pieza的类型是struct fichpiezas *vpiezas[i]的类型现在是struct fichpiezas,修改函数原型后。

另外,关于 while (! feof(fich)) 有一个 answer 详细解释了为什么这是错误的。

还有一件事,添加一个检查i < TAM,否则你有溢出数组的风险。

【讨论】:

  • int leer_fichero (struct fichpiezas vpiezas[])
  • 谢谢!我要证明这一点。
【解决方案2】:

这个

int leer_fichero(struct fichpiezas * vpiezas[]);

vpiezas定义为指向struct fichpiezas的指针,如

int leer_fichero(struct fichpiezas * vpiezas[]);

等价于

int leer_fichero(struct fichpiezas ** vpiezas);

通过做来处理你传递的数组的元素

leer_fichero(&vpiezas);

这样做

(*vpiezas)[index]

leer_fichero() 内部。


定义起来会更直接

int leer_fichero(struct fichpiezas * vpiezas);

然后通过

leer_fichero(vpiezas);

然后你可以像你一样处理元素:

vpiezas[index]

【讨论】:

  • int leer_fichero(struct fichpiezas * vpiezas[]); 没有“将vpiezas 定义为指向struct fichpiezas 的指针的指针”。它将vpiezas 定义为(在函数中用作)指向struct fichpiezas 的指针数组。否则,您的解决方案有效,但您的第一个建议会更清晰,如果您还建议将函数的定义更改为 int leer_fichero(struct fichpiezas (*vpiezas)[]);,或者只是为了清楚起见,在使用 (*vpiezas)[index] 进行访问时更改为 int leer_fichero(struct fichpiezas **vpiezas);。跨度>
  • @kavadias:请看我更新的答案,特别是请注意,在C语言中定义函数参数的上下文中char []相当于char *,以及char *[]相当于@ 987654343@ ...
  • @kavadias: 另请注意,任何传递给函数的数组都会衰减为指向第一个元素的指针。
  • 你是对的!我认为如果函数被声明为,例如int leer_fichero (struct fichpiezas vpiezas[TAM+1]),在main中像leer_fichero(vpiezas);一样调用它,就会出错,但我错了。数组参数是数组的声明——而不是定义——所以它总是简单的指针;而在函数或全局范围内,它始终是一个定义(除非使用extern)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
  • 2012-12-07
  • 2016-06-20
相关资源
最近更新 更多