C中的函数和循环

w51jfk4q  于 2023-02-15  发布在  其他
关注(0)|答案(3)|浏览(151)

我怎样才能让这个函数odddigits返回whilefor循环在i的每次迭代中计算出的变量odd的每个值呢?
当我在main函数中编写循环时,这工作得很好,但是当我将循环抽象成另一个函数时,它似乎没有返回循环中的所有值,而是在所有迭代完成后只返回最后一个值。

#include <cs50.h>
#include <stdio.h>
#include <math.h>

int odddigits(long cardnum);
long odd;

int main(void) {
    long n = get_long("Number: ");
    printf("%i\n", odddigits(n));
}

int odddigits(long cardnum) {
    for (int i = 1; i < 16; i += 2) {
        long x = pow(10, i);
        odd = cardnum % x;

        while (odd >= 10) {
            odd = odd / 10;
        }
     }
     return odd;
}
sczxawaw

sczxawaw1#

假设在数字123456789中,数字1为0,9为8,并且您希望打印奇数数字:

int main(void)
{
    int arr[20];
    size_t size = 0;
    printf("%zu\n", size = odddigits(arr, 1234567));
    for(size_t i = 0; i < size; i++) printf("[%zu] = %d\n", i, arr[i]);
}

size_t odddigits(int *buff, long n)
{
    size_t size = 0;
    long mask = 1;
    long wrk = n / 10;
    while(wrk)
    {
        mask *= 10;
        wrk /= 10;
    }
    while(mask)
    {
        if(size % 2) buff[size / 2] = abs(n / mask);
        size++;
        n %= mask;
        mask /= 10;
    }
    return size / 2;
}

1.需要返回整数数组。
1.当你处理整数时,不要使用像pow这样的数学函数,它几乎不起作用
1.设置代码格式

wlp8pajw

wlp8pajw2#

正如其他评论者已经指出的那样,这有点复杂。以下是我的建议。注意:没有检查,没有平衡,你必须在投入生产前自己把它们全部加进去!

#include <stdio.h>
    /* No need for math.h */
    
    /* For strtol() because I don't want to copy get_long() here */
    #include <stdlib.h>
    /* For CHAR_BIT */
    #include <limits.h>
    
    long odddigits(long cardnum);
    long odddigits_single(long cardnum);
    long *odddigits_array(long cardnum);
    
    /* Input from commandline now! */
    int main(int argc, char **argv)
    {
       long n, copy;
       long *array;
    
       if (argc < 2) {
          fprintf(stderr, "Usage: %s integer\n", argv[0]);
          return 1;
       }
       /* You have to use get_long() here */
       n = strtol(argv[1], NULL, 10);
    
       puts("Not really working as intended, I presume?");
       printf("oddigits %ld\n\n", odddigits(n));
    
       /* We need to work on copy now because we change the input */
       copy = n;
       puts("\nRecursive");
       while (copy > 0) {
          printf("odddigits single %ld\n", odddigits_single(copy));
          copy /= 10;
       }
    
       puts("\nArray");
       array = odddigits_array(n);
    
       /* This will print the whole array not only the digits */
       for (int i = 0; i < 20; i++) {
          printf("odddigits array %ld\n", array[i]);
       }
    
       puts("\nArray, odd digits [1,3,5,7,9] only:");
       /* This will search the whole array not only the digits */
       for (int i = 0; i < 20; i++) {
          long tmp = array[i];
          if ((tmp & 0x1L) == 1) {
             printf("odddigits array %ld\n", tmp);
          }
       }
       free(array);
    
       return 0;
    }
    
    /* You are returning a long */
    long odddigits(long cardnum)
    {
       /* No need for a global variable */
       long odd = 0;
       /* No need for pow() */
       long x = 1;
       /* No need for iterations */
       /* for (int i = 1; i < 16; i+=2) { */
       while (x < cardnum) {
          /*
              This will overflow at one point (prob. throwing SIGFPE "Floating point exception" )
              It is a better idea to shrink cardnum.
           */
          x *= 10;
          odd = cardnum % x;
          printf("odd in for loop: %ld\n", odd);
          while (odd >= 10) {
             odd = odd/10;
             printf("odd in while loop: %ld\n", odd);
          }
       }
       return odd;
    }
    
    long odddigits_single(long cardnum)
    {
       long odd = 0;
       odd = cardnum % 10;
       return odd;
    }
    
    
    long *odddigits_array(long cardnum)
    {
       long odd = 0;
    
       /* this type is way too large for a single digit, you might use "char" instead */
       long *array;
       /* Iterator for array */
       int i=0;
    
       /* Assuming 64 bit "long" */
       array = calloc(20, sizeof(long) * 20 * CHAR_BIT);
       if (array == NULL) {
          fprintf(stderr, "Malloc failed to allocate %zu bytes\n", (sizeof(long) * 20 * CHAR_BIT));
          return NULL;
       }
       while (cardnum > 0) {
          /* Get smalles digit */
          odd = cardnum % 10;
          /* gather digit */
          array[i] = odd;
          i++;
          /* Shrink cardnum to get next digit */
          cardnum /= 10;
       }
       return array;
    }

