Связанный список таймеров в C - PullRequest
1 голос
/ 03 августа 2010

Я должен написать программу с двумя функциями:

Одна функция отвечает за построение структуры данных, заполненной списком функций в ходе выполнения (вы получаете указатель функции), время ее выполнения (через несколько секунд после запуска данной программы).Вы должны знать, как управлять этой функцией, добавлять структуру данных органов, как сделать это более эффективно, сохранять тесты, перекрестные проверки и т. Д. Вторая функция выполняет все функции по порядку.Если, например, запуск программы, когда у вас есть две функции, был одним из пятисекундного периода времени 12, первый запускался через 5 секунд, а остальные семь секунд после первой.(Итого 12 с начала).

Опять придется обратить внимание на то, как это сделать, даже в отношении первой функции.Все было закрыто после запуска, то есть после того, как функция закончила работать, больше не является оправданием.Все перезапуски программы будут вводить в нее новые функции.

Прилагаются два значения: одно неудобное и не проходит компиляцию (по крайней мере, для меня) с основным и выходом для пользователя, а другое не громоздко, но без основного вывода и пользователя.Мне нужно использовать громоздкие с выводом для пользователя (а затем, конечно, вам также нужно основной).Кто-нибудь может мне помочь?Зачем мне нужен указатель на функцию здесь?Любое объяснение или дополнительная документация помогут мне лучше понять, что происходит.

Большое спасибо заранее

    /*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; 
}

Ответы [ 2 ]

2 голосов
/ 03 августа 2010

В первой реализации, в конце main () вы должны изменить это:

  run_timers(&head);
  return 0;
}

По коду ниже! Он скомпилируется и запустится. Можете ли вы заметить разницу?

  run_timers(head);
  return 0;
}

Хорошо, вы можете запутаться с указателями, и я предлагаю вам изучить его немного дольше.

Итак, просто чтобы объяснить, почему ваш код не компилировался, если вы вспомните сигнатуру функции run_timers (),

void run_timers(timers *head);

вы увидите, что он получает указатель (или адрес памяти) на структуру timers , а внутри main () вы объявляете его так, как должно быть:

timers *head = NULL;

Поэтому, когда вам нужно вызвать run_timers (), вы должны передать переменную head такой, как она есть:

run_timers(head); //right

Случилось так, что вы называли это так:

run_timers(&head); //wrong

, что означает адрес памяти указателя структуры таймеров , а не самого указателя.

0 голосов
/ 03 августа 2010

Думаю, я это сделал.Любые оптимизации будут с радостью приветствоваться.

#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; 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...