我阅读了很多关于在结构体中声明函数的问题,但没有得到满意的答案。
我的问题不是关于“是否可以在结构体中声明函数?”
相反,我的问题是:
为什么不能在结构体中声明函数?
我阅读了很多关于在结构体中声明函数的问题,但没有得到满意的答案。
我的问题不是关于“是否可以在结构体中声明函数?”
相反,我的问题是:
为什么不能在结构体中声明函数?
struct
是类的一种特殊情况),而 C 不支持。this
指针来调用函数,这基本上是 C++ 在幕后所做的。再加上合理的命名约定,以便知道哪些函数属于哪个类(这也是 C++ 在幕后进行名称重整的方式),你就可以接近基于对象编程,如果不是面向对象编程的话。例如:typedef struct temp
{
int a;
} classTemp ;
void classTemp_GetData( classTemp* pThis )
{
printf( "Enter value of a : " );
scanf( "%d", &(pThis->a) );
}
classTemp T ;
int main()
{
classTemp_GetData( &T );
}
struct
内部拥有一个指向函数的指针(作为变量)。#include <stdio.h>
struct t {
int a;
void (*fun) (int * a); // <-- function pointers
} ;
void get_a (int * a) {
printf (" input : ");
scanf ("%d", a);
}
int main () {
struct t test;
test.a = 0;
printf ("a (before): %d\n", test.a);
test.fun = get_a;
test.fun(&test.a);
printf ("a (after ): %d\n", test.a);
return 0;
}
我猜是因为在C语言中这样做没有太多意义。如果你在结构体内声明一个函数,那么你期望它与该结构体有某种关联,对吧?比如说,
struct A {
int foo;
void hello() {
// smth
}
}
hello()
至少能够访问foo
吗?否则,hello()
只能得到类似命名空间的东西,所以我们要调用它,就必须写成A.hello()
- 这将是一个静态函数,在C++中与普通的C函数没有太大区别。hello()
可以访问foo
,那么必须有一个this
指针来实现这种访问,在C++中,它总是作为第一个参数隐式地传递给函数。如果一个结构体函数可以访问结构体变量,那么它必须与其他函数的访问方式有所不同,以便为结构体内部的函数增加一些意义。因此,我们有了public
、private
修饰符。virtual
和protected
。我想可能有很多原因,以下是其中几个:
C编程语言于1972年创建,受到纯汇编语言的影响,因此struct被认为是“仅数据”的元素
由于C不是面向对象的语言,所以在“数据结构”内定义函数实际上没有意义,不存在构造函数/方法等实体
函数直接转换为纯汇编push
和call
指令,并且没有像this
这样的隐藏参数
C语言的设计是为了能够使用相对简单的编译系统进行处理。如果允许函数定义出现在其他任何地方,编译器在处理时就必须跟踪函数所出现的上下文。由于结构体、联合体或枚举声明的成员直到声明结束才进入作用域,因此在结构体内声明的函数与在其他地方声明的函数没有什么区别。
从概念上讲,允许在结构体内部声明常量可能会很好;指向文字函数的常量指针将是其中的一个特例(即使函数本身必须在其他地方声明),但这将要求C编译器为每个结构体成员跟踪更多的信息--不仅是它的类型和偏移量,还包括它是否是常量以及如果是常量,则其值应该是什么。这样的事情在今天的编译环境中并不困难,但早期的C编译器预计要运行比今天可用的内存少几个数量级。
鉴于C语言已经扩展到可以处理64K(或更小)系统上运行的编译器无法很好处理的许多功能,因此可以合理地认为它不再受到这些限制的约束。实际上,有一些C语言遗产方面我希望失去,例如整数提升规则要求即使是新的整数类型也必须遵循旧类型的不一致规则,而不允许新类型具有明确定义的行为[例如,有一个wrap32_t
,可以转换为任何其他整数类型而无需进行类型转换,但当添加到任何“非包装”整数类型的任何大小时,将产生一个wrap32_t
]。在结构体内定义函数可能很好,但它在我的改进列表中排名相对较低。
C
进行编程,那么这些就是你需要遵守的规则。 - herohuyongtao