【问题标题】:Define functions in structs在结构中定义函数
【发布时间】:2012-04-09 21:31:55
【问题描述】:

我们可以在 C 编程语言的结构中定义函数吗?

【问题讨论】:

  • 你的意思是像 struct A { void f(void) {...} }; ?

标签: c


【解决方案1】:

不,因为函数不是数据。但是你可以在结构体中定义函数指针。

struct foo {
    int a;
    void (*workwithit)(struct foo *);
}

【讨论】:

    【解决方案2】:

    您不能真正在 C 结构中声明内容。这不是 C++ 或任何其他对象封装某种范围的 OO 语言。

    C 结构是非常简单的对象,它只是管理一块内存的语法糖。当你创建新的结构“instance”struct A a;时,编译器只是根据它的大小保留堆栈空间,然后当你做a.member时,编译器知道该成员的偏移量,所以它跳转到&a+该成员的偏移量.这些偏移量通常不仅仅是前面成员大小的总和,因为编译器通常会在结构中添加一些填充位以更好地对齐到内存中。

    希望它有所帮助。你显然对 C 结构的期望有点过高:-)

    【讨论】:

      【解决方案3】:

      我来这篇文章是因为我正在寻找一种方法来教授一些面向对象“风格”的 C 编程,用于非常简单的数据结构课程。我不想教 C++,因为我不想继续解释它更高级的特性。

      但我想探索如何实现在 Python 中使用的 OO 模式,但在低级语言/运行时。通过解释 C 中发生了什么,学生可能会更好地理解 Python OO 运行时模式。因此,我稍微超出了上面的第一个答案,并改编了https://stackoverflow.com/a/12642862/1994792 中的一些模式,但以某种方式可以稍微阐明 OO 运行时模式。

      首先我在 point.c 中使用“构造函数”创建了“类”:

      #include <stdio.h>
      #include <stdlib.h>
      
      struct point
      {
          int x;
          int y;
          void (*print)(const struct point*);
          void (*del)(const struct point*);
      };
      
      void point_print(const struct point* self)
      {
          printf("x=%d\n", self->x);
          printf("y=%d\n", self->y);
      }
      
      void point_del(const struct point* self) {
        free((void *)self);
      }
      
      struct point * point_new(int x, int y) {
          struct point *p = malloc(sizeof(*p));
          p->x = x;
          p->y = y;
          p->print = point_print;
          p->del = point_del;
          return p;
      }
      

      然后我导入类,从类中构造一个对象,使用该对象,然后在ma​​in.c

      中销毁该对象
      #include "point.c"
      
      int main(void)
      {
          struct point * p3 = point_new(4,5);
          p3->print(p3);
          p3->del(p3);
      }
      

      感觉非常“Pythonic in C”。

      【讨论】:

      • 这真的很有启发性,我觉得我找到了一个复活节彩蛋。这应该有更多的赞成票!
      • 问题是,为什么在释放之前要强制转换为 void 指针?
      • @drchuck 我同意 tgabb 的观点,你的帖子很棒!这对我帮助很大。赞一个!
      • @tgabb - free() 函数需要 (void *) 作为其参数。所以我试图避免任何警告信息。
      【解决方案4】:

      不,您不能在 C 程序中的 struct 中包含函数。我编写了一个代码并将其保存为 .c 和 .cpp。 .cpp 文件符合预期并按预期工作,但 .c 文件甚至无法编译。

      这是供您参考的代码。将其保存为 .cpp 一次,然后运行它。然后将相同的代码保存为 .c 并编译它。你会得到一个编译错误。

      #include <stdio.h>
      struct C {
          void Test(int value) {
             static int var = 0;
             if (var == value) 
                printf("var == value\n");
             else
                printf("var != value\n");
      
             var = value;
           }
       }; 
      
       int main() {
          C c1;
          C c2;
          c1.Test(100);
          c2.Test(100);
          int ii;
          scanf("%d",&ii);
       }
      

      【讨论】:

      • 什么时候在C程序中不可能有函数
      • 我的意思是。 c程序中的结构。将修复
      • 已修复。谢谢。
      【解决方案5】:

      没有。

      您可以在结构中包含函数指针,但这与您将获得的一样接近。

      【讨论】:

        【解决方案6】:

        不,你不能。结构体内部只能包含变量,在结构体内部存储函数指针可以给你想要的结果。

        【讨论】:

          【解决方案7】:

          不,但你可以在 c++ struct 中!

          【讨论】:

          • 所以我用“不”回答了他的问题。你错过了那部分吗?
          【解决方案8】:

          ,你不能在 C 程序的结构中定义函数,但是如果你的文件扩展名为 .cpp(不是 C),你可以有成员类之类的函数,但是这些函数的默认修饰符将是“公共”(与类不同)。

          阅读这些链接以了解有关结构 a good link another good linkOne more good link 的更多信息

          作为 C++ 中的惯例,用于存储函数和变量结构仅用于存储信息(即数据)

          【讨论】:

          • 你的意思可能是:“但是,如果你用另一种叫做 C++ 的编程语言编译它......”
          • 你是对的@Lundin,实际上在初级阶段很少有学生通过在 .cpp 文件中编写 C 代码来混淆自己,这确实是一种不好的做法。
          【解决方案9】:

          你可以用 C++ 代替:

          // Example program
          #include <iostream>
          #include <string>
          
          struct Node
          {
              int data; Node *prev,*next;
              Node(int x, Node* prev=NULL, Node* next=NULL)
              {
                  this->data=x; this->prev=prev; this->next=next;
              }
              void print_list()
              {
                  Node* temp=this;    //temp is created in function call stack
                  while(temp!=NULL)
                  {
                      std::cout<<temp->data<<" ";
                      temp=temp->next;
                  }
              }
              Node* insert_left(int x)
              {
                  Node* temp=new Node(x,this->prev,this);
                  this->prev=temp;
                  return temp;                            //list gets new head
              }
              Node* insert_right(int x)
              {
                  Node* temp=new Node(x,this,this->next);
                  this->next=temp;
                  return this;                            //this would still be head
              }
          
          };
          
          int main()
          {
              Node* head=new Node(-1);    //-1
              head=head->insert_left(0);  //0 -1
              head=head->insert_right(1); //0 1 -1
              head=head->insert_left(2);  //2 0 1 -1
              head->print_list();
          }
          

          【讨论】:

            【解决方案10】:

            C 中只能使用函数指针。在结构初始化后将实际函数的地址分配给该指针,例如:

            #include <stdio.h>
            #include <stdlib.h>
            
            struct unit
            {
              int result;
              int (*add) (int x, int y);
            };
            
            int sumFunc(int x, int y) { return x + y; }
            
            void *unitInit()
            {
              struct unit *ptr = (struct unit*) malloc(sizeof(struct unit));
              ptr->add = &sumFunc;
              return ptr;
            }
            
            int main(int argc, char **argv)
            {
              struct unit *U = unitInit();
            
              U->result = U->add(5, 10);
            
              printf("Result is %i\n", U->result);
            
              free(U);
            
              return 0;
            }
            

            在结构中使用函数指针的好例子你可以在这里找到https://github.com/AlexanderAgd/CLIST 检查标题,然后检查 clist.c 文件。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-10-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-10-20
              相关资源
              最近更新 更多