IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 运算符详解 -> 正文阅读

[C++知识库]运算符详解

一、算数运算符

算数运算符有: +? - ? * ? / ? % 五种。由于运算符有两个操作数。也被称为双目运算符

对于 / 运算符,两个操作数都是整数执行的是整数除法。至少有一个操作数是浮点时执行浮点除法

#include <stdio.h>
int main() {
	int i = 5 / 2;
	printf("%d\n", i);
	return 0;
}

输出

2
#include <stdio.h>
int main() {
	double i = 5.0 / 2;
	printf("%lf\n", i);
	return 0;
}

输出

2.500000

%运算符的两个操作数必须为整数,返回的是整除后的余数

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

对于 a / b ,运算符两个操作数有一个是负数时。如果左操作数是负数,结果为:-((-a) / b)。如果右操作数是负数,结果为:-(a / (-b))

#include <stdio.h>
int main() {
	int i = -7 / 3;
	int j = 5 / -2;
	printf("-7 / 3 = %d\n", i);
	printf("5 / -2 = %d\n", j);
	return 0;
}

输出

-7 / 3 = -2
5 / -2 = -2

对于 a % b ,运算符两个操作数有一个是负数时。如果左操作数是负数,结果为:-((-a) % b)。如果右操作数是负数,结果为:a % (-b)

#include <stdio.h>
int main() {
	int i = -7 % 2;
	int j = 5 % -2;
	printf("-7 %% 2 = %d\n", i);
	printf("5 %% -2 = %d\n", j);
	return 0;
}

输出

-7 % 2 = -1
5 % -2 = 1

二、移位运算符

前言:整数在内存中存储的是二进制。存储有符号整数时将二进制最高位设定为符号位,1表示负数,0表示正数。一个整数二进制表示形式有原码、反码、补码。正整数的原码、反码、补码都相同负整数的原码、反码、补码需要计算使用、打印整数时使用原码,计算时使用补码

int i = 10; //正整数的原码、反码、补码都相同
00000000 00000000 00000000 00001010  //10的原码
00000000 00000000 00000000 00001010  //10的反码
00000000 00000000 00000000 00001010  //10的补码

int j = -1 
10000000 00000000 00000000 00000001  //-1的原码,即将-1化为二进制,最高位用1表示负数
11111111 11111111 11111111 11111110 //-1的反码,符号位不变,原码其他位按位取反
11111111 11111111 11111111 11111111 //-1的补码,反码+1

2.1左移运算符 <<

语法: 数字 << n
对数字的补码向左边移动n位,即左边抛弃,右边补0

#include <stdio.h>
int main() {
	int i = 10 << 2;
	//00000000 00000000 00000000 00001001   原码
	//00000000 00000000 00000000 00001001   反码
	//00000000 00000000 00000000 00001001   补码
	//00000000 00000000 00000000 00100100  对补码左移2位,右边补2个0
	printf("%d\n", i);
	return 0;
}

输出

40
#include <stdio.h>
int main() {
	int i = -1 << 2;
	//10000000 00000000 00000000 00000001   -1原码
	//11111111 11111111 11111111 11111110   -1反码
	//11111111 11111111 11111111 11111111   -1补码
	//11111111 11111111 11111111 11111100  对补码左移2位,右边补2个0

	//11111111 11111111 11111111 11111011 反码,对上面补码-1
	//10000000 00000000 00000000 00000100 原码,对反码符号位不变,其他位按位取反
	printf("%d\n", i);
	return 0;
}

输出

-4

2.2 右移运算符 >>

语法:数字 >> n
对数字的补码右移n位,即右边抛弃,左边填充
根据填充规则分为两种:逻辑移位与算数移位
逻辑移位:左边用0填充
算数移位:左边用该数字符号位填充
大部分编译器使用的是算数移位。我们演示代码的编译器也是算术移位

#include <stdio.h>
int main() {
	int i = -1 >> 2;
	//10000000 00000000 00000000 00000001   -1原码
	//11111111 11111111 11111111 11111110   -1反码
	//11111111 11111111 11111111 11111111   -1补码
	//11111111 11111111 11111111 11111111  对补码右移动2位,左边全部补符号位1

	//计算后结果还是-1的补码,所以还原成原码不再写
	printf("%d\n", i);
	return 0;
}

输出

