[英]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_1
和COMMAND_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.