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语言 -> 正文阅读

[C++知识库]操作符详解—c语言

目录

1. 操作符分类:

2. 算术操作符

3. 移位操作符?

3.1 左移操作符

3.2 右移操作符

4. 位操作符?

5. 赋值操作符?

6. 单目操作符

6.1 单目操作符介绍?

7. 关系操作符

8. 逻辑操作符?

9. 条件操作符?

10. 逗号表达式?

11. 下标引用、函数调用和结构成员?

12. 表达式求值?

12.1 隐式类型转换?

12.2 算术转换?

12.3 操作符的属性?



1. 操作符分类:

  算术操作符
  移位操作符
  位操作符
  赋值操作符
  单目操作符
  关系操作符
  逻辑操作符
  条件操作符
  逗号表达式
  下标引用、函数调用和结构成员

2. 算术操作符

                                  +   -  *  /  %

1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
2.?对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3.?% 操作符的两个操作数必须为整数。返回的是整除之后的余数

3. 移位操作符?

<< 左移操作符? 将二进制序列向左移动
>> 右移操作符??将二进制序列向右移动

说起移位操作符就要说到二进制了

整数的二进制位表示有三种形式:原码 补码 反码

正整数的原码反码补码都相同

而负整数的反码与补码是要计算的

符号位 0 - 表示正数

? ? ? ? ? ? 1 - 表示负数

整数在内存中存储的都是二进制的补码

               int a = 5
原码 000000000000000000000000000000000101
反码 000000000000000000000000000000000101
补码 000000000000000000000000000000000101
                               int a = -5
原码 10000000000000000000000000000101
反码 11111111111111111111111111111010 (原码的符号位不变,其他位取反的就是补码)
补码 11111111111111111111111111111011  (反码+1就是补码)

3.1 左移操作符

左移:就是将二进制序列左边丢弃,右边补0

