Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是否可以将函数参数存储在函数指针中?_C - Fatal编程技术网

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

C 是否可以将函数参数存储在函数指针中?,c,C,出于好奇,我试图理解C语言中函数指针是如何工作的 为了将函数与typedef关联,我在其中声明了一个指针,然后将所需函数的地址存储在其中 这就是我能够做到的: typedef struct { void (*get)(char*, int); char string[10]; } password; int main() { password userPassword; userPassword.get = &hiddenStringInput;

出于好奇,我试图理解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函数的指针中。甚至有可能吗?

我认为这通常是通过提供“分派”功能来实现的:

void get(password * pw) {
  pw->get(pw->string, 10);
}
然后,在设置
userPassword.get
到您的函数后,只需调用:

get(userPassword);

显然,当对多个函数执行时,这会添加一些样板代码。允许实现更有趣的“类”功能。

您可以使用“块”语言扩展在叮当声中实现。正如评论所说,(并没有受到敌意或任何东西的欢迎),但他们进展缓慢

转换为使用块,您的示例可能如下所示:

#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;
}
#包括
#包括
typedef void(^GetPw)(int);//请注意如何使用块指针类型
typedef void(*GetPw_Impl)(char*,int);//与函数指针类型相同
类型定义结构
{
GetPw get;
字符串[10];
}密码;
extern void hiddenStringInput(字符*,整数);
外部无效setPw(字符dst[静态10],字符*src);
GetPw bindPw(GetPw_Impl get_Impl,char*pw)
{
返回块拷贝(^(整数键){
get_impl(pw,key);
});
}
int main()
{
密码用户密码;
setPw(userPassword.string,“secret”);
userPassword.get=bindPw(hiddenStringInput,userPassword.string);
userPassword.get(10);
返回退出成功;
}
捕获数组的方式有一些微妙之处,可能会混淆这种情况;该示例通过普通指针捕获密码,并假设
userPassword
负责该密码的所有权,与块分开

由于块捕获值,它需要为捕获值的副本提供并释放动态存储,这些副本将在块本身被复制到创建它的范围之外时创建;这是通过
Block\u copy
Block\u release
功能完成的

块类型(语法上是函数指针,但使用
^
而不是
*
)只是指针-无法访问底层块实体,就像基本C函数一样



这就是Clang API—标准化会稍微改变这一点,并且可能会减少复制块时动态内存分配的要求(但Clang API反映了当前最常用的方式)。

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

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(“某物”),而发生的事情正是标签上所说的。有什么理由我不应该这样做吗?这看起来很方便


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

如果你迁移到C++,你可以用lambda函数或函数对象来实现。毫无疑问,C语言中有一些技巧,但这比我的工资级别高,但是这个特性还没有以标准化的、一流的方式存在。如果更多的编译器支持它,那么它很可能会包含在C2x(下一个标准版本)中。我正在努力。如果我没弄错的话,你基本上需要成员函数。这就是(为什么一个原因)为什么有C++。几乎像一个很好的建议,但是如果它明确回答了一个问题,它是一个更好的答案,那么,在Bathsheba,我不太熟悉C++,但是我或多或少已经知道,用它来实现这类事情是很容易的。因为C++是面向对象的。完整地讲,我这样做是为了模仿C语言中其他语言的类似对象的结构。我甚至不确定它是否有用,但我真的很想知道它是否可以实现以及如何实现。在寻找这个问题的解决方案时,我无意中发现一篇文章,它暗示C++通过使用指针来实现面向对象的特性,这非常有趣。你想做的事是可以做到的,但是有一百万或两种方法!e、 如果只是因为有一百万种不同风格的OOP可供复制就好了。这看起来可能是一本非常有趣的书!感谢您提供这一点,这是C++,而不是CNO。这是无效的。C,你可能使用C++编译器,这就是为什么它工作。好,这有很多意义,实际上哈哈。对于这个错误我很抱歉,我对这件事还不太熟悉。