views:

111

answers:

2

Hello people,

I'm supposed to write a program with two functions:

One function is responsible for building a data structure populated by a list of functions within a run (you get a function pointer) its run time (a few seconds after starting a given program running). You should know to operate the function, adding the data structure of organs, how to do it more efficiently, saving tests, cross checks, etc.. The second function runs all the functions in order. If for example the start of the program once you have two functions were one of the five second time period of 12, first ran after 5 seconds and the other seven seconds after the first. (Total 12 since the beginning).

Again have to pay attention to how to do it, even in relation to the first function. Everything was closed after the run, ie after a function has finished running is no longer an excuse again. All re-run of the program will be entering her new functions.

Attached are two implentations: one awkward and not going through compiling (at least for me) with the main and an output for user, and the other is not cumbersome but without the main output and the user. I need to use cumbersome with output to the user (and then of course you also need main). Can anyone help me please? Why do I need a function pointer here? Any explanation or additional documentation on help me better understand what's going on.

Many thanks in advance

    /*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  A: 

On the first implementation, at the end of main() you must change this:

  run_timers(&head);
  return 0;
}

By the code below! It will compile and run. Can you spot the difference?

  run_timers(head);
  return 0;
}

Ok, you might be confuse about pointers and I suggest you study it a little longer.

So, just to explain why your code wasn't compiling, if you recall the run_timers() function signature,

void run_timers(timers *head);

you'll see that it receives a pointer to (or memory address of) a timers structure, and inside main() you declare it as it should be:

timers *head = NULL;

Therefore, when you need to call run_timers(), you must pass the head variable as it is:

run_timers(head); //right

What happened is that you were calling it as:

run_timers(&head); //wrong

which means the memory address of the pointer of the timers structure, and not the pointer itself.

karlphillip
Roey
You seem confuse about pointers, so I edited my answer. Don't forget to vote up if it helped you.
karlphillip
A: 

I Think I did it. Any optimizations will be gladly welcomed.

#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; 
}
Roey