首页 > 解决方案 > 警告:从不兼容的指针类型 [-Wincompatible-pointer-types] 传递“...”的参数 1

问题描述

所以,这段代码(或至少这部分代码)的目标是我将在“地籍”中输入人员的信息,然后用“mostra”显示这些人的所有信息。我尝试使用指针,因为我不能对主要功能(老师的指示)做任何事情,但由于某种原因它不起作用,指针对我来说仍然是一个谜。我尝试查看具有相同“通过参数 1 ...”问题的其他帖子,但它们并没有真正帮助我,因为那里的问题似乎略有不同。我最终在菜单功能内的地籍、莫斯特拉和莫斯特拉1中得到“警告:从不兼容的指针类型[-Wincompatible-pointer-types]传递'...'的参数1” 。(我还没有开始 mostra1'

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

struct prof {
    char nome[50];
    char matricula[50];
    char email[50];
    int ativo;
    int dia, mes, ano, hora, min;
};

void cadastro(struct prof *P[100]) {
    char nome1[50];
    char matricula1[50];
    char email1[50];
    int ativo, exit;
    int dia1, mes1, ano1, hora1, min1, last = 0;

    do {
        printf("\n----------------");
        printf("\n1- Digite seu Nome: ");
        scanf("%s", nome1);
        getchar();

        printf("\n2- Digite seu email (exemplo@ufu.br): ");
        scanf("%s", email1);
        getchar();

        printf("\n3- Digite sua matricula: ");
        scanf("%s", matricula1);
        getchar();

        printf("\n4- Data (dia mes ano): ");
        scanf("%d/%d/%d", &dia1, &mes1, &ano1);
        getchar();


        printf("\n5- Horario (hora minutos): ");
        scanf("%d:%d", &hora1, &min1);
        getchar();
        printf("----------------\n");

        for (int i = last; i < last + 1; i++) {
            if (P[i] -> ativo == 0) {
                P[i] -> dia = dia1;
                P[i] -> mes = mes1;
                P[i] -> ano = ano1;
                P[i] -> hora = hora1;
                P[i] -> min = min1;
                P[i] -> ativo = 1;
                strcpy(P[i] -> nome, nome1);
                strcpy(P[i] -> matricula, matricula1);
                strcpy(P[i] -> email, email1);
                last++;
                break;
            }
        }

        printf("\n\n1- Continuar\n0 - Sair\n");
        printf("\nDigite opcao: ");
        scanf("%d", &exit);
    } while (exit != 0);
}

void mostra(struct prof *P[100]) {
    system("cls");

    int exit;
    printf("\nLista de reservas\n");

    do {
        for (int i = 0; i<100; i++) {
            if (P[i] -> ativo == 1) {
                printf("----------------\n");
                printf("1- Nome: %s\n", P[i] -> nome);
                printf("2- E-mail: %s\n", P[i] -> email);
                printf("3- Matricula: %s\n", P[i] -> matricula);
                printf("4- Data: %d/%d/%d\n", P[i] -> dia, P[i] -> mes, P[i] -> ano);
                printf("5- Hora: %d:%d\n", P[i] -> hora, P[i] -> min);
                printf("----------------\n");
            }
            printf("\n1- Continuar\n0 - Sair\n");
            printf("\nDigite opcao: ");
            scanf("%d", &exit);
            getchar();
        }
    } while (exit != 0);
}

void mostra1(struct prof P[100]) {

}

void menu() {
    int opcao;
    struct prof P[100];

    while (1) {
        printf("\nBem vindo ao Sistema de Sistema de Informacao para controle das reservas dos laboratorios e salas da UFU\n");
        printf("\n1- Cadastrar ");
        printf("\n2- Mostrar Todos");
        printf("\n3- Mostrar um");
        printf("\n9- Sair ");
        printf("\nDigite opcao: ");
        scanf("%d", &opcao);

        if (opcao == 1) cadastro(&P);
        if (opcao == 2) mostra(&P);
        if (opcao == 3) mostra1(&P);
        if (opcao == 9) return;
    }
}

int main() {
    menu();
}

标签: cpointers

解决方案


void mostra(struct prof *P[100])需要一个包含 100 个指针的数组struct prof。您传递的是一个指向( )数组的指针struct profmonstra(&P)。差异是微妙的,但非常有意义。

而不是这些选项中的任何一个,将调用更改为cadastromonstramonstra1以传递数组

mostra(P)

并将函数更改为简单地接受一个数组(实际上衰减为指向数组第一个元素的指针)

void mostra(struct prof P[100])

并不是说您必须将成员访问通过指针( ->) 的成员访问更改为成员访问( .),因为数组包含结构元素而不是指向结构的指针。

另一个问题是您在P[i].ativo没有初始化它们的情况下使用找到的值。您应该将数组清零,或者决定一种默认初始化它包含的结构的方法。

struct prof P[100];        
memset(P, 0, sizeof P);

另一个问题是,您通过不限制您读取的字符数量而将自己暴露在缓冲区溢出中。如果你要scanf用来填充

char nome1[50];

您应该将其限制为读取最大大小减一(为 NUL 字符留出空间)

scanf("%49s", nome1);

检查函数的返回值也是一个好主意,scanf因为它们指示成功发生的转换量。如果不检查这一点,您可能正在对不完整、未初始化或其他垃圾数据进行操作。

此外,在cadastro局部变量ativo中未使用,并且该函数中的循环逻辑有可能在您的数组范围之外运行。last可能最终会 >= 100


旁注,exit用作变量名可能会导致混淆。虽然隐藏标识符是完全合法的,但它exit是一个非常知名的标准库函数。乍一看,阅读scanf("%d", &exit);非常混乱。这纯粹是风格,但您将来可能希望避免这种情况。

最后,void main()是完全错误的。main有两个有效的签名:int main(int, char **)int main(void)


推荐阅读