int main()
{
	int a = 5;
	int b = a << 1;
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

?程序运行结果

int main()
{
	int a = -5;
	int b = a << 1;
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

程序运行结果

注意:编译器打印出来的值都是原码?

原码 反码 补码的转换规则

3.2 右移操作符

右移分两种

算术右移:右边丢弃,左边补原符号位

逻辑右移:右边丢弃,左边补0?

到底是算术右移还是逻辑右移是取决于编译器的

注意:对于移位运算符,不要移动负数位,这个是标准未定义的??

4. 位操作符?

& //按(二进制)位与? (对应的二进制位只要有0就为0,只有全1才为1)
|? //按(二进制)位或? ? ?(对应的二进制位只要有1就为1,只有全0才为0)
^ //按(二进制)位异或 (对应的二进制位相同的为0,相异的为1)
注:他们的操作数必须是整数

int main()
{
	int a = 3;
	int b = -5;
	int c = a & b;
	int d = a | b;
	int e = a ^ b;
	printf("%d\n", c);
	printf("%d\n", d);
	printf("%d\n", e);

	return 0;
}
00000000000000000000000000000011  -> 3的补码
11111111111111111111111111111011  -> -5的补码

(再次提醒,编译器打印出来的是原码,而正数原码反码补码相同)
00000000000000000000000000000011  -> 3&-5的结果 结果是3

(补码)
11111111111111111111111111111011  -> 3|-5的结果
10000000000000000000000000000101  (原码) 结果是-5

(补码)
11111111111111111111111111111000  -> 3^-5的结果
10000000000000000000000000001000  (原码) 结果是-8

程序运行结果

一道变态的面试题:

不能创建临时变量(第三个变量),实现两个数的交换

#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;
}

初学者没指望会,知道有这么一种方法即可。

5. 赋值操作符?

赋值操作符是一个很棒的操作符,它可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。

int weight = 120;//体重
weight = 89;//不满意就赋值
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值

复合赋值符?

+= -= *= /= %= >>= <<= &= |= ^=

比如:int x += 2 ;? //x = x+2

6. 单目操作符

6.1 单目操作符介绍?

! ?????逻辑反操作
- ?????负值
+ ?????正值
& ?????取地址
sizeof ???操作数的类型长度(以字节为单位)
~ ?????对一个数的二进制按位取反
-- ?????前置、后置--
++ ?????前置、后置++
* ?????间接访问操作符(解引用操作符)
(类型) ???强制类型转换?

C语言中0表示假,非0表示真

int num =10;
if(num)
{
   printf("hehe\n);
}

//!num 就是假 if语句不进入

1.sizeof(数组名),数组名不是数组首元素的地址,数组名表示整个数组,计算的是整个数组的大小.除这种情况之外,所有的数组名都表示数组首元素的地址。?

?sizeof是一个操作符,不是函数,计算类型创建的变量所占内存的大小,单位是字节?。

sizeof()中的表达式不参与计算?

& 取地址和 * 间接访问操作符(解引用操作符)

int main()
{
	//& 取地址操作符
	//* 解引用操作符(间接访问操作符)

	int a = 10;
	int* pa = &a;
	*pa = 20;//* - 解引用操作符
	//
	//*&a ==> a;
	return 0;
}

7. 关系操作符

> >= < <= !=? ==

没什么好说的?

8. 逻辑操作符?

&& ??逻辑与
|| ?????逻辑或

逻辑与 只有左右两个表达式全为真,整个表达式才为真

逻辑或 只有左右两个表达式全为假,整个表达式才为假?

int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	//i = a++ && ++b && d++;

	i = a++ || ++b || d++;

	printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
	return 0;
}

分析:i = a++ || ++b || d++; a++先使用a,再++,ay一·开始是0,往下走,++b,先b++,在使用,而整个表达式的值已经为真,则后面的d++没有执行,故程序运行结果是1 ,3 ,3 ,4。

9. 条件操作符?

exp1 ? exp2 : exp3

如果语句1为真,表达式结果就为语句2,反之则为语句3?

int main()
{
	int a = 3;
	int b = 5;
	int m = (a > b ? a : b);
	printf("%d\n", m);
	return 0;
}

10. 逗号表达式?

逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果?

int main()
{
	int a = 1;
	int b = 2;
	int c = (a > b, a = b + 10, a, b = a + 1);
	printf("a=%d b=%d\n", a, b);
	printf("%d\n", c);
	return 0;
}

11. 下标引用、函数调用和结构成员?

1. [ ] 下标引用操作符

操作数:一个数组名 + 一个索引值

int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符。
[ ]的两个操作数是arr和9

2. ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

注意:可以没有参数

3. 访问一个结构的成员
?.? 结构体.成员名
-> 结构体指针 ->成员名?

#include <stdio.h>
struct Stu
{
   char name[10];
   int age;
   char sex[5];
   double score;

};

void set_age1(struct Stu stu)
{
   stu.age = 18;
}

void set_age2(struct Stu* pStu)
{
   pStu->age = 18;//结构成员访问
}

int main()
{
   struct Stu stu;
   struct Stu* pStu = &stu;//结构成员访问
   stu.age = 20;//结构成员访问
   set_age1(stu);
   pStu->age = 20;//结构成员访问
   set_age2(pStu);
   return 0;
}

12. 表达式求值?

表达式求值的顺序一部分是由操作符的优先级和结合性决定。
同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。?

12.1 隐式类型转换?

C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。


整型提升的意义:
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度,一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。?

char a,b,c;
...
a = b + c;

b和c的值被提升为普通整型,然后再执行加法运算。

加法运算完成之后,结果将被截断,然后再存储于a中。

如何进行整体提升呢?

整形提升是按照变量的数据类型的符号位来提升的

//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//无符号整形提升,高位补0

举个例子

int main()
{
   char a = 0xb6;
   short b = 0xb600;
   int c = 0xb6000000;
   if(a==0xb6)
     printf("a");
   if(b==0xb600)
     printf("b");
   if(c==0xb6000000)
     printf("c");
   return 0;
}

例子中的 a,b 要进行整形提升,但是c不需要整形提升a,b整形提升之后,变成了负数,所以表达式 a==0xb6 , b==0xb600 的结果是假,但是c不发生整形提升,则表达式 c==0xb6000000 的结果是真.
所程序输出的结果是: c

12.2 算术转换?

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换

long double
double
float
unsigned long int
long int
unsigned int
int

如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算

12.3 操作符的属性?

复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题
的。

比如,该代码在几种编译环境下得出的结果都不相同。

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

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 18:34:21  更:2022-07-20 18:34:55 
 
开发: 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年5日历 -2024/5/14 4:00:10-

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