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语言操作符(史上最全的重点总结!全在这里!)

前言

C语言中操作符总共有10种,分别是:

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

这里我挑了一些重点和易错点来说!

算术操作符,移位操作符,位操作符,复合运行算符,单目操作符、条件操作符,逗号操作符,下标引用、函数调用和结构成员

Let’s get it!

算术操作符

分为:

加:+

减:-

乘:*

除:/

取余:%

注意:

1、/ 如果是整型除法,其结果是

这里请注意,我说的是商!

a ÷ b = c …d,c叫做商,d叫做余数!例子: 9 / 4 = 2

如果两边有一个小数,则进行的就是小数除法,例子: 9 / 4.0 = 2.250000

2、% 代表求模运算,即余数,a % b = c,其中c的范围在 [0,b)

移位操作符

分为:

左移操作符 :<<

右移操作符:>>

在讲解移位操作符以前,这里要强调一个概念:原码反码补码

原反补

学了你就可以知道为char a=127, char b; b=a+1 这个时候你为什么b=-128

一个数在计算机内部如果是有符号数,则其最高位作为符号位,如果符号位为0,表示该数为正数,如果符号位为1,表示该数为负数。(0正1负)

以下求原反补的过程:

原码:最高位作为符号数,其余各位为数值位(0正1负)

反码:正数的反码与原码相同,负数的反码是在原码的基础上符号位不变,其余各位按位取反

补码:正数的补码与原码相同,负数的补码是在反码的基础上加1

这里看例题:

例:求+25和-25的原反补

	①不考虑正负,将25转换成二进制
		25D=11001B
	②     +25             -25
	原: 00011001		10011001
	反: 00011001		11100110
	补: 00011001		11100111

例:求+30和-30的原反补

	①30D=11110B	
	②	  +30			  -30
	原: 00011110		10011110
	反: 00011110		11100001
	补: 00011110		11100010

计算机中用的是补码,什么是补码,怎么去理解补码?

补码可以理解成一个循环。

8位二进制表示的有符号数范围是 -128~127

如果还有不懂的可以去百度一下!

这里我们回到移位操作符上

在计算机内存中,所操作的一切都是操作的 补码,补码,补码,补码!!!

重要的事情多说几遍,只是显示的时候才把补码还原回原码,然后转换成十进制

移位规则:

<<左移操作符:不论算术移位还是逻辑移位,均将左边的数舍弃,右边空缺位补0(左边丢弃,右边补0)
在这里插入图片描述

>>右移操作符:当进行逻辑移位时,右边位丢弃,左边空缺位补0(右边丢弃,左边补0)
在这里插入图片描述
再次强调,计算机操作的是补码

总结:

右移一位具有 /2效果; 右移2位 具有 /4 效果;右移三位 具有 /8 效果;(右移效果只针对正数)…

左移一位 具有x2效果;左移两位 具有x4效果;左移三位 具有x8效果;(左移效果针对所有数)…

注意:

  1. 移位操作不改变原值

  2. 移位时不能移负数位

位操作符

符号:

& :按位与 (两个都是1才是1,否则0)

110101
101110

上面两个结果为 : 100100

| :按位或 (只要有1就是1)

1011011
0101100

上面两个结果为: 1111111

^ :按位异或 (相同为0,相异为1)

1010001
1010101

上面两个结果为:0000100

看到这里可能有点懵,所以我出两道关于位操作符的习题

1、数字交换

给出两个数字 a 和 b ,要求除了这两个变量以外,不准创建任何变量,达到ab交换

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

是不是感觉没看懂?
在这里插入图片描述
我们以 a = 3,b = 5为例;

假设:a ^ b = m,那么我们反过来推导,m ^ a = b 或者 m^b = a

所以这段代码

a = a^b;
b = a^b;
a = a^b;

