共用体,位运算 day18

五:共用体

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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值