5.3.5 和二进制极为密切的运算符

  本小节的运算符需要借助二进制概念来理解。

  二进制数据中,比如一个字节的数据,它的十进制为228,二进制就为11100100,如图5.11,

  注意:如果不懂怎么转换十进制和二进制,可以借用windows的计算器来辅助。

图5.11  228的十进制和二进制表现

  把 11100100 整体往右边挪动一位,就会变为01110010。如果觉得不好理解?请这么想,有一条火车轨道,轨道只有八节,一列无限长的火车在这八节轨道上来回移动,如图5.12所示,

图5.12  想象出的场景1

  火车启动前,在轨道上对应的车厢上标有一串数字 11100100,没有对应的车厢统一设数字为0,如图5.13,

  

图5.13  想象出来的场景2

  当火车往右移动一格的时候,在轨道上车厢显示的数据就为 01110010,当火车往右移动两格的时候,轨道上车厢显示的数据就为00111001。

   以上就是数据右移的表现,同理,数据左移就好比刚才那列火车向左移动,总之八节轨道上的车厢只能显示8个数字。

   再看看十进制的228,二进制为11100100,右移一位变为01110010,十进制值为114,在C语言中有移位运算符 >> 和 << 专门用来让数据移位,如下代码,

#include <stdio.h>

void main()
{
unsigned char a = ;
unsigned char b = ; b = a >> ; printf("b = %d\n", b);
}

  运行结果是:b = 114。

  注意:C语言printf不能显示二进制数据,只能显示十进制,十六进制和八进制的数。

  >> 就是右移运算符, << 就是左移运算符。

  读者可以把上述代码的 >> 改为 << ,向左移动一位就会使得 11100100 变为 11001000 ,十进制的值就为200。如果移动2位结果又是怎样呢,读者可以自行脑补。

  上述案例用的是 unsigned char 无符号的字符型数据,它的取值范围是 0~255,所以不管怎么移动,这个数据都是在 0~255 范围内。如果数据是unsigned int 类型,那么这列火车的轨道就要加长到32节,数据就会在 0~4294967295 之内浮动。

  难点来了,如果类型是带负号的 char 型呢?首先它的范围只可以在 -128~127 之间,那就随机选一个数来研究,比如选124,同样是刚才那份代码,将unsigned除去,将 a = 228 改成 a = 124。

  a右移一位运行结果:b = 62,a 左移一位运行结果: b = -8 。这些都与计算机存储数据方式有关,八个字节中,第一位是符号位,如果是0表示符号为正,如果是1表示符号为负,因为笔者写文章动力不足,所以笔者打算不讨论这块,希望读者自行去了解这块知识,可以借助windows的计算机结合写代码来分析有符号的数据移位规律是怎样的。

  

  下一个讲位运算,&, |  , ^,~

  按位与运算&,看起来很熟悉吧,感觉就是取地址符号一样,在运算表达式中它的作用是将左边的数据与右边的数据进行与的运算,与运算就是把每个对应的位进行比对,如果都为1这个位就设置为1,如果不相等或者都为0这个位就设置为0,如图5.14,

  

图5.14  与运算案例

  取二进制数 01011011 同 10011001 进行与运算,结果为 00011101,与运算规则正是遵循了同位都为1取1,其它情况取0,代码如下:

#include <stdio.h>

void main()
{
unsigned char a = ;
unsigned char b = ;
unsigned char c = ; c = a & b; printf("c = %d\n", c);
}

   运行结果:c = 25,十进制数25,它的二进制恰好就为图5.14所运算的结果为 00011001。

    同理,按位或运算 | ,就是左边和右边两个数的每一位进行比对,如果有一个位是1就取1,其它取0。

异或运算 ^ ,左边和右边两个数的每一位进行对比,如果相同取0,不同取1。

     非运算 ~ ,上面三个运算有左边的数和右边的数,非运算只针对一个数进行运算,就是将这个数的每一位都取反,也就是如果是0就取1,如果是1就取0。

   最后讲解比较常用的逻辑运算符 &&, ||, !

    逻辑与 && ,返回的是bool值,也就是返回true或者false,用法如下代码:

