【问题标题】:Assignment from incompatible pointer type and derefrencing pointer to incomplete type从不兼容的指针类型和取消引用指针到不完整类型的赋值
【发布时间】:2017-02-05 19:53:54
【问题描述】:

我正在尝试获取字符和每个字符的数量并将它们放入链接列表中。正如标题所述,我不断收到有关不兼容指针类型的警告和有关取消引用不完整类型的错误。我认为我说的最后一个是因为 start 为空,但我不明白为什么当我将它分配给 temp 时。请帮忙。

/* Author: Miller Kahihu
Date:  2017-02-01
Program getChars.c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct linkedList
{
    struct Element* start;
    int size;
} LinkedList;

typedef struct element
{
    char key;
    int value;
    struct Element* next;
} Element;

int main(int argc, char** argv)
{   
    LinkedList* list = malloc(sizeof(LinkedList));
    list->start = NULL;
    list->size = 0;

    char* fileName = NULL;
    if(argc > 1)
    {
        fileName = argv[1];
    }
    else
    {
        exit(1);
    }
    FILE* fpIn = fopen(fileName, "r");
    if(!fpIn)
    {
        fprintf(stderr, "file %s could not be opened\n", fileName);
        exit(1);
    }
    int c;
    Element* temp = (Element*) malloc(sizeof(Element));
    while((c=fgetc(fpIn)) !=EOF)
    {
        if(list->start == NULL)
        {
            temp->key = (char) c;
            temp->value = 1;
            temp->next = NULL;
            list->start = temp;
            printf("%c kappa\n", list->start->key);
        }
        else
        {
            printf("%c\n", (char) c);
        }
    }
    //free(temp);
    return 0;
}

这是完整的错误信息

getChars.c: In function ‘main’:
getChars.c:51:25: warning: assignment from incompatible pointer type [enabled by default]                                                                 
         list->start = temp;
                     ^
getChars.c:52:45: error: dereferencing pointer to incomplete type
         printf("%c kappa\n", list->start->key);
                                         ^

【问题讨论】:

  • 似乎有 Element 的寄生虫 fwd decl。你应该在链表之前声明你的元素结构。

标签: c


【解决方案1】:

问题不在于struct Elementclang 在其警告中提供了更多线索。

test.c:52:25: warning: incompatible pointer types assigning to 'struct Element *' from 'Element *'
      (aka 'struct element *') [-Wincompatible-pointer-types]
            list->start = temp;
                        ^ ~~~~

您有struct elementElement,但没有struct Element

typedef struct element
{
    char key;
    int value;
    struct Element* next;
} Element;

使用不同的案例会冒这种愚蠢的风险。你最好用这样的东西:

typedef struct Element
{
    char key;
    int value;
    struct Element* next;
} Element_t;

使用大写字母意味着您不会与内置插件发生冲突。 struct Element 不会与任何东西冲突。并且Element_t 明确表示它是一种类型,并且不会与变量和函数名称冲突。

【讨论】:

  • 可能不想使用_t 后缀,特别是如果他现在或将来要针对 POSIX 系统。
  • @JeffMercado 大写应该避免与 POSIX 类型发生冲突,是吗?
  • 或许可以,但我不会冒险。后缀是限制,而不是其他所有内容的大写方式,因此所有内容都被保留。同样的原因,你不应该在任何东西前面加上双下划线,因为它们也是保留的。就个人而言,我使用的约定是在结构名称前加上下划线,在实际类型名称前加上大写。所以所有用户定义的类型都是大写的。
猜你喜欢
  • 2013-12-12
  • 2019-08-09
  • 2013-03-11
  • 2021-04-07
  • 1970-01-01
相关资源
最近更新 更多