当前位置 博文首页 > HyDraZya的博客:【C语言基础】C语言操作符
分类:
算术操作符
移位操作符
位操作符?
赋值操作符
复合赋值符
单目操作符
关系操作符
逻辑操作符
条件操作符(三目操作符)
逗号表达式
下标引用、函数调用和结构成员
+? ? -? ? *? ? /? ? %
1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除 法。
3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
#include <stdio.h>
int main()
{
int a = 5 / 2; //商2余1取商
printf("a = %d\n", a);
int b = 5 % 2; //模2得1
printf("a = %d\n", a);
float c = 5 / 2.0;
printf("c = %lf\n", c);
return 0;
}
<<? 左移操作符? ? ? >>? 右移操作符
左移操作符:
左边丢弃,右边补0
向左移动有×2的效果
#include <stdio.h>
int main()
{
int a = 5;
//0000 0000 0000 0000 0000 0000 0000 0101
int b = a << 1;
//0000 0000 0000 0000 0000 0000 0000 1010
printf("%d\n", b); //10
return 0;
}
右移操作符:
1.算术右移
? ?右边丢弃,左边补原符号位
2.逻辑右移
? ? 右边丢弃,左边补0
#include <stdio.h>
int main()
{
int a = 16;
//>> --右移操作符
//移动的是二进制位
//0000 0000 0000 0000 0000 0000 0001 0000
int b = a >> 1;
printf("%d\n", b); //8
//0000 0000 0000 0000 0000 0000 0000 1000
int c = -1;
//整数的二进制表示有:原码、反码、补码
//存储到内存中的是补码
//1000 0000 0000 0000 0000 0000 0000 0001 - 原码
//1111 1111 1111 1111 1111 1111 1111 1110 - 反码
//1111 1111 1111 1111 1111 1111 1111 1111 - 补码
//补码存储, 原码打印
int d = c >> 1;
printf("%d\n", d); //-1
return 0;
}
警告:
例如:
int num = 10;
num >> -1; //error
num >> 1.3 //error
位操作符有:
注:他们的操作数必须是整数。
练习:
按位与:&? ?当两个二进制数位都为0则输出0,都为1则输出1,1、0都有则输出0。
#include <stdio.h>
int main()
{
//& - 按2进制位与
int a = 3;
int b = 5;
int c = a&b;
//3 - 0011
//5 - 0101
//a&b 0001
printf("%d\n", c); //1
return 0;
}
按位或:|? (当两个二进制数位都为0则输出0,只要有一个二进制位数为1则输出1)
#include <stdio.h>
int main()
{
//| - 按2进制位或
int a = 3;
int b = 5;
int c = a|b;
//3 - 0011
//5 - 0101
//a|b 0111
printf("%d\n", c); //7
return 0;
}
按位异或:^? ?(当两个二进制数位相同则为0,相异则为1)(同假异真)
#include <stdio.h>
int main()
{
//^ - 按2进制位异或
int a = 3;
int b = 5;
b = a^b;
//3 - 0011
//5 - 0101
//a^b 0110
printf("%d\n", c); //6
return 0;
}
不能创建临时变量(第三个变量),实现两个数的交换:
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
//3 - 0011
//5 - 0101
a = a^b; //0110 6
b = a^b; //0011 3
a = a^b; //0101 5
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
编写代码实现:求一个整数存储在内存中的二进制中1的个数。
#include <stdio.h>
int main()
{
int num = 0;
int count = 0;
printf("请输入一个数,来得出他在二进制中有几个1\n");
scanf("%d", &num);
//统计num的补码中有几个1
int i = 0;
for(i = 0; i < 32; i++)
{
if(1 == ((num >> i) & 1))
count++;
}
printf("%d\n", count);
return 0;
}
赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。
int weight = 120;//体重
weight = 89;//不满意就赋值
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值。
赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
这样的代码感觉怎么样?
那同样的语义,你看看:
x = y+1;
a = x;
这样的写法是不是更加清晰爽朗而且易于调试。
? ? ? ? ? ? ? ? 复合赋值符号 | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 功能 |
+= | 加法赋值 |
- = | 减法赋值 |
*= | 乘法赋值 |
/= | 除法赋值 |
%= | 模运算赋值 |
>>= | 右移赋值 |
<<= | 左移赋值 |
&= | 按位逻辑与赋值 |
|= | 按位逻辑或赋值 |
^= | 按位逻辑异或赋值 |
符号 | 含义 |
! | 逻辑反操作 |
- | 负值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作数的类型长度(以字节为单位) |
~ | 对应二进制数按位取反 |
- -? | 前置、后置- - |
++ | 前置、后置++ |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
a+b
+双目操作符,有两个操作数
单目操作符,只有一个操作数
例子:
逻辑反操作符 !:
int a = 0;
printf("%d\n", !a); //1
int b = 10;
printf("%d\n", !b); //0
int c = 0;
if(!c)//逻辑反操作符
{
printf("123\n");
}
if(c)
{
printf("321\n");
}
取地址、解引用操作符 & 、*:
int i = 10;
int*p = &i;//取地址操作符
*p = 20;//解引用操作符
sizeof 类型长度操作符:
int a = 10;
char c = 'r';
char*p = &c;
int arr[10] = {0};
//sizeof 计算的变量所占内存空间的大小,单位是字节
printf("%d\n",sizeof(a)); //4
printf("%d\n",sizeof(int)); //4
printf("%d\n",sizeof(c)); //1
printf("%d\n",sizeof(char)); //1
printf("%d\n",sizeof(p)); //8
printf("%d\n",sizeof(char*)); //8
printf("%d\n",sizeof(arr)); //40
printf("%d\n",sizeof(int[10])); //40
short s = 0;
int a = 10;
printf("%d\n", sizeof(s = a + 5)); //2
//sizeof内部不参与运算
printf("%d\n", s); //0
按位取反 ~ :
int a = 0;
//~ 按(2进制)位取反
//0000 0000 0000 0000 0000 0000 0000 0000 - 按位取反next
//1111 1111 1111 1111 1111 1111 1111 1111 - 补码
//1111 1111 1111 1111 1111 1111 1111 1110 - 反码
//1000 0000 0000 0000 0000 0000 0000 0001 - 原码
printf("%d\n", ~a);//-1
int b = 11;
//0 1011 - 按位取反next
//1 0100 - 补码
//1 0011 - 反码
//1 1100 - 原码
printf("%d\n", ~b);//-12
补充:
int a = 11;
a = a | (1<<2);
printf("%d\n", a); //15
a = a ^ (1<<2);
printf("%d\n", a); //11
前置、后置 ++ / --:
//前置++,先++,后使用
int a = 10;
printf("%d\n", ++a); //11
//后置++,先使用,后++
int b = 10;
printf("%d\n", b++); //10
//前置--,先--,后使用
int c = 10;
printf("%d\n", --c); //9
//后置--,先使用,后--
int d = 10;
printf("%d\n", d--); //10
强制类型转换(类型):
int a = (int)3.14;
//不要写成int a = int(3.14);
printf("%d\n", a); //3
Sizeof和数组:
//数组传参是真正传过去的是数组的首元素地址
//地址接收指针变量
//指针大小根据32/64位平台打印出长度为4/8个字节
void test1(int arr[])
{
printf("%d\n", sizeof(arr)); //4 / 8
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch)); //4 / 8
}
int main()
{
int arr[10] = {0};
char ch[10] = {0};
printf("%d\n", sizeof(arr)); //40
printf("%d\n", sizeof(ch)); //10
test1(arr);
test2(ch);
return 0;
}
符号 | 表示 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
!= | 不等于(不相等) |
== | 等于(相等 |
注:=在C中是赋值,不是等于的意思,和==不能搞混?
逻辑与 &&:
int main()
{
int a = 3;
int b = 5;
int c = a && b;
printf("%d\n", c); //1
int d = 0;
int e = a && d;
printf("%d\n", e); //0
return 0;
}
逻辑或 ||:
int main()
{
int a = 3;
int b = 5;
int c = a || b;
printf("%d\n", c); //1
int d = 0;
int e = a || d;
printf("%d\n", e); //1
int f = 0;
int g = d || f;
printf("%d\n", g); //0
return 0;
}
?结论:
练习题1:
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
//a=1 b=2 c=3 d=4
return 0;
}
解题思路:
练习题2:
#include <stdio.h>
int main()
{
int i = 0,a=1,b=2,c =3,d=4;
i = a++||++b||d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
//a=2 b=3 c=3 d=4
return 0;
}
解题思路:
exp1 ? exp2 :exp3
练习1:
if (a > 5)
b = 3;
else
b = -3;
转换成条件表达式,是什么样?
b = (a > 5 ? 3 : -3);
练习2:使用条件表达式实现找两个数中较大值
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int max = 0;
if(a > b)
max = a;
else
max = b;
max = (a > b ? a : b); //条件表达式
return 0;
}
exp1, exp2, exp3, …expN
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式
//假 a=12 a=12 b=13
printf("%d\n", c); //13
注:逗号表达式主要看最右边的运算
a = get_val();
count_val(a);
while (a > 0)
{
//业务处理
a = get_val();
count_val(a);
}
//逗号表达式
while(a = get_val(), count_val(a),a>0)
{
//业务处理
}
1.[ ] 下标引用操作符
操作数:一个数组名+一个索引值
int arr[10] = {0}; //创建数组初始化
arr[9] = 10; //实用下标引用操作符
//[]的两个操作数是9和arr
2.( )函数调用操作符
接受一个或多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
#include <stdio.h>
int get_max(int x, int y)
//此处为定义函数的语法规则,不是函数调用操作符
{
return x > y ? x : y;
}
int main()
{
int a = 10;
int b = 20;
int max = get_max(a, b);
//调用函数的时候()就是函数调用操作符
printf("max = %d\n", max);
return 0;
}
3.访问一个结构的成员
. 结构体 . 成员名
->结构体指针 -> 成员名
#include <stdio.h>
//创建一个结构体类型-struct-Stu
struct Stu
{
//成员变量
char name[10];
int age;
char id[20];
};
int main()
{
int a = 10;
//使用struct Stu这个类型创建了一个学生对象s1,并初始化
struct Stu s1 = {"张三", 20, "202100001"};
struct Stu *ps = &s1;
printf("%s\n", ps->name);
printf("%s\n", ps->age);
//结构体指针->
// printf("%s\n", (*ps).age);
// printf("%s\n", (*ps).name);
// printf("%s\n", s1.name);
// printf("%s\n", s1.age);
// printf("%s\n", s1.id);
//结构体变量.成员名
return 0;
}
cs