从 C 中的函数原型返回多个值结果是多个产品

问题描述

所以我有一个函数原型,可以从两个数字中查找所有产品,无论是 2 位还是 3 位数字。我相信该函数只能返回一个值。那么如何使用 printf 语句打印出 main 中所有可能的值?

int find_largest_products(int ndigits){
    
    int min = 1;
    int max;
    int smallest_num;
    int largest_num = 0;
    int product = 0;
    int max_min_product = 0;

    //Finding the minima. 1 digit = 1; 2 digits = 10; 3 digits = 100
    smallest_num = min * pow(10,ndigits-1);
    

    //Finding the maxima. 1 digits = 9; 2 digits = 99; 3 digits = 999
    for (int i = 0; i < ndigits; i++){
        max  =  9 * pow(10,i);
        largest_num += max;
    }
    

    
    for (int x = largest_num; x >= smallest_num; x--){
        for (int y = smallest_num; y <= largest_num; y++){
            product = x * y;
            max_min_product = product;
        }
        
    }
    return max_min_product;
    
}



 
int main() {
    
    int num = find_largest_palindrome(2);
    printf("Results: %d\n",num);        
   
    return 0;
    
}

解决方法

回调函数:

int find_largest_products(int ndigits,int (*callback)(int,void *),void *baton){
        //...
             //max_min_product = product;
             int r= callback(product,baton);
             if (r) return r;
        //...
    return 0;
}

int print_product(int product,void *ignored) {
    printf(" %d",product);
    return 0;
}

int main()
{
    //...
    printf("Results:");
    find_largest_products(2,print_product,NULL); // Invocation is here
    printf("\n");
    //...
}

逗号呢?每这么多换行符怎么样?我们可以调整回调。

int print_product(int product,void *baton) {
    int *counter = baton;
    if (counter % 8 == 7) {
        printf(",%d\n",product);
    else if (counter % 8 == 0)
        printf("%d\n",product);
    else
        printf(",product);
    ++*counter;
    return 0;
}

但是现在调用应该是这样的:

    int counter = 0;
    find_largest_products(2,&counter); // Invocation is here

注意这如何在调用之间保持状态。这里是一个 int,但它可以很容易地成为一个 struct 或其指针,以保持任意数量的状态。

所以这是一个回调函数的模式,它可以为所欲为。回调函数采用 find_largest_products 找到的累加参数和 find_largest_products 中的状态参数指挥棒,并返回 0 继续或非零保释。这里的回调函数只打印出值并且永远不会失败。我也认为这比动态记忆的技能水平低。我们只需要学习有点烦人的函数指针语法和其他简单的概念。请注意,我们没有使用 &; 获取函数指针的地址。在这方面它就像一个数组。

为了说明这一点,这是一般形式;这是可以传递以检索列表的回调。

struct product_info {
    int *products;
    int nproducts;
    int aproducts;
};

int gather_products(int product,void *baton)
{
    struct product_info *info = baton;
    // normal dynamic stretchy array zzzzz
    if (info->nproducts == info->aproducts) {
        if (info->aproducts == 0) {
            info->products = malloc(sizeof(int)*4);
            if (!info->products) return 1;
            info->aproducts = 0;
        } else {
            void *more = realloc(sizeof(int) * (info->aproducts << 1));
            if (!more) return 1;
            info->aproducts <<= 1;
            info->products = more;
        }
    }
    // end stretchy array
    info->products[info->nproducts++] = product;
    return 0;
}

int main()
{
    //...
    printf("Results: ");
    struct product_info info = { NULL,0 };
    if (find_largest_products(2,gather_products,&info)) { // Invocation is here
        fprintf(stderr,"Out of memory\n");
        free(info->products);
    }
    for (int i = 0; i < info->nproducts; i++)
        printf("%s%d",(i == 0) ? "" : ",",info->products[i]);
    free(info->products);
    printf("\n");
    //...
}

返回列表需要动态内存。有趣的是,函数指针提供了最近我开始欣赏的关注点分离;我们可以将生成算法与结果存储分开。

另一个样本:找到最大的!

int biggest_product(int product,void *baton) {
    int *biggest = baton;
    if (*biggest < product) *biggest = product;
    return 0;
}

int main()
{
    int biggest = 0;
    find_largest_products(2,biggest_product,&biggest); // Invocation is here
    printf("Biggest product is: %d\n",biggest);
}

请注意,在生成产品时交换您对产品所做的工作是多么容易。