Mise en œuvre d'une file d'attente FIFO en C
Pour une application embarquée, je suis en train de mettre en œuvre une méthode du premier entré, premier sorti (FIFO) de la file d'attente de structures à l'aide de la norme ANSI C. la façon La plus simple de faire ce qui semble être par la mise en œuvre d'une liste liée, de sorte que chaque structure contient un pointeur vers le suivant dans la file d'attente. J'ai donc définir la structure elle-même:
typedef enum { LED_on, LED_off, etc } Action;
typedef struct Queued_Action QueuedAction;
struct Queued_Action
{
Action action;
int value;
QueuedAction *nextAction;
};
So far So good. Si je définir des pointeurs vers les premier et dernier éléments de la file d'attente comme:
QueuedAction *firstAction;
QueuedAction *lastAction;
...alors, je voudrais être en mesure d'ajouter une nouvelle action à la file d'attente en indiquant (par exemple):
if (!add_action_to_queue(LED_on, 100, &lastAction))
printf("Error!\n);
...donc sur le retour, lastAction serait un pointeur vers la nouvellement créée, la dernière action dans la file d'attente. D'où la routine pour l'ajout de l'action à la file d'attente ressemblerait à:
int add_action_to_queue(Action newAction, int newValue, QueuedAction **lastAction)
{
QueuedAction *newQueuedAction;
//Create a new action in memory
if ((newQueuedAction = (QueuedAction *)malloc(sizeof(QueuedAction))) == NULL)
return 0;
//Make the old 'lastAction' point to the new Action,
//and the new Action to point to NULL:
*lastAction -> nextAction = newQueuedAction;
newQueuedAction -> nextAction = NULL;
newQueuedAction -> action = newAction;
newQueuedAction -> value = newValue;
//Designate the new Action as the new lastAction:
*lastAction = newQueuedAction;
return 1;
}
Tout irait bien dans le meilleur des mondes, sauf que ce code ne compile pas. L'erreur est à la ligne en disant
*lastAction -> nextAction = newQueuedAction;
...où le compilateur revendications de l'élément à gauche de la '-> " n'est pas valide struct. Certes, toutefois, il doit l'être. Si, en fait, je fais ce que devrait être une filiale redondant cast:
fakeAction = (QueuedAction *)(*lastAction);
fakeAction -> nextAction = newQueuedAction;
...puis le compilateur est assez heureux. Cependant, je suis inquiet que le message d'erreur est faire allusion à quelque chose de subtil que j'ai fait de mal ici. (À venir au point), quelqu'un peut me dire pourquoi le compilateur n'est pas heureux, et si il ya une meilleure façon de faire ce que j'essaie de faire ici.
OriginalL'auteur Eos Pengwern | 2010-10-18
Vous devez vous connecter pour publier un commentaire.
Avez-vous essayé:
Merci à vous deux; c'était bien une question de priorité des opérateurs, et de mettre les crochets autour de l' (*lastAction) résout le problème.
OriginalL'auteur mouviciel
Vous pourriez aussi le faire:
Je pense que c'est un problème d'opérateur pecedence.
OriginalL'auteur frast
J'ai fait une petite bibliothèque qui peut gérer les files d'attente. "UltraQueue"
Il est écrit en C++, mais il est entièrement compatible avec la norme ANSI C.
Il peut être facilement converti en C ANSI, si vous le voulez vraiment.
Code Source est disponible via GIT.
Grtz
OriginalL'auteur xback
J'espère que cela va vous aider à l'avance.
Tout d'abord, désolé pour mon anglais. Il pourrait avoir plusieurs gramatical ou ortographical erreurs.
Le problème que je vois dans votre code est essentiellement que vous mélangez définition d'un pointeur et la mise en œuvre de la même.
De la norme ANSI C à C99, même en C++ (pas testé en C#), il y a un gros hack en utilisant les pointeurs pourrait être utile à l'avance: pense que le pointeur est le premier élément d'un vecteur, la [0] un.
Un grand site expliquant ce concept est le suivant: http://boredzo.org/pointers/
Ce hack, est une simple traduction, et un bel outil de piratage pour mieux comprendre les pointeurs.
Passer à l'action, les garçons.
La fonction que vous utilisez pour ajouter des éléments dans une liste,
Contient quelques erreurs. Tout d'abord, pensez à l'aide de
comme
Comme vous le voyez, vous ne pouvez pas utiliser la -> opérateur pour accéder à l'intérieur des éléments.
La même chose se passe ici:
Vous ne pouvez pas copier un pointeur à l'intérieur d'une structure. lastAction, à l'aide de ce hack pour mieux comprendre, n'est pas un pointeur de plus -en fait, c'est le contenu du premier élément de la structure le compilateur a assigné en y - donc, vous avez besoin de changer cette ligne, aussi, pour modifier la valeur du pointeur:
À l'aide de cette traduction et la anotations, votre code sera, maintenant:
Les erreurs sont, maintenant, visible: vous essayez d'utiliser la -> opérateur à tort. Cela signifie que votre code sera modifié de deux façons:
Il ressemble à ceci:
Il ressemble à ceci:
Et n'oubliez pas d'effacer le == NULL code, vous rencontrez avec un passif-agressif programmeur qui définit la valeur NULL comme quelque chose d'autre. Toujours utiliser des accolades pour assurer l'extensibilité. Cette ligne est seulement une recommandation de code de style.
Espérons que cela aide,
OriginalL'auteur José Manuel Ramos