#include <stdio.h>
#include <stdbool.h> void main()
{
int a = ;
int b = ;
int c = ;
int d = ;
bool e = false; e = ((a > b)&&(c > d)); printf("e = %d\n", e);
}

  运行结果:e = 1。

  逻辑与 && 是用来连接表达式,表达式的结果是bool 值,好比上述例子,a > b 是true,c > d 是true,所以 true && true 的结果是true,得到 c 的值就为1。读者可以自行修改,比如把 a > b 改为 a < b 得到的 c 是 false && true ,结果是false。所以逻辑与 && 只有三种可能两种结果(不是true就是false):true && true 为 true,true && false 为 false, false && false 为 false。

同理,逻辑或 || ,true || true 为 true,true || false 为 true,false || false 为 false。

   逻辑非 !,加在表达式前,如果数值为0,结果为1;如果数值不为0,结果为0。可以参考以下代码,

  

#include <stdio.h>
#include <stdbool.h> void main()
{
int a = ;
int b = ;
int c = -;
int d = ; d = !a;
printf("d = %d\n", d); d = !b;
printf("d = %d\n", d); d = !c;
printf("d = %d\n", d);
}

  运行后,d的值分别为:0,1,0。

最后的最后讲解一个非主流的运算符 sizeof  。

   C语言学到后期,一般都会误认为 sizeof 是个C库的函数,其实它是个运算符,用于计算变量或者字符串占用内存的字节数,代码如下:

  

#include <stdio.h>
#include <stdbool.h> void main()
{
int a = ;
char b = ;
float c = 3.1415;
bool d = false;
int result = -; result = sizeof(a);
printf("result = %d\n", result); result = sizeof(b);
printf("result = %d\n", result); result = sizeof(c);
printf("result = %d\n", result); result = sizeof(d);
printf("result = %d\n", result);
}

  运行结果 result 的值依次为:4,1,4,1。这个结果刚好就是一个整型int占用字节数4,一个char占用字节数1,一个float占用字节数4,一个bool占用字节数1。

5.4 变量命名法

  本节最后讲解两种变量的命名方式,之前变量命名由于代码比较短小,很容易就能理解代码的意思,所以随便用个a或者b就凑合着用了,但是如果要用C语言做个大一点的项目,也就是当代码量很大的时候,变量名就需要人性化一些,便于多人一起维护项目,就像学生写作文一样,评卷老师看到字写得好看,不管内容如何,先给50分。

5.4.1 匈牙利命名法

   参考链接:

  https://baike.baidu.com/item/%E5%8C%88%E7%89%99%E5%88%A9%E5%91%BD%E5%90%8D%E6%B3%95/7632397?fr=aladdin

  

  比如我要给的年龄的变量命名,首先采用的是 int 类型,在匈牙利命名规则中,整型一般用 i 或者 n ,所以这么声明变量:

int nAge;

5.4.2 其它命名法

  笔者在 linux 驱动代码中选取了一个比较有代表性的变量命名:

  注意:linux 驱动代码几乎都是用C语言完成的,驱动是用来驱动设备的,C语言在这方面有它的优越性,比如位运算,指针操作等等。

int input_devices_state;

  一看就能明白这个变量的意义,表示输入设备的状态。

bool mutex_acquired;

  这个是互斥锁请求,不明白单词的意思可以用翻译软件。

int retval = ;

  ret 意思为 return ,val 意思为 value,组合起来 retval 就是返回值的意思,后续学函数就能明白返回值的作用了。

  本章终于完结!下一章节讲解的是控制语句,能用C语言做的事情多起来了!

