【发布时间】:2012-04-09 21:31:55
【问题描述】:
我们可以在 C 编程语言的结构中定义函数吗?
【问题讨论】:
-
你的意思是像 struct A { void f(void) {...} }; ?
标签: c
我们可以在 C 编程语言的结构中定义函数吗?
【问题讨论】:
标签: c
不,因为函数不是数据。但是你可以在结构体中定义函数指针。
struct foo {
int a;
void (*workwithit)(struct foo *);
}
【讨论】:
您不能真正在 C 结构中声明内容。这不是 C++ 或任何其他对象封装某种范围的 OO 语言。
C 结构是非常简单的对象,它只是管理一块内存的语法糖。当你创建新的结构“instance”struct A a;时,编译器只是根据它的大小保留堆栈空间,然后当你做a.member时,编译器知道该成员的偏移量,所以它跳转到&a+该成员的偏移量.这些偏移量通常不仅仅是前面成员大小的总和,因为编译器通常会在结构中添加一些填充位以更好地对齐到内存中。
希望它有所帮助。你显然对 C 结构的期望有点过高:-)
【讨论】:
我来这篇文章是因为我正在寻找一种方法来教授一些面向对象“风格”的 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;
}
然后我导入类,从类中构造一个对象,使用该对象,然后在main.c
中销毁该对象#include "point.c"
int main(void)
{
struct point * p3 = point_new(4,5);
p3->print(p3);
p3->del(p3);
}
感觉非常“Pythonic in C”。
【讨论】:
不,您不能在 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++ struct 中!
【讨论】:
否,你不能在 C 程序的结构中定义函数,但是如果你的文件扩展名为 .cpp(不是 C),你可以有成员类之类的函数,但是这些函数的默认修饰符将是“公共”(与类不同)。
阅读这些链接以了解有关结构 a good link 、another good link、One more good link 的更多信息
作为 C++ 中的惯例,类用于存储函数和变量,结构仅用于存储信息(即数据)。
【讨论】:
你可以用 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();
}
【讨论】:
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 文件。
【讨论】: