主题: 给定一个不超过5位的正整数,要求:
当我使用函数指针调用以下程序时,我发现参数“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;
}
我希望函数指针中的参数由其他函数生成的指针变量传递。
当您用零覆盖每个函数中的
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;
}
}
参数传递没有问题。问题是你不断地对
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 为基数的十进制数字是一种麻烦的格式,迫使您一遍又一遍地使用除法。
,则可以避免这里的大错误,这意味着不应修改的指针参数应标记为只读。那就是:
void outputDigit(const int *number, int *digit);
void outputNumber(const int *number, const int *digit);
void outputReverseNumber(const int *number, const int *digit)
虽然现在函数有不同的类型,所以函数指针数组也不能再使用了。
outputDigit
的函数计算数字,他们期望它打印一个数字。
int
使用动态分配是没有意义的。同样,转换
malloc
的结果是没有意义的。
typedef void func_t (int*, int*);
...
func_t* fun[3] = {outputDigit, outputNumber, outputReverseNumber};
...
void function(int *number, int *digit, func_t* fun[3])