将功能指针分配给另一个功能中的功能

时间:2018-10-24 18:06:46

标签: c function pointers

我当前正在尝试在分配功能指针的过程中提示用户。我的问题是我无法再次在main中获得现在分配的函数指针。 代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>

double print_2 (void);

double print_1 (void);

void promt_user_input(double (*fn)(void));

//program to test funtion pointers inside funtions

//proof of consept

int    main(void) {
  double result;
  double (*fn)(void);

  promt_user_input(fn);
  //result = *fn;
  printf("het %lf",(fn)());
  //This will not print no matter what i do.
}

void promt_user_input(double (*fn)(void)) {
  int coice;
  printf("Enter 1 or 2\n");

  scanf(" %d",&coice);

  switch(coice) {
    case 1: *(&fn) = print_1; printf("you typed 1\n"); break;
    case 2: *(&fn) = print_2; printf("you typed 2\n"); break;
    default: printf("INVALID INPUT"); break; 
  }
  printf("hi %lf\n",(fn)());
}

double print_1 (void){
  printf("This is option 1\n");
  return 1;
}

double print_2 (void){
  printf("This is option 2\n");
  return 2;
}

由于printf函数内部的prompt_user_input打印正确的值,因此编译就很好,并且函数分配正确。但是在该功能之外,似乎不起作用。 printf函数甚至无法运行。

2 个答案:

答案 0 :(得分:0)

由于C是按值传递的,所以您需要将指针指向指针传递给uid_0 Henry 函数:

promt_user_input

如果创建typedef,事情将变得更容易理解:

int main(void)
{
    double (*fn)(void);

    promt_user_input(&fn);
    printf("het %lf",fn());
}

void promt_user_input(double (**fn)(void))
{
    int coice;
    printf("Enter 1 or 2\n");

    scanf(" %d", &coice);

    switch(coice){
        case 1: *fn = print_1; printf("you typed 1\n"); break;
        case 2: *fn = print_2; printf("you typed 2\n"); break;
        default: printf("INVALID INPUT"); break; 
    }
}

然后您可以通过使函数返回值来避免使用指针指向指针:

typedef double (*func)(void);
void promt_user_input(func *fn);

int main(void)
{
    func fn;

    promt_user_input(&fn);
    printf("het %lf", fn());
}

void promt_user_input(func *fn)
{
    // Same as above....

答案 1 :(得分:0)

main()函数中,您定义了指向函数fn的未初始化指针,并将其(通过 value )传递给另一个对其进行初始化的函数promt_user_input通过用户输入print_1print_2>内部 ...

但是,当流程返回到main()时,fn内部的main()仍保持初始化状态。取消引用会导致不确定的行为。为了正确初始化fn,您需要将其地址传递给promt_user_input,当然,其签名也必须正确更新(输入参数的类型应为指向函数的指针或使其返回函数指针(无论您喜欢什么)。

#include <stdio.h>

double print_2 (void);
double print_1 (void);

void promt_user_input(double (**fn)(void));

int main(void)
{
  double result;
  double (*fn)(void);

  fn = NULL;    
  promt_user_input(&fn);

  if (fn)
  {
    printf("het %lf",(fn)());
  }

  return 0;
}

void promt_user_input(double (**fn)(void))
{
  unsigned int coice;
  int res;

  printf("Enter 1 or 2\n");

  res = scanf("%u",&coice);
  if (res != 1 || !coice || coice > 2)
  {
      printf("Invalid input!\n");
      return;
  }

  switch(coice)
  {
    case 1: *fn = print_1; printf("you typed 1\n"); break;
    case 2: *fn = print_2; printf("you typed 2\n"); break;
  }

  printf("hi %lf\n",(*fn)());
}

double print_1 (void)
{
  printf("This is option 1\n");
  return 1.0;
}

double print_2 (void)
{
  printf("This is option 2\n");
  return 2.0;
}

少量备注:

  1. 您必须检查scanf的返回值以处理无效的输入。
  2. 由于输入无效,fn将保持未初始化状态,因此在这种情况下,您一定不要取消引用。您需要将fn初始化为某个无效值,然后在使用之前检查其是否具有有效值,或者使promt_user_input返回一个状态,该状态指示输入参数是否已成功初始化。
  3. double常量必须具有 floating 浮点:1-> int,1.0-> double
  4. 当负值无意义时(例如coice),首选使用无符号类型。
  5. int main(void)应该在流程结束时返回一个int值。