C++程序表达式分析

技术C++程序表达式分析这篇文章主要介绍“C++程序表达式分析”,在日常操作中,相信很多人在C++程序表达式分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++程序表达式分析”的疑惑有

本文主要介绍“C程序表达式分析”。在日常操作中,相信很多人对C程序的表达式分析有所怀疑。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮你解答“C程序表达式分析”的疑惑!接下来,请和边肖一起学习!

在C语言中,所有代码都由标识符、表达式和语句以及一些必要的符号(如大括号)组成。在这里,我们将首先解释什么是标识符。

标识符

标识符是字母序列,由大写和小写英文字母、下划线和数字组成,用于标识。Logo是为了标记和识别,也就是名字。它可以作为后面要提到的变量或函数或类的名称,也就是说,它用于标识c语言中的特定变量或函数或类以及其他元素。

例如,abc是一个合法的标识符,即abc可以作为变量、函数等元素的名称,但并不意味着abc是某个变量或函数的名称。所谓合法标识符,就是任何标识符都不能以数字开头,只包括大小写英文字母、下划线和数字,不能有其他符号,比如!等等。并且不能与c关键字相同。也就是说,我们在给一个变量或者函数命名的时候,一定要把这个名字当成一个标识符,然后一定要满足上面的要求。比如12ab_C不是合法的标识符,所以我们不能把一个变量或者函数命名为12ab _ C;Ab_12C是合法的标识符,因此可以用作变量或函数的名称。

如上所述,在下面的语句和一些声明修饰符的介绍中,我们会发现C提供了一些特殊的标识符作为语句的名称来标识特定的语句,比如if、while等。或者提供一些修饰符修饰变量、函数等元素来实现语义或者提供一些特定的信息给编译器和连接器进行优化、错误检查等操作,比如extern、static等。因此,在命名变量或函数或其他元素时,不能用if、extern这样的C关键字作为名称,否则编译器无法确认是变量(或函数或其他C元素)还是语句,那么就无法编译。

如果希望标识符是特定变量、函数或类的名称,则需要使用声明,这将在后续文章中详细解释。

数字

C作为一种计算机编程语言,计算机处理数字,所以C语言中最基本的东西就是数字。c提供两种数字,整数和浮点,即整数和小数。但是由于计算机实际上并不是想象中的数字(详见《C++从零开始(三)》中的类型部分),整数分为有符号整数和无符号整数,而浮点数则是根据精度的不同分为单精度和双精度浮点数,同样的整数也是根据长度分为长整数和短整数。

用C代码表示一个数字,直接写数字就可以了,比如:123,34.23,-34.34等。因为计算机不是以数字为基础的,所以导致了以前数字的分类。为了在代码中显示出来,C提供了一系列后缀,比如:

或者u表示数字是无符号整数,如:123u,但不表示是长整数还是短整数。

或l表示数字为长整数,如:123l并且123ul是无符号长整数;34.4l是长双精度浮点数,相当于一个双精度浮点数。

I64或i64表示该数字是一个长整数,它是为64位操作系统定义的,比长整数长。如:43i64

或f表示该数字是单精度浮点数,如:12.3f

或者e代表一个数的幂,如:34.4e-2为0.344;0.2544e3f表示值为254.4的单精度浮点数。

不写后缀时,根据是否有小数点或数字确定其具体类型,例如:123代表有符号整数,12341434代表有符号长整数;34.43表示双精度浮点数。

你为什么要做这么多事情?为什么有迹象而没有迹象?这都是因为计算机不是基于数字的,而是基于状态的,这将在下一章详细解释。

作为科学计算,我们可能经常会遇到非十进制数的使用,比如十六进制、八进制等。c还提供了一些前缀来支持这一点。

在数字前面加0x或0X表示数字是用十六进制表示的,如:0xF3Fa和0x11cF。而在它前面加一个0,就意味着这个数是用八进制表示的,比如:0347,变成十进制数就是231。但是十六进制和八进制都不能表示浮点数,只能表示整数,即0x34.343是错误的。

字符串

不仅提供了最基本的数字表示,还提供了字符和字符串。这只是为了方便编程而提供的。作为一种计算机语言,C完全不需要提供字符串。但是,由于人们对计算机的基本要求是显示结果,而字符和字符串由于是人类可读的符号,所以用于显示结果,所以C语言特别提供了对字符串的支持。

我前面说过,计算机只知道数字,字符是文字符号,是图形符号的一种。为了让计算机处理符号,符号必须以某种方式变成数字。在计算机中,这是通过在符号和数字之间建立映射来实现的,即建立一个表。表格中有两列。一列是我们要显示的图形符号,另一列是数字。通过这样的表格,我们可以建立图形符号和数字之间的映射。现在定义了一个标准表,叫做ASCII码表。几乎所有的计算机硬件都支持这个转换表,把数字变成符号,然后显示计算结果。

