【问题标题】:Struct initialized in function loses values (although it's an array)在函数中初始化的结构丢失值(尽管它是一个数组)
【发布时间】:2021-04-26 21:01:39
【问题描述】:

我正在尝试在“leggif1”中初始化数组 *dip,如果您在其中进行打印,则一切正常,但如果您尝试在主目录中打印,则在初始化后,所有内容都会丢失其值。 一年级“Divisione”的 ADT 也会发生同样的事情,我不明白为什么(尽管由于他们的指针,它们是“通过引用”传递的)。

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

typedef struct {
  int matricola;
  char nome[20+1],cognome[20+1];
  int comp[4];            
}dipendente;

typedef struct divisione  *Divisione;
struct divisione{
dipendente *dip;
char nome[10+1];
int terna[4][3];        //numero minimo di addetti,competenza minima totale, competenza ottimale totale
                        //per ognuna delle 4 tipologie
};

void leggif1(dipendente *dip, char *filename);
int leggif2(Divisione *Div, char *filename);
void DIVstampa(Divisione *Div,char *filename,int D);
Divisione DIVinit();
void DIVfree(Divisione *Div);

int main(int argc,char **argv) {
dipendente *dip;
Divisione *Div;
leggif1(dip,argv[1]);
int D=leggif2(Div, argv[2]);
DIVstampa(Div,"stdout",D);

return 0;
}

void leggif1(dipendente *dip, char *filename) {
FILE *fp=fopen(filename,"r");
int i,N;

fscanf(fp,"%d",&N);
dip=malloc(N*sizeof(dipendente));

for(i=0;i<N;i++)
    fscanf(fp,"%d %s %s %d %d %d %d",&dip[i].matricola,dip[i].nome,dip[i].cognome,
           &dip[i].comp[0],&dip[i].comp[1],&dip[i].comp[2],&dip[i].comp[3]);

}

int leggif2(Divisione *Div, char *filename) {
FILE *fp=fopen(filename,"r");
int i,j,D;
fscanf(fp,"%d",&D);
Div=malloc(D*sizeof(Divisione));
for(i=0;i<D;i++)
    Div[i]=DIVinit();

for(i=0;i<D;i++) {
    fscanf(fp, "%s", Div[i]->nome);
    for (j = 0; j < 4; j++)
        fscanf(fp, "%d %d %d", &Div[i]->terna[j][0], &Div[i]->terna[j][1], &Div[i]->terna[j][2]);
}

return D;
}

void DIVstampa(Divisione *Div, char *filename, int D) {
FILE *fp;
if(strcmp(filename,"stdout")==0)
    fp=stdout;
else
    fp=fopen(filename,"w");

int i,j;
for(i=0;i<D;i++) {
    fprintf(fp,"%s\n", Div[i]->nome);
    for(j=0;j<4;j++)
        fprintf(fp,"%d %d %d\n", Div[i]->terna[j][0], Div[i]->terna[j][1], Div[i]->terna[j][2]);
}

}
Divisione DIVinit(){
Divisione Div=malloc(sizeof (*Div));
return Div;
}

void DIVfree(Divisione *Div){
free(Div);
}

【问题讨论】:

  • 您在dipendente *dip; 中声明了一个指向结构的指针,但它指向哪里?你从一开始就有未定义的行为,所以所有其他的赌注都没有。
  • 请编辑问题并修正缩进。此代码不可读。

标签: c struct pass-by-reference adt


【解决方案1】:

leggif1 函数忽略dip 的值并为其分配一个新值。该值永远不会返回给 main。

dip 的类型是dipendente*,当在 main 中调用时,指针的值被传递给函数。在函数中覆盖该本地副本不会影响main中指针的值。

C 只有“按值调用”,始终确保您知道该值代表什么。

这可以通过返回函数中的dip而不是将其作为参数来解决:

dipendente* leggif1(char *filename)
{
    //open file and read N
    dipendente *dip = malloc(N * sizeof *dip);
    if (!dip) {
        return NULL;
    }
    // read in the data

    return dip;
}

另一种方法是使用dipendente**(指向指针的指针),但在这种情况下,这会使代码变得不必要地复杂。

leggif2 函数也有同样的问题。

【讨论】:

  • 但是*dip 既是指针又是数组,c 中的数组总是通过引用传递,所以这不应该也适用于结构数组吗? @koder
  • @BrcMat,但是您没有传递数组,而是传递了一个未初始化的指针。如果你传递一个数组,你只能改变它的内容。你不能重新定义数组本身。
  • 好的,非常感谢 koder 的努力,我会记住的。
猜你喜欢
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 2013-10-29
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
相关资源
最近更新 更多