为了更好理解我暂时用am代替 a^b 出来的值a(图中m

am = a ^ b

b = am ^ b (新得到的值其实是a,只是把值赋给了b)

a = am ^ b (am异或b,其实是异或的a,能理解吧?那么异或a得到的值就是b,所以赋值给a)

所以这样就是不要变量达到了完美的交换!

再问:数字的二进制(补码)有多少个1 ???

我们先不管二进制,假设给你一个数字a = 12334565,喊你求这个数字有几个3?

正常思路是不是 a%10 == 3 a = a/10 --> a%10 == 3 a = a/10 --> a%10 == 3 a = a/10这样循环下去计算?

那么我们二进制也是一样 a%2 == 1 a = a/2这样循环下去数

代码一:

#include <stdio.h>
int main()
{
    int n = 15;
    int count = 0;
    while (n)
    {
        if (n % 2 == 1)
            count++;
        n /= 2;
    }
    printf("%d", count);
    return 0;
}

但是这样写只能算正数,所以有缺陷

下面我就介绍 位操作

我们知道只有数字1 & 1 结果才是1

步骤一: 所以我们可以通过把一个数字的二进制与00000000000000000000000000000001 相&

步骤二: 如果结果为1,代表末尾为1

步骤三: 然后把该数字右移一位,再 与 000000000000000000000000000000001 相&

以此循环…

代码二:

#include <stdio.h>
int main()
{
    int n = -1;
    int count = 0;
	for(int i = 0;i<32;i++)
    {
        if (n & 1 == 1)
            count++;
        n = n >> 1;
    }
    printf("%d", count);
    return 0;
}

复合运算符

这个没什么讲的 ,就是组合起来操作

例子:

a = a + 3<==> a += 3

a = a & 2<==> a &= 2

a = a >> 1<==>a >>= 1

单目操作符

字面理解:目,眼睛;即这个操作符只需要一个操作数

例如:!3、-4、&a、a++

在这里插入图片描述
这里主要讲解一下 ++ ~ sizeof (类型)

其中sizeof()strlen()的区别请看这里:sizeof和strlen的区别

例1:sizeof

#include <stdio.h>
int main()
{
    short s = 0;
    int a = 10;
    printf("%d\n", sizeof(s = a+5));
    printf("%d\n", s);
	return 0;
}

结果是多少???

2 0

因为sizeof里面的表达式中s不参与运算

例2:++

1、前置++:即先++,再使用
代码如下:

#include <stdio.h>
int main()
{
    int a = 5;
    printf("%d  ", a++);
    printf("%d", a);
    return 0;
}

//结果
5  6
   
//因为它先使用了a的值,然后再++

2、后置++:即先使用,再++

代码如下:

#include <stdio.h>
int main()
{
    int a = 5;
    printf("%d  ", ++a);
    printf("%d", a);
    return 0;
}

//结果
6  6

--的使用和++一样

例3:~

~ :按位取反

问题: 假设我想把 00001011 的倒数第三个0改为1 怎么用代码弄?

很简单,我们只有把它和00000100 相 |一下就行,那么00000100怎么来的??

数字1左移两位 1<<2

代码如下:

#include <stdio.h>
int main()
{
    /*1011代表的是 11*/
    int a = 11;
    int ret;
    ret = a | (1<<2);
    printf("%d", ret);
	return 0;
}

//结果是 15
1111刚好就是15

再问: 那如果我想把1111改回去呢???

  • 00000000 00000000 0000000 00001111

  • 我们需要把它和11111111 11111111 11111111 111110111 相&

  • 那11111111 11111111 11111111 111110111怎么得来的呢???

  • 00000000 00000000 00000000 00000100取反得来

  • 00000000 00000000 00000000 00000100而这个又是1左移两位

  • 00000000 00000000 00000000 00000001(数字1)

所以逻辑是:首先 1<<2,然后取反,最后相与

代码如下:

#include <stdio.h>
int main()
{
    int a = 15;
    int ret;
    ret = a & (~(1<<2));
    printf("%d", ret);
	return 0;
}

//结果是11

例4:(类型)(强制类型转换)

srand((unsigned int)time(NULL)); 

注意:

1.sizeof是一个操作符,关键字,而不是函数,求的是操作数的类型长度(以字节为单位)

2.sizeof求类型的长度时不可省略括号,求变量的长度时可以省略括号

3.!操作符是对一个数做逻辑反操作,而~操作符是对一个数的二进制按位取反

4.前置++、前置–是先使用,再++;而后置++、后置–是先–,再使用

条件操作符

符号:exp1 ? exp2 : exp3

含义:表达式exp1如果成立,则返回表达式2的值,否则返回表达式3的值

例子: 例如我们需要把 a,b中的大值给max,小值给min

#include <stdio.h>
int main()
{
    int a = 15,b = 24;
    int max,min;
	max = a>b?a:b;
    min = a>b?b:a;
    printf("max = %d  min = %d", max,min);
	return 0;
}

逗号表达式

符号:exp1, exp2, exp3, ..., expN

含义:逗号表达式(用逗号隔开的表达式),从左往右依次执行;整个表达式的结果为最后一个表达式的结果

举例说明:

int a = 3,b = 4;

c = (a>b,a = b*4,b = a+2)

c等于多少呢? 答案:18

代码如下:

#include <stdio.h>
int main()
{
    a = get_val();
    count(a);
    while(a>0)
    {
        a = get_val();
    	count(a); 
        //语句
    }
	return 0;
}

//上面这样写是不是重复了? 可以写成下面这样!

#include <stdio.h>
int main()
{    
    while(a = get_val(),a>0,count(a))
    {
        //语句
    }
	return 0;
}

注意:

逗号表达式的结果虽然是最后一个表达式的结果,但不可认为与前面的表达式就无关了,

因为前面表达式可能会影响最后一个表达式的结果

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

1、下标引用

符号:[ ]

符号说明:下标引用操作符,有两个操作数(数组名和索引值)

举例说明:

int arr[10] = {3,7,4,8,2,15,25,6,9,1};
arr[3] = 8;    //[ ]:下标引用操作符,其两个操作数为arr和3

注意:下标引用共有两个操作数(数组名和索引值)

2、函数调用

符号:()

符号说明:函数调用操作符,有一个或多个操作数(函数名和参数)。

举例说明:

void test1()
{
  printf("fine day!\n");
}
 
void test2(char *ch)
{
  printf("%s\n",ch);
}
 
int main()
{
  test1();    //():函数调用操作符
  test2("fine day!");    //():函数调用操作符
}

注意:函数调用操作符有一个或多个操作数

3、访问结构体成员

符号:.

符号说明:结构体对象

举例说明:

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

#include <stdio.h>
int main()
{
 struct student xiaoming = { "小明",25,"男人" };


 /*访问结构成员*/

 printf("姓名:%s\n", xiaoming.name);
 printf("年龄:%d\n", xiaoming.age);
 printf("性别:%s\n", xiaoming.sex);
 return 0;
}

4、结构体指针访问

符号:->

符号说明:结构体指针

举例说明:

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


#include <stdio.h>
int main()
{
struct student xiaoming = { "小明",25,"男人" };
struct student* people = &xiaoming;
/*访问结构成员*/

printf("姓名:%s\n", people->name);
printf("年龄:%d\n", people->age);
printf("性别:%s\n", people->sex);
return 0;
}

注意:当结构体中有数组成员时,给该成员赋值用strcpy()函数,将目标串拷贝给该数组成员

see you!

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

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