C中结构体在定义时可以定义自身类型的成员吗?

Lengineer 郑州轻工业学院 学生  2013-01-30 04:22:02

typedef struct DATA{
void (*fun)(struct DATA *data);//这种可以,好多人写的函数这样用,有什么好处?怎么调用
void (*fun2)(struct DATA data2);//这种是不是不可以?why?
}DATA_T;
...全文
465 15 点赞 打赏 收藏 举报
写回复
15 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
电子科学 2015-06-08
定义结构体指针可以,结构体变量就错误了
  • 打赏
  • 举报
回复
rickys2035 2013-12-05
赵老师威武
引用 5 楼 zhao4zhong1 的回复:
Typedef Declarations A typedef declaration is a declaration with typedef as the storage class. The declarator becomes a new type. You can use typedef declarations to construct shorter or more meaningful names for types already defined by C or for types that you have declared. Typedef names allow you to encapsulate implementation details that may change. A typedef declaration is interpreted in the same way as a variable or function declaration, but the identifier, instead of assuming the type specified by the declaration, becomes a synonym for the type. Syntax declaration : declaration-specifiers init-declarator-list opt ; declaration-specifiers : storage-class-specifier declaration-specifiers opt type-specifier declaration-specifiers opt type-qualifier declaration-specifiers opt storage-class-specifier : typedef type-specifier : void char short int long float double signed unsigned struct-or-union-specifier enum-specifier typedef-name typedef-name : identifier Note that a typedef declaration does not create types. It creates synonyms for existing types, or names for types that could be specified in other ways. When a typedef name is used as a type specifier, it can be combined with certain type specifiers, but not others. Acceptable modifiers include const and volatile. Typedef names share the name space with ordinary identifiers (see Name Spaces in Chapter 2 for more information). Therefore, a program can have a typedef name and a local-scope identifier by the same name. For example: typedef char FlagType; int main() { } int myproc( int ) { int FlagType; } When declaring a local-scope identifier by the same name as a typedef, or when declaring a member of a structure or union in the same scope or in an inner scope, the type specifier must be specified. This example illustrates this constraint: typedef char FlagType; const FlagType x; To reuse the FlagType name for an identifier, a structure member, or a union member, the type must be provided: const int FlagType; /* Type specifier required */ It is not sufficient to say const FlagType; /* Incomplete specification */ because the FlagType is taken to be part of the type, not an identifier that is being redeclared. This declaration is taken to be an illegal declaration like int; /* Illegal declaration */ You can declare any type with typedef, including pointer, function, and array types. You can declare a typedef name for a pointer to a structure or union type before you define the structure or union type, as long as the definition has the same visibility as the declaration. Typedef names can be used to improve code readability. All three of the following declarations of signal specify exactly the same type, the first without making use of any typedef names. typedef void fv( int ), (*pfv)( int ); /* typedef declarations */ void ( *signal( int, void (*) (int)) ) ( int ); fv *signal( int, fv * ); /* Uses typedef type */ pfv signal( int, pfv ); /* Uses typedef type */ Examples The following examples illustrate typedef declarations: typedef int WHOLE; /* Declares WHOLE to be a synonym for int */ Note that WHOLE could now be used in a variable declaration such as WHOLE i; or const WHOLE i;. However, the declaration long WHOLE i; would be illegal. typedef struct club { char name[30]; int size, year; } GROUP; This statement declares GROUP as a structure type with three members. Since a structure tag, club, is also specified, either the typedef name (GROUP) or the structure tag can be used in declarations. You must use the struct keyword with the tag, and you cannot use the struct keyword with the typedef name. typedef GROUP *PG; /* Uses the previous typedef name to declare a pointer */ The type PG is declared as a pointer to the GROUP type, which in turn is defined as a structure type. typedef void DRAWF( int, int ); This example provides the type DRAWF for a function returning no value and taking two int arguments. This means, for example, that the declaration DRAWF box; is equivalent to the declaration void box( int, int );
  • 打赏
  • 举报
回复
Ericz 2013-11-30
引用 12 楼 chenxue1111 的回复:
[quote=引用 11 楼 zhou19891113 的回复:] [quote=引用 10 楼 chenxue1111 的回复:] [quote=引用 9 楼 zhou19891113 的回复:] 针对楼主的例子,两种都是可以的 针对楼主的问题:C中结构体在定义时可以定义自身类型的成员吗? 不行,因为结构体中的各个成员所需的存储空间大小是编译的时候确定的, 在结构体定义中如果定义自身类型的成员,因为此时结构体大小还不确定, 所以此时定义的成员所需的存储空间大小就不确定,因此编译不会通过。 但是可以定义成自身类型的指针,因为指针所需的存储空间大小是可以确定的。 比如:

struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
}; 
struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test &t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
};
这样子呢?如果可以的话如何进行初始化呢?[/quote] 你后面定义的引用是可以的,正常使用就行了。不过在C++中尽量不要用struct定义一个类,用class定义要好一些。[/quote] 引用必须初始化的啊,像这种该如何初始化呢?像你说的,如果是类的情况又怎么初始化呢?
class Test{private:
public:Test&Ref;};
[/quote] 定义引用的时候必须初始化,但你这里并没有定义引用啊,这里你是在定义类。
  • 打赏
  • 举报
回复
chenxue1111 2013-11-29
引用 11 楼 zhou19891113 的回复:
[quote=引用 10 楼 chenxue1111 的回复:] [quote=引用 9 楼 zhou19891113 的回复:] 针对楼主的例子,两种都是可以的 针对楼主的问题:C中结构体在定义时可以定义自身类型的成员吗? 不行,因为结构体中的各个成员所需的存储空间大小是编译的时候确定的, 在结构体定义中如果定义自身类型的成员,因为此时结构体大小还不确定, 所以此时定义的成员所需的存储空间大小就不确定,因此编译不会通过。 但是可以定义成自身类型的指针,因为指针所需的存储空间大小是可以确定的。 比如:

struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
}; 
struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test &t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
};
这样子呢?如果可以的话如何进行初始化呢?[/quote] 你后面定义的引用是可以的,正常使用就行了。不过在C++中尽量不要用struct定义一个类,用class定义要好一些。[/quote] 引用必须初始化的啊,像这种该如何初始化呢?像你说的,如果是类的情况又怎么初始化呢?
class Test{private:
public:Test&Ref;};
  • 打赏
  • 举报
回复
Ericz 2013-11-29
引用 10 楼 chenxue1111 的回复:
[quote=引用 9 楼 zhou19891113 的回复:] 针对楼主的例子,两种都是可以的 针对楼主的问题:C中结构体在定义时可以定义自身类型的成员吗? 不行,因为结构体中的各个成员所需的存储空间大小是编译的时候确定的, 在结构体定义中如果定义自身类型的成员,因为此时结构体大小还不确定, 所以此时定义的成员所需的存储空间大小就不确定,因此编译不会通过。 但是可以定义成自身类型的指针,因为指针所需的存储空间大小是可以确定的。 比如:

struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
}; 
struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test &t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
};
这样子呢?如果可以的话如何进行初始化呢?[/quote] 你后面定义的引用是可以的,正常使用就行了。不过在C++中尽量不要用struct定义一个类,用class定义要好一些。
  • 打赏
  • 举报
回复
chenxue1111 2013-11-28
引用 9 楼 zhou19891113 的回复:
针对楼主的例子,两种都是可以的 针对楼主的问题:C中结构体在定义时可以定义自身类型的成员吗? 不行,因为结构体中的各个成员所需的存储空间大小是编译的时候确定的, 在结构体定义中如果定义自身类型的成员,因为此时结构体大小还不确定, 所以此时定义的成员所需的存储空间大小就不确定,因此编译不会通过。 但是可以定义成自身类型的指针,因为指针所需的存储空间大小是可以确定的。 比如:

struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
}; 
struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test &t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
};
这样子呢?如果可以的话如何进行初始化呢?
  • 打赏
  • 举报
回复
Ericz 2013-02-01
针对楼主的例子,两种都是可以的 针对楼主的问题:C中结构体在定义时可以定义自身类型的成员吗? 不行,因为结构体中的各个成员所需的存储空间大小是编译的时候确定的, 在结构体定义中如果定义自身类型的成员,因为此时结构体大小还不确定, 所以此时定义的成员所需的存储空间大小就不确定,因此编译不会通过。 但是可以定义成自身类型的指针,因为指针所需的存储空间大小是可以确定的。 比如:

struct test {
    struct test *pt;   /* pt是指针,指针占用空间已经确定,因此可以 */
    struct test t;    /* 在结构体还没定义完之前,编译器不知道该类型所需多大空间,
                         所以在这里会出错 */
}; 
  • 打赏
  • 举报
回复
mymtom 2013-02-01
引用 3 楼 akirya 的回复:
都可以啊,这只是一个函数指针而已。
++ 五颗星星,水平就是不一样啊!
  • 打赏
  • 举报
