C语言中各种运算类型全面总结

目录
  • 一、概述
  • 二、四则运算
  • 三、关系运算
  • 四、逻辑运算与位运算
  • 五、深度剖析位运算

一、概述

C语言中支持下面4种类型的运算

运算类型 运算符
四则运算 +,-,*,/,%
关系运算 <,>,<=,>=,==,!=
逻辑运算 &&,||,!
位运算 &,|,^,>>,<<,~

二、四则运算

(+,-,*,/,%)

  • 就是数学中的加,减,乘,除等运算
  • 遵循先乘除后加减的运算优先级
  • 可以使用括号改变运算顺序

注意:

C语言中的除法运算,其除数不能为0

下面通过一段程序感受一下:

#include <stdio.h>
int main()
{
    int a = 5;
    int b = 2;
    double c = 3;
    c = a / b;
    printf("c = %f\n", c);
    c = a % b;
    printf("c = %f\n", c);
    return 0;
}

下面为输出结果:

通过上面的代码,可以得到一些小结论:

  • 整型数的除法运算结果会舍弃小数部分
  • 取余(%)运算也是一种除法运算,结果为余数
  • 浮点数不能进行取余运算

三、关系运算

(<,>,<=,>=,==,!=)

  • 比较两个值大小关系或相等关系的运算
  • 比较的结果为逻辑值: 真(1),假(0)
  • 可以使用括号()改变关系运算的顺序

如上面的图片所示,c 的值就为0

下面通过一段代码,感受一下:

#include <stdio.h>
int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    c = a != b;
    printf("c = %d\n", c);
    c = a - b >= a + b;
    printf("c = %d\n", c);
    c = (a < b) + (c < b);
    printf("c = %d\n", c);
    return 0;
}

下面为输出结果:

小技巧:如果不同类型的运算同时出现在一个表达式中,那么尽量使用括号()指明运算顺序。

运算优先级(优先级:四则运算 > 关系运算 > 赋值操作)

四则运算

  • 正负号 > 乘除运算 > 加减运算

关系运算

  • 大小比较运算 > 相等比较运算

赋值操作

下面看一段代码,深入感受一下运算优先级:

#include <stdio.h>
int main()
{
    int a = 1;
    int b = 2;
    int c = 0;
    c = a != b + a * b;
    printf("c = %d\n", c);
    return 0;
}

下面为输出结果,可以看出,c 的输出结果为1,为什么为1呢?这是由于乘法优先级大于加法优先级大于关系运算优先级,所以程序执行过程是这样,先计算 a * b,然后将 a * b 的结果 2 加上 b,得到4,最后再比较 a != 4,得到的结果当然为1啦,我们还可以通过反汇编来观察代码的执行过程。

c = a != b + a * b的汇编代码

所以如果想得到a != b 再加上a * b的结果,一定要记得加括号,如下:

#include <stdio.h>
int main()
{
    int a = 1;
    int b = 2;
    int c = 0;
    c = (a != b) + (a * b);
    printf("c = %d\n", c);
    return 0;
}

这样才能得到正确结果,如下所示:

小结:

  • 整型数除法有两种:取商(/),取余(%)
  • 浮点数除法与数学中除法运算相同,结果为浮点数
  • 不同运算的优先级不同,可使用括号改变运算优先级
  • 同一个表达式中应避免不同的运算类型(四则运算,关系运算)

四、逻辑运算与位运算

逻辑运算(&&,ll,!)

  • 逻辑运算的参与者为逻辑值(真或假)
  • 任何非零值在逻辑运算中都为真
  • 任何零值在逻辑运算中都为假
&&运算
左操作数 右操作数 结果
0 0 0
0 1 0
1 0 0
1 1 1
||运算
左操作数 右操作数 结果
0 0 0
0 1 1
1 0 1
1 1 1

逻辑运算中的短路法则

对于&&运算

  • 从左向右进行,如果有一个操作数为假,则整个表达式为假
  • 第一个为假的操作数之后的其它操作数不再计算

对于||运算

  • 从左向右进行,如果有一个操作数为真,则整个表达式为真
  • 第一个为真的操作数之后的其它操作数不再计算

取非运算(!)

单目运算(只需要一个操作数),运算结果为逻辑值

  • 对真值取非的结果为假
  • 对假值取非得结果为真

话不多说,上代码:

#include <stdio.h>
int main()
{
    int a = 1;
    int b = 2;
    int c = 0;
    c = a && b;
    printf("c = %d\n", c);
    c = !(a - b) || (c < b);
    printf("c = %d\n", c);
    c = 10000;
    c = !!c;
    printf("c = %d\n", c);
    return 0;
}

下面为运行结果:

