5.2.2 有名结构体
typedef struct student{ char name[32]; int age; float weight; }student_t; //类型名 student_t 变量1,变量2;
5.2.3 struct的特殊赋值方式
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct person{ char name[32]; char sex; int age; int high; float weight; }person; int main(int argc, const char *argv[]) { person p; p = (person){"张安",'m',20,189,80}; printf("name = %s,sex = %c age = %d high = %d weight = %f\n",p.name,p.sex,p.age,p.high,p.weight); //结构体数组赋值 //方法1 person p1[2] = { { .name = "zhangsan", .age = 19 }, { .name = "zhangsi", .age = 20 } }; //方法2: person p2[3] = { [0] = { .name = "zhangsan", .age = 19 }, [2] = { .name = "zhangsi", .age = 20 } }; return 0; } //方法3: person p3[3]; p3[0].name
5.3 结构体占用字节大小
规则:
结构体占用字节大小的口诀是:
1.如果结构体内部的变量类型最大成员小于等于4字节,就按照最大的类型进行内存对齐
2.如果结构体内部变量类型大于四字节,就按照四字节对齐
3.结构体最终大小和结构体中成员最大类型对齐(32位和4字节对齐,64位和8字节对齐)
#include <stdio.h> struct aa{ char a; //1个字节 }; struct bb{ short a; //2个字节 }; struct cc{ int a; //4个字节 }; struct dd{ char a; // 2个字节 char b; }; struct ee{ int a; // 8个字节 char b; }; struct ff{ char a; // 6个字节 short b; char c; }; struct gg{ char a; // 8个字节 short b; int c; }; struct hh{ short a; // 8个字节 char b; int c; }; struct ii{ char a[3]; // 12个字节 int b; char c; short d; }; struct jj{ double a; // 24个字节 char b; int c; short d; float e; }; int main(int argc, const char *argv[]) { struct ff a; struct gg b; struct jj c; struct ii d; printf("aa = %ld\n",sizeof(struct aa)); printf("bb = %ld\n",sizeof(struct bb)); printf("cc = %ld\n",sizeof(struct cc)); printf("dd = %ld\n",sizeof(struct dd)); printf("ee = %ld\n",sizeof(struct ee)); printf("ff = %ld\n",sizeof(struct ff)); printf("gg = %ld\n",sizeof(struct gg)); printf("hh = %ld\n",sizeof(struct hh)); printf("ii = %ld\n",sizeof(struct ii)); printf("jj = %ld\n",sizeof(struct jj)); printf("ff.a = %p\nff.b = %p\nff.c = %p\n",&a.a,&a.b,&a.c); printf("gg.a = %p\ngg.b = %p\ngg.c = %p\n",&b.a,&b.b,&b.c); printf("jj.a = %p\njj.b = %p\njj.c = %p\njj.d = %p\njj.e = %p\n\n",&c.a,&c.b,&c.c,&c.d,&c.e); printf("ii.a = %p\nii.b = %p\nii.c = %p\nii.d = %p\n",d.a,&d.b,&d.c,&d.d); return 0; }
5.3.1 结构体的位域
压缩结构体大小的一种方式
#include <stdio.h> struct aa{ char a:1; char b:5; char c:3; }; int main(int argc, const char *argv[]) { printf("sizeof(aa) = %ld\n",sizeof(struct aa)); return 0; } 1.在结构体内部进行位域操作的时候,是从内存最低位置开始站位,如果这个变量是有 符号的,那么它的最高位就是符号位,如果这个位域只有一位,它既是符号位又是数据位 2.结构体位域的成员不能够取地址
六 共用体
6.1 基本用法
union内部的成员公用同一块内存空间,共用体的大小就是内部最大成员的内存空间
不管union有多少个成员,union的内存空间都是这个最大成员的内存空间
格式:
union 类型名{
char a;
short b;
int c;
};
6.2 大小端的判断
字节序:
大端序:高字节存放在低地址,低字节存放在高地址(网络序)
小端序:高字节存放在高地址,低字节存放在低地址
#include <stdio.h> typedef union aa{ unsigned char a; int c; }aa_t; int main(int argc, const char *argv[]) { aa_t a; a.c = 0x12345678; if(a.a == 0x12) { printf("这是大端机器\n"); } else if(a.a == 0x78) { printf("这是小端机器\n"); } return 0; }
6.3 结构体中定义联合体
让结构体的通用性更强
#include <stdio.h> struct aa { char a; union{ int b; char c; }; }; int main(int argc, const char *argv[]) { struct aa a; a.a = 10; a.b = 0xaabb; printf(“size = %ld\n”,sizeof(a)); printf(“c = %#x\n”,a.c); return 0; }
七 枚举类型
枚举就是有限数据的罗列,比如一周有七天,一年有12个月,
这些都是有限的罗列,适合用枚举
格式: enum 类型名{ 成员1, 成员2, 成员3, 成员4 = 10, 成员5, .。。 成员n, }; (2)枚举类型的关键是enum (2)枚举的成员没有变量类型 (3)成员间通过逗号来区分 (4)枚举的成员的值依次向下递增1 (5)枚举中的成员访问不是通过.或者->来访问,直接拿成员使用 (6)枚举类型的大小是4个字节 (7)枚举类型如果不赋初值,默认从0开始
练习:
实例一:
#include <stdio.h> enum week{ MON = 1, TUS, WED, THU, FRI, SAT, SUN }; int main(int argc, const char *argv[]) { enum week day; printf("day size = %ld\n",sizeof(day)); day = TUS; printf("day = %d\n",day); day = 10; //虽然编译器不会报错,但是不能这样赋值 //给枚举类型变量赋值的时候,只能赋值枚举常量 printf("day = %d\n",day); return 0; }
实例二
#include <stdio.h> #define S(n) case n: return #n typedef enum leds{ RED, GREEN, BLUE, }leds; char *led_type_to_str(enum leds led) { switch(led) { S(RED); S(GREEN); S(BLUE); default: return "不存在的"; } } leds led_open(leds led) { printf("打开%s灯\n",led_type_to_str(led)); return led; } int main(int argc, const char *argv[]) { #if 0 char *p = NULL; enum leds led; led = led_open(RED); p = led_type_to_str(led); printf("打开%s-ok!\n",p); #endif printf("打开%s-ok!\n",led_type_to_str(led_open(RED))); return 0; }