【问题标题】:warning: passing argument 1 of '...' from incompatible pointer type [-Wincompatible-pointer-types]警告:从不兼容的指针类型 [-Wincompatible-pointer-types] 传递“...”的参数 1
【发布时间】:2021-05-30 21:09:40
【问题描述】:

所以,这段代码(或至少这部分代码)的目标是我将在“地籍”中输入人员的信息,然后用“mostra”显示这些人的所有信息。我尝试使用指针,因为我无法对主要功能(老师的指示)做任何事情,但由于某种原因它不起作用,指针对我来说仍然是一个谜。我尝试查看其他具有相同“通过参数 1...”问题的帖子,但它们并没有真正帮助我,因为那里的问题似乎略有不同。 我最终在 cadastra、mostra 和 mostra1 中收到“警告:从不兼容的指针类型 [-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();
}

【问题讨论】:

  • 在函数 cadastromostra 的声明中,尝试删除参数中的星号,因此 struct prof P[100] 而不是 struct prof *P[100],如函数 mostra1。现在,这两个函数需要一个指向结构的指针数组,而不是结构数组
  • 谢谢,现在可以使用了。虽然我仍然收到“从不兼容的指针类型 [-Wincompatible-pointer-types] 传递'...'的参数 1”警告..​​.
  • 你在哪一行得到错误?
  • 哦等等,在menu()函数里面,好的,所以,在4个ifs中,在调用不同的函数时删除&amp;。数组变量根据定义已经是一个指针,所以你不需要传递它的地址来处理数组
  • 欢迎来到 Stack Overflow。请阅读AboutHow to Ask 页面,还请阅读有关如何创建 MCVE(Minimal, Complete, Verifiable Example — 或 MRE 或 SO 现在使用的任何名称)或 SSCCE(Short, Self-Contained, Correct Example)的信息 — 同样的想法来自不同的名字。

标签: c pointers


【解决方案1】:

void mostra(struct prof *P[100]) 需要一个包含 100 个指向 struct prof 的指针的 数组。您传递的是一个指向struct prof 数组的指针 (monstra(&amp;P))。区别很微妙,但很有意义。

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

mostra(P)

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

void mostra(struct prof P[100])

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

另一个问题是您在使用P[i].ativo 中的值而从未初始化它们。您应该清零数组,或者决定默认初始化它包含的结构的方式。

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

还有一个问题是,由于不限制读取的字符数量,您将自己暴露在缓冲区溢出中。如果你要使用scanf来填写

char nome1[50];

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

scanf("%49s", nome1);

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

此外,在cadastro 中,局部变量ativo 未使用,并且该函数中的循环逻辑有可能在数组边界之外运行。 last 最终可能是&gt;= 100


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

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

【讨论】:

    【解决方案2】:

    指针基本上是一个指向某个东西的内存地址,它可以是一个整数、一个整数数组(这也是一个指针!)或任何东西。 让我们看一个例子

        int* p = malloc(50); //Allocate 50 bytes for this pointer
        int P[50];           //Create an array of 50 ints;
        p[0] = 20;           //The pointer is an array too!
        P[0] = 20;
        printf("p[0] = %d\n",p[0]); //Output: p[0] = 20
        printf("P[0] = %d\n",P[0]); //Output p[0] = 20
    
        printf("Adress of p: %p\n",&p); //Output (depends on every computer and every run): 0x7ffceb5e2ba8
        printf("Adress of P: %p\n",&P); //Output: 0x7ffceb5e2bb0
    

    所以基本上当您执行struct prof* P[100] 时,这是一个指向 prof 结构的指针数组。 但是在您的 menu() 函数中,您只创建了一个 struct prof P[100] 然后将 &P 传递给您的函数,这没关系,因为 &P 它是您结构的内存地址,但是 c 向您发出警告,这不是错误,只是一个警告。 如果您只是创建一个struct prof* P[100],然后将其作为cadastra(P) 传递给函数,那会更自然。 然后你的代码中有很多错误(例如,你没有要求输入 ativo,但你是在条件中使用它)

    【讨论】:

      猜你喜欢
      • 2020-09-24
      • 1970-01-01
      • 2021-07-25
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      相关资源
      最近更新 更多