1.算术操作符
算术操作符有:+ - * / %
/:整型除法 eg:1/2,答案为0
浮点型除法(/两端至少有一个是小数) eg:1.0/2 或 1/2.0 或 1.0/2.0 ,答案为0.5
%:计算的是整除后的余数,同时该操作符的两端必须是整数。
eg:1%2 正确 1.2/2 错误 1/2.2 错误
2.移位操作符
移位操作符有:<<(左移操作符) >>(右移操作符)
移位操作符这里的位是二进制位,移动的是二进制。
同时,移位操作符的操作数只能是整数。
2.1 整数的原码、反码、补码
首先,整数在内存中存储的是补码。
而整数的二进制表示分为:原码、反码、补码
正整数的原码、反码、补码相同;负整数的原码、反码、补码要计算。
eg:7——>二进制是111
7是整型,整型在内存中占4个字节,一共32个比特位(除了已知的二进制111,且7是正整数,符号位为0,其余位补0)
所以7的原码是0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1(标红的为符号位)
正整数的原码、反码、补码相同,均为上述。
-7的原码是 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1(标红的为符号位)
-7的反码是1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0(原码除了符号位,即标红的位置,其余由0变成1,由1变成0,这个过程称为取反)
-7的补码是1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1(补码是反码+1)
2.2 左移操作符
左移操作符:左边丢弃,右边补0
整数在内存中存储的是补码,所以对补码进行移位。
eg:-7的补码是1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
-7<<1左移1位 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
左移之后最左边的一位丢弃,最右边补0:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0(补码)
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1(反码)
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0(原码)
得到-7<<1的答案:-14
2.3 右移操作符
右移操作符:
1.算术移位:右边丢弃,左边补原符号位(正整数补0,负整数补1)
2.逻辑移位:右边丢弃,左边补0
整数在内存中存储的是补码,所以对补码进行移位。
eg:7的补码是0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
7>>1右移1位 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
这里采用算术移位,正整数的算术移位和逻辑移位一致,负整数不一致
右移之后最右边的一位丢弃,最左边补0:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 (补码)
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1(原码)
7>>1右移1位的答案是:3
3.位操作符
位操作符有:&(按位与) |(按位或) ^(按位异或)
这里的位同样是二进制位。
3.1 & 按位与
int main()
{
int a=3;
int b=5;
int c=a&b;
printf("%d\n",c);
return 0;
}
a=3,3的原码是: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
3的补码是: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
b=-5,-5的原码是: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
-5的反码是: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0
-5的补码是: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
c=a&b,即3&-5 3的补码是:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
-5的补码是:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
二进制位一 一对应,对应的二进制位,只要有0,则为0;同时为1,则为1。
c=a&b :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
所以打印结果为c=3
3.2 | 按位或
int main()
{
int a=3;
int b=5;
int c=a|b;
printf("%d\n",c);
return 0;
}
a=3,3的原码是: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
3的补码是: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
b=-5,-5的原码是: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
-5的反码是: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0
-5的补码是: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
c=a|b,即3|-5 3的补码是:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
-5的补码是:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
二进制位一 一对应,对应的二进制位,只要有1,则为1;同时为0,则为0。
c=a|b :1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 (补码)
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 (反码)
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1(原码)
所以打印结果为c=-5
3.3 ^按位异或
int main()
{
int a=3;
int b=5;
int c=a^b;
printf("%d\n",c);
return 0;
}
a=3,3的原码是: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
3的补码是: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
b=-5,-5的原码是: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
-5的反码是: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0
-5的补码是: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
c=a^b,即3^-5 3的补码是:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
-5的补码是:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
二进制位一 一对应,对应的二进制位,相同为0;相异为1
c=a^b : 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0(补码)
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 (反码)
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0(原码)
所以打印结果为c=-8
4.赋值操作符
赋值操作符有:= += -= /= %= *= >>= <<= |= &= ^=
5.单目操作符
单目操作符有:!逻辑反操作符 - 负 + 正 & 取地址 sizeof 得操作数的类型长度
~ 按位取反 -- 前置 后置-- ++前置 后置++ * 间接访问操作符,解引用操作符
(类型)强制类型转换
5.1 ! 逻辑反操作符
int flag=3
if (flag)//flag为真,进入if
{
{
if(!flag)//flag为假,进入if
{
}
5.2 sizeof
计算变量所占内存空间的大小;计算类型所创建的变量占据空间的大小
sizeof的单位是字节
sizeof是操作符,不是函数,可以求变量,数组等
strlen是库函数,是用来求字符串的长度的。
5.3 前置++ 前置-- 后置++ 后置--
前置++:先++,后使用
后置++:先使用,后++
前置--:先--,后使用
后置--:先使用,后--
5.4 *间接访问操作符,解引用操作符
int main()
{
int a=10;
int* p=&a;//p是存放指针的变量,int*是指针类型,
*p=20;//p所指的对象
printf("%d\n",a);
return 0;
}
打印结果为20
a中存放10,而a在内存中起始地址为:0x0012ff40
p中存放a的起始地址0x0012ff40
*p是通过p中存放的地址找到a
5.5(类型)强制转换类型
int main()
{
int a=3.14;
printf("%d\n",a);
return 0;
}
该程序会报错,a是浮点型 却用整型,所以报错,可以改为:
int main()
{
int a=(int)3.14;
printf("%d\n",a);
return 0;
}
打印结果为3
6.关系操作符
关系操作符有:> < >= <= != ==
不是所有对象都可以用> < 等来比较的,可以来比较数值。
如果比较两个字符串的内容是否相等,不能用关系操作符,应该用strcmp()函数
7.逻辑操作符
逻辑操作符有:&&逻辑与 ||逻辑或
&&:操作符两端都为真,才为真。
||:操作符两端只要有一个为真,就为真。
int main()
{
int a=3;
int b=0;
int c=a&&b;
printf("%d\n",c);
return 0;
}
a为真,b为假,而c=a&&b,所以c为假,打印结果为0。&&逻辑与是左右两端都为真,才为真。
int main()
{
int a=3;
int b=0;
int c=a||b;
printf("%d\n",c);
return 0;
}
a为真,b为假,而c=a||b,所以c为真,打印结果为1.||逻辑或是左右两端只要有一个为真,就为真
&&:左边为假,右边就不计算了
||:左边为真,右边就不计算了
int main()
{
int i=0,a=0,b=2,c=3,d=4;
i=a++&&++b&&d++;
printf("&d\n",a,b,c,d);
return 0;
}
打印结果为:1,2,3,4
i=a++&&++b&&d++
先算a++,后置++是先使用后++,所以第一个&&左端先是0,为假,&&逻辑与左边为假,后面就不用计算了。使用后,a再++,所以a为1,b则是2,c是3,d是4
int main()
{
int i=0,a=1,b=2,c=3,d=4;
i=a++&&++b&&d++;
printf("&d\n",a,b,c,d);
return 0;
}
打印结果为:2,3,3,5
先算a++, 后置++是先使用后++,所以第一个&&左边是1,为真,再++,a变为2继续,第一个&&右边是++b,先++后使用,所以是3,也为真,第二个&&左边为真,右边为d++,先使用后++,4为真,再++,d变为5
int main()
{
int i=0,a=0,b=2,c=3,d=4;
i=a++||++b||d++;
printf("&d\n",a,b,c,d);
return 0;
}
打印结果为:1,3,3,4
先算a++,后置++是先使用后++,所以第一个||左边是0,为假,再++,a变为1,第一个||右边是++b,先++后使用,所以是3,为真,所以第二个||左边为真,后面不用计算了。
int main()
{
int i=0,a=1,b=2,c=3,d=4;
i=a++||++b||d++;
printf("&d\n",a,b,c,d);
return 0;
}
打印结果为:2,2,3,4
先算a++, 后置++是先使用后++,所以第一个||左边是1,为真,a++||++b为真,则第二个||左边为真,后面不用计算了。
8.条件操作符(三目操作符)
条件操作符有:表达式1?表达式2:表达式3
如果表达式1为真,则表达式2成立,表达式3不成立
如果表达式1为假,则表达式2不成立,表达式3成立
9.逗号表达式
逗号表达式:,
从左向右依次计算,整个表达式的结果是最后一个表达式的结果
10.下标引用,函数调用,结构成员
10.1下标引用
下标引用操作符:[]
int main()
{
int arr[10]={0};
arr[7]=8;//表示数组第7个元素是8
return 0;
}
10.2函数调用
函数调用操作符:()
int Add(int x,int y)
{
return x+y;
}
int main()
{
int a=10;
int b=20;
int c=Add(a,b);//()就是函数调用操作符,操作数是Add,a,b
return 0;
}
10.3结构成员
· 结构体·成员名
—> 结构体指针—>成员名
struct Stu
{
char name[20];
int age;
double score;
};
void set_stu(struct Stu*ps)
{
strcpy(*ps.name,"zhangsan");
(*ps).age=20;
(*ps).score=100.0;
}
void print_stu(struct Stu ss)
{
printf("%s %d %lf\n",ss.name,ss.age,ss.score);
}
int main()
{
struct Stu s={0};
set_Stu(&s);
print_stu(s);
return 0;
}