C - struct里面的函数

xRe*_*Red 69 c struct function

我试图在结构内创建一个函数,到目前为止我有这个代码:

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

        pno AddClient() 

        {
            /* code */
        }

};

int main()
{

    client_t client;

    //code ..

    client.AddClient();

}
Run Code Online (Sandbox Code Playgroud)

错误:client.h:24:2:错误:在'{'标记之前预期':',',',';','}'或' attribute '.

这是正确的方法吗?

Fat*_*ror 92

它不能直接完成,但您可以使用函数指针模拟相同的事情并显式传递"this"参数:

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

        pno (*AddClient)(client_t *);    
};

pno client_t_AddClient(client_t *self) { /* code */ }

int main()
{

    client_t client;
    client.AddClient = client_t_AddClient; // probably really done in some init fn

    //code ..

    client.AddClient(&client);

}
Run Code Online (Sandbox Code Playgroud)

事实证明,这样做并没有真正给你带来太大的收益.因此,您将看不到以此样式实现的许多C API,因为您也可以只调用外部函数并传递实例.

  • X11 API做了类似这样的事情.见[XImage](https://en.wikipedia.org/wiki/XImage). (3认同)
  • Windows API 下的代码充满了这样的内容。从技术上讲,“窗口类”是一个具有两个回调函数指针和开放端的结构(对于“窗口类具体数据”,您可以在注册时提供) (2认同)

jxh*_*jxh 22

正如其他人所说,直接在结构中嵌入函数指针通常是为了特殊目的而保留的,比如回调函数.

您可能想要的是更像虚拟方法表的东西.

typedef struct client_ops_t client_ops_t;
typedef struct client_t client_t, *pno;

struct client_t {
    /* ... */
    client_ops_t *ops;
};

struct client_ops_t {
    pno (*AddClient)(client_t *);
    pno (*RemoveClient)(client_t *);
};

pno AddClient (client_t *client) { return client->ops->AddClient(client); }
pno RemoveClient (client_t *client) { return client->ops->RemoveClient(client); }
Run Code Online (Sandbox Code Playgroud)

现在,添加更多操作不会改变client_t结构的大小.现在,这种灵活性仅在您需要定义多种客户端时才有用,或者希望允许您的client_t界面用户能够增强操作的行为方式.

这种结构确实出现在实际代码中.OpenSSL BIO层看起来与此类似,UNIX设备驱动程序接口也有这样的层.

  • @smalinux 请参阅:/sf/answers/1233573211/ (2认同)
  • @LORDTEK 请参阅我提供给 smalinux 的链接 (2认同)

QSQ*_*QSQ 13

这只适用于C++.结构中的函数不是C的特征.

您的client.AddClient(); call ...这是对成员函数的调用,它是面向对象的编程,即C++.

将您的源转换为.cpp文件,并确保您正在编译.

如果你需要坚持使用C,下面的代码是(等同于)等效的:

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

};


pno AddClient(pno *pclient) 
{
    /* code */
}


int main()
{

    client_t client;

    //code ..

    AddClient(client);

}
Run Code Online (Sandbox Code Playgroud)


小智 10

这个怎么样?

#include <stdio.h>

typedef struct hello {
    int (*someFunction)();
} hello;

int foo() {
    return 0;
}

hello Hello() {
    struct hello aHello;
    aHello.someFunction = &foo;
    return aHello;
}

int main()
{
    struct hello aHello = Hello();
    printf("Print hello: %d\n", aHello.someFunction());

    return 0;
} 
Run Code Online (Sandbox Code Playgroud)

  • “一点点”JavaScrip 之类的解决方案 (2认同)

Chr*_*eid 6

您正在尝试根据struct对代码进行分组。C分组是通过文件进行的。您可以将所有函数和内部变量放在标头或标头和从ac源文件编译的对象“ .o”文件中。

对于不是面向对象语言的C程序,无需从头开始重新设计面向对象。

我以前看过 这是一件奇怪的事。编码器(其中有些编码器)不愿意将要更改的对象传递给函数以对其进行更改,即使这样做是标准的方式。

我归咎于C ++,因为它隐藏了以下事实:类对象始终是成员函数中的第一个参数,但它是隐藏的。因此,即使它确实没有将对象传递给函数。

Client.addClient(Client& c); // addClient first parameter is actually 
                             // "this", a pointer to the Client object.
Run Code Online (Sandbox Code Playgroud)

C是灵活的,可以通过引用传递事物。

AC函数通常仅返回状态字节或int,并且通常将其忽略。在您的情况下,适当的格式可能是

 err = addClient( container_t  cnt, client_t c);
 if ( err != 0 )
   { fprintf(stderr, "could not add client (%d) \n", err ); 
Run Code Online (Sandbox Code Playgroud)

addClient将位于Client.h或Client.c中