C语言编程入门之--第五章C语言基本运算和表达式-part4的更多相关文章

  1. C语言编程入门之--第五章C语言基本运算和表达式-part1

    导读:程序要完成高级功能,首先要能够做到基本的加减乘除.本章从程序中变量的概念开始,结合之前学的输出函数和新介绍的输入函数制作简单人机交互程序,然后讲解最基础的加减法运算,自制简单计算器程序练手. 5 ...

  2. C语言编程入门之--第五章C语言基本运算和表达式-part2

    5.1.4 再来一个C库函数getchar吸收回车键 回车键也是一个字符,在使用scanf的时候,输入完毕要按下回车键,这时候回车键也会被输入到stdin流中,会搞乱我们的程序. 注意:stdin是输 ...

  3. C语言编程入门之--第五章C语言基本运算和表达式-part3

    5.3  挑几个运算符来讲 常用的运算符除了加减乘除(+-*/)外,还有如下: 注意:以下运算符之间用逗号隔开,C语言中也有逗号运算符,这里不讲逗号运算符. 1. 赋值运算符 =,+=,*= 2. 一 ...

  4. C语言编程入门之--第四章C语言基本数据类型

      导读:C语言程序中经常涉及一些数学计算,所以要熟悉其基本的数据类型.数据类型学习起来比较枯燥,不过结合之前的内存概念,以及本节的字节概念,相信数据类型也就不难理解了.本章从二进制的基本概念开始,然 ...

  5. C语言编程入门之--第六章C语言控制语句

    导读:本章带读者理解什么是控制语句,然后逐个讲解C语言常用的控制语句,含有控制语句的代码量多起来后就要注意写代码的风格了,本章末节都是练习题,大量的练习才能掌握好控制语句的使用. 6.1 什么是控制语 ...

  6. C语言编程入门之--第三章编写第一个C语言程序

    第三章 编写第一个C语言程序 导读:一般学一门计算机语言的第一堂上机课(“上机”顾名思义,上了计算机),就是往屏幕输出“hello world”,本章也不例外. 1.1 Hello,World! 这一 ...

  7. C语言编程入门之--第一章初识程序

    第一章 初识程序 导读:计算机程序无时不刻的影响着人类的生活,现代社会已经离不开程序,程序的作用如此巨大,那么程序到底是什么呢?本章主要讨论程序的概念,唤起读者对程序的兴趣,同时对C语言程序与其它语言 ...

  8. linux 操作系统下c语言编程入门

    2)Linux程序设计入门--进程介绍 3)Linux程序设计入门--文件操作 4)Linux程序设计入门--时间概念 5)Linux程序设计入门--信号处理 6)Linux程序设计入门--消息管理  ...

  9. VS2010/MFC编程入门之四十五(MFC常用类:CFile文件操作类)

    上一节中鸡啄米讲了定时器Timer的用法,本节介绍下文件操作类CFile类的使用. CFile类概述 如果你学过C语言,应该知道文件操作使用的是文件指针,通过文件指针实现对它指向的文件的各种操作.这些 ...

随机推荐

  1. (CVE-2017-10271)weblogic12.1.3.0漏洞测试与打补丁过程

    1.漏洞测试 搭建完成weblogic12.1.3.0后,开始用工具测试 点击connect,右下角显示connected,说明已连接→说明漏洞存在 CMD输入:ls   ,然后点击Execute执行 ...

  2. java多线程总结-同步容器与并发容器的对比与介绍

    1 容器集简单介绍 java.util包下面的容器集主要有两种,一种是Collection接口下面的List和Set,一种是Map, 大致结构如下: Collection List LinkedLis ...

  3. 个人永久性免费-Excel催化剂功能第80波-按条件查找数字,扩展原生查找功能

    Excel的查找替换功能,只能对文本类数据查找较为得力,若需查找数字类型的数据,如查找大于100的数字,就无能为力,此篇Excel催化剂补足其短板. Excel数据类型知识背景介绍 用好Excel,必 ...

  4. 2019牛客多校第二场D-Kth Minimum Clique

    Kth Minimum Clique 题目传送门 解题思路 我们可以从没有点开始,把点一个一个放进去,先把放入一个点的情况都存进按照权值排序的优先队列,每次在新出队的集合里增加一个新的点,为了避免重复 ...

  5. IIS应用程序池标识(程序池账户)ApplicationPoolIdentify

    IIS中应用程序池的运行账户(标识)有以下4个选项 LocalService 本地服务 LocalSystem 本地系统 NetWorkService 网络服务 ApplicationPoolIden ...

  6. 2019牛客暑期多校训练营(第四场)K.number

    >传送门< 题意:给你一个字符串s,求出其中能整除300的子串个数(子串要求是连续的,允许前面有0) 思路: >动态规划 记f[i][j]为右端点满足mod 300 = j的子串个数 ...

  7. datatables editor fields type

    其实editor fields type 默认支持的输入类型就是w3c输入框类型. text   number   password   textarea   select   checkbox   ...

  8. request获取容器过程

    获取容器过程 CoyoteAdapter.postParseRequest(org.apache.coyote.Request req, Request request, org.apache.coy ...

  9. Selenium浏览器自动化测试框架

    selenium简介 介绍 Selenium [1]  是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 1 ...

  10. 原创:微信小程序如何使用自定义组件

    本博文是通过实际开发中的一个实例来讲解自定义组件的使用. 第一步:新建自定义组件目录,如图,我新建了个componts和tabList目录,然后右键tabList目录选择新建compont取名为tab ...