(原码 ——> 反码: 符号位不变其他按位取反 ——> 补码: 反码加1 )
(正数原反补相同)
一.关于操作符的理解
需要注意:/ 是取整,%是取余
1.按2进制位移位操作符: >>、 <<
int a = 12; //12
int b = a << 1;//24
一个整形32个比特位 12的原码 000000000000000000000000000000110 = 12(整数的原反补是一样的)
左移一位是 0000000000000000000000000000011000 = 24
2.按2进制位位操作符 & 与 |或 ^异或
&运算:同真为真,一假为假
int a = 3; //00000000000000000000000000000011
int b = 5; //00000000000000000000000000000101
int c = a & b;//00000000000000000000000000000001
(首先取到a和b的补码,之后补码进行与运算,得到结果为1)(注意:正数的原反补是一样的)
int a = - 3; //11111111111111111111111111111101 (-3的补码)
int b = - 5; //11111111111111111111111111111011 (-5的补码)
int c=a&b; //11111111111111111111111111111001 (a&b运算后的补码)
//11111111111111111111111111111000 (转反码)
//100000000000000000000000000111(转原码的到运算接果为:-7)
(上述为负数的运算方法)
|或运算:一真为真,同假为假
int a = 3; //00000000000000000000000000000011
int b = 5; //00000000000000000000000000000101
int d = a | b;//00000000000000000000000000000111
(首先取到a和b的补码,之后补码进行或运算,得到结果为7)
负数计算参考与运算。
^异或运算:相同为假,相异为真
int a = 3; //00000000000000000000000000000011
int b = 5; //00000000000000000000000000000101
int e = a | b;//00000000000000000000000000000110 (结果为6)
负数计算参考与运算。
3.赋值操作符 = += -= *= /= &= ^= |= >>= <<=
float a = 0.0; (这是赋值操作,== 才是等于。)
a = 95.5f;
95.5默认是double类型,95.5f 制定为float类型。(需要注意一下这里的强制类型转换)
4.单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
5.逻辑操作符
&& 逻辑与 并且
|| 逻辑或 或者
6.条件操作符 exp1 ? exp2 : exp3
exp1为真就执行 exp2 否则exp3
列如:
int x = 10;
int y = 20;
int max = (x > y) ? (x) : (y);
printf("%d\n", max);
7.逗号表达式 exp1, exp2, exp3, …expN
int a = 3, b = 5, c = 6;
int d = (a -= 2, b = a + c, c = a - b);
printf("%d\n", d);//-6
从左向右求,整个表达式的结果就是最后一个表达式的后果。
二:关键字(32个)
关于typedef :
typedef 顾名思义是类型定义,应该理解为类型重命名。
将unsigned int 重命名为uint:typedef unsigned int uint;(将unsigned int重命名为uint)
观察num1和num2,这两个变量的类型是一样的
unsigned int num1 = 0;
uint num2 = 0;
关于static:
static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用
一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
三.#define 定义常量和宏
#define NUM 1000
主函数中:
int a = NUM;
printf("%d\n", a); (得到结果是1000。)
#define可以定义宏
#define ADD(X,Y) ((X)+(Y))
主函数中:
int a = 10, b = 20;
int sum = ADD(a, b);//在这里替换成了int sum =((a)+(b));
四.关于指针的理解
int a = 10;
printf("%p\n", &a);
%p - (16进制)地址 。
&a是取得4个字节中的第一个地址,这里a的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)。
int *pa = &a;
pa为指针变量 int 是pa的对象; * 告诉我们pa是指针
*pa = 20;这里*pa = a ,这是将a赋了20的值。
注意:指针大小在32位平台是4个字节,64位平台是8个字节。
看两个比较坑的代码,以后遇见要注意。
//int main()
//{
// int a = 0;
// int b = 2;
// if (a == 1) //这里没进去 ,底下没执行。
// if (b == 2)
// printf("hehe\n");
// else //else 和离得最近的可以匹配的if匹配
// printf("haha\n");
// return 0;
//}
//int main()
//{
// int a = 0;
// int b = 2;
// if (a == 1) //这里没进去 ,底下没执行。
// {
// if (b == 2)
// printf("hehe\n");
// else //else 和离得最近的可以匹配的if匹配
// printf("haha\n");
// }
// return 0;
//}
//int main()
//{
// int a = 1;
// if (a = 5) //bug = 是赋值 ,所以这里死循环了。
// printf("haha\n");
// return 0;
//}