结构、联合、位字段、枚举
2016-12-19 23:32
351 查看
结构
结构体在声明的时候并没有分配任何的内存资源,只有定义了结构体变量才会产生相应的内存分配。
typedef和#define的区别
#define仅仅是做简单的替换,而typedef是给某种数据类型创建一个替代名。
看这样的例子:
#include <stdio.h> #define charP char* int main(){ charP s1="I love you.", s2="hello"; return 0; }1
2
3
4
5
6
编译:
$ 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"; ^1
2
3
4
5
typedef:
#include <stdio.h> typedef char* charP; int main(){ charP s1="I love you.", s2="hello"; return 0; }1
2
3
4
5
6
编译:
$ gcc typedef.c1
结构体直接赋值
#include <stdio.h> typedef struct node{ char *s; int a; float b; }Node; int main(){ Node A; A.s = "hello"; A.a = 12; A.b = 2.5; Node B = A; printf("s is %s, a is %d, b is %f\n",B.s,B.a,B.b); return 0; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h> #include <string.h> typedef struct node{ char s[30]; int a; float b; }Node; int main(){ Node A; strcpy(A.s,"hello"); A.a = 12; A.b = 2.5; Node B = A; printf("s is %s, a is %d, b is %f\n",B.s,B.a,B.b); return 0; } /* edemon@ubuntu1:~/workspace$ ./a.out s is hello, a is 12, b is 2.500000 */1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
结构体的嵌套
结构体定义中含有另一种结构体,这是合法的:struct point{ int x,y; }; struct trangle{ struct point p[3]; };1
2
3
4
5
6
但是含有自身类型就是非法的了。
struct trangle{ struct trangle p[3]; }; /* $ gcc struct1.c struct1.c:8:17: error: array type has incomplete element type struct trangle p[3]; ^ */1
2
3
4
5
6
7
8
9
结构体定义中可以拥有指向自身类型结构的指针。这样的自指结构是合法的。
struct trangle{ struct trangle* p[3]; };1
2
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 EXIT_SUCCESS; }1
2
3
4
5
6
7
8
9
10
11
12
直接编译,我们会得到这样的信息:
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); } };1
2
3
4
5
6
7
8
9
结构体中的成员默认都是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 EXIT_SUCCESS; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
我们将得到:
error: request for member ‘show’ in ‘man2’, which is of non-class type ‘man()’1
将man()删除仍然有这样的错误,这是为什么,因为结构体是没有默认的构造函数的,涉及到initobj等指令。
结构从基类OBJECT继承,但它不支持继承。
联合
联合体的存储
联合变量的存储区域可以存储多类型的数据。但是在任何时候,它只能存储一种数据,联合变量的大小是size最大成员的大小。 下面是一个联合的例子,涉及到C++的typeid操作符,用于判断数据类型。
#include <typeinfo> #include <iostream> #include <stdio.h> using namespace std; union numbers{ char letter; int number; float dec_number; double pre_number; }; int main(){ union numbers num; num.letter = 'a'; printf("typeid return %s, out data type size is %d, union numbers size is %d\n",\ typeid(num.letter).name(),sizeof(num.letter),sizeof(num)); num.number = 1; printf("typeid return %s, out data type size is %d, union numbers size is %d\n",\ typeid(num.number).name(),sizeof(num.number),sizeof(num)); num.dec_number = 1.0f; printf("typeid return %s, out data type size is %d, union numbers size is %d\n",\ typeid(num.dec_number).name(),sizeof(num.dec_number),sizeof(num)); num.pre_number = 1.0; printf("typeid return %s, out data type size is %d, union numbers size is %d\n",\ typeid(num.pre_number).name(),sizeof(num.pre_number),sizeof(num)); return 0; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
执行:
# ./a.out typeid return c, out data type size is 1, union numbers size is 8 typeid return i, out data type size is 4, union numbers size is 8 typeid return f, out data type size is 4, union numbers size is 8 typeid return d, out data type size is 8, union numbers size is 81
2
3
4
5
联合的嵌套
在联合的定义中可以存在另一种不同的联合类型。比如:union numbers{ char letter; int number; float dec_number; double pre_number; }; union Union{ union numbers num; };1
2
3
4
5
6
7
8
9
和结构体是一样的,它不能自身嵌套定义,比如:
union Union{ union Union num; };1
2
3
我们也能定义含有指向自身类型的指针的联合类型。
union Union{ union Union* num; };1
2
3
在这种情况下,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-field1
2
看看这个例子:
#include <stdio.h> #include <stdlib.h> struct temp{ int field1:8; int field2:16; long long t; }; int main(){ struct temp num; //printf("struct temp size is %d, field1 size is %d, field2 size is %d\n",sizeof(struct temp),sizeof(num.field1),sizeof(num.field2)); //void *p = (void *)&num.field1; printf("struct temp size is %d\n",sizeof(struct temp)); return 0; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
编译执行
[root@CentOS workspace]# gcc bit.c [root@CentOS workspace]# ./a.out struct temp size is 121
2
3
field1和field2的内存占用是3个字节,int数据类型的字节数是4,所以最终结构体的内存占用是4+8 = 12.
枚举
通过枚举,我们可以定义自己的几种可能值的数据类型。 在默认的情况下,第一个值和0关联,第二个值和1关联…
C语言中没有布尔数据类型,我们可以自定义。
比如:
#include <stdio.h> #include <stdlib.h> enum Boolean {false,true}; typedef enum Boolean bool; bool check(int tag){ if(tag&1) return false; return true; } int main(){ if(check(2)) puts("even"); else puts("odd"); return 0; }1
2
3
4
5
6
7
8
9
10
11
12
13
如果是自定义枚举成员的值,那么未自定义的成员按照顺序增大的原则赋值。比如:
#include <stdio.h> #include <stdlib.h> enum Node{t1=1, t2, t3=5, t4, t5}; int main(){ printf("t2 is %d, t4 is %d, t5 is %d\n",t2,t4,t5); return 0; } /* [root@CentOS workspace]# ./a.out t2 is 2, t4 is 6, t5 is 7 */1
2
3
4
5
6
7
8
9
10
11
值得注意的是,enum的变量可以被任意赋值(不过只能给枚举变量赋值整数哈),不一定是定义的枚举成员。
#include <stdio.h> #include <stdlib.h> enum Node{t1=1, t2, t3=5, t4, t5}; int main(){ //printf("t2 is %d, t4 is %d, t5 is %d\n",t2,t4,t5); enum Node t=-1; printf("t is %d\n",t); return 0; }
相关文章推荐
- ANSI C (5) —— 结构、联合、位字段、枚举
- C语言(Head First C)-6_2:结构、联合与位字段:结构更新、联合、枚举和位字段
- C语言(Head First C)-6_1:结构、联合与位字段:创建自己的结构
- 【C语言总结】结构、联合、位段和枚举
- c++笔记01---c++ 简介,g++ 编译器,名字空间,结构,联合,枚举
- qt开发环境 - c++之结构,联合,枚举
- c语言中结构、联合、枚举的用法
- C:笔记:枚举 结构 联合
- c语言中结构、联合、枚举的用法
- unit01_C++语言背景介绍 、 第一个C++程序 、 名字空间 、 结构、联合和枚举 、 布尔型与操作符别名
- 【c语言问题系列教程之二】结构、联合和枚举
- 《你必须知道的495个C语言问题》笔记--结构、联合和枚举
- C语言基础教程(四)指针、结构、联合和枚举
- MOOC——C语言11:结构类型:枚举,结构,联合
- 结构,联合和枚举
- C语言结构、联合、位操作、位域和枚举
- 结构、联合和枚举
- C++中的枚举,结构,联合等。。。。
- 结构、位域、联合、枚举之小小总结
- C++:C++背景、名字空间、结构联合枚举、字符串类型