#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <time.h>
//--------------------------------------------------------------------------------------------------------4.位操作符
// &----按(2进制补码)位与(全1 为 1)
// | ----按(2进制补码)位或(有1则1,全0则0)
//^ ----按(2进制补码)位异或(相同为0,相异为1)
//------------------------------- &----按(2进制补码)位与
int main()
{
int a = 3; //32个bit位
//00000000000000000000000000000011-------3的补码
int b = -5;
//10000000000000000000000000000101------- -5的原码
//11111111111111111111111111111010------- -5的反码
//11111111111111111111111111111011------- -5的补码
int c = a & b;
//00000000000000000000000000000011-------3的补码
//11111111111111111111111111111011------- -5的补码
//3的补码和-5的补码按位与&(同时为1才为1)
//00000000000000000000000000000011---高位为0,是正数,正数原反补相同 3
printf("c=%d\n", c); // 输出3
//%d代表打印一个有符号的整数(原码)
int d = a | b;
//00000000000000000000000000000011-------3的补码
//11111111111111111111111111111011------- -5的补码
//3的补码和-5的补码按位或 |(有1则1,全0则0)
//11111111111111111111111111111011---高位为1,是负数,找源码
//10000000000000000000000000000101--- -5
printf("d=%d\n", d); // 输出-5
int e = a ^ b;
//00000000000000000000000000000011-------3的补码
//11111111111111111111111111111011------- -5的补码
//3的补码和-5的补码按位或 ^(相同为0,相异为1)
//11111111111111111111111111111000---高位为1,是负数,找源码
//10000000000000000000000000001000--- -8
printf("e=%d\n", e); // 输出-8
return 0;
}
// 不创建临时变量,实现两个数的交换
//3^3
//011
//011
//000=0
//0^5
//000
//101
//101=5
//3^3^5=5
//3^5^3
//011
//101
//110
//011
//101=5
//异或^操作符支持交换律//实际的开发过程中,通常用方法1,创建临时变量去实现两个数的交换
int main()
{
int a = 3;
int b = 5;
//方法1(创建临时变量)
int c = 0;
printf("交换前a=%d b=%d\n", a, b);
c = a;
a = b;
b = c;
printf("交换后a=%d b=%d\n", a, b);
//方法2(可能会有溢出)
printf("交换前a=%d b=%d\n", a, b);
a = a + b;
b = a - b;
a = a - b;
printf("交换后a=%d b=%d\n", a, b);
//方法3(异或^操作符)
printf("交换前a=%d b=%d\n", a, b);
a = a ^ b;//a=3^5
b = a ^ b;//b=3^5^5-->b=3
a = a ^ b;//a=3^5^3-->a=5
printf("交换后a=%d b=%d\n", a, b);
return 0;
}
//--------------------------------------------------------------------练习
//编写代码实现:求一个整数存储在内存中的二进制中 1的个数
//求补码中1的个数
int main()
{
int a = 0;
scanf("%d", &a);
return 0;
}
//---------------------------------------------------------------------------------------------------------5.赋值操作符
//=赋值
//与==判断相对 区分
//---------------------------------------------------------------------------------------------------------6.单目操作符
//单目操作符只有1个操作数
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置 --
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
//---------------------------------------------------------------------------------------------------6.1 操作符介绍
int main()
{
//---------------------------------------------操作符 !
int flag = 3;
//C语言中,0表示假,非0表示真
if (flag) // 如果flag为真,进入if
{}
if (! flag) // 如果flag为假,进入if
{}
//---------------------------------------------操作符 +
int a = +10;
int b = +a;
printf("%d\n", a); //10
printf("%d\n", b); //10
// --------------------------------------------操作符 -
int c = -10;
int d = -c;
printf("%d\n", c); //-10
printf("%d\n", d); //10
//----------------------------------------------操作符 &
printf("%p\n", &a);//a是整型,占4个字节,取地址取的是第一个字节的地址
int* p = &a; //p就是指针,p的类型是int*,表示p是指针变量
//---------------------------------------------操作符 sizeof
// 计算的变量所占内存的大小
int n = sizeof(a); //计算 a 所占内存的大小,单位是字节
printf("%d\n", n);// 4
// 计算类型所创建的变量占据空间的大小
int m = sizeof(int);
printf("%d\n", m);// 4
// 计算整个数组的大小
int arr[10] = { 0 };
printf("%d\n", sizeof(arr)); //40
//----------------------------------------------操作符 ~
//按位取反(二进制位)
int x = 0;
printf("%d\n", ~x);// -1
//00000000000000000000000000000000 ---0的补码
//11111111111111111111111111111111 ---按位取反
//还原成源码 -1再取反
//11111111111111111111111111111110
//10000000000000000000000000000001--- -1
int y = 3;
printf("%d\n", ~y);// -4
//00000000000000000000000000000011--- 3的补码
//~3
//11111111111111111111111111111100--- 补码
//恢复原码
//11111111111111111111111111111011
//10000000000000000000000000000100----4
return 0;
}
//--------------------------------------------------------------------------------------练习
//把2进制位里的0改成1,就用 | 或上1
//把2进制位里的1改成0,就用 & 与上0
int main()
{
int z = 13;
z |= (1 << 1);
//00000000000000000000000000001101---13的补码
// | (全1则1)
//00000000000000000000000000000010(可以由 1的补码向左移动1位 得到这个)
// =
//00000000000000000000000000001111--15
printf("%d\n", z); //15
//把2进制位里的0改成1,就用 |或上1
int p = 13;
p |= (1 << 4);
//00000000000000000000000000001101---13的补码
// |(有1则1,全0则0)
//00000000000000000000000000010000(可以由 1的补码向左移动1位 得到这个)
// =
//00000000000000000000000000011101---29的补码
printf("%d\n", p); //29
p &= ~(1 << 4);
//00000000000000000000000000011101---29的补码
//&(全1 为 1)
//11111111111111111111111111101111(由00000000000000000000000000010000按位取反得到)
//=
//00000000000000000000000000001101---13的补码
printf("%d\n", p); //13
return 0;
}
test()
{}
int main()
{
//-------------------------------------------------操作符 ++
int a = 3;
int b = ++a; //前置++, 先++,后使用
//a=a+1,b=a
printf("a=%d\n", a); // 4
printf("b=%d\n", b);// 4
int c = 3;
int d = c++; //后置++, 先使用,后++
// d=3, c=3+1
printf("c=%d\n", c); // 4
printf("d=%d\n", d);// 3
//-------------------------------------------------操作符 --
int aa = 3;
int bb = --aa; //前置--, 先--,后使用
//aa=aa-1,bb=aa
printf("aa=%d\n", aa); // 2
printf("bb=%d\n", bb);// 2
int cc = 3;
int dd = cc--; //后置--, 先使用,后--
// dd=3, cc=3-1
printf("cc=%d\n", cc); // 2
printf("dd=%d\n", dd);// 3
int x = 10;
printf("%d\n", x--); //10 因为x先使用,使用完再--
printf("%d\n", x); // 9
int y = 10;
test(y--); //调用函数,test接收到的 y 是10,因为是先使用,后--
printf("%d\n", y); //9
//-----------------------------------------------操作符 *
//间接访问操作符(解引用操作符),与指针配合使用
int z = 10;
int* p = &z; //把 z 的地址存到 p 中
*p; //通过p的地址,找到他所指向的对象 10
printf("z=%d\n", z); //10
printf("&z=%p\n", &z); //00000001774FFA84
printf(" p=%d\n", p); //00000001774FFA84
printf("*p=%d\n", *p); //10
return 0;
}
int main()
{
//-----------------------------------------------() 强制类型转换
int a = (int)3.14; //把3.14强制转化为整型
printf("%d\n", a);// 3
//随机数的生成
srand((unsigned int)time(NULL));//把srand 的返回值强制转换为 unsigned int
return 0;
}
//sizeof是操作符,不是函数
//strlen是库函数,用来求字符串长度
int main()
{
int a = -10;
int* p = NULL;
printf("%d\n", !2);
printf("%d\n", !0);
a = -a;
p = &a;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof a);//这样写行不行? 可以,证明了 sizeof是操作符,不是函数,函数后的括号不可以省略
//printf("%d\n", sizeof int);//这样写行不行? 不可以
return 0;
}
//---------------------------------------------------------------------------------6.2 sizeof 和 数组
void test1(int arr[])
{
printf("sizeof(arr)(2)=%d\n", sizeof(arr));//(2)--8 /4
}
void test2(char ch[])
{
printf("sizeof(ch)(4)%d\n", sizeof(ch));//(4)--8 / 4
}
int main()
{
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("sizeof(arr)(1)=%d\n", sizeof(arr));//(1)---40
printf("sizeof(ch)(3)=%d\n", sizeof(ch));//(3)---10
test1(arr);
test2(ch);
return 0;
}
// (1)(2)(3)(4)分别输出多少
//(x64环境下,一个地址8个字节)
//(x86环境下,一个地址4个字节)
//--------------------------------------------------------------------------------------------------7. 关系操作符
//>
//>=
//<
//<=
//!= 用于测试不相等
//== 用于测试相等
//两个字符串比较相等用 strcmp 库函数
//-----------------------------------------------------------------------------------------------------8. 逻辑操作符
//&&
// ||