C: Looping without using looping statements or recursion

前端 未结 16 1825
走了就别回头了
走了就别回头了 2021-02-04 07:56

I want to write a C function that will print 1 to N one per each line on the stdout where N is a int parameter to the function. The function should not use while, for, do-while

相关标签:
16条回答
  • 2021-02-04 08:53

    I'm very disappointed that this doesn't work. To me, the phrase "a function is called after any previously registered functions that had already been called at the time it was registered" suggests that it is possible to register atexit handlers after they have started to be called. That is, a handler can register another handler. Otherwise, how is it even possible for there to exist a function which has been called at the time another function is registered? But for me the call to atexit is returning 0 success, but not actually resulting in another call. Anyone know why, have I made some silly error?

    #include "stdio.h"
    #include "stdlib.h"
    
    int count = 0;
    int limit = 10;
    
    void handler() {
        printf("%d of %d\n", ++count, limit);
        if (count < limit) atexit(handler);
    }
    
    int main(int argc, char **argv) {
        if (argc > 1) limit = atoi(argv[1]);
        atexit(handler);
    }
    

    By the way, not recursion because atexit doesn't call its parameter, it queues it to be called later. Obviously the C runtime contains a loop to call atexit handlers, but that loop exists whether you actually register any atexit handlers or not. So if this program contains a loop, so does every C program ;-)

    0 讨论(0)
  • 2021-02-04 08:55

    You did not forbid fork().

    0 讨论(0)
  • 2021-02-04 08:56

    With blocking read, signals and alarm. I thought I'd have to use sigaction and SA_RESTART, but it seemed to work well enough without.

    Note that setitimer/alarm probably are unix/-like specific.

    #include <signal.h>
    #include <sys/time.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    volatile sig_atomic_t counter;
    volatile sig_atomic_t stop;
    
    void alarm_handler(int signal)
    {
      printf("%d\n", counter++);
      if ( counter > stop )
      {
        exit(0);
      }
    }
    
    int main(int argc, char **argv)
    {
      struct itimerval v;
      v.it_value.tv_sec = 0;
      v.it_value.tv_usec = 5000;
      v.it_interval.tv_sec = 0;
      v.it_interval.tv_usec = 5000;
      int pipefds[2];
      char b;
    
      stop = 10;
      counter = 1;
    
      pipe(pipefds);
    
      signal(SIGALRM, alarm_handler);
    
      setitimer(ITIMER_REAL, &v, NULL);
    
      read(pipefds[0], &b, 1);
    }
    
    0 讨论(0)
  • 2021-02-04 09:00
    #include <stdlib.h>
    
    int callback(const void *a, const void *b) {
        static int n = 1;
    
        if (n <= N)
            printf("%d\n", n++);
    
        return 0;
    }
    
    int main(int argc, char *argv) {
        char *buf;
        /* get N value here */
    
        buf = malloc(N);  // could be less than N, but N is definitely sufficient
        qsort(buf, N, 1, callback);
    }
    

    I think it doesn't count as recursion.

    0 讨论(0)
  • 2021-02-04 09:00

    I'd go for using longjmp()

    #include <stdio.h>
    #include <setjmp.h>
    
    void do_loop(int n) {
      int val;
      jmp_buf env;
    
      val = 0;
    
      setjmp(env);
    
      printf("%d\n", ++val);
    
      if (val != n)
        longjmp(env, 0);  
    }
    
    int main() {
      do_loop(7);
      return 0;
    }
    
    0 讨论(0)
  • 2021-02-04 09:00

    This does it:

    int main ()
    {
    printf ("1 to N one per each line\n");
    return 0;
    }
    

    Here is another one:

    #include <stdlib.h>
    #include <stdio.h>
    
    int main (int c, char ** v) {
        char b[100];
        sprintf (b, "perl -e 'map {print \"$_\\n\"} (1..%s)'", v[1]);
        system (b);
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题