【问题标题】:Incompatible pointer type - C不兼容的指针类型 - C
【发布时间】:2016-08-25 06:51:00
【问题描述】:

我有这种结构的结构,在这段代码中显示:

typedef void* DataP;
typedef struct Table* TableP;
typedef const void* ConstKeyP;

typedef struct DataPointer
{
    DataP dataP;
    ConstKeyP key;
}DataPointer;

typedef struct HashTableSet
{
DataPointer *hashSet[MAX_ROW_ELEMENTS];
}HashTableSet;

typedef struct HashTableSet *HashTable;

typedef struct Table
{
int size, d;
HashTable hashTable;
}Table;

这就是结构。 现在这里是创建哈希表的函数 -

TableP createTable(size_t tableSize)
{
TableP tableP = (TableP)malloc(sizeof(Table));
HashTable table = (HashTable)malloc(sizeof(HashTable));
tableP->d = 1;
tableP->size = tableSize;
nullTable(tableP);
return tableP;
}

其中 nullTable 是一个函数,我希望它既可以为实际集合提供内存,也可以提供 null 初始值:

void nullTable(TableP tableP)
{
HashTable hashTable = tableP->hashTable;
int i = 0;
for(;  i < tableP->size; i++)
{
    int j = 0;
    HashTableSet *hashTableSet = (HashTableSet*)malloc(sizeof(HashTableSet));
    for (; j < MAX_ROW_ELEMENTS ; ++j)
    {

        DataPointer *data = (DataPointer*)malloc(sizeof(HashTableSet));
        hashTableSet->hashSet[j] = data;
    }
    hashTable[i] = *hashTableSet;
    //hashTable->hashSet = *hashTableSet;
    hashTable += sizeof(HashTableSet);

    }
}

这里出现第一个问题 - 在 nullTable 的最后几行中,我试图将我的 hashTable 指针“跳转”到下一组内存。这意味着我已经为一个集合分配了我需要的所有空间,将我的 hashTable[i] 指向它,然后我将 sizeof(HashTableSet) 添加到 hashTable,因为我希望它到达另一个 hashTableSet 的下一个“点”。这已经填满了,就像我做错了什么一样。

接下来我要解决我真正的问题,即理解这个指针迭代在这个函数中是如何工作的:

DataP removeData(TableP table, const void* key)
{
TableP tableP = table;
int cell = table->hfun(key, table->size);
HashTable hashTable = table->hashTable;
HashTableSet *setPtr = hashTable->hashSet;
int i = 0;
int j = 0;
int d = 1;
while(d < tableP->d)
{
    for (; i < MAX_ROW_ELEMENTS; i++)
    {
        if (table->fcomp(setPtr->hashSet[i]->key, key) == 0)
        {
            DataP dataP = setPtr->hashSet[i]->dataP;
            setPtr->hashSet[i] = NULL;
            table->freeKey((void*)key);
            return dataP;
        }
    }
    setPtr *= 2;
    i = 0;
}
return NULL;
}

我希望 setPtr 指向我表的第一个 HashTableSet。但我收到此错误消息:

 warning: initialization from incompatible pointer type
 HashTableSet *setPtr = hashTable->hashSet;

我在理解如何将 setPtr 带到下一个 hashSet 时也遇到了问题,假设我设法根据我的需要正确地定义了 setPtr。

【问题讨论】:

  • setPtr的类型是HashTableSet*,而hashTable-&gt;hashSet转换的类型是DataPointer**。这是不匹配的地方。
  • 停止使用强制类型转换和指针类型定义。它将使您的代码更易于阅读(并帮助编译器诊断问题)。
  • .. 或者至少与命名一致:ConstKeyP key; --> ConstKeyP keyP;typedef struct HashTableSet *HashTable; --> typedef struct HashTableSet *HashTableP; 等等...

标签: c pointers struct


【解决方案1】:

根据您的定义:

typedef void* DataP;
typedef struct Table* TableP;
typedef const void* ConstKeyP;

typedef struct DataPointer
{
    DataP dataP;
    ConstKeyP key;
}DataPointer;

typedef struct HashTableSet
{
DataPointer *hashSet[MAX_ROW_ELEMENTS];
}HashTableSet;

typedef struct HashTableSet *HashTable;

typedef struct Table
{
int size, d;
HashTable hashTable;
}Table;

来自您的代码:

HashTable hashTable = tableP->hashTable;
HashTableSet *setPtr = hashTable->hashSet;

所以hashTable 类型为HashTable,即struct HashTableSet*。到目前为止,一切都很好。 下一行是问题: HashTableSet *setPtr = hashTable->hashSet;

hashTable-&gt;hashSet 不是 HashTableSet 类型!

这将起作用:

DataP removeData(TableP table, const void* key) 
  { 
      TableP tableP = table; 
      int cell = table->hfun(key, table->size); 
      HashTable hashTable = table->hashTable; 
      /*  
       * See change in the following line: 
       * Before the change you were trying to assign type  
       * `HashSet` into type `HashTableSet*`, this will   
       */ 
      HashTableSet *setPtr = hashTable;                                                         
      int i = 0;         
      int j = 0;         
      int d = 1;         
      while(d < tableP->d)         
      {         
          for (; i < MAX_ROW_ELEMENTS; i++)     
          {     
              if (table->fcomp(setPtr->hashSet[i]->key, key) == 0) 
              { 
                  DataP dataP = setPtr->hashSet[i]->dataP;
                  setPtr->hashSet[i] = NULL;
                  table->freeKey((void*)key);
                  return dataP;
              } 
          }     
          setPtr *= 2;     
          i = 0;     
      }         
      return NULL;         
  }      

【讨论】:

  • 谢谢,我想我现在明白了。我有一个问题 - 我现在遇到了 setPtr *= 2 的问题。如果我的目标是达到下一个指数级的 hashSet,假设我的第一个集合有 setPtr 点,我希望下一次迭代指向第二个,下一次迭代指向第 4 次,然后是第 8 次,exc.. 增加我的 setPtr 的正确方法是什么?
  • 您好 Eyzuky,这是一个不同的问题,并且比可以在评论中回答的问题更广泛。如果您的原始问题有一个已接受的答案,请将其标记为已回答并在新线程中提出新问题。
  • @Eyzuky for (i=1; i &lt; number_of_sets; i*=2) { /*do some stuff */ setPtr +=i;}
  • 当然,@KlasLindbäck 也总是可以准确回答您的第二个问题 (; +1
  • 非常感谢大家!我从你的回答中学到了很多。话虽如此,还有很多东西要学:)
猜你喜欢
  • 2016-11-12
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 2013-11-06
  • 1970-01-01
相关资源
最近更新 更多