2010-08-03 7 views
1

Je suis censé écrire un programme avec deux fonctions:liste chaînée de minuteries en C

Une fonction est responsable de la construction d'une structure de données peuplée par une liste de fonctions dans une course (vous obtenez un pointeur de fonction) son temps d'exécution (quelques secondes après le démarrage d'un programme donné). Vous devez savoir utiliser la fonction, ajouter la structure de données des organes, comment le faire plus efficacement, sauvegarder les tests, les vérifications croisées, etc. La deuxième fonction exécute toutes les fonctions dans l'ordre. Si par exemple le début du programme une fois que vous avez deux fonctions étaient l'une des cinq secondes période de 12, d'abord couru après 5 secondes et l'autre sept secondes après le premier. (Total 12 depuis le début).

Encore une fois faire attention à la façon de le faire, même par rapport à la première fonction. Tout a été fermé après la course, c'est-à-dire après qu'une fonction ait fini de fonctionner n'est plus une excuse. Toute nouvelle exécution du programme entrera dans ses nouvelles fonctions.

Ci-joint deux implentations: une maladroite et ne pas passer par la compilation (au moins pour moi) avec le principal et une sortie pour l'utilisateur, et l'autre n'est pas encombrante mais sans la sortie principale et l'utilisateur. Je dois utiliser encombrant avec la sortie à l'utilisateur (et bien sûr vous avez également besoin principal). Quelqu'un peut-il m'aider s'il-vous-plaît? Pourquoi ai-je besoin d'un pointeur de fonction ici? Toute explication ou documentation supplémentaire pour m'aider à mieux comprendre ce qui se passe.

Un grand merci, vous devez changer à l'avance

/*First implemntation: heavy and doesn't compile*/ 


#ifndef __MY_TIMER_H__ 
#define __MY_TIMER_H__ 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

typedef void(*fun_t)(int); 
typedef struct timer 
{ 
    int time; 
    fun_t func; 
    struct timer *next; 
}timers; 

void add_timer(int sec, fun_t func,timers *head); 

void run_timers(timers *head); 

void timer_func(int); 

#endif /* __MY_TIMER_H__ */ 

---------------------------------------------------------------------- 

#include "my_timer.h" 

#undef DEBUG 
#define DEBUG 1 

int main() 
{ 
    int time = 1; 
    timers *head = NULL; 
    fun_t func = timer_func; 

    while (time < 1000) 
    { 
    printf("\nCalling add_timer(time=%d, func=0x%x, head=0x%x)\n", time, func, &head); 
    add_timer(time, func,&head); 
    time *= 2; 
    } 

    run_timers(&head); 
    return 0; 
} 

timers *head; 

void timer_func(int time) 
{ 
    printf("Called %s at time %d.\n", __FUNCTION__, time); 
    return; 
} 

void add_timer(int sec, fun_t func, timers *head) 
{ 
    timers *curr = head, *prev = NULL; 
    timers *new_timer = NULL; 

    new_timer = (timers*)malloc(sizeof(timers)); 
    new_timer->time = sec; 
    new_timer->func = func; 
    new_timer->next = NULL; 

    if (curr == NULL) { 
    head = new_timer; 
    return; 
    } 

    while (curr != NULL && curr->time < sec) { 
    prev = curr; 
    curr = curr->next; 
    } 

    if (curr == head) { 
    new_timer->next = curr; 
    head = new_timer; 
    } 
    else { 
    new_timer->next = prev->next; 
    prev->next = new_timer; 
    }  

    return; 
} 

void run_timers(timers *head) 
{ 
    int elapsed_time = 0; 
    timers *curr = head; 
    timers *timer_p = NULL; 

    while (curr != NULL) { 
    printf("\nGoing to sleep for %d secs\n", curr->time - elapsed_time); 
    printf("\ncurr->time = %d elapsed_time = %d\n", curr->time, elapsed_time); 
    usleep(curr->time - elapsed_time); 
    printf("\nWoke up after %d secs\n", curr->time - elapsed_time); 
    elapsed_time = curr->time; 
    curr->func(curr->time); 
    timer_p = curr; 
    curr = curr->next; 
    free(timer_p); 
    head = curr; 
    } 

    return; 
} 

/*second implemntation: no main and no output for user*/ 

#include <stdio.h> 
#include<conio.h> 
#include <stdlib.h> 
#include <windows.h> 

typedef void(*fun_t)(void); 

typedef struct timer_s{ 
int time; 
fun_t fun; 
struct timer_s* next; 
}timer; 

timer* head=NULL; 

void add_timer(int sec, fun_t fun) 
{ 
    timer* curr,*new_timer; 
    new_timer=(timer*)malloc(sizeof(timer)); 
    new_timer->time=sec; 
    new_timer->fun=fun; 
    new_timer->next=NULL; 
    curr=head; 

    if(curr==NULL) 
    { 
     head=new_timer; 
     return; 
    } 

    while((curr->next!=NULL)&&(curr->next->time<sec)) 
     curr=curr->next; 

    new_timer->next=curr->next; 
    curr->next=new_timer; 

    return; 
} 

void run_timers() 
{ 
    int elapsed=0; 
    timer* tmp; 

    while(head) 
    { 
     Sleep((head->time-elapsed)*1000); 
     elapsed=head->time; 
     head->fun(); 
     tmp=head; 
     head=head->next; 
     free(tmp); 
    } 
    return; 
} 
+3

Des odeurs de devoirs pour moi. N'importe quels preneurs? – Puppy

Répondre

2

Sur la première mise en œuvre, à la fin de main():

run_timers(&head); 
    return 0; 
} 

