You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让C语言结构体的函数指针访问并修改结构体成员?

在C语言中为结构体实现类似C++成员函数的功能

当然可行,核心思路是给函数指针加上一个指向结构体实例的参数(对应C++里隐式的this指针),手动传递实例地址来让函数访问成员。

具体实现步骤:

  1. 修改结构体的函数指针类型
    把原来的void (*Draw)()改成接受Ball*类型的参数,这样函数就能拿到当前实例的指针,访问所有成员。注意因为typedef在结构体定义之后生效,所以定义时要写struct Ball*:

    typedef struct Ball {
      float x, y;
      float speedX, speedY;
      float radius;
      void (*Draw)(struct Ball*); // 新增结构体指针参数
    } Ball;
    
  2. 实现Draw函数
    函数参数为Ball*,直接通过指针访问实例的成员变量:

    void Ball_Draw(Ball* self) {
      // 直接访问self的成员,逻辑和C++里的this->x一致
      DrawCircle((int)self->x, (int)self->y, (int)self->radius, WHITE);
      // 如果需要修改成员也可以,比如 self->x += self->speedX;
    }
    
  3. 初始化结构体并绑定函数
    创建Ball实例时,把Draw函数指针指向实现好的Ball_Draw:

    int main() {
      Ball ball;
      ball.x = 100.0f;
      ball.y = 100.0f;
      ball.radius = 20.0f;
      ball.Draw = Ball_Draw; // 绑定函数到结构体
    
      // 调用函数,手动传递实例指针
      ball.Draw(&ball);
    }
    

优化调用体验(可选)

如果觉得每次调用都要传&ball麻烦,可以定义一个宏来模拟C++的调用方式:

#define BALL_DRAW(ball) (ball)->Draw(ball)

// 调用时:
Ball* ball_ptr = &ball;
BALL_DRAW(ball_ptr); // 写法接近C++的 ball->Draw()

你之前写法的问题

你之前的Draw函数需要传一堆单独的成员指针,不仅繁琐,而且结构体里的函数指针没有对应参数,导致调用时无法传递这些参数,自然没法工作。而通过传递整个结构体实例指针,函数可以直接访问所有成员,逻辑更清晰,也和C++成员函数的底层逻辑一致。

内容的提问来源于stack exchange,提问作者Noname

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:55:29