C - struct里面的函数

时间:2013-06-11 19:46:12

标签: c function struct

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

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();

}

错误 client.h:24:2:错误:预期':',',',';','}'或'属性'before'{'token。

这是正确的方法吗?

6 个答案:

答案 0 :(得分:89)

它无法直接完成,但您可以使用函数指针模拟相同的事情并显式传递“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);

}

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

答案 1 :(得分:21)

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

您可能想要的更像是虚拟方法表。

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); }

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

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

答案 2 :(得分:11)

这只适用于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);

}

答案 3 :(得分:9)

这个怎么样?

#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;
} 

答案 4 :(得分:3)

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

没有必要从头开始重新构建面向对象 对于C程序,它不是面向对象的语言。

我之前见过这个。 这是一件奇怪的事情。其中一些编码器厌恶将要更改的对象传递给更改它的函数,即使这是标准方法。

我责怪C ++,因为它隐藏了这样一个事实,即类对象始终是成员函数中的第一个参数,但它是隐藏的。所以看起来它没有将对象传递给函数,即使它是。

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

C非常灵活,可以通过引用传递内容。

C函数通常只返回一个状态字节或int,并且经常被忽略。 在您的情况下,正确的形式可能是

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

addClient将在Client.h或Client.c

答案 5 :(得分:-1)

您可以将结构指针作为函数参数传递给函数。 它称为按引用传递。

如果您修改该指针内的某些内容,则其他内容将更新为。 试试这个:

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 *client)
{
        /* this will change the original client value */
        client.password = "secret";
}

int main()
{
    client_t client;

    //code ..

    AddClient(&client);
}