par le code ci-dessous! Il compilera et fonctionnera. Pouvez-vous repérer la différence?

run_timers(head); 
    return 0; 
} 

Ok, vous pourriez être confus au sujet des pointeurs et je vous suggère de l'étudier un peu plus longtemps.

Alors, juste pour expliquer pourquoi votre code n'a pas été compilation, si vous vous rappelez la signature de la fonction run_timers(),

vous
void run_timers(timers *head); 

verrez qu'il reçoit un pointeur vers (ou une adresse mémoire de) une minuteries la structure, et à l'intérieur main() vous déclarez comme il devrait être:

timers *head = NULL; 

par conséquent, lorsque vous avez besoin d'appeler run_timers(), vous devez passer la tête variable de comme il est:

run_timers(head); //right 

Qu'est-il arrivé est que vous appeliez comme:

run_timers(&head); //wrong 

qui signifie l'adresse mémoire du pointeur de la structure minuteries, et non le pointeur lui-même.

+0

Karl n'est-ce pas la même chose? L'envoi d'une adresse (appel par référence) est avec ou sans? n'est-ce pas? – Roey

+0

Vous semblez confus au sujet des pointeurs, alors j'ai édité ma réponse. N'oublie pas de voter si ça t'a aidé. – karlphillip

0

Je pense que je l'ai fait. Toutes les optimisations seront les bienvenues.

#include <stdio.h> 
#include<conio.h> 
#include <stdlib.h> 
#include <windows.h> 

typedef void(*fun_t)(int); 

typedef struct timer_s{ 
int time; 
fun_t fun; 
struct timer_s* next; 
}timer; 

timer* head=NULL; 
void timer_func(int time); 
void run_timers(); 
void add_timer(int sec, fun_t fun) ; 

int main() 
{ 
    int time = 1; 
    timer *head = NULL; 
    fun_t func = timer_func; 

    while (time < 20) 
    { 
    printf("\nCalling add_timer(time=%d, func=0x%x, head=0x%x)\n", time, func, &head); 
    add_timer(time, func); 
    time *= 2; 
    } 

    run_timers(); 
    return 0; 
} 

void timer_func(int time) 
{ 
    printf("\nCalled %s before %d seconds.\n", __FUNCTION__, time); 
    return; 
} 

void add_timer(int sec, fun_t fun) 
{ 
    timer* curr,*new_timer; 
    new_timer=(timer*)malloc(sizeof(timer)); 
    new_timer->time=sec; 
    new_timer->fun=fun; 
    new_timer->next=NULL; 
    curr=head; 

    if(curr==NULL) 
    { 
     head=new_timer; 
     return; 
    } 

    while((curr->next!=NULL)&&(curr->next->time<sec)) 
     curr=curr->next; 

    new_timer->next=curr->next; 
    curr->next=new_timer; 

    return; 
} 

void run_timers() 
{ 
    int elapsed=0; 
    timer* tmp; 

    while(head) 
    { 
     Sleep((head->time-elapsed)*1000); 
     elapsed=head->time; 
     head->fun(elapsed); 
     tmp=head; 
     head=head->next; 
     free(tmp); 
    } 
    return; 
}