一、union
//联合--共用体
早期的时候,计算机的硬件资源有限,
能不能让多个成员变量 公用同一块空间
//使用方式 类似 结构体 --- 也是构造类型
union 共用体名
{
成员变量名
}; //表示构造了一个共用体类型
//定义变量
//定义指针
//定义数组
//做函数形参
//做函数返回值类型
注意:
(一)大小
共用体类型的大小 等于最大的成员的大小
(二)初始化
共用体初始化只能写一个值,这个值是给第一个成员变量的值
#include<stdio.h>
union demo
{
int a;
char b;
short c;
};
int main(int argc, const char *argv[])
{
union demo d = {0x12345678};
printf("d.a = %#x\n",d.a);
printf("d.b = %#x\n",d.b);
printf("d.c = %#x\n",d.c);
putchar('\n');
printf("%p\n",&d.a);
printf("%p\n",&d.b);
printf("%p\n",&d.c);
return 0;
}

(三)访问
共用体成员的访问方式 和 结构体一样
(四)赋值
共用体因为公用同一块空间
赋值时,后赋值的会影响前面赋值的结果
(五)用途
a.节省空间
b.数据转换
c.判断电脑大小端
#include<stdio.h>
int isEndian(void)
{
#if 0
union
{
int a;
char b;
}d = {0x12345678};
printf("%#x\n",d.a);
printf("%#x\n",d.b);
#endif
union
{
int a;
char b;
}d ={1};
return d.b == 1;
}
int main(int argc, const char *argv[])
{
if(isEndian())
{
printf("System is Little-endian.\n");
}else
{
printf("System is Big-endian.\n");
}
return 0;
}
192.168.0.59 //ip地址 --- 网络环境中 ---实际对应是一个32位的数值
#include <stdio.h>
union Ip
{
unsigned char ip[4];
unsigned int iip;
};
int main(int argc, const char *argv[])
{
union Ip d = {192,168,0,59};
printf("ip = %#x\n",d.iip);
return 0;
}
二、枚举
//提高代码可读性
如果一个变量只有几种可能的值,则可以定义为枚举类型。 所谓"枚举"是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。
枚举 --- 将变量的可能值(常量值) 一一列举出来
将有关联的常量值,一一列举出来,组合成一个枚举类型
enum 枚举名
{
枚举值
//sun,mon,tue,wed,thu,fri,sat
};
//构造了一个枚举类型
注意: 1.枚举类型 本质是 用int型数据表示的
枚举类型 设计的不严谨的地方
(一)应用:歌曲的状态
#include<stdio.h>
enum mu
{
Playing = 1,
Pause,
Stop
};
int main(int argc, const char *argv[])
{
int n;
while(1){
scanf("%d",&n);
switch(n)
{
case Playing:
printf("song is Playing\n");
break;
case Pause:
printf("song is Pause\n");
break;
case Stop:
printf("song is Stop\n");
break;
case 0:
return 1;
}
}
return 0;
}
三、typedef
//type define 表示给已有类型起别名
#include<stdio.h>
typedef struct stu
{
int age;
char name[20];
}stu;
int main(int argc, const char *argv[])
{
stu s1 = {1,"tom"};
printf("%d\n",s1.age);
printf("%s\n",s1.name);
typedef int t;
t a = 1;
printf("%d\n",a);
return 0;
}
四、位运算
//指的是二进制位上的运算
c语言位运算:
& 与
运算规则: 一假则假
| 或
运算规则: 一真则真
^ 异或
运算规则: 相同为0 不同为1
<< 左移 a<<n
运算规则: 将 左操作数a 左移 n位
左移一位 相当于 结果乘以2
右移: 要看 要移动的数据的类型
有符号 --- 最高位补符号位 //算术右移
无符号 --- 最高位补0 //逻辑右移
(一)用途
嵌入式 --- 位运算 非常普遍
操作硬件
(二)应用
1、偶数位置0,奇数位置1;
#include<stdio.h>
int main(int argc, const char *argv[])
{
//偶数位置0
#if 0
int a = 0xffffffff;
int i = 0;
for(i = 0;i < 32;i+=2)
{
a = a & ~(1 << i);
}
printf("a = %#x\n",a);
#endif
//奇数位置1
int a = 0;
int i = 0;
for(i = 1;i < 32;i+=2)
{
a = a | (1<<i);
}
printf("a = %#x\n",a);
return 0;
}
2、计算 一个int 类型中有多少个1
#include<stdio.h>
int main(int argc, const char *argv[])
{
int i = 0;
unsigned int a = 12134;
int n = 0;
for(i = 0;i < 32;i++)
{
if((a & 1) == 1)
{
n++;
}
a = a >> 1;
}
printf("%d\n",n);
return 0;
}
3、编写程序实现循环左移
step1:从最高位移出一位
是0还是1
step2:将最高位的 这个 0 或者 1
塞到尾部
step3:左移几位
循环走几遍
#include<stdio.h>
int main(int argc, const char *argv[])
{
int a = 0xefffffff;
int i = 0;
int n;
scanf("%d",&n);
for(i = 0;i < n;i++)
{
if((a & 0x80000000) != 0)
{
a = (a<<1) + 1;
}else
{
a = (a<<1);
}
}
printf("%#x\n",a);
return 0;
}