2009-11-02 3 views
1

Je voulais écrire une pile standard en C mais je ne suis pas sûr que ma fonction stk_size() puisse fonctionner sur d'autres plateformes à l'exception de mon PC 32 bits. J'ai lu que ce n'est pas bon de jeter un pointeur sur int. Mais quelle pourrait être une meilleure mise en œuvre? Je ne veux pas ajouter une "taille" -variable parce que c'est redondant à mes yeux.C - Pointeur vers int pour obtenir des éléments dans la pile

Voici quelques parties de la source:

#define MAX_STACK_SIZE 100 

    typedef struct stk stack; 

    struct stk 
    { 
      /* Stack */ 
      int * stk; 

      /* Pointer to first free element of stack */ 
      int * sp; 
    }; 

    void stk_init(stack* s) 
    { 
      /* Allocate memory for stack */ 
      s->stk   = malloc(sizeof(s->stk) * MAX_STACK_SIZE); 

      /* Set stack pointer to first free element of stack -> 0 */ 
      s->sp   = s->stk; 
    } 

    int stk_size(stack* s) 
    { 
      return ((int) s->sp - (int) s->stk)/sizeof(int *); 
    } 

    int main(int argc, char * argv[]) 
    { 
      stack * s; 
      stk_init(s); 
    } 

Merci!

+0

Si vous devez jeter, pourquoi ne pas jeter (si nécessaire) après la soustraction? –

Répondre

9

Vous pouvez simplement utiliser (s->sp - s->stk). La soustraction des pointeurs génère un ptrdiff_t, qui est un type intégral signé.

0

Ne pas convertir les deux pointeurs en int. Soustrayez les pointeurs et placez le résultat dans un int, unsigned int (si vous connaissez s-> sp est toujours> = s-> stk). Cela élimine le besoin de diviser par sizeof (int *).

0

Il existe un type défini par les normes, intptr_t, dont la taille est suffisamment grande pour pouvoir stocker un type int ou n'importe quel type de pointeur. Utiliser ça. Par exemple, si vous étiez sur une plate-forme où int est 32 bits mais qu'un pointeur est 64 bits, intptr_t serait un type 64 bits.

5

Pour commencer, vous avez un bug. Vous n'avez alloué aucun espace pour votre objet stack. Vous voulez soit

int main(int argc, char * argv[]) 
{ 
     stack s; 
     stk_init(&s); 
} 

ou

int main(int argc, char * argv[]) 
{ 
     stack * s = malloc(sizeof(stack)); 
     stk_init(s); 
} 

Quant à votre question, je vois @Crashworks a déjà répondu pendant que je tapais cela.

+0

... ou 's = stk_init()' – caf

+0

@caf Cela n'aiderait pas, sauf si stk_init a été réécrit pour allouer une pile et la retourner. C'est peut-être ce que vous suggérez. – Grumdrig

+0

Eh bien, oui - tout comme 'stk_init' aurait besoin d'être changé pour votre première suggestion. – caf

1

Pas besoin de jeter, et pas besoin de diviser tant que vous voulez que votre réponse dans ints

size_t stk_size(stack* s) 
{ 
     return (s->sp - s->stk); 
} 
2

En stk_init Vous devez utiliser

s->stk = malloc(sizeof(int) * MAX_STACK_SIZE); 

parce stk est un int *. En d'autres termes, votre pile est composée de int s.

En stk_size vous devriez faire ceci:

return s->sp - s->stk; 

Lorsque vous soustrayez des pointeurs en C, C prend en compte la taille de l'objet qu'ils pointent vers (qui dans ce cas est un int).

C'est une idée stupide, mais si vous voulez vraiment, vous feriez comme ceci: ((int) s->sp - (int) s->stk)/sizeof(int);

+0

Alternativement, 'malloc (MAX_STACK_SIZE * sizeof * s-> stk)'. – caf

+0

Oui, même si je trouve cela plus difficile à lire. IMO un typedef serait mieux. – Artelius

Questions connexes