位运算(&,|,~,^,<<,>>)

  • 直接对数据的二进制位进行操作
  • 位运算的基本单位是二进制位,所以也是一种0和1的操作
  • 可以使用括号()改变位运算的运算顺序
  • 位运算的操作数只能是整型数(浮点数不能直接进行位运算)
运算符 含义 示例 优先级
~ 按位求反 ~0101 -> 1010 1(高)
<< 左移:高位移出,低位补0 0011 << 1 -> 0110  2
>> 右移:低位移出,高位补符号位 0101 >> 2 -> 0001 2
& 按位与 0111 & 1100 -> 0100 3
^ 按位异或:相同为0,不同为1 0111 ^ 1100 -> 1011 4
| 按位或 0111 | 1100 -> 1111 5(低)

注:

1.按位与和逻辑与的计算法相同:两者为1,结果为1,否则为0

2.按位或和逻辑或的计算法相同:两者为0,结果为0,否则为1

位运算实例

  • 将整数5的第2个二进制位置1
  • 将整数7的第4个二进制位取反
  • 将整数2的最后两位取反
  • 将整数15右移2位,再将第2个二进制位置0
  • 设变量a的二进制数是10101101,若想通过运算a ^ b使得a的中间4位取反,其余位不变,则b的值是多少?

代码如下:

#include <stdio.h>
int main()
{
    printf("c = %d\n", 5 | 2);
    printf("c = %d\n", 7 ^ 8);
    printf("c = %d\n", 2 ^ 3);
    printf("c = %d\n", (15 >> 2) & 13);
    printf("c = %d\n", 173 ^ 60);
    return 0;
}

运行结果如下:

这里需要特别注意:对某一位或者某几位取反可以用异或(^)运算,这在工程里常用!!!

运算优先级(优先级从上到下为由高到低)

  • 正负号>逻辑非>按位取反
  • 乘除>加减>按位左右移
  • 大小比较运算>相等比较运算
  • 按位与>按位异或>按位或
  • 逻辑与>逻辑或
  • 赋值操作

小结

  • 逻辑运算中有特殊的短路法则,结果确定后不再向下计算
  • C语言中的真值对应非零值,假值对应零值
  • 位运算直接对数据的二进制位进行操作
  • 位运算的操作数只能是整型数(浮点数不能直接进行位运算)

五、深度剖析位运算

不同类型的本质在于:

占用的内存大小不同,如:short占用2字节,int占用4字节

表示具体数据的方式不同

  • 正整数用原码表示,负整数用补码表示
  • 整数型和浮点型的二进制表示不同

位运算时需要明确的知道的事

  • 操作数的类型(占用的内存大小)
  • 操作数是正数还是负数(符号位,数据表示)
  • 不同类型的操作数先自动对齐再进行位运算(补符号位)

如下面的一段代码:

short a = 1;
int b = 4;
int c = a | b;
printf("c = %d\n",c);

b为int类型,占4个字节,a为short类型,占2个字节。所以a要先要补符号位,由于a是正数,所以补0,这样就可以进行位运算了,得出c的结果为5。

下面来看一段代码:

#include <stdio.h>
int main()
{
    short a = 1;
    short b = 2;
    int c = a - b;
    c = c >> 4;
    printf("c = %d\n", c);
    c = c * -1 * 16 >> 4;
    printf("c = %d\n", c);
    printf("c = %d\n", 16 << 2);
    return 0;
}

下面为输出结果:

小结论

  • 正数符号位为0,右移运算时,高位补0,低位移除
  • 负数符号位为1,右移运算时,高位补1,低位移除
  • 左移运算时,最高位移除,低位补0
  • 最高位的具体位置,由数据类型决定

类型补充小知识

  • char 字符型,一个字节的整型,范围[-128,127]
  • 字符数据(单引号括起来的字符)的本质是整型数
  • char类型的变量可以打印为整数或者字符

再看一段代码:

#include <stdio.h>
int main()
{
    char c = 'A';
    short a = c;
    int b = c;
    printf("c = %c\n", c);
    printf("c = %d\n", c);
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    c = 0x40;
    printf("c = %x\n", c);
    printf("c = %d\n", c);
    c = c << 1;
    printf("c = %d\n", c);
    c = c << 1;
    printf("c = %d\n", c);
    return 0;
}

下面为输出结果:

需要注意的是,因为c为char类型,所以64左移1位后,用二进制表示为1000 0000,最高位的1表示符号位,所以就是-128。

小结

  • 不同类型的本质区别是:占用内存不同,数据表示不同
  • 右移运算时,高位补符号位,低位移除
  • char是只占用一个字节的整型,可表示英文字符
  • 数据符号位的具体位置由数据类型决定