-1
#include <stdio.h>
int main() {
	int i =10 >> 2;
	//00000000 00000000 00000000 00001010   10原码
	//00000000 00000000 00000000 00001010   10反码
	//00000000 00000000 00000000 00001010   10补码
	//00000000 00000000 00000000 00000010  对补码右移动2位,左边全部补符号位0
	printf("%d\n", i);
	return 0;
}

输出

2

对于移位运算符,不要移动负数位,这个是C语言标准未定义的
如 int i = 10 >> -1 ;

三、位运算符

位运算符有:按位与 & 按位或 | 按位异或 ^ 三种

3.1 按位与 &

语法: num1 & num2
将两个数的补码计算出来,两个数对应的二进位都为1时,结果为1,否则为0

#include <stdio.h>
int main() {
	int i = 10 & -3;
	//00000000 00000000 00000000 00001010   10 的原码、反码、补码

	//10000000 00000000 00000000 00000011    -3 的原码
	//11111111 11111111 11111111 11111100    -3 的反码
	//11111111 11111111 11111111 11111101  -3 的补码
	 
	//00000000 00000000 00000000 00001010  10补码
	//11111111 11111111 11111111 11111101  -3 补码
	//00000000 00000000 00000000 00001000  对应二进制位都为1,结果为1,否则为0 
	printf("%d\n", i);
	return 0;
}

输出

8

3.2 按位或 |

语法: num1 | num2
将两个数的补码计算出来,两个数对应的二进位至少有1个为1时,结果为1,否则为0

#include <stdio.h>
int main() {
	int i = -4 | -3;
	//10000000 00000000 00000000 00000100   -4 的原码
	//11111111 11111111 11111111 11111011   -4 的反码
	//11111111 11111111 11111111 11111100   -4 的补码
	
	//10000000 00000000 00000000 00000011    -3 的原码
	//11111111 11111111 11111111 11111100    -3 的反码
	//11111111 11111111 11111111 11111101  -3 的补码
	 
	//11111111 11111111 11111111 11111100   -4补码
	//11111111 11111111 11111111 11111101   -3 补码
	//11111111 11111111 11111111 11111101  对应二进制位至少1个为1时,结果为1,否则为0 (此结果为补码)
	//11111111 11111111 11111111 11111100  反码,补码-1
	//10000000 00000000 00000000 00000011  原码,反码符号位不变,其他位按位取反
	printf("%d\n", i);
	return 0;
}

输出

-3

3.3 按位异或 ^

语法: num1 ^ num2
将两个数的补码计算出来,两个数对应的二进位相同时,结果为0,否则为1

#include <stdio.h>
int main() {
	int i = -4 ^ -3;
	//10000000 00000000 00000000 00000100   -4 的原码
	//11111111 11111111 11111111 11111011   -4 的反码
	//11111111 11111111 11111111 11111100   -4 的补码
	
	//10000000 00000000 00000000 00000011    -3 的原码
	//11111111 11111111 11111111 11111100    -3 的反码
	//11111111 11111111 11111111 11111101  -3 的补码
	 
	//11111111 11111111 11111111 11111100   -4补码
	//11111111 11111111 11111111 11111101   -3 补码
	//00000000 00000000 00000000 00000001  对应二进制位相同时,结果为0,否则为1 

	printf("%d\n", i);
	return 0;
}

输出

1

3.4 经典笔试题

题目:有两个整数类型变量a、b,不创建临时变量交换a与b的值

方法一

#include <stdio.h>
//当两个数相加和大于int类型时,存在溢出,此方法就不能使用
int main() { 
	int a = 10;
	int b = 20;
	printf("交换前 a = %d b = %d\n",a,b);
	a = a + b; 
	b = a - b;
	a = a - b;
	printf("交换后 a = %d b = %d\n", a, b);
	return 0;
}

输出

交换前 a = 10 b = 20
交换后 a = 20 b = 10

方法二

