Несовместимый тип указателя и возврат делает целое число без проблемы приведения - PullRequest
2 голосов
/ 06 марта 2019

Я пытаюсь создать программу рюкзака, не используя связанный список, но столкнулся с проблемой, которую вполне могу понять.Почти во всех моих функциях я получаю эту ошибку в одной строке с несовместимым типом указателя, и я не совсем понимаю, как ее исправить.Другая проблема, с которой я сталкиваюсь, это 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;

knapsack.c

#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 ]

2 голосов
/ 06 марта 2019

Относительно предупреждения -

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 из функции, возвращающей значение типа int.

относительно других предупреждений, вы пытаетесь присвоить listitemptr типу listitemptr*.(*present)->next относится к типу listitemptr, а knapsack относится к типу listitemptr*.

1 голос
/ 06 марта 2019

Глядя на линию

temp=(*temp)->next;

temp определяется как const listitemptr *temp, что означает его тип const listitemptr *.

Чтобы найти тип (*temp)->next, мы можем посмотреть на его части. Мы уже знаем, что temp является const listitemptr *, поэтому удаление ссылки на него приводит к listitemptr.

Глядя на ваш источник, мы можем найти тип next,

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

теперь мы можем видеть, что next, и, следовательно, (*temp)->next, имеет тип listitemptr.

Итак, вы назначаете listitemptr для const listitemptr *.

Похоже, что большинство этих ошибок вызвано путаницей listitemptr для указателя на listitemptr*.

...