试试看:

$ ./so_odddigits 1234
    Not really working as intended
    odd in for loop: 4
    odd in for loop: 34
    odd in while loop: 3
    odd in for loop: 234
    odd in while loop: 23
    odd in while loop: 2
    odd in for loop: 1234
    odd in while loop: 123
    odd in while loop: 12
    odd in while loop: 1
    oddigits 1
    
    
    Recursive
    odddigits single 4
    odddigits single 3
    odddigits single 2
    odddigits single 1
    
    Array
    odddigits array 4
    odddigits array 3
    odddigits array 2
    odddigits array 1
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    odddigits array 0
    
    Array, odd digits [1,3,5,7,9] only:
    odddigits array 3
    odddigits array 1

但我警告过你:

$ ./so_odddigits 123456789123123123123
    Not really working as intended
    odd in for loop: 7
    odd in for loop: 7
    odd in for loop: 807
    odd in while loop: 80
    odd in while loop: 8
    odd in for loop: 5807
    odd in while loop: 580
    odd in while loop: 58
    odd in while loop: 5
    odd in for loop: 75807
    odd in while loop: 7580
    odd in while loop: 758
    odd in while loop: 75
    odd in while loop: 7
    odd in for loop: 775807
    odd in while loop: 77580
    odd in while loop: 7758
    odd in while loop: 775
    odd in while loop: 77
    ...
    odd in for loop: 9223372036854775807
    odd in while loop: 922337203685477580
    odd in while loop: 92233720368547758
    odd in while loop: 9223372036854775
    odd in while loop: 922337203685477
    odd in while loop: 92233720368547
    odd in while loop: 9223372036854
    odd in while loop: 922337203685
    odd in while loop: 92233720368
    odd in while loop: 9223372036
    odd in while loop: 922337203
    odd in while loop: 92233720
    odd in while loop: 9223372
    odd in while loop: 922337
    odd in while loop: 92233
    odd in while loop: 9223
    odd in while loop: 922
    odd in while loop: 92
    odd in while loop: 9
    Floating point exception (core dumped)

剩下的,跟踪收集的数字量,错误处理等pp.,留给你。这是一个快速的黑客,可能有一个bug潜伏在某处。
另一个技巧,不管什么原因,很少教,是"滴"的方法:每个函数调用一个数字。

#include <stdio.h>
    
    long odddigits_single_static(long cardnum);
    
    /* Input from commandline now! */
    int main(void)
    {
       long n=12345678901, t;
    
       puts("\nSingle shots");
       /* Another method */
       while ((t = odddigits_single_static(n)) > 0) {
          printf("odddigits single shots %ld\n", t);
       }
       /* Check if reset worked: */
       puts("\nSingle shots second time");
       /* Another method */
       while ((t = odddigits_single_static(n)) > 0) {
          printf("odddigits single shots second time %ld\n", t);
       }
       return 0;
    }
    
    long odddigits_single_static(long cardnum)
    {
       static long odd = 0;
       static long n = -1;
    
       if (n < 0l) {
          n = cardnum;
       }
       do {
          if (n == 0l) {
             odd = 0l;
             n = -1l;
             return -1l;
          }
          odd = n % 10l;
          n /= 10l;
       } while ((odd & 0x1l) == 0);
    
       return odd;
    }
bf1o4zei

bf1o4zei3#

oddigits()将执行每个for循环,并在所有循环完成后返回最后一个odd值,该值由main函数打印。
也许可以考虑一下printf的位置。

相关问题