是否可以将函数参数存储在指向函数的指针中?

时间:2019-05-04 13:53:33

标签: c

出于好奇,我试图了解C中函数的指针是如何工作的。

为了将一个函数与一个typedef相关联,我在其中定义了一个指针,然后在其中存储了所需函数的地址。

这是我能够实现的:

typedef struct
{

    void (*get)(char*, int);
    char string[10];

} password;

int main()
{
    password userPassword;

    userPassword.get = &hiddenStringInput; 

    userPassword.get(userPassword.string, 10);

    return EXIT_SUCCESS;
}

尽管这确实可以正常工作,但我希望“ userPassword.get”成为一种快捷方式,在使用该快捷方式时会调用hiddenStringInput函数并填写请求的参数(在这种情况下,是字符数组和整数) 。

基本上,由于我总是将userPassword.get与参数“ userPassword.string”和“ 10”结合使用,因此我试图找到一种方法,以某种方式将这些参数存储在指向到hiddenString函数。甚至有可能吗?

3 个答案:

答案 0 :(得分:2)

我通常看到的方式是通过提供“调度”功能:

void get(password * pw) {
  pw->get(pw->string, 10);
}

然后,在将userPassword.get设置为函数后,您只需调用:

get(userPassword);

很显然,完成多种功能后,这会添加一些样板代码。不过,允许实现更多有趣的“类”事物。

答案 1 :(得分:1)

您可以使用“块”语言扩展名在Clang中执行此操作。正如所评论的,there have been attempts to standardize this(并没有收到敌意或其他任何东西),但是他们的行动缓慢。

翻译为使用块,您的示例如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<Api1Service>();
    services.AddSingleton<Api2Service>();
}

捕获数组的方式有些细微之处,可能会混淆这种情况;该示例通过普通指针捕获了密码,并假定[Route("api/[controller]")] [ApiController] public class MyController : ControllerBase { private readonly Api1Service _api1Service; private readonly Api2Service _api2Service; public MyController(Api1Service api1Service, Api2Service api2Service) { _api1Service = api1Service; _api2Service = api2Service; } [HttpPost] public async Task Post([FromBody] string value) { var result1 = await apiService1.GetApiResultAsync(); var result2 = await apiService2.GetApiResultAsync(); } } 与该密码块分开负责#include <stdlib.h> #include <Block.h> typedef void (^GetPw)(int); // notice how Block pointer types are used typedef void (*GetPw_Impl)(char*, int); // the same way as function pointer types typedef struct { GetPw get; char string[10]; } password; extern void hiddenStringInput(char*, int); extern void setPw(char dst [static 10], char * src); GetPw bindPw (GetPw_Impl get_impl, char * pw) { return Block_copy (^ (int key) { get_impl (pw, key); }); } int main() { password userPassword; setPw(userPassword.string, "secret"); userPassword.get = bindPw(hiddenStringInput, userPassword.string); userPassword.get(10); return EXIT_SUCCESS; } 的所有权。

由于块捕获值,因此它需要为捕获的值的副本提供并释放动态存储,这些副本将在将块本身复制到创建范围之外时创建。这是通过userPasswordBlock_copy函数完成的。

块类型(语法上是函数指针,但使用Block_release而不是^)是 just 指针-无法访问基本的块实体,就像基本的C语言一样功能。


这是Clang API-标准化会对此稍作更改,并且可能会减少动态内存分配以在其周围复制块的需求(但Clang API反映了当前最常用的方式)。

答案 2 :(得分:-1)

所以,我刚刚意识到我可以直接在结构内部编写函数

typedef struct
{

    char string[10];

    void get(void)
    {
        hiddenStringInput(string, 10);

        return;
    }

    void set(const char* newPassword)
    {
        strcpy(string, newPassword);

        return;
    }

    void show(void)
    {
        printf("%s", string);

        return;
    }



} password;

现在,我可以只调用userPassword.get(),userPassword.show()和userPassword.set(“ something”),然后发生的事情正是标签上所说的。有什么原因我不应该这样做吗?看起来很方便。

编辑:因此,这仅在C ++中是可能的。我没有意识到我正在使用C ++编译器,并且通过尝试做一些随机的事情,我想到了这个解决方案。所以这不是我真正想要的。

相关问题