#include <stdio.h>
int main() { //此方法只适用两个整数之间交换
	int a = 10;
	int b = 20;
	printf("交换前 a = %d b = %d\n",a,b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("交换前 a = %d b = %d\n", a, b);
	return 0;
}

输出

交换前 a = 10 b = 20
交换前 a = 20 b = 10

四、赋值运算符 =

将赋值运算符右侧的值赋给左侧的变量

#include <stdio.h》
int main() {
	int a = 20;
	a = 30; //使用赋值运算符将30赋给变量i
	int x = 1;
	int y;
	int z;
	z = y = x+1; //连续赋值 等同于 y = x+1; z=y;
	return 0;
}

复合赋值运算符: +=? -= ?*=? /= ?%= ?>>= ?<<=? &=? |= ?^=

等同于将复合赋值运算符左侧的变量与右侧的值通过运算符计算得到的结果赋值给左侧变量

#include <stdio.h>
int main(){
	int i = 10;
	i += 30 ;  // 等同于 i = i + 30;
	printf("%d\n",i);
	return 0;
}

输出

40

五、单目运算符

5.1 逻辑非运算符 !

在c语言中,0为假,非0为真。 逻辑非运算符逆转逻辑状态,
!真 -> 假 ? !假 ->真

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

输出

!i = 0
!j = 1
#include <stdio.h>
int main() {
	int i = 0;
	if (!i)  //当i为假时候输出哈哈哈
		printf("哈哈哈\n");
	return 0;
}

输出

哈哈哈

5.2 取地址运算符 & 与 间接寻址运算符 *

&变量名 : 取出变量在内存的地址 ? * 指针变量 :访问指针变量存储的地址所对应内存空间

#include <stdio.h>
int main() {
	int i = 10;
	int* p = &i;//取出i在内存中地址并存储在指针变量p中,这里 * 代表指针类型
	*p = 20;  //通过指针p间接访问变量i的内存空间,并修改i的值为20,这里* 代表间接寻址访问,即找到指针存储的地址对应的空间
	printf("i = %d\n", i);
	return 0;
}

输出

20

5.3 sizeof 运算符

sizeof是运算符而不是一个函数,求变量(类型)所占内存空间大小,单位为字节

#include <stdio.h>
int main() {
	int i = 10;
	printf("i所占空间大小为:%d\n", sizeof(i));
	printf("int类型所占空间大小为:%d\n", sizeof(int));
	printf("i所占空间大小为:%d\n", sizeof i); //这里 sizeof 求i的大小没有使用(),可以说明sizeof不是一个函数
	return 0;
}

输出

i所占空间大小为:4
int类型所占空间大小为:4
i所占空间大小为:4

5.4 取反运算符 ~

取反运算符 : 对一个数的二进制位(补码)取反 。 1变0,0变1

#include <stdio.h>
int main() {
	int i = ~10;
	//00000000 00000000 00000000 00001010  10的原码、反码、补码
	//11111111 11111111 11111111 11110101  按位取反后的补码
	//11111111 11111111 11111111 11110100  反码
	//10000000 00000000 00000000 00001011  原码
	printf("%d\n", i);
	return 0;
}

输出

-11

5.5 自增运算符 ++ 自减运算符- -

自增运算符分为前置++与后置++两种
前置++ 即先自增,后使用
后置++ 即先使用,后自增

#include <stdio.h>
int main() {
	int i = 10;
	int j = ++i; //i先自增+1,此时i=11,将11赋值给j
	int x = 10;
	int y = x++; //先将x赋值给y,此时y=10,然后x自增+1
	printf("i = %d\n", i);
	printf("j = %d\n", j);
	printf("x = %d\n", x);
	printf("y = %d\n", y);
	return 0;
}

输出

i = 11
j = 11
x = 11
y = 10

自减运算符分为前置- -与后置- -两种
前置- - 即先自减,后使用
后置- - 即先使用,后自减

5.6 强制类型转换运算符 ( )

强制类型转换是把变量从一种类型转换为另一种数据类型
语法:(type_name) expression

#include <stdio.h>
int main() {
	int i = (int)3.14; //将3.14这个double类型强制转换为int类型,小数位会被丢弃
	printf("%d\n", i);
	return 0;
}

输出

3

六、关系运算符

关系运算符包括: >?>=?<?<=?!=?==
注意: 赋值运算符是 = , 判断两数是否相等使用 ==

#include <stdio.h>
int main() {
	int i = 10;
	int j = 20;
	if (i == j)
		printf("相等\n");
	else
		printf("不相等\n");
	return 0;
}

输出

不相等

七、逻辑运算符

7.1 逻辑与运算符 &&

如果&&左右两边表达式都为真,则结果为真,否则为假。当左边表达式为假,右边表达式不会进行判断执行

#include <stdio.h>
int main() {
	int age = 15;
	if (age > 12 && age < 18) //只有age大于12且小于18时才会执行
	{
		printf("青少年\n");
	}
	return 0;
}

输出

青少年
#include <stdio.h>
int main() {
	int i = 0;
	int j = 1;
	int c = i++ && j++; //i++是后置++,所以&&左边表达式为假,则右边表达式不会执行
	printf("i = %d j = %d c = %d\n",i,j,c);

	return 0;
}

输出

i = 1 j = 1 c = 0

7.2 逻辑或运算符 ||

如果||左右两边表达式至少有一个为真,则结果为真,否则为假。当左边表达式为真,右边表达式不会进行判断执行

#include <stdio.h>
int main() {
	int weight = 80; 
	if(weight < 90 || weight > 130) //当weight小于90或者大于130则执行
	{
		printf("体重不健康\n");
	}
	return 0;
}

输出

体重不健康
#include <stdio.h>
int main() {
	int i = 1;
	int j = 2;
	int z = i++ || j++; //i是后置++,此时i为1,左侧表达式为真,则右边表达式不会执行
	printf("i = %d j = %d z = %d\n", i, j, z);
	return 0;
}

输出

i = 2 j = 2 z = 1

八、条件运算符(三目运算符)

语法: 条件 ? X : Y
当条件为真时,值为X,否则为Y

#include <stdio.h>
int main() {
	int x = 10;
	int y = 20;
	int max = x > y ? x : y;
	printf("x与y的较大值为:%d\n", max);
	return 0;
}

输出

x与y的较大值为:20

九、逗号运算符

逗号运算符:从左向右依次执行。整个表达式的结果是最后一个表达式的结果
语法: (exp1, exp2, exp3, …expN)

#include <stdio.h>
int main() {
	int i = 10;
	int x = (10, i++,30);//括号内多个表达式从左到右依次执行,但最终结果只跟最后一个表达式有关,即 x = 30
	printf("%d\n",i);
	printf("%d\n", x);
	return 0;
}

输出

11
30

十、下标引用运算符 [ ] 与 函数调用运算符 ( )

10.1 下标引用运算符 [ ]

需要引用数组某个元素时: 数组名[下标]
数组下标从0开始,所以数组最后一个元素下标为数组大小-1
下标引用运算符 [ ] 有两个操作数,一个是数组名,一个是下标

#include <stdio.h>
int main() {
    int arr[5] = { 1,2,3,4,5 };
    printf("%d\n", arr[3]); //通过下标引用运算符引用arr数组的第4个元素
    printf("%d\n", 3[arr]); // [ ]是运算符,所以操作数可以交换位置,类似 a + b  等同于 b + a
    return 0;
}

输出

4
4

10.2 函数调用运算符 ( )

语法: 函数名(参数)
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数

#include <stdio.h>
void print1() {
    printf("哈哈哈\n");
}

void print2(char* p) {
    printf("%s\n",p);
}
int main() {
   
    print1(); //使用函数调用运算符,有1个参数print1
    print2("hello");//使用函数调用运算符,有2个参数print1、"hello“
    return 0;
}

输出

哈哈哈
hello

十一、引用结构体(联合体)成员运算符

引用结构体(联合体)成员运算符有两个,一个是点运算符 . ? 一个是箭头运算符 ->
语法:
结构体变量.成员名
结构体指针变量->成员名

#include <stdio.h>

struct person {
    char name[10];
    int age;
    char sex[5];
};

void print1(struct person p) {
    printf("姓名:%s  年龄:%d  性别:%s\n", p.name, p.age, p.sex); //使用点运算符访问结构体变量的成员,运算符左侧为结构体变量
}

void print2(struct person* p) {
    printf("姓名:%s  年龄:%d  性别:%s\n", p->name, p->age, p->sex); //使用箭头运算符访问结构体变量的成员,运算符左侧为结构体指针变量
}
int main() {
    struct person p = { "康小龙",18,"男" };
    print1(p);
    print2(&p);
    return 0;
}

输出

姓名:康小龙  年龄:18  性别:男
姓名:康小龙  年龄:18  性别:男
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 12:51:59  更:2022-01-16 12:52:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:24:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码