Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使函数找到函数指针的地址它';有人打电话给他吗?_C - Fatal编程技术网

C 如何使函数找到函数指针的地址它';有人打电话给他吗?

C 如何使函数找到函数指针的地址它';有人打电话给他吗?,c,C,我想为纯C结构实现toString()方法。当然,这可以使用函数指针来完成,但关键是我不想将对象的位置传递给函数,我希望函数根据所述结构中的函数指针自行计算出来。如果我们有这样一个结构: typedef struct some { int32_t a; const char * str; void* (*toString)(); }Node; 实例化后,我希望它的内容以与Java相同的方式打印,如下所示: Node a; a.toString(); 除非我们的toSt

我想为纯C结构实现
toString()
方法。当然,这可以使用函数指针来完成,但关键是我不想将对象的位置传递给函数,我希望函数根据所述结构中的函数指针自行计算出来。如果我们有这样一个结构:

typedef struct some
{
    int32_t a;
    const char * str;
    void* (*toString)();
}Node;
实例化后,我希望它的内容以与Java相同的方式打印,如下所示:

Node a;
a.toString();
除非我们的toString()将打印字符串化对象本身,并且实际上不会返回字符串

我慢慢想了想,这就是我想到的:

#include <stdio.h>
#include <stdint.h>

typedef struct some
{
    int32_t a;
    const char * str;
    void* (*toString)();
}Node;


void f()
{
  Node *beginnning = __builtin_frame_address(1) - sizeof(Node);
  const char ** temp = (const char *) beginnning + 8;
  printf("{%d, %s}\n", *((int*)beginnning), *temp);
}

int main()
{
    Node a, b;
    a.a = 67, a.str = "alpine", a.toString = f;
    a.toString();
    b.a = 25, b.str = "hello world", b.toString = f;
    b.toString();
}
但实际产出实际上是:

{67, alpine}
{67, alpine}
有没有办法强制“结束”帧,或者以某种方式重置,以便下一个函数调用返回我们需要的内容?我相信如果有办法做到这一点,这个问题是可以解决的。但是,我在
\uu builtin\u frame\u address()
文档中找不到类似的内容

我收集的函数是linux上gcc编译器的一部分。我不会在窗户上找的。因此,为了节省时间,您可能需要测试它。

您不能这样做。 您发现了一种在上一个调用帧顶部打印
节点
对象内容的方法。这与表达式
a.toString
无关,您可以在该位置调用
f
,效果相同

我不想把对象的位置传递给函数


为什么不呢?这就是Java(隐式)所做的。

如果您真的想这样做,就必须使用包装器。事实上,它是第一个C++编译器:简单的预处理器,(除其他之外)替换了诸如<代码> Obj.方法(ARG,…)<代码> > <代码> ObjCaseLoad方法(Obj.Ag..…)< /> >p> 我远不是一个宏专家,但是如果你能用一个简单用例的宏来实现它,我也不会感到惊讶。对于更复杂的,您必须构建一个真正的预处理器,但是Clang的解析器可能是一个很好的起点

尽管如此,我强烈建议你不要这样做,除非你有非常严肃的理由。调试将是一场噩梦,因为您必须针对预处理代码(*)进行调试。因此,如果你想使用C坚持C语法并明确地传递对象,那么使用一个像C++这样的对象语言。

在以前的生活中,我使用了Oracle SQL预编译器,调试程序非常糟糕…

C不是一种对象语言,并且不会传递任何隐式
指针。更改C++,如果你需要它,或者接受显式地传递它…@ @ SergBaleLista没有“<代码>这个< /Cult>指针开始。但从我所学的内容来看,C语言是一种非常灵活的语言,几乎任何东西都可以用它来实现!简单地说,它让程序员告诉它他们想要什么,并且在这个方向上没有语法糖分。它只是被认为是无用的,因为程序员需要它可能会变成C++。@ PAPGRISHA可以在C.编写任何程序,但仍然需要用C语言编写。您可以用C语言编写模拟(一种编程语言)的程序,但您编写的程序必须是C语言而不是Lisp。Lisp模拟C程序看起来像是
次(n,阶乘(负(n,1))
,它看起来不像
(*n(阶乘(-n1-)))
。C编译器不可能让您编写
(*n(阶乘(-n1‘);)
。在任何一家理智的软件商店中,您只能这样做一次。第一次之后,他们会递给你一个纸板箱,告诉你收拾东西离开校园。我不知道Java是如何做到的,但我猜调用类方法时,可以从调用它的对象的范围中找出它。即使事实并非如此,在C中是否真的没有办法做到这一点?也许有某种环境变量跟踪函数从何处被调用?@PapaGrisha在Java中,
n.toString()
实际上是
n->class->toString(n)
@PapaGrisha Java从参数列表中忽略了被调用的对象,因为它定义了
x.toString()的含义
x处的对象引用作为
包含在方法主体中。C没有做到这一点,Python也没有做到(它确实传递对象,显式地作为第一个参数)什么样的宏可以做到这一点?我尝试了
#define(x).toString()f((x))
,但这显然是无效的。
{67, alpine}
{67, alpine}