指针类型和返回值不兼容,使整数变为强制类型

时间:2019-03-05 23:38:47

标签: c pointers casting linked-list

我正在尝试使用链表创建背包程序,但是我遇到了一个我很想知道的问题。在几乎所有的函数中,我都会在不兼容的指针类型的同一行上遇到此错误,而我对如何解决它感到困惑。我遇到的另一个问题是return makes integer from pointer without a cast错误。以下是完整的代码和错误。错误在于knapsack.c文件中,test_knapsack.c仅作为测试的主要功能示例给出。

错误

knapsack.c: In function ‘KnapsackRemove’:
knapsack.c:37:16: warning: return makes integer from pointer without a cast [-Wint-conversion]
         return NULL;
                ^
knapsack.c:47:29: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
                     knapsack=(*present)->next;

knapsack.c:59:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
     return *knapsack;
            ^
knapsack.c: In function ‘KnapsackPrint’:
knapsack.c:69:17: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
             temp=(*temp)->next;
                 ^
knapsack.c: In function ‘KnapsackItemCount’:
knapsack.c:82:13: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
         temp=(*temp)-> next;
             ^
knapsack.c: In function ‘KnapsackSize’:
knapsack.c:94:13: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
         temp=(*temp)-> next;

背包。

#include <stdio.h>
#include "knapsack.h"
#include <stdlib.h>

listitemptr KnapsackAdd(listitemptr *knapsack, int item){
    if(knapsack == NULL){
        listitemptr newer = (listitemptr)malloc(sizeof(listitemptr));
        newer-> item = item;
        newer-> count = 1;
        newer-> next = NULL;
        return newer;
    }else{
        listitemptr *temp = knapsack;
        listitemptr previous = NULL;
        while(temp!= NULL){
            if((*temp)->item == item){
                (*temp)->count=(*temp)->count+1;
                break;
            }
            previous = *temp;
            *temp = (*temp)->next;
        }
        if(temp == NULL){
            listitemptr newer = (listitemptr)malloc(sizeof(listitemptr));
            newer->item = item;
            newer->count =1;
            newer->next = NULL;
            previous->next = newer;
            return newer;
        }
        return *temp;
    }
}

int KnapsackRemove(listitemptr *knapsack, int item){
    if(knapsack==NULL)
        return NULL;
    listitemptr *present = knapsack;
    listitemptr previous = NULL;

    while(present != NULL){
        if((*present)->item == item){
            if((*present)-> count > 1){
                (*present)->count=(*present)->count-1;
            }else{
                if(previous==NULL){
                    knapsack=(*present)->next;
                }else{
                    previous->next=(*present)->next;
                    free(present);
                }
            }
            break;
        }
        previous=*present;
        *present=(*present)->next;
    }

    return *knapsack;
}

void KnapsackPrint(const listitemptr *knapsack){
    if(knapsack == NULL)
        printf("(nothing)\n");
    else{
       const listitemptr *temp = knapsack;
        while(temp!= NULL){
            printf("%d (%d), ",(*temp)->item, (*temp)->count);
            temp=(*temp)->next;
        }
        printf("\n");
    }
}

unsigned int KnapsackItemCount(const listitemptr *knapsack, int item){
    if(knapsack== NULL)
        return 0;
    const listitemptr *temp = knapsack;
    while(temp != NULL){
        if((*temp)-> item== item)
            return (*temp)-> count;
        temp=(*temp)-> next;
    }
    return 0;
}

unsigned int KnapsackSize(const listitemptr *knapsack){
    if(knapsack == NULL)
        return 0;
   const listitemptr *temp = knapsack;
    unsigned int sum = 0;
    while(temp!= NULL){
        sum+= (*temp)-> count;
        temp=(*temp)-> next;
    }
    return sum;
}

knapsack.h

/* knapsack.h
 * implements simple knapsack data structure as a linked list 
 * NOTE: a function may update the value of input argument *knapsack if it changes the first node of the knapsack to another node. Such a change include the case when an item is added to an empty knapsack
 */

typedef struct listitem* listitemptr;


struct listitem {
  int item;           // actual int item
  unsigned int count; // number of the same item in the knapsack; should be >= 1
  listitemptr next;   // pointer to next item 
};


listitemptr KnapsackAdd(listitemptr *knapsack, int item);


int KnapsackRemove(listitemptr *knapsack, int item);


void KnapsackPrint(const listitemptr *knapsack);


unsigned int KnapsackItemCount(const listitemptr *knapsack, int item);


unsigned int KnapsackSize(const listitemptr *knapsack);

test_knapsack.c

#include "knapsack.h"
#include <stdio.h>
#include <assert.h>

int main(){
   //knapsack k1
   listitemptr head=KnapsackAdd(NULL,10);
   KnapsackAdd(&head,-20);
   KnapsackAdd(&head,10);
   KnapsackAdd(&head,15);
   KnapsackAdd(&head,-20);
   KnapsackAdd(&head,10);

   KnapsackPrint(&head);

   int count=KnapsackItemCount(&head,10);
   assert(count==3);

   count=KnapsackItemCount(&head,8);
   assert(count==0);

   count=KnapsackSize(&head);
   assert(count==6);

   //knapsack2
   listitemptr head2=KnapsackAdd(NULL,5);
   KnapsackAdd(&head2,10);
   KnapsackAdd(&head2,15);
   KnapsackAdd(&head2,20);
   KnapsackAdd(&head2,-5);


   KnapsackPrint(&head2);

   KnapsackRemove(&head2,15);
   count=KnapsackSize(&head2);
   assert(count==4);

   count=KnapsackItemCount(&head2,15);
   assert(count==0);

   KnapsackRemove(&head2,10);
   count=KnapsackSize(&head2);
   assert(count==3);

   KnapsackAdd(&head,10);

   count=KnapsackSize(&head2);
   assert(count==3);

   count=KnapsackSize(&head);
   assert(count==7);   


   return 0;
   }

2 个答案:

答案 0 :(得分:2)

关于警告-

knapsack.c:37:16: warning: return makes integer from pointer without a cast [-Wint-conversion]
     return NULL;

NULL的定义取决于编译器,可能是在您的编译器NULL中将其定义为(void*)0,因此您尝试返回一个指针,但是将函数定义为int KnapsackRemove(...),因此期望返回一个int值。

关于-

knapsack.c:59:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
 return *knapsack;

您正在尝试从返回整数的函数中返回listitemptr类型。

关于其他警告,您正在尝试将listitemptr分配给listitemptr*类型。 (*present)->next的类型为listitemptrknapsack的类型为listitemptr*

答案 1 :(得分:1)

看那行

temp=(*temp)->next;

temp被定义为const listitemptr *temp,表示其类型为const listitemptr *

要找到(*temp)->next的类型,我们可以看一下它的各个部分。我们已经知道tempconst listitemptr *,因此取消引用它会导致listitemptr

查看您的来源,然后我们可以找到next的类型,

struct listitem {
  listitemptr next;   // pointer to next item 
};

现在我们可以看到next,因此(*temp)->next的类型为listitemptr

因此,您正在将listitemptr分配给const listitemptr *

这些错误中的大多数似乎是由于混淆listitemptr指向listitemptr*的指针引起的。