五:共用体
1.语法
union 共用体名
{
//各个成员变量
......
....
};定义
1.共用体类型的定义和结构体类型的定义 类似
2.共用体中各个成员变量 — 共用一块内存空间因为共用体成员变量共用同一块空间
3.结构体中各个成员变量—–独立各自空间,共用体的大小= 成员变量中最大的那个成员大小
共用体各个成员的起始地址是一样的,但是,因为各个成员变量,本身类型大小不一样,最终能使用到的字节数是 不一样的。
4.共用体初始化时,默认值是给到第一个变量的 //注意:初始化时,要看第一个变量的类型
5.共用体成员可以赋值但是因为共用一块空间,最终空间上结果,要看最后一次给到的结果
union demo
{
int c;
char a;
short b;
};
int main(int argc, const char *argv[])
{
union demo d = {0x12345678};
printf("sizeof(union demo) = %ld\n",sizeof(union demo));
printf("a = %#x\n",d.a);
printf("b = %#x\n",d.b);
printf("c = %#x\n",d.c);
printf("&a = %p\n",&d.a);
printf("&b = %p\n",&d.b);
printf("&c = %p\n",&d.c);
return 0;
}
sizeof(union demo) = 4
a = 0x78
b = 0x5678
c = 0x12345678
&a = 0x7ffc11fa01f4
&b = 0x7ffc11fa01f4
&c = 0x7ffc11fa01f4
2.判断大小端
int judLitterENdian(void)
{
union
{
unsigned int a;
unsigned int b;
}d = {1};
return d.b;
}
int main(int argc, const char *argv[])
{
if(judLitterENdian() == 1)
{
printf("little\n");
}else
{
printf("big\n");
}
return 0;
}
六:共用体和共用体结合实例
struct member
{
char name[20];
int sno;
union
{
float score;
float salary;
}data;
};
int main(int argc, const char *argv[])
{
printf("sizeof(struct member) = %ld\n",sizeof(struct member));
struct member stu = {"tom",110,99.5};
struct member teacher = {"jerry",110,9999.5};
printf("----stu-----\n");
printf("name = %s\n",stu.name);
printf("sno = %d\n",stu.sno);
printf("score = %f\n",stu.data.score);
printf("----teacher-----\n");
printf("name = %s\n",teacher.name);
printf("sno = %d\n",teacher.sno);
printf("score = %f\n",teacher.data.score);
return 0;
}
七:枚举(类似宏定义)
1.语法
enum 枚举类型名
{
枚举常量名1,//逗号隔开
枚举常量名2,
....
};//枚举类型
//枚举类型;是把一组相关的常量组合到一个类型中
常量的值本质上是一个整型的数值 ,从0开始,依次递增,也可以直接第一个元素赋值1,那就从1开始,如果指定了,后续的没指定的,是在指定的基础上依次递增
枚举类型的变量 可以接受 任意整数因为枚举类型在c语言中,是以int
类型来实现
本质上就是整数型
八:typedef
类型定义(给已有类型起别名)
typedef int Size_t;
Size_t b =10;
printf("b = %d\n",b);
对结构体 定义
typedef struct student
{
char name[20];
int sno;
int sex;
}stu_s;
stu_s s[1] = {"Tom",110,1};
九:位运算
unsigned char a = 0x55;
unsigned char b = 0x33;
0101 0101 //a 0101 0101 //a
& 0011 0011 //b //一假则假 | 0011 0011 //b //一真则真
-------------------------------------------------------------------------------------------------
0001 0001 //0x11 0111 0111 //0x77
----------------------------------------------------------------------------------------------
0101 0101 //a
~ 1010 1010 //0Xffffffaa //真假对立
异或 //相同为0,不同为1
0101 0101 //a
^ 0011 0011 //b
------------------------------------------------------------------------------------------------
0110 0110 //0x66
------------------------------------------------------------------------------------------------ 左移 m<<n //将m中的二进制位向左移动n位,最右边空出来的位置补0,左移只是运算,并不影响运算数本身
7654 3210
<< 0101 0101 //a << 1
01010 1010
-------------------------------------------------------------------------------------------
1010 1010 //0xaa
-------------------------------------------------------------------------------------------
右移 m>>n //将m中的二进制位向右移动n位,要看左操作数的数据类型是否是有符号的
7654 3210 //有符号的右移,signed 最高位补符号位----算数右移
>> 0101 0101 //a >> 1 //无符号的右移,unsigned 最高位补0-------逻辑右移
0010 1010 //因为原本是0,补符号位0
--------------------------------------------------------------------------------------------
signed char a = 0x95;
unsigned char b = 0x33;
printf(">> result = %#hhx\n",a>>1);//0xca---------算术右移,由于符号位是1,补符号位1
printf(">> result = %#hhx\n",b>>1);//0x19
& —清零
int a = 0xffff //将第10位清0
1111 1111 1111 1111
1 //1 << 10
---------------------------------------------------------
1111 1101 1111 1111 //a & ~(1 << 10)
int a = 0xffff;
printf("result = %#x\n",a&~(1<<10));
int a = 0xffff;
printf("result = %#x\n",a&~(1<<3)&~(1<<5)&~(1<<7) &~(1<<10));//3,5,7,10清0 //fb57
a = a & (1<<3|1<<5|1<<7|1<<10);//也可以这样写
| -----置1操作
a | (1<<10)
int a = 0;//奇数位置1
for(int i=1;i<32;i++,i++)
{
a = a | (1<<i);
}
printf("result = %#x\n",a); //result = 0xaaaaaaaa
^ 异或运算:简单加密
int a = 0xab;
int b = 3;
1010 1011
^0000 0011
------------------------------------------------------------------------------------------
1010 1000 //加密后
^0000 0011 //再次异或,实现解密
--------------------------------------------------------------------------------------------
1010 1011 //解密后
异或运算:两数交换
a = a ^ b;
b = a ^ b;
a = a ^ b;
int a= 55;
int b = 33;
printf("a = %d,b = %d\n",a,b);
#if 0
a = a + b;
b = a - b;
a = a - b;
#endif
a = a ^ b;//逻辑同上
b = a ^ b;
a = a ^ b;
printf("a = %d,b = %d\n",a,b);
位运算不适用于指针交换或浮点类型
int a = 1213;//查找a二进制有多少个1
int count = 0;
for(int i=0;i<32;i++)
{
if((a & (1<<i)))
{
count++;
}
}
printf("%d nun1\n",count);
//实现循环左移
int a = 1;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
if(a & 1<<31)//找最高位
{
a = a << 1;
a = a | 1;//0x00000001
}else
{
a = a << 1;
}
}
printf("a = %#x\n",a);