簡體   English   中英

何時在C中初始化結構?

[英]When is a struct initialized in C?

我是Java新手,來自Java背景。

如果我有一個動態初始化的結構,其中的數據來自結構定義中的函數,那么這些函數什么時候被調用? 這段代碼什么時候運行? 它只是第一次引用sample_struct_table[i]

static struct sample_struct {
    int         command;
    int         (*foo)( obj1 *banana, int num);
} sample_struct_table[] = {
    {   .command    =   COMMAND_1,
        .foo =   function_name,
    },
    {   .command    =   COMMAND_2,
        .foo =   another_function_name,
    },
};

static int function_name(obj1 *banana, int num)
{
      // do stuff here
      // When does this get called?
}

調用它們時會調用這些函數。 在您的示例中,您所做的只是將結構的字段設置為函數指針。 該函數未被調用,您只需指向它的指針。

簡短的回答:當調用數組中的指針時調用它。 例如:

sample_struct_table[0].foo(...);

(顯然用調用函數所需的參數替換elipses)。

答案很長:C可以有一個指向函數的指針,這意味着您可以加載共享對象(.dll,.so等)並查找在運行時定義的函數,然后調用這些函數,而不是鏈接到它們。 這非常強大。 如果要創建一個包含指向函數的指針的結構,那么只有在想要使用循環調用一系列函數時才最有用。 我想如果結構的一部分是一個int,那么函數可以指定接下來調用哪個函數,但是我無法想象這會有用的場景。 如果您熟悉Scala並在系統中使用它,那么這應該不難理解,因為Scala一直這樣做。

scala> 1 to 10 foreach println

這里foreach函數接受一個接受單個Int作為參數的函數。 我們將println函數(def println(x:Any)= ...)作為參數傳遞給foreach。

意外62,我認為你的困惑源於struct的定義。 你認為foo的類型是int嗎?

我們有:

static struct sample_struct {
    int         command;
    int         (*foo)( obj1 *banana, int num);
} sample_struct_table[] = {
    {   .command    =   COMMAND_1,
        .foo =   function_name,
    },
    {   .command    =   COMMAND_2,
        .foo =   another_function_name,
    },
};

我們可以使用typedef重寫一下這個。 第一步:

typedef struct _sample_t
{
    int         command;
    int         (*foo)( obj1 *banana, int num);
} sample_t;

從那里到第二個:

typedef int (*foo_t)( obj1 *banana, int num);
typedef struct _sample_t
{
    int         command;
    foo_t       foo;
} sample_t;

如果你是C的新手,這應該讓foo的類型變得更加明顯。

現在,即使您對數組進行聲明和初始化,最終也會將數組初始化為兩個函數的地址以及COMMAND_1COMMAND_2背后的文字。

現在假設你有以下程序(我用值即興創作),你可以看到如何在main()函數體內的for循環中調用這些函數。

#include <stdio.h>
#include <stdlib.h>

#define COMMAND_1 1
#define COMMAND_2 2
typedef void* obj1;
static int function_name(obj1 *banana, int num);
static int another_function_name(obj1 *banana, int num);

typedef int (*foo_t)( obj1 *banana, int num);
typedef struct _sample_t
{
    int         command;
    foo_t       foo;
} sample_t;

sample_t sample_struct_table[] = {
    {   .command    =   COMMAND_1,
        .foo =   function_name,
    },
    {   .command    =   COMMAND_2,
        .foo =   another_function_name,
    },
};

static int function_name(obj1 *banana, int num)
{
    // do stuff here
    // When does this get called?
    return 0;
}

static int another_function_name(obj1 *banana, int num)
{
    // do stuff here
    // When does this get called?
    return 0;
}

int main(int argc, char** argv)
{
    int i;
    for(i = 0; i < sizeof(sample_struct_table)/sizeof(sample_struct_table[0]); i++)
    {
        printf("%i\n", i);
        if(sample_struct_table[i].foo(NULL, i))
            return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

TL; DR:

與Pascal不同,調用函數總是需要說function_name(...) ,而function_name只是引用該函數的地址。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM