c语言sscanf函数的用法是什么
284
2022-09-01
ANSI C (5) —— 结构、联合、位字段、枚举
结构
typedef和#define的区别
#define仅仅是做简单的替换,而typedef是给某种数据类型创建一个替代名。 看这样的例子:
#include
编译:
$ gcc typedef.c typedef.c: In function ‘main’:typedef.c:4:29: warning: initialization makes integer from pointer without a cast charP s1="I love you.", s2="hello"; ^
typedef:
#include
编译:
$ gcc typedef.c
结构体直接赋值
#include
#include
结构体的嵌套
结构体定义中含有另一种结构体,这是合法的:
struct point{ int x,y;};struct trangle{ struct point p[3]; };
但是含有自身类型就是非法的了。
struct trangle{ struct trangle p[3]; };/*$ gcc struct1.c struct1.c:8:17: error: array type has incomplete element type struct trangle p[3]; ^*/
结构体定义中可以拥有指向自身类型结构的指针。这样的自指结构是合法的。
struct trangle{ struct trangle* p[3]; };
自指结构最典型的应用就是链表。
结构体定义的注意点
和C++不同,C不能在结构体中定义函数,因为C约定结构和算法(函数)是分开的。 看下面的代码:
struct man{ char *name; void show(){ printf("hello, I'm %s.\n",name); }};int main(void) { struct man man1; man1.name = "wei"; man1.show(); return
直接编译,我们会得到这样的信息: error: ‘struct man’ has no member named ‘show’ 而如果是在C++ 中编译,这不会有问题。 C++ 中的struct是有this指针的,如下代码可以正常运行:
struct man{ char *name; man(const char *name){ strcpy(this->name,name); } void show(){ printf("hello, I'm %s.\n",name); }};
结构体中的成员默认都是public的。 结构体不能包含显式的无参构造函数。如:
struct man{ char *name; man(const char *name){ //strcpy(this->name,name); this->name = (char *)name; } man(){ this->name = "??"; } void show(){ printf("hello, I'm %s.\n",name); }};int main(void) { struct man man2(); man2.show(); return
我们将得到:
error: request for member ‘show’ in ‘man2’, which is of non-class type ‘man()’
将man()删除仍然有这样的错误,这是为什么,因为结构体是没有默认的构造函数的,涉及到initobj等指令。
结构从基类OBJECT继承,但它不支持继承。
联合
联合体的存储
联合变量的存储区域可以存储多类型的数据。但是在任何时候,它只能存储一种数据,联合变量的大小是size最大成员的大小。 下面是一个联合的例子,涉及到C++的typeid操作符,用于判断数据类型。
#include
执行:
# ./a.out typeid return c, out data type size is 1, union numbers size is 8typeid return i, out data type size is 4, union numbers size is 8typeid return f, out data type size is 4, union numbers size is 8typeid return d, out data type size is 8, union numbers size is 8
联合的嵌套
在联合的定义中可以存在另一种不同的联合类型。比如:
union numbers{ char letter; int number; float dec_number; double pre_number;};union Union{ union
和结构体是一样的,它不能自身嵌套定义,比如:
union Union{ union Union num;};
我们也能定义含有指向自身类型的指针的联合类型。
union Union{ union Union* num;};
在这种情况下,num的类型已经改变,不再是自身。
位字段
首先复习一下字节、位等关键概念。Byte为字节,bit即位。转换 1B = 8b; 1KB = 1024B; 1MB = 1024KB; 1GB = 1024MB. 使用位字段,结构的成员被压缩到了一起,允许程序员在位的层次上访问内存,节省存储空间。注:位字段的数据类型必须是(signed) int、unsigned int。同时,位字段类型变量
不能地址操作 //--> error: cannot take address of bit-field ‘field1’ 不能计算字节数,sizeof //error: ‘sizeof’ applied to a bit-field
看看这个例子:
#include
编译执行
[root@CentOS workspace]# gcc bit.c [root@CentOS workspace]# ./a.out struct temp size is 12
field1和field2的内存占用是3个字节,int数据类型的字节数是4,所以最终结构体的内存占用是4+8 = 12.
枚举
通过枚举,我们可以定义自己的几种可能值的数据类型。 在默认的情况下,第一个值和0关联,第二个值和1关联… C语言中没有布尔数据类型,我们可以自定义。 比如:
#include
如果是自定义枚举成员的值,那么未自定义的成员按照顺序增大的原则赋值。比如:
#include
值得注意的是,enum的变量可以被任意赋值(不过只能给枚举变量赋值整数哈),不一定是定义的枚举成员。
#include
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~