C、 这条线是干什么的?

C、 这条线是干什么的?,c,pointers,struct,C,Pointers,Struct,我在codegolf的一个主题中看到了这行代码 struct { int (*log)(const char *,...); } console = { printf }; 这是原帖 虽然我懂c/c++,但我不能理解这一行。 我认为要创建同义词,可以使用typefs,那么这是什么(console={printf})。 而且,我一点也不懂结构。为什么是一个结构和里面发生了什么。。。这是指针的投射吗?这是什么,。。。。我们看到内部?定义并初始化函数指针log(),最初指向结构中的项作为其唯一元素的

我在codegolf的一个主题中看到了这行代码

struct { int (*log)(const char *,...); } console = { printf };
这是原帖 虽然我懂c/c++,但我不能理解这一行。 我认为要创建同义词,可以使用typefs,那么这是什么(console={printf})。
而且,我一点也不懂结构。为什么是一个结构和里面发生了什么。。。这是指针的投射吗?这是什么,。。。。我们看到内部?

定义并初始化函数指针
log()
,最初指向结构中的项作为其唯一元素的
printf

原型与printf完全兼容。像这样使用它:

console.log ("format string %d %d", param1, param2);
struct { int (*log)(const char *, ...); } console = { printf };
...
console.log("%s\n", "This is a test");
如果在计算过程中的某个时刻,应该使用不同的实际函数作为输出,则可以重新分配指针

int myoutputfunction (const char *, ...)
{
    (do something useful here)
}

console.log = myoutputfunction;

它是一个结构,其中包含一个成员,该成员是指向返回int类型的函数的指针,并且它被初始化为printf函数的地址

struct {
    // struct with one member
    // that member is called log
    // accepts one const char *
    // and an arbitrary amount of optional extra arguments
    int (*log)(const char *,...);
}
// declared console variable of type that struct
console = {
    // and initialises its first member to
    printf
};
在语义上等同于:

typedef int (*FncPtr)(const char *,...);   // function pointer

typedef struct c {
    FncPtr log;
} Console;                                 // struct holding function pointer

Console console;
console.log = printf;                      // initialization of this pointer
console.log("abc");                        // possible usage
这只不过是一种可能的方法:

console.log( /* some parameters */ );
产生与以下完全相同的结果:

printf( /* some parameters */ );
这里的
console
是struct的
变量,它有一个成员
log

结构有一个
成员,该成员是指向函数的指针,该函数返回整数并以常量字符串和可变长度参数
作为参数。
赋值创建一个
struct变量console
console.log
指向
printf()

所以,让我们从外向内工作:

struct { T m; } console = { i };
您正在使用类型为
T
的单个成员
m
定义一个匿名结构类型,然后使用该类型声明名为
console
的变量,并使用初始值设定项
{i}
初始化它

那么什么是
T
m
i

成员声明

int (*log)(const char *, ...);
分解为

      log                         -- log
    (*log)                        -- is a pointer to
    (*log)(                 )     -- a function
    (*log)(const char *, ...)     -- taking a fixed parameter of type 
                                         const char *, followed by a variable
                                         number of parameters
int (*log)(const char *, ...);    -- returning int
因此,成员
m
被命名为
log
,其类型
T
int(*)(const char*,…)

初始值设定项表达式为

{ printf }
printf
的原型是

int printf(const char *, ...);
除非它是
sizeof
或一元
&
运算符的操作数,否则“函数返回
T
”类型的函数指示符将转换为“指向函数返回
T
的指针”类型的表达式。因此,初始值设定项中表达式
printf
的类型为

int (*)(const char *, ...);
看起来眼熟吗?这与
log
成员的类型相同

TL;DR版本

您正在创建一个结构类型,其中包含一个名为
log
的成员,该成员用于指向类似
printf
的函数。它的用途如下:

console.log ("format string %d %d", param1, param2);
struct { int (*log)(const char *, ...); } console = { printf };
...
console.log("%s\n", "This is a test");

如果您不能识别函数指针、变量函数和初始值设定项列表,那么您可能不“了解c/c++”。此外,我认识这些元素,但我永远不会这样编码。百万年来从未有过……无论是谁写的,都不会以“C”作为第一语言。他们正试图使C语言看起来像Java或它的后代。@wallyk这段代码是关于用一种语言编写,使它看起来像另一种语言。我甚至猜他会说两种语言:)这是一个高尔夫密码。人们不应该对这些条目的体系结构和可读性感到太多疑惑。在这里,他试图使这个C代码看起来像Java或其他东西,所以他当然不得不绕开常规的C范例。@CJohnson:在一行中编写太多代码只会降低可读性。保持代码干净总是好的:)