回复
mymtom 2013-02-01
楼上的都没有试过吧! 实际上是可以的。 原因也很简单, 函数指针的size是能计算的,也没有什么循环的问题。
  • 打赏
  • 举报
回复
AnYidan 2013-01-30
引用 2 楼 sniffer12345 的回复:
struct DATA *data是指针,指针的长度已知 struct DATA data2是结构体,结构体的长度由结构体的成员决定。你这样变成了死循环
++
  • 打赏
  • 举报
回复
赵4老师 2013-01-30
Typedef Declarations A typedef declaration is a declaration with typedef as the storage class. The declarator becomes a new type. You can use typedef declarations to construct shorter or more meaningful names for types already defined by C or for types that you have declared. Typedef names allow you to encapsulate implementation details that may change. A typedef declaration is interpreted in the same way as a variable or function declaration, but the identifier, instead of assuming the type specified by the declaration, becomes a synonym for the type. Syntax declaration : declaration-specifiers init-declarator-list opt ; declaration-specifiers : storage-class-specifier declaration-specifiers opt type-specifier declaration-specifiers opt type-qualifier declaration-specifiers opt storage-class-specifier : typedef type-specifier : void char short int long float double signed unsigned struct-or-union-specifier enum-specifier typedef-name typedef-name : identifier Note that a typedef declaration does not create types. It creates synonyms for existing types, or names for types that could be specified in other ways. When a typedef name is used as a type specifier, it can be combined with certain type specifiers, but not others. Acceptable modifiers include const and volatile. Typedef names share the name space with ordinary identifiers (see Name Spaces in Chapter 2 for more information). Therefore, a program can have a typedef name and a local-scope identifier by the same name. For example: typedef char FlagType; int main() { } int myproc( int ) { int FlagType; } When declaring a local-scope identifier by the same name as a typedef, or when declaring a member of a structure or union in the same scope or in an inner scope, the type specifier must be specified. This example illustrates this constraint: typedef char FlagType; const FlagType x; To reuse the FlagType name for an identifier, a structure member, or a union member, the type must be provided: const int FlagType; /* Type specifier required */ It is not sufficient to say const FlagType; /* Incomplete specification */ because the FlagType is taken to be part of the type, not an identifier that is being redeclared. This declaration is taken to be an illegal declaration like int; /* Illegal declaration */ You can declare any type with typedef, including pointer, function, and array types. You can declare a typedef name for a pointer to a structure or union type before you define the structure or union type, as long as the definition has the same visibility as the declaration. Typedef names can be used to improve code readability. All three of the following declarations of signal specify exactly the same type, the first without making use of any typedef names. typedef void fv( int ), (*pfv)( int ); /* typedef declarations */ void ( *signal( int, void (*) (int)) ) ( int ); fv *signal( int, fv * ); /* Uses typedef type */ pfv signal( int, pfv ); /* Uses typedef type */ Examples The following examples illustrate typedef declarations: typedef int WHOLE; /* Declares WHOLE to be a synonym for int */ Note that WHOLE could now be used in a variable declaration such as WHOLE i; or const WHOLE i;. However, the declaration long WHOLE i; would be illegal. typedef struct club { char name[30]; int size, year; } GROUP; This statement declares GROUP as a structure type with three members. Since a structure tag, club, is also specified, either the typedef name (GROUP) or the structure tag can be used in declarations. You must use the struct keyword with the tag, and you cannot use the struct keyword with the typedef name. typedef GROUP *PG; /* Uses the previous typedef name to declare a pointer */ The type PG is declared as a pointer to the GROUP type, which in turn is defined as a structure type. typedef void DRAWF( int, int ); This example provides the type DRAWF for a function returning no value and taking two int arguments. This means, for example, that the declaration DRAWF box; is equivalent to the declaration void box( int, int );
  • 打赏
  • 举报
回复
derekrose 2013-01-30
递归定义了...
  • 打赏
  • 举报
回复
都可以啊,这只是一个函数指针而已。
  • 打赏
  • 举报
回复
sniffer12345 2013-01-30
struct DATA *data是指针,指针的长度已知 struct DATA data2是结构体,结构体的长度由结构体的成员决定。你这样变成了死循环
  • 打赏
  • 举报
回复
ForestDB 2013-01-30
incomplete type
  • 打赏
  • 举报
回复
相关推荐
发帖
C语言
加入

6.5w+

社区成员

C语言相关问题讨论
申请成为版主
帖子事件
创建了帖子
2013-01-30 04:22
社区公告
暂无公告