可以使用struct指针作为多个函数的参数

时间:2014-12-12 00:27:23

标签: c function pointers struct

这是一个在图书馆注册书籍的程序,包括标题,作家和价格。还有计算平均值,最高价格书等内容......当我使用矢量{struct livro Livros [1000]时运行良好而不是指针{struct livro * Livros}。 我使用指针为书籍列表动态分配内存,所有内容都可以很好地注册书籍。但是当我尝试计算平均值时,调用另一个函数为main,程序崩溃,编译器(我在学校使用visual studio)显示消息:

Livraria.exe中0x00ec174c处的未处理异常:0xC0000005:访问冲突读取位置0xcccccd94。

我尝试使用该函数来定位编写器而不是平均值,并且在我放入字符串之后它就崩溃了。当然,当它使用“Livros [i] .autor”比较字符串时

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

#define flush_toilet (fflush(stdin))
//mude o #define dependendo do seu SO
//__fpurge(stdin); "linux"
//fflush(stdin);    "windows"

struct livro {
char titulo [100];
char autor [100];
float prec;
};

//register
void cadastro (int *qtd, struct livro *Livros){
    int i;
    Livros=NULL;



printf("Insira a quantidade de livros:");//defines the quantity(variable "qtd") of books which will pass to the main function(it worked when i used vectors)
scanf ("%i",qtd);
flush_toilet;

Livros = malloc( *qtd *sizeof(struct livro));    //allocates the memory for the list

printf ("insira os dados de cada livro:");

    for (i=0;i<*qtd;i=i+1){
    printf ("\n\n\ninsira o titulo:"); 
    gets (Livros[i].titulo);      //title
    flush_toilet;

    printf ("\ninsira o nome:");
    gets (Livros[i].autor);      //writer
    flush_toilet;

    printf ("\ninsira o preco :");
    scanf ("%f",&Livros[i].prec);//price
    flush_toilet;
    }
}





//calculate average of prices
float media (int qtd, struct livro *Livros){
int i;
float  media=0;
    for (i=0;i<qtd;i=i+1){
    media=media+Livros[i].prec;
    }

media=media/qtd;
return media;

}


//calculate number of books above average
int qtd_acima_med (float media, struct livro *Livros, int qtd){
int acima=0,i;

    for (i=0;i<qtd;i=i+1){

        if(Livros[i].prec>media){
        acima=acima+1;
        }
    }

return acima;


}


//locate a book by writer
void localizar(int qtd, struct livro *Livros){
int i;
char autor[100];

printf("\ndigite o nome do autor cujos livros deseja encontrar:\n");
gets (autor);
flush_toilet;
printf("\n");

    for (i=0;i<qtd;i=i+1){

        if((strcmp (autor, Livros[i].autor))==0){
        puts(Livros[i].titulo);
        printf("\n");
        }


    }
}


//finds and displays the most expensive book
void mais_caro (int qtd, struct livro *Livros ){
int i, ncaro;
float caro=0;
    for (i=0;i<qtd;i=i+1){

        if (Livros [i].prec>caro){
        caro=Livros [i].prec;
        ncaro=i;
        }

    }

puts (Livros[ncaro].titulo);
printf ("preco:  %f\n", Livros[ncaro].prec);
}


void main (){
struct livro *Livros;

int qtd=-1, selec=1, nacima=-1;
float med=-1;

    while (selec!=0){
    printf ("\n\n\nDigite 0 para sair,\n 1 para cadastrar,\n 2 para calcular a media,\n 3 para calcular os livros acima da media,\n 4 para localizar o livro pelo autor,\n 5 para achar o mais caro.\n\n");
    scanf("%i", &selec);
flush_toilet;
        switch (selec){

            case 0:
            break;


            case 1:{
            cadastro(&qtd, Livros);
            break;
            }


            case 2:{

                if(qtd<0){
                printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
                break;
                }
            med=media(qtd, Livros);
            printf("A media e igual a: %f \n", med);

            break;
            }


            case 3:{

                if(med<0){
                printf("erro a media n foi calculada\n");
                break;
                }

            nacima = qtd_acima_med (med, Livros, qtd);
            printf("A qtd de livros com preco acima da media e: %i \n", nacima);
            break;
            }


            case 4:{
                if(qtd<0){
                printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
                break;
                }

            localizar(qtd, Livros);

            break;
            }


            case 5:{
                if(qtd<0){
                printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
                break;
                }

            mais_caro (qtd, Livros);

            break;
            }
        }

    }

free(Livros);
}

1 个答案:

答案 0 :(得分:1)

编译时,我收到以下错误:

1>main.c(138) : warning C4700: uninitialized local variable 'Livros' used

这看起来是bug的原因。要修复,您需要从cadastro

返回已分配的数组
struct livro * cadastro (int *qtd){
    int i;
    struct livro *Livros =NULL;

    printf("Insira a quantidade de livros:");//defines the quantity(variable "qtd") of books which will pass to the main function(it worked when i used vectors)
    scanf ("%i",qtd);
    flush_toilet;

    Livros = malloc( *qtd * sizeof(struct livro));    //allocates the memory for the list

    printf ("insira os dados de cada livro:");

    for (i=0;i<*qtd;i=i+1){
        printf ("\n\n\ninsira o titulo:"); 
        gets (Livros[i].titulo);      //title
        flush_toilet;

        printf ("\ninsira o nome:");
        gets (Livros[i].autor);      //writer
        flush_toilet;

        printf ("\ninsira o preco :");
        scanf ("%f",&Livros[i].prec);//price
        flush_toilet;
    }

    return Livros;
}

然后使用main ()中的回报:

void main (){
    struct livro *Livros = NULL;

    int qtd=-1, selec=1, nacima=-1;
    float med=-1;

    while (selec!=0){

// Snip

        switch (selec){

// snip
            case 1:
                {
                    if (Livros != NULL)
                    {
                        free(Livros);
                        Livros = NULL;
                    }
                    Livros = cadastro(&qtd);
                }
                break;                  

如果没有更多输入或无效输入,您还需要检查scanf()gets()的返回值,并且如果用户输入{的无效值,则需要检查默认情况{1}}。您还应该考虑替换gets() with fgets()以防止缓冲区溢出。但崩溃的直接原因是未初始化的变量。据推测,您的编译器也会报告类似的警告,如果是,则应始终修复此类警告。