目录
操作符
算数操作符
+ - * / %
int / int=int
想要小数(除数和被除数之间至少一个小数)
默认写小数double类型(加上f 5.5f是单精度)
取余% 两边必须是整数
移位操作符 << >>
<< 左移操作符
2 << 1( 把2的二进制位向左移动1位)
左丢弃,右补零
>> 右移操作符
(第一个二进制位)是符号位
1.算数右移
右边丢弃,左边补原符号位
2.逻辑右移
右边丢弃,左边补0
int a=b >> 2(b不变)
位操作符 & | ^
&按位与
int c=a&b
00000000000000000000000000000011
00000000000000000000000000000101
(都是1,才是1)
|按位或
(一个1,则是1)
^按位异或
(相同为0,相异为1)
----交换两个变量的值,不使用第三个变量
int main()
{
int a = 9;
int b = 19;
a = a + b;
b = a - b;
a = a - b;
printf("%d %d", a, b);
return 0;
}
有缺陷,数字太大容易内存溢出
--------密码和钥匙(异或)
a ^ b ^ b结果为a
int main()
{
int a = 9;
int b = 90;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d %d", a, b);
return 0;
}
----求二进制数在内存中二进制中1的个数
用逻辑与(两个都是1则是1)
赋值操作符
= += -= *= /= >>= <<= %=
(赋值:都是=)
a=x=y-1(y-1的值先赋值给x,x的值再赋值给a)
单目操作符
只有一个操作数
!逻辑反操作
if(!flag)(如果flag为假)
size of
size of 是操作符,不是函数
sizeof(int)必须加上() sizeof a size fo(int [10])数组的类型
short a = 5;
int b = 10;
///sizeof(a=b+2)
//a
2 5
2:高内存到低内存必须强制类型转换
5:sizeof()里的表达式不参与运算
----源文件到可执行文件
sizeof(a+1)在编译期间就运行了 到了运行时相当于sizeof(2)
----sizeof和数组
void ARR(int a[])
{
printf("%d\n", sizeof(a));//8
}
void CH(char a[])
{
printf("%d\n",sizeof(a));//8
}
int main()
{
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("%d\n", sizeof(arr));//40
printf("%d\n", sizeof(ch));//10
ARR(arr);
CH(ch);
return 0;
}
传过去的是首元素的地址(x86是8,其他的还可能是4)
~二进制位按位取反
int a = -1;
int b = ~a;
//b
b为0;
内存中存的是补码 补码按位取反为0
----把a的二进制位第5位改成0
0000000000000000000000000010000按位取反
再与他按位与
++,--
前置与后置
int b=a++(后置++)
先使用(赋值给b,再++)
强制类型转换
int a = (int)3.14;
高内存类型强制转化为低内存
关系操作符
比较
> >= <= != ==
比较两个字符串不能使用==(字符可以)
逻辑操作符 && ||
位操作符是&单个
&&(逻辑与) 从前到后 一真则真
||(逻辑或) 从前到后 一假则假
if(a || b)(一真则真)
int c= a++ && n++ && k
(一旦a为0(为假,一假则假)后面不再计算)
条件表达式
三目操作符
exp1?exp2:exp3
1是真,计算2。1是假,计算3
逗号表达式
(c=5,a=c+3,b=a-4)
从左到右依次计算,整个表达式结果是最后一个表达式结果
下标引用,函数调用,结构成员
[ ]下标引用操作符
int arr[ ]不是
arr[4]是 4是操作数
()函数调用
Add(a,b)
. ->结构成员访问
结构类似与类
Struct Book b
struct Book *pb =&b(结构体指针)
b.name *pb.name pb->name
(调用成员变量)
表达式求值
表达式求值的顺序一部分是由操作符的优先级和结合性决定
隐式类型转换
----整型提升
例:
char a,b,c
a=b+c
b和c被提升为普通整型,然后再执行加法操作
加法完成之后,结果将被截断,然后再存储于a中
意义
--------计算
是按照变量的数据类型的符号位来提升的
char a=3;
//00000011
char b=127;
//01111111
符号位为0 提升
00000000000000000000000000000011
char c=-1;
//11111111 存的是补码
符号位为1 提升
11111111111111111111111111111111
无符号数高位补0
--------------------
例:
char a=0xb6
a==0xba //整型提升 提升后不是他
short b=0x600
b==0x600//整型提升 提升之后不是他
char c
sizeof(c)//1
sizeof(+c)//4
sizeof内不参与运算,这是推算
a+b值属性 类型属性
算数转换
如果操作符的各个操作数属于不同类型,那么除非其中一个操作数转化为另一个操作数的类型否则操作无法进行
寻常算数转换
向精度更高的类型转换
操作符的属性
1.操作符的优先级
2.操作符的结合性(例:从左到右结合)
3.是否控制求值属性
问题表达式
1.
a*b+c*d+e*f
a.....是表达式
1.a*b b*c e*f再加
2.a*b b*c + 再e*f 再+
没有办法确定唯一的计算路径
2.
c+ --c
--的优先级高
c的值到底是--前准备好的,还是--后准备好的
3.
int fun()
{
static int a = 1;//静态相当于全局变量
return ++a;
}
int main()
{
int b = fun() - fun() * fun();
return 0;
}
错误代码 求值顺序不一定(不同编译器)
4.
(a++)+(a++)+(a++)
同1
数组作业
字符串大小
"hello bit"
计算sizeof 时 空格 \0都算一个
strlen 只要空格算
----数组元素逆置
//逆序数组
void print(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf(" %d", *arr);
arr++;
}
printf("\n");
}
void reserve(int arr[], int sz)
{
int left = 0;
int right = sz - 1;
while (left <= right)
{
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
print(arr, sz);
reserve(arr, sz);
print(arr, sz);
return 0;
}
----交换两个数组(一样大)
//交换两个数组
void print(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf(" %d", *arr);
arr++;
}
printf("\n");
}
int main()
{
int arr[] = { 1,2,3,4,5 };
int arr2[] = { 2,5,8,2,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz; i++)
{
int tmp =arr[i];
arr[i] = arr2[i];
arr2[i] = tmp;
}
print(arr,sz);
print(arr2, sz);
}