操作符详解

C语言操作符

操作符分类:

  • 算数操作符:+ 、- 、* 、/ 、%
  • 移位操作符:<< 、>>
  • 位操作符:| 、& 、^
  • 赋值操作符: = 、+= 、 -= 、 *= 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^=
  • 单⽬操作符: !、++、–、&、*、+、-、~ 、sizeof、(类型)
  • 关系操作符: > 、>= 、< 、<= 、 == 、 !=
  • 逻辑操作符: && 、||
  • 条件操作符: ? :
  • 逗号表达式: ,
  • 函数调⽤: ()
  • 下标引⽤: []
  • 结构成员访问: . 、->
    有一部分操作符与二进制有关系,关于进制转换讲解请点击查看文章

原码,反码,补码

整数的2进制表示方法有三种即原码,反码,补码。
有符号的整数的三种表示方法有符号位和数值位两部分,2进制序列中,最高位被当作符号位,剩余的都是数值位。
最高位符号位用“0”表示“正”,“1”表示“负”。
正数的原反补都相同,负整数的三种表示方法各不相同。

  • 原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码;
  • 反码:将原码的符号位不变,其他位依次按位取反就可以得到反码;
  • 补码:反码+1即可;
    补码得到原码也可以使用符号位不变其他位按位取反+1的操作
    对于整型来说:数据存放在内存中其实存放的是补码:
    在计算机系统中,数值一律用补码来表示和存储。原因是使用补码可以将符号位和数值域通一处理;同时加法和减法也可以同意处理(因为CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外电路。

移位操作符

  •  <<  左移操作符
    
  •  >>  右移操作符
    

左移操作符:左边抛弃,右边补0。

#include <stdio.h>
int main()
{
	int num = 10;
	int n = num<<1;
	printf("n= %d\n", n);
	printf("num= %d\n", num);
	return 0;
}

在这里插入图片描述
右移操作符

  1. 算术右移:左边用0填充,右边丢弃
  2. 逻辑右移:左边用原该值的符号位填充,右边丢弃
#include <stdio.h>
int main()
{
	int num = 10;
	int n = num>>1;
 	printf("n= %d\n", n);
 	printf("num= %d\n", num);
 	return 0;
}

在这里插入图片描述
!!!不可以移动负数位,移动负数位是标准未定义的!!!
错误演示

int num=10;
num>>-1//error

位操作符

  • 按位与:&
  • 按位或:|
  • 按位异或:^
  • 按位取反:~
    以上四个操作符的操作数必须是整数!!!
  • &: 与,对应二进制位同为1,则结果对应二进制位为1 比如 1&1结果为 1
  • |: 或,对应二进制位只要有一个为1,则结果对应二进制位为1 比如 1 | 1 结果为1 1 | 0 结果为1
  • ^: 异或,对应二进制位不相同,则结果对应二进制位为1 比如 1 ^0 的结果为1
//代码一
#include <stdio.h>
int main()
{
 int num1 = -3;
 int num2 = 5;
 printf("%d\n", num1 & num2);
 printf("%d\n", num1 | num2);
 printf("%d\n", num1 ^ num2);
 printf("%d\n", ~0);
 return 0;
}

拓展问题:不创建第三个变量或临时变量,实现两个整数的交换
直接上代码:

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	a = a^b;
	b = a^b;
	a = a^b;
	printf("a = %d b = %d\n", a, b);
 	return 0;
}

在这里插入图片描述

//代码二
#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	a = a+b;
	b = a-b;
	a = a-b;
	printf("a = %d b = %d\n", a, b);
	return 0;
}

逗号表达式

exp1, exp2, exp3, …expN//逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果
/代码1 
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式 
c是多少?
//代码2 
if (a =b + 1, c=a / 2, d > 0)
//代码3 
a = get_val();
count_val(a);
while (a > 0)
{
 //业务处理 
 //...
 a = get_val();
 count_val(a);
}
如果使⽤逗号表达式,改写:
while (a = get_val(), count_val(a), a>0)
{
 //业务处理 
}

结构成员访问操作符

结构体声明
struct tag
{
	member-list;
}variable-list;
//描述一个学生
struct Stu
{
 char name[20];//名字 
 int age;//年龄 
 char sex[5];//性别 
 char id[20];//学号 
}; //分号不能丢 
结构体变量的定义和初始化
//代码1:变量的定义 
struct Point
{
 int x;
 int y;
}p1; //声明类型的同时定义变量p1 
struct Point p2; //定义结构体变量p2 
//代码2:初始化。 
struct Point p3 = {10, 20};
struct Stu //类型声明
{
 char name[15];//名字 
 int age; //年龄 
};
struct Stu s1 = {"zhangsan", 20};//初始化 
struct Stu s2 = {.age=20, .name="lisi"};//指定顺序初始化 
//代码3 
struct Node
{
 int data;
 struct Point p;
 struct Node* next; 
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化 
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化 
结构成员访问操作符

结构体成员的直接访问:结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。

#include <stdio.h>
struct Point
{
 int x;
 int y;
}p = {1,2};
int main()
{
 printf("x: %d y: %d\n", p.x, p.y);
 return 0;
}//结构体变量.成员名

结构体成员的间接访问:有时候我们得到的不是⼀个结构体变量,⽽是得到了⼀个指向结构体的指针。

#include <stdio.h>
struct Point
{
 int x;
 int y;
};
int main()
{
 struct Point p = {3, 4};
 struct Point *ptr = &p;
 ptr->x = 10;
 ptr->y = 20;
 printf("x = %d y = %d\n", ptr->x, ptr->y);
 return 0;
}
//结构体指针->成员名

如有问题可以评论区留言

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值