有了上表,当你想表示结果是“A”的时候,查查ASCII码表,得到图形符号“A”对应的数字是65,然后告诉电脑输入。

出序号为65的字符,最后屏幕上显示“A”。
这明显地繁杂得异常,为此C++就提供了字符和字符串。当我们想得到某一个图形符号的ASCII码表的序号时,只需通过单引号将那个字符括起来即可,如:'A',其效果和65是一样的。当要使用不止一个字符时,则用双引号将多个字符括起来,也就是所谓的字符串了,如:"ABC"。因此字符串就是多个字符连起来而已。但根据前面的说明易发现,字符串也需要映射成数字,但它的映射就不像字符那么简单可以通过查表就搞定的,对于此,将在后续文章中对数组作过介绍后再说明。

操作符


电脑的基本是数字,那么电脑的所有操作都是改变数字,因此很正常地C++提供了操作数字的一些基本操作,称作操作符(Operator),如:+ - * / 等。任何操作符都要返回一个数字,称为操作符的返回值,因此操作符就是操作数字并返回数字的符号。作为一般性地分类,按操作符同时作用的数字个数分为一元、二元和三元操作符。

一元操作符有:

+

其后接数字,原封不动地返回后接的数字。如: +4.4f的返回值是4.4;+-9.3f的返回值是-9.3。完全是出于语义的需要,如表示此数为正数。

-

其后接数字,将后接的数字的符号取反。如: -34.4f的返回值是-34.4;-(-54)的返回值是54。用于表示负数。

!

其后接数字,逻辑取反后接的数字。逻辑值就是“真”或“假”,为了用数字表示逻辑值,在 C++中规定,非零值即为逻辑真,而零则为逻辑假。因此3、43.4、'A'都表示逻辑真,而0则表示逻辑假。逻辑值被应用于后续的判断及循环语句中。而逻辑取反就是先判断“!”后面接的数字是逻辑真还是逻辑假,然后再将相应值取反。如: !5的返回值是0,因为先由5非零而知是逻辑真,然后取反得逻辑假,故最后返回0。 !!345.4的返回值是1,先因345.4非零得逻辑真,取反后得逻辑假,再取反得逻辑真。虽然只要非零就是逻辑真,但作为编译器返回的逻辑真,其一律使用1来代表逻辑真。

~

其后接数字,取反后接的数字。取反是逻辑中定义的操作,不能应用于数字。为了对数字应用取反操作,电脑中将数字用二进制表示,然后对数字的每一位进行取反操作(因为二进制数的每一位都只能为1或0,正好符合逻辑的真和假)。如~123的返回值就为-124。先将123转成二进制数01111011,然后各位取反得10000100,最后得-124。这里的问题就是为什么是8位而不是16位二进制数。因为123小于128,被定位为char类型,故为8位(关于char是什么将下篇介绍)。如果是~123ul,则返回值为4294967172。 为什么要有数字取反这个操作?因为CPU提供了这样的指令。并且其还有着很不错且很重要的应用,后面将介绍。

关于其他的一元操作符将在后续文章中陆续提到(但不一定全部提到)。

二元操作符有:

+-*/%

其前后各接一数字,返回两数字之和、差、积、商、余数。如:34+4.4f的返回值是38.4;3+-9.3f的返回值是-6.3。34-4的返回值是30;5-234的返回值是-229。3*2的返回值是6;10/3的返回值是3。10%3的返回值是1;20%7的返回值是6。

&&||

其前后各接一逻辑值,返回两逻辑值之“与”运算逻辑值和“或”运算逻辑值。如:'A'&&34.3f的返回值是逻辑真,为1;34&&0的返回值是逻辑假,为0。0||'B'的返回值是逻辑真,为 1;0||0的返回值是逻辑假,为0。

&|^

其前后各接一数字,返回两数字之“与”运算、“或”运算、“异或”运算值。如前面所说,先将两侧的数字转成二进制数,然后对各位进行与、或、异或操作。如:4&6的返回值是4,4转为00000100,6转为00000110各位相与得,00000100,为4。4|6的返回值是6,4转为00000100,6转为00000110各位相或得,00000110,为6。4^6的返回值是2,4转为00000100,6转为00000110各位相异或得,00000010,为2。

><==>=<=!=

其前后各接一数字,根据两数字是否大于、小于、等于、大于等于、小于等于及不等于而返回相应的逻辑值。如:34>34的返回值是0,为逻辑假;32<345的返回值为1,为逻辑真。23>=23和23>=14的返回值都是1,为逻辑真;54<=4的返回值为0,为逻辑假。56==6的返回值是0,为逻辑假;45==45的返回值是1,为逻辑真。5!=5的返回值是0,为逻辑假;5!=35的返回值是真,为逻辑真。

>><<

其前后各接一数字,将左侧数字右移或左移右侧数字指定的位数。与前面的 ~、&、|等操作一样,之所以要提供左移、右移操作主要是因为CPU提供了这些指令,主要用于编一些基于二进制数的算法。 <<将左侧的数字转成二进制数,然后将各位向左移动右侧数值的位数,如:4,转为00000100,左移2位,则变成00010000,得16。 >>与<<一样,只不过是向右移动罢了。如:6,转为00000110,右移1位,变成00000011,得3。如果移2位,则有一位超出,将截断,则6>>2的返回值就是00000001,为1。 左移和右移有什么用?用于一些基于二进制数的算法,不过还可以顺便作为一个简单的优化手段。考虑十进制数3524,我们将它左移2位,变成352400,比原数扩大了100倍,准确的说应该是扩大了10的2次方倍。如果将3524右移2位,变成35,相当于原数除以100的商。同样,前面4>>2,等效于4/4的商;32>>3相当于32/8,即相当于32除以2的3次方的商。而4<<2等效于4*4,相当于4乘以2的2次方。因此左移和右移相当于乘法和除法,只不过只能是乘或除相应进制数的次方罢了,但它的运行速度却远远高于乘法和除法,因此说它是一种简单的优化手段。

,

其前后各接一数字,简单的返回其右侧的数字。如: 34.45f,54的返回值是54;-324,4545f的返回值是4545f。 那它到底有什么用?用于将多个数字整和成一个数字,在《C++从零开始(四)》中将进一步说明。 关于其他的二元操作符将在后续文章中陆续提到(但不一定全部提到)。 三元操作符只有一个,为?:,其格式为:<数字1>?<数字2>:<数字3>。它的返回值为:如果<数字1>是逻辑真,返回<数字2>,否则返回<数字3>。如: 34?4:2的返回值就是4,因为34非零,为逻辑真,返回4。而0?4:2的返回值就是2,因为0为逻辑假,返回2。

表达式
你应该发现前面的荒谬之处了——12>435返回值为0,那为什么不直接写0还吃饱了撑了写个12>435在那?这就是表达式的意义了。
前面说“>”的前后各接一数字,但是操作符是操作数字并返回数字的符号,因为它返回数字,因此可以放在上面说的任何一个要求接数字的地方,也就形成了所谓的表达式。如:23*54/45>34的返回值就是0,因为23*54的返回值为1242;然后又将1242作为“/”的左接数字,得到新的返回值27.6;最后将27.6作为“>”的左接数字进而得到返回值0,为逻辑假。
因此表达式就是由一系列返回数字的东西和操作符组合而成的一段代码,其由于是由操作符组成的,故一定返回值。而前面说的“返回数字的东西”则可以是另一个表达式,或者一个变量,或者一个具有返回值的函数,或者具有数字类型操作符重载的类的对象等,反正只要是能返回一个数字的东西。如果对于何谓变量、函数、类等这些名词感到陌生,不需要去管它们,在后继的文章中将会一一说明。

因此34也是一个表达式,其返回值为34,只不过是没有操作符的表达式罢了(在后面将会了解到34其实是一种操作符)。故表达式的概念其实是很广的,只要有返回值的东西就可以称为表达式。 

由于表达式里有很多操作符,执行操作符的顺序依赖于操作符的优先级,就和数学中的一样,*、/的优先级大于+、-,而+、-又大于>、<等逻辑操作符。不用去刻意记住操作符的优先级,当不能确定操作符的执行顺序时,可以使用小括号来进行指定。如:
((1+2)*3)+3)/4的返回值为3,而1+2*3+3/4的返回值为7。注意3/4为0,因为3/4的商是0。当希望进行浮点数除法或乘法时,只需让操作数中的某一个为浮点数即可,如:3/4.0的返回值为0.75。

& | ^ ~等的应用


前面提过逻辑操作符“&&”、“||”、“!”等,作为表示逻辑,其被C++提供一点都不值得惊奇。但是为什么要有一个将数字转成二进制数,然后对二进制数的各位进行逻辑操作的这么一类操作符呢?首先是CPU提供了相应的指令,并且其还有着下面这个非常有意义的应用。
考虑一十字路口,每个路口有三盏红绿灯,分别指明能否左转、右转及直行。共有12盏,现在要为它编写一个控制程序,不管这程序的功能怎样,首先需要将红绿灯的状态转化为数字,因为电脑只知道数字。所以用3个数字分别表示某路口的三盏红绿灯,因此每个红绿灯的状态由一个数字来表示,假设红灯为0,绿灯为1(不考虑黄灯或其他情况)。
后来忽然发现,其实也可以用一个数字表示一个路口的三盏红绿灯状态,如用110表示左转绿灯、直行绿灯而右转红灯。上面的110是一个十进制数字,它的每一位实际都可以为0~9十个数字,但是这里只应用到了两个:0和1,感觉很浪费。故选择二进制数来表示,还是110,但是是二进制数了,转成十进制数为6,即使当为111时转成十进制数也只是7,比前面的110这个十进制数小多了,节约了……??什么??

我们在纸上写数字235425234一定比写134这个数字要更多地占用纸张(假设字都一样大)。因此记录一个大的数比记录一个小的数要花费更多的资源。简直荒谬!不管是100还是1000,都只是一个数字,为什么记录大的数字就更费资源?因为电脑并不是数字计算机,而是电子计算机,它是基于状态而不是基于数字的,这在下篇会详细说明。电脑必须使用某种表示方式来代表一个数字,而那个表示方式和二进制很像,但并不是二进制数,故出现记录大的数较小的数更耗资源,这也就是为什么上面整型数要分什么长整型短整型的原因了。

下面继续上面的思考。使用了110这个二进制数来表示三盏红绿灯的状态,那么现在要知道110这个数字代表左转红绿灯的什么状态。以数字的第三位表示左转,不过电脑并不知道这个,因此如下:110&100。这个表达式的返回值是100,非零,逻辑真。假设某路口的状态为010,则同样的010&100,返回值为0,逻辑假。因此使用“&”操作符可以将二进制数中的某一位或几位的状态提取出来。所以我们要了解一个数字代表 的红绿灯状态中的左转红绿灯是否绿灯时,只需让它和100相与即可。

现在要保持其他红绿灯的状态不变,仅仅使左转红绿灯为绿灯,如当前状态为010,为了使左转红绿灯为绿灯,值应该为110,这可以通过010|100做到。如果当前状态是001,则001|100为101,正确——直行和右转的红绿灯状态均没有发生变化。因此使用“|”操作符可以给一个二进制数中的某一位或几位设置状态,但只能设置为1,如果想设置为0,如101,要关掉左转的绿灯,则101&~100,返回值为001。
上面一直提到的路口红绿灯的状态实际编写时可以使用一个变量来表示,而上面的100也可以用一个标识符来表示,如state&TS_LEFT,就可以表示检查变量state所表示的状态中的左转红绿灯的状态。
上面的这种方法被大量地运用,如创建一个窗口,一个窗口可能有二三十个风格,则通过上面的方法,就可以只用一个32位长的二进制数字就表示了窗口的风格,而不用去弄二三十个数字来分别代表每种风格是否具有。

到此,关于“C++程序表达式分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/127531.html

(0)

相关推荐

  • Linux操作系统启动时怎样自动启用oracle standby备库日志应用

    技术Linux操作系统启动时怎样自动启用oracle standby备库日志应用这期内容当中小编将会给大家带来有关Linux操作系统启动时怎样自动启用oracle standby备库日志应用,文章内容丰富且以专业的角度为

    攻略 2021年11月30日
  • C#如何实现基于Socket套接字的网络通信封装

    技术C#如何实现基于Socket套接字的网络通信封装小编给大家分享一下C#如何实现基于Socket套接字的网络通信封装,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让

    攻略 2021年11月26日
  • python模块shutil函数怎么用

    技术python模块shutil函数怎么用小编给大家分享一下python模块shutil函数怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!本文大纲os模块是Python标准库中一个重要的模块,里面

    攻略 2021年10月27日
  • 嵌入式Linux Framebuffer怎么描点画线

    技术嵌入式Linux Framebuffer怎么描点画线这篇文章主要讲解了“嵌入式Linux Framebuffer怎么描点画线”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学

    攻略 2021年11月23日
  • 学而时习之不亦说乎有朋自远方来,学而时习之不亦乐乎读音

    技术学而时习之不亦说乎有朋自远方来,学而时习之不亦乐乎读音“学而时习之学而时习之不亦说乎有朋自远方来,不亦说乎”的读音是什么?学而时习之,不亦说乎的读音:xué ér shí xí zhī,bú yì yuè hū。

    生活 2021年10月20日
  • Java的三大版本有什么区别

    技术Java的三大版本有什么区别这篇文章主要介绍“Java的三大版本有什么区别”,在日常操作中,相信很多人在Java的三大版本有什么区别问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Jav

    攻略 2021年11月24日