学习目标:
学习掌握结构体 共用体 枚举 别名 位运算等语法
重点:结构体对齐,位运算
学习内容:
结构体:
c语言 --- 提供了一种方式,可以让用户自定义数据类型
构造一个数据类型 --就叫学生类型
学生类型 ---
int --- 整型数据
结构体:
提供一种可以让程序员自定义数据类型的方式
目的:用来解决 一些 复杂的数据类型问题
结构体 是一种数据类型 --- 构造类型
结构体类型 构造(定义)语法:
//构造一个结构体类型 --- 声明结构体
struct 结构体名
{
成员列表
};
语法:
1.struct //结构体 类型 关键字
2.结构体名
//表明这个结构体类型的 名称
//student
3.成员列表
//来描述结构体类型中 具体的一些数据
//成员变量
// char name[20];
// char sex;
// int age;
// int sno;
// float score;
4.最后结束时 } 后面,注意要有一个分号
//结构体变量初始化
struct student s = {"xiaoMing",0,1110,99.5} ; //初始化 ,需要按照 成员列表的顺序,依次初始化
//成员与成员之间的初始化的值,用逗号隔开
//s变量中,存储的是某一个学生的信息
//结构体的大小
结构体变量的引用:
方法:
结构体变量名.成员名
. 结构体成员运算符 //表示 从属关系
s.name //表示访问s变量中的 name
//结构体变量 赋值
1.结构体变量 不能 整体 输入值 ,只能输入给成员变量
声明结构体类型并使用的方式:
1. 方式1
先声明类型 后定义变量
struct student
{
...
};//声明类型
struct student s; //定义变量
2. 方式2
声明类型的同时定义变量
struct student
{
...
}s;//声明类型 并 定义变量
3. 方式3
声明类型的同时,定义变量,但是结构体名,可以省略
struct
{
...
}s;//声明类型 并 定义变量
对比 结构体 和 数组:
结构体特点:
1.成员变量 一般是不同类型 //表示不同的含义
2.对于成员变量的访问
只能通过 . (成员运算符),逐个访问
不能通过类似 数组下标的方式,进行逐个遍历
. //成员运算
方法:
结构体变量名.成员变量名
-> //指针的结构体成员运算
方法:
结构体类型指针->成员变量名
注意:
1.同一类型的结构体变量间 是可以相互赋值的
2.通过结构体类型的指针 也可以访问到结构体成员
->
3.结构体类型 ,既可以做函数形参,也可以做函数返回值类型
1.在32位的平台上,默认都是按4字节对齐的。
2.对于成员变量,
各自在自己的自然边界上对齐。
char -- 1字节
short -- 2字节
int -- 4字节
3.如果 成员变量中有比4字节大。
此时 整个结构体按照4字节对齐。
4.如果 成员变量中没有有比4字节大。
此时 整个结构体按照最大的那个成员对齐。
//32位的平台
//如果有超过4字节 ,按照4字节对齐
//如果没有超过4字节的,则按成员变量中最大对齐
//64位的平台
//如果超过4字节的,按照最大的成员对齐
//如果没有超过4字节的,则按成员变量中最大对齐
---------------------------------------------------------------
总结:
1.结构体
作用: 处理复杂的数据
2.使用
先构造出"结构体类型",
然后,用"结构体类型"
定义变量,
定义数组,
定义指针,
...
做函数的形参
做函数的返回值类型
3.语法
struct 结构体名
{
成员列表;
};
4.结构体给值
初始化 //按照结构体成员变量的顺序依次初始化
赋值 //结构体整体没有办法直接输入值的,但是可以给每个基本类型的成员变量输入值
//同种结构体类型的变量间 可以 相互赋值
struct demo
{
int a;
char b;
short c;
};
struct data
{
struct Demo d;
char e;
};
struct data dt = {{123,'c',456},'x'};
struct data dt1 = dt; //同一类型的结构体变量间,可以相互赋值
scanf("",&dt.d.a);
5.结构体变量的使用
两种方式
方式1 是一个结构体类型的变量 .(成员运算符去访问)
struct data dt;
dt.d.a
方式2 是一个结构体指针变量 ->(指针的成员运算符)
struct data *p = &dt;
p->d.a
6.结构体类型大小
共用体 (union)
共用体技术:
可以让,多个变量,共用同一块内存空间
语法:
union 共用体名
{
成员列表
};
注意:
1.共用体初始化时,只能给一个值,这个值默认时给到第一个成员的
2.共用体空间中数据,取决最后一次给到值
赋值的时候,每个成员只能影响,自己对应的字节
3.共用体类型
可以定义变量
可以定义数组
可以定义指针
可以做函数参数 和 返回值
4.共用体节省空间
枚举:
一枚枚的列举 //一个个的列举
enum
枚举语法:
enum 枚举名
{
枚举常量 //名字
};
eg:
enum weekday
{
MON,
TUES,
WED,
THURS,
FRI,
SAT,
SUN //枚举常量
};
注意:
1.c语言中 对于枚举类型 实际上是 当作整型处理的
2.提高代码可读性,
写成枚举,可以做语法检查
3.枚举常量,之间用逗号隔开
4.枚举常量,可以给初值,给了初值之后,后面的值会依次影响到
typedef //type define
//typdef 是不是定义了一个新的类型?
注意: typedef 不能定义出一个新的类型,它是给已有类型起别名
用法:
int a; //定义了一个int型变量 a
typedef int a; //此时 表示 给 int型 起了一个别名 叫 a
用途:
往往用于 给复杂类型 起别名
为了 可移植性 给一些类型起别名
size_t //long int
typedef long int size_t;
size_t
位运算:
主要用途,操作硬件
操作硬件的逻辑:
写程序 <----> 控制硬件
写程序 ---控制寄存器中的某些二进制位 ----->关联到某些硬件引脚 ---->电平的变化
& 按位与运算
---- 清零运算
运算规则: 一假则假
0x23 &= 0x00;
| 按位或运算
---- 置位(1)运算
运算规则: 一真则真
^ 异或运算
运算规则:相同为0 ,不同为1
~ 取反运算
运算规则:真假相对
<< 左移运算
eg:
操作数1 << 操作数2
操作数1 表示 要进行移位操作的数据
操作数2 表示 要移动位数
a << 2 //表示对a 左移 2位
>> 右移运算
eg:
操作数1 >> 操作数2
操作数1 表示 要进行移位操作的数据
操作数2 表示 要移动位数
eg:
unsigned char a = 0x80; //1000 0000
a>>1
1000 0000
0100 0000
算术右移
要移动的数据,本身是有符号类型 ,如果右移,最高位 补 符号位
逻辑右移
要移动的数据,本身是无符号类型 ,如果右移,最高位 补 0