结构体struct用法手札

来源:互联网 发布:红海军知乎 编辑:程序博客网 时间:2024/06/10 07:53

结构体用法手札

初识C语言时,对于结构体总有一种莫名的恐惧,虽然对于定义有着些许了解,但是用起来还是不怎么顺手。尤其,对于半吊子的编程者,结构体和类都是蹩脚之处。这几天,详细看了这部分概念,对其了解又加深了一步。

结构体很好,能封装成新的类型,更有效的打理数据结构。其实C++中的类也是相同的效果,不过封装性更好一些。

另外,类也可以用结构体声明的(这里不再赘述,详见《C++ Primer》,注意不是《C++ Primer Plus》)。

使用用结构体要注意几个方面:

 

1.声明两个相同结构的结构体(即使成员列表完全相同),但是对于编译器来说,就是两个不同的类型,这时调用会有问题:

 

struct{int a;char b;float c;}x;struct{int a;char b;float c;}y[20],*z;
如上面,可以看出两个结构体内部完全相同,但是它是两个结构,所以z=&x;是非法的,这种问题在多个头文件中链接混合使用时会出现,而且对于初出茅庐的编程者往往无从下手。

这里有两种方法解决:

1).运用结构体标签(tag)

struct SIMPLE{int a;char b;float c;};struct SIMPLE x;struct SIMPLE y[20],*z;
这样就不会出问题。

2).运用typedef

这个是推荐的用法,一开始我看这种类似宏定义的东西总是不顺眼,当然它不是宏定义。不过这个用法真的很好,完全简便的封装了一个类型:
typedef struct {int a;char b;float c;}SIMPLE;
这样SIMPLE就是一个新的类型名,如同int一样,不过比int类型结构更复杂而已。很方便吧!

另附:为了多个源文件中使用同一种类型的结构,应把标签(tag)或typedef形式的声明放在一个头文件中。当源文件需要这个声明时,可以使用#include指令包含。

2.结构体的自引用

结构体的自引用也往往会出问题:
//第一种
struct SIMPLE{int a;struct SIMPLE b;int c;};
//----------------parting line----------------------------//第二种struct SIMPLE{int a;struct SIMPLE *b;int c;};
上面两种用法,第一种是错误的,因为会结构无限嵌套进去。机器永远不知道你要开辟多少空间!第二种用指针是正确的,因为指针的长度是已知的,记住它实时上所指向的是同一种类型的不同结构。这个与链表和树类似(这里不再赘述)。
但是注意 的一点是,结构自引用时如果加上typedef容易出问题。这个我在调试网上的一些程序时自主修改时经常碰到的问题。
//第一种
typedef struct{int a;SIMPLE *b;int c;}SIMPLE;
//--------------------parting line-------------------//第二种
typedef struct SIMPLE_temp{int a;struct SIMPLE_temp *b;int c;}SIMPLE;
第一种会出问题,提示结构SIMPLE未定义,这个很奇怪的错误提示表明了C语言的严谨性。所以,我们用第二种typedef来解决这个问题。

结构体的初始化类似于多维数组的初始化,这里不再赘述。

3.结构体的成员访问

 

这里会出现一个让许多编程初学者云里雾里的问题:

操作符:点操作符“.”与箭头操作符“->”

其实最大的区别和是建立于良好的编程习惯的:如果一个结构体则用点操作符访问其成员变量;如果是结构体指针则用“->”操作符访问成员变量。

先总结这么多以后再慢慢修补,等对class理解深刻了再把二者的区别整理一下。


笔者参考书籍《POINTERS ON C》与《C++ Primer》

另附:

typedef 行为有点像 #define 宏,用其实际类型替代同义字。

不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换

typedef函数指针用法:

typedef int (*MYFUN)(int, int);
这种用法一般用在给函数定义别名的时候
上面的例子定义MYFUN是一个函数指针, 函数类型是带两个int 参数, 返回一个int

分析这种形式的定义的时候可以用下面的方法:
先去掉typedef 和别名, 剩下的就是原变量的类型.去掉typedef和MYFUN以后就剩: int (*)(int, int)








原创粉丝点击