到此这篇关于C语言中各种运算类型全面总结的文章就介绍到这了,更多相关C语言运算类型内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言位运算符的具体使用

    目录 布尔位运算符 移位运算符 对于更多紧凑的数据,C 程序可以用独立的位或多个组合在一起的位来存储信息.文件访问许可就是一个常见的应用案例.位运算符允许对一个字节或更大的数据单位中独立的位做处理:可以清除.设定,或者倒置任何位或多个位.也可以将一个整数的位模式(bit pattern)向右或向左移动. 整数类型的位模式由一队按位置从右到左编号的位组成,位置编号从 0 开始,这是最低有效位(least significant bit).例如,考虑字符值'*',它的 ASCII 编码为 42,相当

  • 谈谈C语言中位运算你要知道的那些事儿

    目录 一.概念说明 1.概念 1.1位运算 1.2位运算符 2.举例及补充 2.1位运算 2.2位运算符 二.问题实战 1.问题描述(开放题) 2.输入输出 三.源码实现(+详细注释) 1.注释版 2.纯源码版 四.输出结果展示 1.输出结果 总结 一.概念说明 1.概念 先来看一下位运算的概念: 1.1位运算 位运算简单来说,就是按二进制位进行运算. 位运算: 从现代计算机中所有的数据二进制的形式存储在设备中.即 0.1 两种状态,计算机对二进制数据进行的运算(+.-.*./)都是叫位运算,即

  • C语言 详细讲解逻辑运算符的使用

    目录 一.&& 与 II 分析 二.!分析 三.小结 一.&& 与 II 分析 下面的程序运行结束后,i, j,k 的值分别为多少? #include <stdio.h> int main() { int i = 0; int j = 0; int k = 0; ++i || ++j && ++k; printf("i = %d\n", i); printf("j = %d\n", j); printf(&

  • C语言详细讲解位运算符的使用

    目录 一.位运算符分析 二.小贴士 三.位运算与逻辑运算 四.小结 一.位运算符分析 C语言中的位运算符 位运算符直接对 bit 位进行操作,其效率最高. & 按位与 | 按位或 ^ 按位异或 ~ 取反 << 左移 >> 右移 左移和右移注意点 左操作数必须为整数类型 char 和 short 被隐式转换为 int 后进行移位操作 右操作数的范围必须为:[0,31] 左移运算符<< 将运算数的二进制位左移 规则:高位丢弃,低位补0 右移运算符>> 把

  • C语言简明讲解三目运算符和逗号表达式的使用

    目录 一.三目运算符 二.逗号表达式 三.小结 一.三目运算符 三目运算符( a ? b : c)可以作为逻辑运算的载体 规则:当 a 的值为真时,返回 b 的值:否则返回 c 的值 下面看一段代码: #include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = a < b ? a : b; (a < b ? a : b) = 3; printf("%d\n", a); printf(&

  • C语言运算符的重载详解

    目录 写一个Add函数 为什么不用加号作为函数名 运算符的重载 上面问题解决 总结 写一个Add函数 我们先讨论下面代码,并复习前面的内容 class Complex { private: double Real, Image; public: Complex() :Real(0), Image(0) {} Complex(double r, double i) :Real(r), Image(i) {} ~Complex() {} //Complex Add(const Complex* co

  • C语言实现数学表达式运算

    本文实例为大家分享了C语言实现数学表达式运算的具体代码,供大家参考,具体内容如下 1.开发思路: (假设有表达式 2 * 3 * ( 1 + 2) ) 数字要一个一个取出放在内存中,根据相邻前后2个计算符号,判断是否要取出数字进行计算,2个数字的计算值重新放在内存中且顺序放置.考虑使用栈这种数据结构去保存数字和符号,用2个栈,1个栈保存数字,一个栈保存运算符号. 2.因要使用栈这种数据结构,本代码使用纯C语言开发,故先编写栈的代码,参考: c语言实现通用数据结构(三):通用椎栈 3.重要处理逻辑

  • C语言中各种运算类型全面总结

    目录 一.概述 二.四则运算 三.关系运算 四.逻辑运算与位运算 五.深度剖析位运算 一.概述 C语言中支持下面4种类型的运算 运算类型 运算符 四则运算 +,-,*,/,% 关系运算 <,>,<=,>=,==,!= 逻辑运算 &&,||,! 位运算 &,|,^,>>,<<,~ 二.四则运算 (+,-,*,/,%) 就是数学中的加,减,乘,除等运算 遵循先乘除后加减的运算优先级 可以使用括号改变运算顺序 注意: C语言中的除法运算,其

  • C语言中的自定义类型之结构体与枚举和联合详解

    目录 1.结构体 1.1结构的基础知识 1.2结构的声明 1.3特殊的声明 1.4结构的自引用 1.5结构体变量的定义和初始化 1.6结构体内存对齐 1.7修改默认对齐数 1.8结构体传参 2.位段 2.1什么是位段 2.2位段的内存分配 2.3位段的跨平台问题 2.4位段的应用 3.枚举 3.1枚举类型的定义 3.2枚举的优点 3.3枚举的使用 4.联合 4.1联合类型的定义 4.2联合的特点 4.3联合大小的计算 1.结构体 1.1结构的基础知识 结构是一些值的集合,这些值称为成员变量.结构

  • Go语言中的复合类型详细介绍

    golang复合类型包括:结构体.数组.切片.Maps. 1.数组 数组 golang中的数组与C语言中的数组差异很大,倒更类似Pascal中的数组. (Slice,下个话题,有些像C语言中的数组) 复制代码 代码如下: var ar [3]int 声明ar为一个拥有三个整型数的数组,所有元素初始化为0. 大小是类型的一个组成部分. 内置的函数len可以用于获取数组大小: 复制代码 代码如下: len(ar) = 3 数组是值类型 golang中的数组是值,而非C语言中的隐式指针.你可以获得数组

  • R语言中的因子类型详解

    一.Factor函数 #函数factor可以把一个向量编码为一个因子,其一般形式为: #factor(x,levels=sort(unique(x),na.last=TRUE),labels,exculde=NA,order=FALSE) #其中x是向量,levels是水平,可以自行指定各离散的取值,不指定时由x的不同值来表示,labels可以用来指定各水平的标签 #不指定时用各离散取值的对应字符串 sex<-c("M","F","M",&

  • 详解易语言中的数据类型

    各种数据存放在磁盘或内存中都有其不同的存放格式,因此就存在不同的数据类型.了解各种数据的特性,对编程开发来说是十分重要. 程序中经常会进行一些运算,易语言中的运算都要使用运算符进行识别处理,并通过运算表达式来完成运算操作.程序中对各数据之间的关系的描述也要通过运算符. 1.易语言的数据类型 一个程序内部应包括两个方面的内容:1.数据的描述.2.操作步骤,即对程序动作的描述. 数据是程序操作的对象,操作的结果会改变数据的内容.打个比方:要做一道菜,做菜前先选择烹饪的原材料(即对数据进行描述),然后

  • GO语言中的常量

    常量是程序中最基础的元素,在定义之后就不能再重新赋值了.Go语言中的常量类型有布尔常量.整数常量.浮点数常量. 字符常量.字符串常量和复数常量 . 布尔常量 复制代码 代码如下: const x = true fmt.Print(x) //输出true 整数常量 复制代码 代码如下: const x = 20 fmt.Print(x) //输出20 浮点数常量 复制代码 代码如下: constx = 0.618 fmt.Print(x) //输出%f0.618 字符常量 复制代码 代码如下: c

  • C语言中的字符(char)详细讲解

    1.字符型(char)简介 字符型(char)用于储存字符(character),如英文字母或标点. 严格来说,char 其实也是整数类型(integer type),因为 char 类型储存的实际上是整数,而不是字符. 计算机使用特定的整数编码来表示特定的字符. 2. 声明字符型变量 3. 字符常量与初始化 实例: 用 char 类型来专门表示一个字符,例如: char a='1'; char b='$'; char c='X'; char d=' '; // 空格也是一个字符 char e=

  • go语言中的面向对象

    Go语言没有继承.构造函数和析构函数等概念,但是它是面向对象的. .net中类型系统分为值类型和引用类型,两种转换需要进行装箱和拆箱,都是继承自Object类型 Go语言大多数类型都是值类型,需要的话可以给任何类型增加功能 1.为类型添加方法 C++等语言的面向对象都相当于C语言的一个语法糖 下面看看Go语言如何实现面向对象的 可以看出,面向对象只是换了一种语法形式来表达.C++语言的面向对象之所以让有些人迷惑的 一大原因就在于其隐藏的this指针.而Java和C#其实都是遵循着C++语言的惯例

  • Go语言中的指针运算实例分析

    本文实例分析了Go语言中的指针运算方法.分享给大家供大家参考.具体分析如下: Go语言的语法上是不支持指针运算的,所有指针都在可控的一个范围内使用,没有C语言的*void然后随意转换指针类型这样的东西.最近在思考Go如何操作共享内存,共享内存就需要把指针转成不同类型或者对指针进行运算再获取数据. 这里对Go语言内置的unsafe模块做了一个实验,发现通过unsafe模块,Go语言一样可以做指针运算,只是比C的方式繁琐一些,但是理解上是一样的. 下面是实验代码: 复制代码 代码如下: packag

随机推荐