函数中生成的指针变量不能传入函数指针的参数中

问题描述 投票:0回答:2

主题: 给定一个不超过5位的正整数,要求:

  1. 找出它有多少位数字;
  2. 单独输出每一位数字;
  3. 以相反的顺序输出每个数字。例如,如果原始数字是 321,则应输出 123。

当我使用函数指针调用以下程序时,我发现参数“number”和“digit”无法传递给每个函数。

#include <stdio.h>
#include <stdlib.h>

void inputNumber(int *number){
    printf("Enter number: ");
    scanf_s("%d", number);
    while(*number <= 0 || *number > 9999){
        if(*number <= 0){
            printf("The number is not positive integer! Retry!\nEnter number: ");
        }
        if(*number > 9999){
            printf("The number is more than 5 digits! Retry!\nEnter number: ");
        }
        scanf_s("%d", number);
    }
}

void outputDigit(int *number, int *digit){
    int i;
    for(i = 0; *number != 0; i++){
        *number /= 10;
    }
    *digit = i;
    //printf("%d\n", *number);    Test Output
    printf("The number is %d digits!\n", i);
}

void outputNumber(int *number, int *digit){
    int base = 10;
    int temp = *number;
    for(int i = 1; i < *digit - 1; i++){
        base *= 10;
    }
    //printf("%d %d\n", *number, temp);    Test Output
    for(int i = 0; i < *digit; i++){
        printf("%d ", temp / base);
        temp -= temp / base * base;
        base /= 10;
    }
    printf("\n");
}

void outputReverseNumber(int *number, int *digit){
    int temp = *number;
    for(int i = 0; i < *digit; i++){
        printf("%d ", temp % 10);
        temp = (temp - temp % 10) / 10;
    }
    printf("\n");
}

void function(int *number, int *digit, void (*fun[])(int*, int*)){
    for(int i = 0; i < 3; i++){
        fun[i](number, digit);
    }
}

int main(){
    int *number = (int*)malloc(sizeof(int));
    int *digit = (int*)malloc(sizeof(int));
    void (*fun[3])(int*, int*) = {outputDigit, outputNumber, outputReverseNumber};
    inputNumber(number);
    function(number, digit, fun);
    free(number);
    free(digit);
    system("pause");
    return 0;
}

我希望函数指针中的参数由其他函数生成的指针变量传递。

c parameter-passing function-pointers
2个回答
0
投票

当您用零覆盖每个函数中的

number
时,下一次调用将使用修改后的值。你已经陷入了副作用的陷阱。

您需要在每次通话前恢复它:

void function(int *number, int *digit, void (*fun[])(int*, int*))
{
    int savedNumber = *number;

    for(int i = 0; i < 3; i++)
    {
        fun[i](number, digit);
        *number = savedNumber;
    }
}

https://godbolt.org/z/6GWKqbfMq


0
投票

参数传递没有问题。问题是你不断地对

outputDigit
内的数字进行除法,从而确保在离开函数时原始数字为零。这可以通过使用临时变量来解决:

void outputDigit(int *number, int *digit){
    int i;
    int tmp = *number;
    for(i = 0; tmp != 0; i++){
        tmp /= 10;
    }
    *digit = i;
    printf("The number is %d digits!\n", i);
}

另一个错误是

*number > 9999
检查数字是否大于 位,而不是五位。应该是
99999

一般代码审查:

  • 避免

    scanf_s
    ,因为它的标准化程度很低。原来
    scanf
    实际上支持读取固定数量的字符,如果你检查结果的话。然而,在这种特定情况下,使用 fgets 将输入读取为字符串会更方便,因为以 10 为基数的十进制数字是一种麻烦的格式,迫使您一遍又一遍地使用除法。
    
    

  • 在这里使用函数指针根本没有任何意义。数组中的各个函数执行不相关的任务,因此使用抽象层的通用编程只会使程序难以阅读而没有任何好处。我认为您只是将它们用于学习目的。
  • 如果您使用
  • const正确性

    ,则可以避免这里的大错误,这意味着不应修改的指针参数应标记为只读。那就是: void outputDigit(const int *number, int *digit); void outputNumber(const int *number, const int *digit); void outputReverseNumber(const int *number, const int *digit)

    虽然现在函数有不同的类型,所以函数指针数组也不能再使用了。

  • 一般不要将算法(计算位数)与用户 I/O(打印或获取输入)混淆。程序员并不期望名为
  • outputDigit

    的函数计算数字,他们期望它打印一个数字。

    
    

  • 对单个
  • int

    使用动态分配是没有意义的。同样,转换

    malloc
    的结果是没有意义的。
    
    

  • 处理函数指针时始终使用 typedef,以提高可读性。在这种情况下,你可以这样做:
  • typedef void func_t (int*, int*); ... func_t* fun[3] = {outputDigit, outputNumber, outputReverseNumber}; ... void function(int *number, int *digit, func_t* fun[3])

    
        
© www.soinside.com 2019 - 2024. All rights reserved.