论坛积分策略 论坛VIP区开放申请 我爱电脑万人签名活动 原声大碟520欢迎你 广告位招租
 15 12
发新话题
打印

[C++] C++从零开始

C++从零开始

C++从零开始(一)——何谓编程
, [" q& i4 F( @电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
& A& d/ S, l9 q6 w我爱电脑技术社区--打造最好的电脑技术自学交流平台C++从零开始(二)——何谓表达式
- ]9 l# I5 P/ R" D1 }1 n6 F我爱电脑技术社区--打造最好的电脑技术自学交流平台
. K4 Y- C1 ?0 H5 @  @# b我爱电脑技术社区--打造最好的电脑技术自学交流平台C++从零开始(三)——何谓变量 www.520diannao.com( L1 m- ^2 d: g% A
我爱电脑技术论坛6 p3 ?$ U/ N7 n" Q) E6 q
C++从零开始(四)——赋值cao作符
5 V9 N  A8 \& f" u) x1 K我爱电脑技术论坛
+ I5 Q& Q( V4 y1 t3 c* I* y" q电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站C++从零开始(五)——何谓指针
$ u6 ]- u! d' B9 D) Q. x我爱电脑技术论坛
- d4 `) k. n1 e" v我爱电脑技术社区--打造最好的电脑技术自学交流平台C++从零开始(六)——何谓语句 我爱电脑技术论坛" ^  n0 r, n% k  U  C3 h8 r

$ }7 r* F* _7 h3 \0 @- d; yC++从零开始(七)——何谓函数 打造最好的电脑自学交流论坛3 P: ^$ l: i% |' o. v4 U- C

* X5 Z! W# t/ A/ g我爱电脑技术社区--打造最好的电脑技术自学交流平台C++从零开始(八)——C++样例一
$ g* A, N+ Z, [" ^5 R" [4 f* A% E% |: A7 p' V
C++从零开始(九)——何谓结构 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站: Y3 H& {0 J- N8 @9 _; v0 I
我爱电脑技术社区--打造最好的电脑技术自学交流平台* [, C+ R7 w  L0 G9 A2 F
C++从零开始(十)——何谓类 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站7 c2 B% n: g$ j8 [  m2 b) M
www.520diannao.com  k% T' J% P; O5 a* L! w
C++从零开始(十一)(上)——类的相关知识
0 n6 k) r" R# @" E我爱电脑技术社区--打造最好的电脑技术自学交流平台www.520diannao.com) Z* [2 \) S) J4 [' e# g; l
C++从零开始(十一)(中)——类的相关知识
' O% e! E: @( @  H2 ~! F  R8 f电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站: x4 e( k! ?2 k3 Z' g" p
C++从零开始(十一)(下)——类的相关知识 打造最好的电脑自学交流论坛9 z# o8 `8 L* d+ }8 f. [2 A

2 _) f3 j, q$ O, n( T: F电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站C++从零开始(十二)何谓面向对象编程思想

TOP

C++从零开始(一)——何谓编程我爱电脑技术论坛8 h3 Q, U, I! N! A
曾经有些人问我问题,问得都是一些很基础的问题,但这些人却已经能使用VC编一个对话框界面来进行必要的cao作或者是文档/视界面来实时接收端口数据并动态显示曲线(还使用了多线程技术),却连那些基础的问题都不清楚,并且最严重的后果就是导致编写出拙劣的代码(虽然是多线程,但真不敢恭维),不清楚类的含义,混杂使用各种可用的技术来达到目的(连用异常代替选择语句都弄出来了),代码逻辑混乱,感觉就和金山快译的翻译效果一样。
' r0 m, t  _( v2 c( O电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站我认为任何事情,基础都是最重要的,并且在做完我自定的最后一个项目后我就不再做编程的工作,守着这些经验也没什么意义,在此就用本系列说说我对编程的理解,帮助对电脑编程感兴趣的人快速入门(不过也许并不会想象地那么快)。由于我从没正经看完过一本C++的书(都是零碎偶尔翻翻的),并且本系列并不是教条式地将那些该死的名词及其解释罗列一遍,而是希望读者能够理解编程,而不是学会一门语言(即不止会英翻汉,还会汉翻英)。整个系列全用我自己的理解来写的,并无参考其他教材(在一些基础概念上还是参考了MSDN),所以本系列中的内容可能有和经典教材不一致的地方,但它们的本质应该还是一样的,只是角度不同而已。本系列不会仔细讲解C++的每个关键字(有些并不重要),毕竟目的不是C++语言参考,而是编程入门。如果本系列文章中有未提及的内容,还请参考MSDN中的C++语言参考(看完本系列文章后应该有能力做这件事了),而本系列给出的内容均是以VC编译器为基础,基于32位Windowscao作系统的。我爱电脑技术论坛2 K& R9 I8 l# o3 j
下面罗列一下各文章的标题和主要内容,红色修饰的文章标题表示我认为的重点。www.520diannao.com, Y$ p2 P/ ], J2 n2 S1 C
C++从零开始(一)——何谓编程(说明编程的真正含义及两个重要却容易被忽略的基础概念)
9 I, B" S0 l1 DC++从零开始(二)——何谓表达式(说明各cao作符的用处,但不是全部,剩余的会在其它文章提到)我爱电脑技术社区--打造最好的电脑技术自学交流平台) u* m: k. _2 {8 D; ^! _
C++从零开始(三)——何谓变量(说明电脑的工作方式,阐述内存、地址等极其重要的概念)我爱电脑技术论坛7 O9 q6 ]5 ~/ P0 P( D2 E. L
C++从零开始(四)——赋值cao作符(《C++从零开始(二)》的延续,并为指针的解释打一点基础)我爱电脑技术社区--打造最好的电脑技术自学交流平台, M6 b! s+ |0 h: K
C++从零开始(五)——何谓指针(阐述指针、数组等重要的概念)
5 D+ Y$ }, j6 |$ e' n  S5 z* W我爱电脑技术论坛C++从零开始(六)——何谓语句(讲解C++提供的各个语句,说明各自存在的理由)
# U( d  {. G/ ]+ _' CC++从零开始(七)——何谓函数(说明函数及其存在的理由)
6 ?+ s) z! [$ k* L# q; o/ z7 [电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站C++从零开始(八)——C++样例一(给出一两个简单算法,一步步说明如何从算法编写出C++代码)我爱电脑技术社区--打造最好的电脑技术自学交流平台' Z9 f9 Q! E2 P7 v
C++从零开始(九)——何谓结构(简要说明结构、枚举等及其存在的理由)7 s! J% Y3 k# q. D/ O
C++从零开始(十)——何谓类(说明类及其存在的理由,以及声明、定义、头文件等概念)
7 S7 I% Q* X+ R) _: H打造最好的电脑自学交流论坛C++从零开始(十一)——类的相关知识(说明派生、继承、名字空间、cao作符重载等)www.520diannao.com" d$ g; H( I- @# B' E: l
C++从零开始(十二)——何谓面向对象编程思想(阐述何谓编程思想,重点讲述面向对象编程思想)打造最好的电脑自学交流论坛; v; Q2 j! N& B5 D: |
C++从零开始(十三)——C++样例二(说明如何设计基于面向对象编程思想的C++程序)打造最好的电脑自学交流论坛2 d1 \& k  u! T  P8 Q7 x
C++从零开始(十四)——何谓模板(说明模板技术及其存在的理由)
# Q' |2 x# z1 W) `8 g* c我爱电脑技术社区--打造最好的电脑技术自学交流平台C++从零开始(十五)——何谓异常(说明异常技术及其存在的理由)
$ ]- h/ Z& f; O我爱电脑技术论坛C++从零开始(十六)——何谓预编译指令(说明预编译指令的概念及几个常用指令的应用)我爱电脑技术社区--打造最好的电脑技术自学交流平台; r3 R" k% U, }  P
C++从零开始(十七)——C++中的一些生僻关键字(explicit、mutable、volatile等的说明)
, n; A" |. a4 v% ^我爱电脑技术论坛C++从零开始(十八)——何谓SDK(说明为什么没有放音乐的指令却依然可以编出放音乐的程序)
3 h' D8 K+ B& F4 M# A9 pwww.520diannao.comC++从零开始(十九)——何谓C运行时期库(说明C运行时期库这一大多数问题的元凶)我爱电脑技术社区--打造最好的电脑技术自学交流平台$ z  }& r; P0 b5 l3 q9 ^8 i
C++从零开始(二十)——关于VC的一点点基础知识(说明VC的几个基本概念和一些常用设置)
+ |/ z; u4 k% \! m8 l% e+ o0 u我爱电脑技术社区--打造最好的电脑技术自学交流平台C++从零开始(二十一)——C++样例三(使用VC编写一个通过DLL实现多态性的简单程序)电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站7 v7 ]# k, i3 v. h# }

0 J  e- n& [* Awww.520diannao.com
+ Y$ @3 ?7 z$ C( u% A4 g何谓程序
/ b) q4 Y- a+ Y/ R我爱电脑技术论坛
, L- n* F& w( G* x2 E9 A程序,即过程的顺序,准确地说应该是顺序排列的多个过程,其是方法的描述。比如吃菜,先用筷子夹起菜,再用筷子将菜送入嘴中,最后咀嚼并吞下。其中的夹、送、咀嚼和吞下就被称作命令,而菜则是资源,其状态(如形状、位置等)随着命令的执行而不断发生变化。上面就是吃菜这个方法的描述,也就是吃菜的程序。
7 {6 q2 M. x  |+ V, T. u  p. R4 S任何方法都是为了改变某些资源的状态而存在,因此任何方法的描述,也就是程序,也都一定有命令这个东西以及其所作用的资源。命令是由程序的执行者来实现的,比如上面的吃菜,其中的夹、送等都是由吃菜的人来实现的,而资源则一定是执行者可以改变的东西,而命令只是告诉执行者如何改变而已。打造最好的电脑自学交流论坛7 F* W6 E3 e0 |4 r! W9 J5 D
电脑程序和上面一样,是方法的描述,而这些方法就是人期望电脑能做的事(注意不是电脑要做的事,这经常一直混淆着许多人),当人需要做这些事时,人再给出某些资源以期电脑能对其做正确的改变。如计算圆周率的程序,其只是方法的描述,本身是不能发生任何效用的,直到它被执行,人为给定它一块内存(关于内存,请参考《C++从零开始(三)》),告诉它计算结果的精度及计算结果的存放位置后,其才改变人为给定的这块内存的状态以表现出计算结果。我爱电脑技术社区--打造最好的电脑技术自学交流平台. V/ G' L- Q7 Y! D. K: O
因此,对于电脑程序,命令就是CPU的指令,而执行者也就由于是CPU的指令而必须是CPU了,而最后的资源则就是CPU可以改变其状态的内存(当然不止,如端口等,不过一般应用程序都大量使用内存罢了)。所以,电脑程序就是电脑如何改变给定资源(一般是内存,也可以是其他硬件资源)的描述,注意是描述,本身没有任何意义,除非被执行。www.520diannao.com2 K  W7 G" W& x; u* `, G
我爱电脑技术社区--打造最好的电脑技术自学交流平台5 M1 O8 x# r7 z0 N5 V

$ }  I0 P0 V% W- ]( m: W6 B- V我爱电脑技术论坛何谓编程
( _5 F, y5 [. ^: s: l1 L我爱电脑技术论坛打造最好的电脑自学交流论坛  C5 a$ @+ W# D+ F; C
编程就是编写程序,即制订方法。为什么要有方法?方法是为了说明。而之所以要有说明就有很多原因了,但电脑编程的根本原因是因为语言不同,且不仅不同,连概念都不相通。我爱电脑技术社区--打造最好的电脑技术自学交流平台6 V2 W, W* b" B% \6 B* o" x
人类的语言五花八门,但都可以通过翻译得到正解,因为人类生存在同一个四维物理空间中,具有相同或类似的感知。而电脑程序执行时的CPU所能感受到的空间和物理空间严重不同,所以是不可能将电脑程序翻译成人类语言的描述的。这很重要,其导致了大部分程序员编写出的拙劣代码,因为人想的和电脑想的没有共性,所以他们在编写程序时就随机地无目的地编写,进而导致了拙劣却可以执行的代码。我爱电脑技术论坛: u! v' W2 R) O( ?( g
电脑的语言就是CPU的指令,因为CPU就这一个感知途径(准确地说还有内存定位、中断响应等感知途径),不像人类还能有肢体语言,所以电脑编程就是将人类语言书写的方法翻译成相应的电脑语言,是一个翻译过程。这完全不同于一般的翻译,由于前面的红字,所以是不可能翻译的。
7 F0 |. l, B! {1 Q  x8 |3 L4 ?我爱电脑技术社区--打造最好的电脑技术自学交流平台既然不可能翻译,那电脑编程到底是干甚?考虑一个木匠,我是客人。我对木匠说我要一把摇椅,躺着很舒服的那种。然后木匠开始刨木头,按照一个特殊的曲线制作摇椅下面的曲木以保证我摇的时候重心始终不变以感觉很舒服。这里我编了个简单的程序,只有一条指令——做一把摇着很舒服的摇椅。而木匠则将我的程序翻译成了刨木头、设计特定的曲木等一系列我看不懂的程序。之所以会这样,在这里就是因为我生活的空间和木工(是木工工艺,不是木匠)没有共性。这里木匠就相当于电脑程序员兼CPU(因为最后由木匠来制作摇椅),而木匠的手艺就是CPU的指令定义,而木匠就将我的程序翻译成了木工的一些规程,由木匠通过其手艺来实现这些规程,也就是执行程序。
; V+ t9 s$ d6 ?. T' ~. d我爱电脑技术社区--打造最好的电脑技术自学交流平台上面由于我生活的空间和木工(指木工工艺,不是工人)没有共性,所以是不可能翻译的,但上面翻译成功了,实际是没有翻译的。在木工眼中,那个摇椅只是一些直木和曲木的拼接而已,因为木工空间中根本没有摇椅的概念,只是我要把那堆木头当作摇椅,进而使用。如果我把那堆木头当作凶器,则它就是凶器,不是什么摇椅了。www.520diannao.com( J3 E3 k0 t3 c9 L
“废话加荒谬加放屁!”,也许你会这么大叫,但电脑编程就是这么一回事。CPU只能感知指令和改变内存的状态(不考虑其他的硬件资源及响应),如果我们编写了一个计算圆周率的程序,给出了一块内存,并执行,完成后就看见电脑的屏幕显示正确的结果。但一定注意,这里电脑实际只是将一些内存的数值复制、加减、乘除而已,电脑并不知道那是圆周率,而如果执行程序的人不把它说成是圆周率那么那个结果也就不是圆周率了,可能是一个随机数或其他什么的,只是运气极好地和圆周率惊人地相似。
% d+ M! r$ p3 H上面的东西我将其称为语义,即语言的意义,其不仅仅可应用在电脑编程方面,实际上许多技术,如机械、电子、数学等都有自己的语言,而那些设计师则负责将客户的简单程序翻译成相应语言描述的程序。作为一个程序员是极其有必要了解到语义的重要性的(我在我的另一篇文章《语义的需要》中对代码级的语义做过较详细的阐述,有兴趣可以参考之),在后续的文章中我还将提到语义以及其对编程的影响,如果你还没有理解编程是什么意思,随着后续文章的阅读应该能够越来越明了。
0 ]. ~! \# x# ~$ r) \2 v1 c" C打造最好的电脑自学交流论坛
- v+ y- |# P9 i) W/ ?  Cwww.520diannao.com
  {" c! |! Z# U5 e) ^8 C; t; O0 t( G' n电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站电脑编程的基础知识——编译器和连接器
, r) G5 O* R7 k) S5 e* i8 B我爱电脑技术社区--打造最好的电脑技术自学交流平台www.520diannao.com) k$ h; f1 h, [' Q7 R. ^- @% Q. ^
我从没见过(不过应该有)任何一本C++教材有讲过何谓编译器(Compiler)及连接器(Linker)(倒是在很老的C教材中见过),现在都通过一个类似VC这样的编程环境隐藏了大量东西,将这些封装起来。在此,对它们的理解是非常重要的,本系列后面将大量运用到这两个词汇,其决定了能否理解如声明、定义、外部变量、头文件等非常重要的关键。  Q7 F8 `7 G* x/ \
前面已经说明了电脑编程就是一个“翻译”过程,要把用户的程序翻译成CPU指令,其实也就是机器代码。所谓的机器代码就是用CPU指令书写的程序,被称作低级语言。而程序员的工作就是编写出机器代码。由于机器代码完全是一些数字组成(CPU感知的一切都是数字,即使是指令,也只是1代表加法、2代表减法这一类的数字和工作的映射),人要记住1是代表加法、2是代表减法将比较困难,并且还要记住第3块内存中放的是圆周率,而第4块内存中放的是有效位数。所以发明了汇编语言,用一些符号表示加法而不再用1了,如用ADD表示加法等。
1 j; G7 l0 M- ~* X9 j7 t电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站由于使用了汇编语言,人更容易记住了,但是电脑无法理解(其只知道1是加法,不知道ADD是加法,因为电脑只能看见数字),所以必须有个东西将汇编代码翻译成机器代码,也就是所谓的编译器。即编译器是将一种语言翻译成另一种语言的程序。
4 A% d( B+ t/ a" W) k, K我爱电脑技术论坛即使使用了汇编语言,但由于其几乎只是将CPU指令中的数字映射成符号以帮助记忆而已,还是使用的电脑的思考方式进行思考的,不够接近人类的思考习惯,故而出现了纷繁复杂的各种电脑编程语言,如:PASCAL、BASIC、C等,其被称作高级语言,因为比较接近人的思考模式(尤其C++的类的概念的推出),而汇编语言则被称作低级语言(C曾被称作高级的低级语言),因为它们不是很符合人类的思考模式,人类书写起来比较困难。由于CPU同样不认识这些PASCAL、BASIC等语言定义的符号,所以也同样必须有一个编译器把这些语言编写的代码转成机器代码。对于这里将要讲到的C++语言,则是C++语言编译器(以后的编译器均指C++语言编译器)。
4 Y/ z; s: v- N" i8 x/ K4 X打造最好的电脑自学交流论坛因此,这里所谓的编译器就是将我们书写的C++源代码转换成机器代码。由于编译器执行一个转换过程,所以其可以对我们编写的代码进行一些优化,也就是说其相当于是一个CPU指令程序员,将我们提供的程序翻译成机器代码,不过它的工作要简单一些了,因为从人类的思考方式转成电脑的思考方式这一过程已经由程序员完成了,而编译器只是进行翻译罢了(最多进行一些优化)。
# R" E' v$ Q2 m  C8 n: q电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站还有一种编译器被称作翻译器(Translator),其和编译器的区别就是其是动态的而编译器是静态的。如前面的BASIC的编译器在早期版本就被称为翻译器,因为其是在运行时期即时进行翻译工作的,而不像编译器一次性将所有代码翻成机器代码。对于这里的“动态”、“静态”和“运行时期”等名词,不用刻意去理解它,随着后续文章的阅读就会了解了。打造最好的电脑自学交流论坛6 T. @( S5 |- O1 \
编译器把编译后(即翻译好的)的代码以一定格式(对于VC,就是COFF通用对象文件格式,扩展名为.obj)存放在文件中,然后再由连接器将编译好的机器代码按一定格式(在Windowscao作系统下就是Portable Executable File Format——PE文件格式)存储在文件中,以便以后cao作系统执行程序时能按照那个格式找到应该执行的第一条指令或其他东西,如资源等。至于为什么中间还要加一个连接器以及其它细节,在后续文章中将会进一步说明。
2 c: J" O/ k; B6 h" g* I" F& X我爱电脑技术社区--打造最好的电脑技术自学交流平台也许你还不能了解到上面两个概念的重要性,但在后续的文章中,你将会发现它们是如此的重要以至于完全有必要在这唠叨一番。

TOP

C++从零开始(二)——何谓表达式
% S0 K* ], u, D3 d2 C$ N: v% \! p我爱电脑技术论坛本篇是此系列的开头,在学英语时,第一时间学的是字母,其是英语的基础。同样,在C++中,所有的代码都是通过标识符(Identifier)、表达式(Expression)和语句(Statement)及一些必要的符号(如大括号等)组成,在此先说明何谓标识符。
0 p8 ~; D  J' f  K: a打造最好的电脑自学交流论坛标识符 标识符是一个字母序列,由大小写英文字母、下划线及数字组成,用于标识。标识就是标出并识别,也就是名字。其可以作为后面将提到的变量或者函数或者类等的名字,也就是说用来标识某个特定的变量或者函数或者类等C++中的元素。
% @) m9 U( k% A9 o打造最好的电脑自学交流论坛比如:abc就是一个合法的标识符,即abc可以作为变量、函数等元素的名字,但并不代表abc就是某个变量或函数的名字,而所谓的合法就是任何一个标识符都必须不能以数字开头,只能包括大小写英文字母、下划线及数字,不能有其它符号,如,!^等,并且不能与C++关键字相同。也就是我们在给一个变量或函数起名字的时候,必须将起的名字看作是一个标识符,并进而必须满足上面提出的要求。如12ab_C就不是一个合法的标识符,因此我们不能给某个变量或函数起12ab_C这样的名字;ab_12C就是合法的标识符,因此可以被用作变量或函数的名字。
( Q- I2 j- ]" G, C2 Y1 g: r我爱电脑技术论坛前面提到关键字,在后续的语句及一些声明修饰符的介绍中将发现,C++提供了一些特殊的标识符作为语句的名字,用以标识某一特定语句,如if、while等;或者提供一些修饰符用以修饰变量、函数等元素以实现语义或给编译器及连接器提供一些特定信息以进行优化、查错等cao作,如extern、static等。因此在命名变量或函数或其他元素时,不能使用if、extern等这种C++关键字作为名字,否则将导致编译器无法确认是一个变量(或函数或其它C++元素)还是一条语句,进而无法编译。我爱电脑技术社区--打造最好的电脑技术自学交流平台+ `4 k* T  g) K" t! S4 N
如果要让某个标识符是特定变量或函数或类的名字,就需要使用声明,在后续的文章中再具体说明。
+ x0 u% e, L. F5 J# q: mwww.520diannao.com数字
& z" Q. P! T9 Y6 M2 R1 n1 I电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
- }4 m" p7 `6 x1 @我爱电脑技术论坛C++作为电脑编程语言,电脑是处理数字的,因此C++中的基础东西就是数字。C++中提供两种数字:整型数和浮点数,也就是整数和小数。但由于电脑实际并不是想象中的数字化的(详情参见《C++从零开始(三)》中的类型一节),所以整型数又分成了有符号和无符号整型数,而浮点数则由精度的区别而分成单精度和双精度浮点数,同样的整型数也根据长度分成长整型和短整型。
* `; _6 |' _( Zwww.520diannao.com要在C++代码中表示一个数字,直接书写数字即可,如:123、34.23、-34.34等。由于电脑并非以数字为基础而导致了前面数字的分类,为了在代码中表现出来,C++提供了一系列的后缀进行表示,如下:我爱电脑技术社区--打造最好的电脑技术自学交流平台+ ^& n' H+ @5 q8 j8 |( g

. ^3 z  i( N4 z6 c我爱电脑技术社区--打造最好的电脑技术自学交流平台电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站; u$ o6 a7 A* |  M  h' L% i$ ]

% \( Y, L* X5 ~4 k; o- ?/ ]
1 _1 `8 J  e2 s  Uwww.520diannao.comwww.520diannao.com- f! {/ c. P+ Q7 G1 u

( Y, r$ w$ R( L& v' C打造最好的电脑自学交流论坛电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站  w1 D! R9 Z6 P# L' R

* M+ a5 S* K  O" e我爱电脑技术论坛u或U 我爱电脑技术社区--打造最好的电脑技术自学交流平台2 J: j: n; O% S

5 i' [7 i! f  i' u  Y( w电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站表示数字是无符号整型数,如:123u,但并不说明是长整型还是短整型
9 m( b' U0 L9 G! K- M# ]电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
6 I6 D. b1 i$ F- E; `: I
) g5 O2 K2 i" }1 o# b, Z4 \9 f; A电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站0 w7 N# |* ]  D, n
打造最好的电脑自学交流论坛2 }6 ?$ l9 L8 j1 ?# W
l或L
9 o7 D/ ~* a$ Z  i1 ~7 ?* T5 Kwww.520diannao.com打造最好的电脑自学交流论坛# Y! k! M% q$ [8 `" X- Q" W' S
表示数字是长整型数,如:123l;而123ul就是无符号长整型数;而34.4l就是长双精度浮点数,等效于双精度浮点数 我爱电脑技术论坛' n/ C4 f# Z, B5 L

5 K$ D: U8 ?: G. Q* b# s我爱电脑技术论坛电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站, U5 u4 W/ N9 E2 `7 \% T4 r
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站  m, o  k; v  S- j: L7 H! h3 k6 L
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站; {7 g9 U, O7 J
i64或I64
1 A& d& R/ I4 I; Z; R我爱电脑技术论坛打造最好的电脑自学交流论坛2 g0 g/ |2 A2 u! N7 c' H) t
表示数字是长长整型数,其是为64位cao作系统定义的,长度比长整型数长。如:43i64 打造最好的电脑自学交流论坛- ?9 g+ |/ @3 Y, C& S6 }8 `/ W1 d" T
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站4 u8 [2 N) N, z0 L# D, i( e

* l6 @1 W9 B" i$ O8 K, X' p电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
+ B! w5 |) `8 R4 j我爱电脑技术社区--打造最好的电脑技术自学交流平台
% A  ]9 L1 i9 \  h  F* P: Pwww.520diannao.comf或F 打造最好的电脑自学交流论坛; L3 M2 u! K0 H
我爱电脑技术社区--打造最好的电脑技术自学交流平台3 ]' i+ }% k& C" f4 F8 M$ N4 ?% h
表示数字是单精度浮点数,如:12.3f 我爱电脑技术论坛( d# Q- k8 k. T% f

$ M# f1 {" y1 q" a4 ?2 r  i* rwww.520diannao.comwww.520diannao.com# U8 q! K1 \9 V" n

% h- a9 }. g9 N1 J; ?2 w/ w打造最好的电脑自学交流论坛打造最好的电脑自学交流论坛* W1 ]% P5 a+ K5 n& V7 P/ T( }& u
e或E 我爱电脑技术社区--打造最好的电脑技术自学交流平台5 Y) l* U7 s+ [0 ]6 e$ ^( z

7 q9 b4 ^) {: r打造最好的电脑自学交流论坛表示数字的次幂,如:34.4e-2就是0.344;0.2544e3f表示一个单精度浮点数,值为254.4 我爱电脑技术社区--打造最好的电脑技术自学交流平台* W! t0 [) h5 z. C! a* _
当什么后缀都没写时,则根据有无小数点及位数来决定其具体类型,如:123表示的是有符号整型数,而12341434则是有符号长整型数;而34.43表示双精度浮点数。
" _) B" L3 U# @# S4 y8 F( w; N% Q8 {我爱电脑技术社区--打造最好的电脑技术自学交流平台为什么要搞这么多事出来,还分什么有符号无符号之类的?这全是因为电脑并非基于数字的,而是基于状态的,详情在下篇中将详细说明。www.520diannao.com8 B3 N8 r* q: N
作为科学计算,可能经常会碰到使用非十进制数字,如16进制、8进制等,C++也为此提供了一些前缀以进行支持。
4 f/ J( W  |( o2 H在数字前面加上0x或0X表示这个数字是16进制表示的,如:0xF3Fa、0x11cF。而在前面加一个0则表示这个数字是用8进制表示的,如:0347,变为十进制数就为231。但16进制和8进制都不能用于表示浮点数,只能表示整型数,即0x34.343是错误的。
* r) V9 [- ?4 @, m. Xwww.520diannao.comwww.520diannao.com# _) C- e  D% E0 ~" Z6 V! `  N

: e5 z) @" G& o" Z我爱电脑技术论坛字符串 C++除了提供数字这种最基础的表示方式外,还提供了字符及字符串。这完全只是出于方便编写程序而提供的,C++作为电脑语言,根本没有提供字符串的必要性。不过由于人对电脑的基本要求就是显示结果,而字符和字符串都由于是人易读的符号而被用于显示结果,所以C++专门提供了对字符串的支持。我爱电脑技术论坛0 z) g5 ^7 \, X% d3 N3 p( ~7 C
前面说过,电脑只认识数字,而字符就是文字符号,是一种图形符号。为了使电脑能够处理符号,必须通过某种方式将符号变成数字,在电脑中这通过在符号和数字之间建立一个映射来实现,也就是一个表格。表格有两列,一列就是我们欲显示的图形符号,而另一列就是一个数字,通过这么一张表就可以在图形符号和数字之间建立映射。现在已经定义出一标准表,称为ASCII码表,几乎所有的电脑硬件都支持这个转换表以将数字变成符号进而显示计算结果。5 g) g1 J# p" \, z7 R
有了上面的表,当想说明结果为“A”时,就查ASCII码表,得到“A”这个图形符号对应的数字是65,然后就告诉电脑输出序号为65的字符,最后屏幕上显示“A”。我爱电脑技术社区--打造最好的电脑技术自学交流平台' s7 P, i, b; u. z% n6 X  w6 P5 t
这明显地繁杂得异常,为此C++就提供了字符和字符串。当我们想得到某一个图形符号的ASCII码表的序号时,只需通过单引号将那个字符括起来即可,如:'A',其效果和65是一样的。当要使用不止一个字符时,则用双引号将多个字符括起来,也就是所谓的字符串了,如:"ABC"。因此字符串就是多个字符连起来而已。但根据前面的说明易发现,字符串也需要映射成数字,但它的映射就不像字符那么简单可以通过查表就搞定的,对于此,将在后续文章中对数组作过介绍后再说明。7 e: R8 k7 a, S8 }
cao作符
( m$ b. j# y; ^# D1 f+ C! @, {( S电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站. ~' y# d: {: X9 D9 A
电脑的基本是数字,那么电脑的所有cao作都是改变数字,因此很正常地C++提供了cao作数字的一些基本cao作,称作cao作符(Operator),如:+ - * / 等。任何cao作符都要返回一个数字,称为cao作符的返回值,因此cao作符就是cao作数字并返回数字的符号。作为一般性地分类,按cao作符同时作用的数字个数分为一元、二元和三元cao作符。电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站) s: h+ w" D7 v! F
一元cao作符有:
/ C/ H7 W) f. D1 _- w; K6 }9 D2 K8 N我爱电脑技术社区--打造最好的电脑技术自学交流平台
4 s1 _2 G- H3 c: ]$ p电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站2 W9 |; A1 J9 a7 x8 H8 j

, [# t! ^2 y' r8 r! Q我爱电脑技术论坛
) A4 T/ \* o% O% a: @9 ~  ]www.520diannao.com
  G7 x6 _4 \! O. I2 O) F我爱电脑技术社区--打造最好的电脑技术自学交流平台我爱电脑技术社区--打造最好的电脑技术自学交流平台. S2 t! K6 d' I  Y
www.520diannao.com% Y# m$ t$ B$ c/ g

0 L2 q3 f' d9 l+
% {3 W6 m  u9 g  p3 M
% n9 Y3 k# z* z) o5 D  ]- `& D我爱电脑技术社区--打造最好的电脑技术自学交流平台其后接数字,原封不动地返回后接的数字。如: +4.4f的返回值是4.4;+-9.3f的返回值是-9.3。完全是出于语义的需要,如表示此数为正数。
! W  ^* E0 g7 }
3 r8 C: S) Z* i3 ^我爱电脑技术论坛
' l8 k# v1 _8 w& s- C* b我爱电脑技术社区--打造最好的电脑技术自学交流平台
2 H/ n9 W4 b" P9 r打造最好的电脑自学交流论坛我爱电脑技术社区--打造最好的电脑技术自学交流平台+ H; `) @2 S8 O5 v) n
- www.520diannao.com: S( v: q; N2 d  X9 h
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站! L1 J2 l# V3 B$ {
其后接数字,将后接的数字的符号取反。如: -34.4f的返回值是-34.4;-(-54)的返回值是54。用于表示负数。 我爱电脑技术论坛$ D% x* p! D3 }
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站4 j" [! u- P6 L6 o2 Q7 Z. ~

: D$ p0 {3 a$ k# o! K) s/ Mwww.520diannao.com我爱电脑技术社区--打造最好的电脑技术自学交流平台% q. G+ l- t6 a2 X5 \
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站' @! l6 K' `0 s* Y5 v
!
+ f& g: C; l' \% y电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
  D* U$ W1 j0 T( t; W% t4 M3 X我爱电脑技术论坛其后接数字,逻辑取反后接的数字。逻辑值就是“真”或“假”,为了用数字表示逻辑值,在 C++中规定,非零值即为逻辑真,而零则为逻辑假。因此3、43.4、'A'都表示逻辑真,而0则表示逻辑假。逻辑值被应用于后续的判断及循环语句中。而逻辑取反就是先判断“!”后面接的数字是逻辑真还是逻辑假,然后再将相应值取反。如:
8 |1 x, I) ]3 ?!5的返回值是0,因为先由5非零而知是逻辑真,然后取反得逻辑假,故最后返回0。6 a9 ]5 B- D& x5 B
!!345.4的返回值是1,先因345.4非零得逻辑真,取反后得逻辑假,再取反得逻辑真。虽然只要非零就是逻辑真,但作为编译器返回的逻辑真,其一律使用1来代表逻辑真。
, \2 @$ Z# F* H& p
  _9 b( @: A# F) z0 H, X* F电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
. j6 e7 i) l/ e3 d1 |% g) K我爱电脑技术社区--打造最好的电脑技术自学交流平台8 O/ A* g0 f) k& l) c# R- D3 H
2 ?. _! |. _" e: r
~ * V: B0 C9 g1 }, \( }

# X0 ?3 F0 h& ^+ i* K6 \打造最好的电脑自学交流论坛其后接数字,取反后接的数字。取反是逻辑中定义的cao作,不能应用于数字。为了对数字应用取反cao作,电脑中将数字用二进制表示,然后对数字的每一位进行取反cao作(因为二进制数的每一位都只能为1或0,正好符合逻辑的真和假)。如~123的返回值就为-124。先将123转成二进制数01111011,然后各位取反得10000100,最后得-124。
0 j! N( z  d; r* F5 Y, f9 u! mwww.520diannao.com这里的问题就是为什么是8位而不是16位二进制数。因为123小于128,被定位为char类型,故为8位(关于char是什么将下篇介绍)。如果是~123ul,则返回值为4294967172。# [7 h( b7 _6 a! S  H7 G
为什么要有数字取反这个cao作?因为CPU提供了这样的指令。并且其还有着很不错且很重要的应用,后面将介绍。
7 Z: O% c9 R' T) e$ e# E我爱电脑技术论坛关于其他的一元cao作符将在后续文章中陆续提到(但不一定全部提到)。
( J4 s+ ~! r" _" k/ A* D* N/ W2 G8 X我爱电脑技术社区--打造最好的电脑技术自学交流平台二元cao作符有:
5 C$ w# y3 Y  S. A
# D9 C, \& a! N我爱电脑技术社区--打造最好的电脑技术自学交流平台
& u, H( Y9 H- W6 C3 O# Z4 J6 k- O; H8 t打造最好的电脑自学交流论坛我爱电脑技术论坛$ r# m% y. @3 x
我爱电脑技术论坛0 X1 T) t1 G7 q4 {% u

/ w+ D, B! h6 e打造最好的电脑自学交流论坛, w7 L  U0 H3 a( F; y2 E

, w) l: A* q. f; b$ T6 rwww.520diannao.com我爱电脑技术论坛* H! h4 q+ }, M$ n0 g$ y( l* E
+
; Z" a0 M+ U/ t# {9 k0 R( r* Mwww.520diannao.com-我爱电脑技术论坛# Q3 W5 K! i- U# Z
*打造最好的电脑自学交流论坛, z( J9 ?0 ^3 z1 g  L) \
/电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站- J/ E2 t  M- L; }8 L
%
5 }  q3 W: X; o7 {& u$ e4 e0 N1 s电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
8 L% Q; R  v% a打造最好的电脑自学交流论坛其前后各接一数字,返回两数字之和、差、积、商、余数。如:www.520diannao.com5 ~4 L6 o% l' b
34+4.4f的返回值是38.4;3+-9.3f的返回值是-6.3。
! Q& b1 n9 c2 T' T4 \/ vwww.520diannao.com34-4的返回值是30;5-234的返回值是-229。
9 p5 k6 D; I0 Z电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站3*2的返回值是6;10/3的返回值是3。
8 y1 K  Z# X7 [/ X$ d+ e* U我爱电脑技术论坛10%3的返回值是1;20%7的返回值是6。 www.520diannao.com& Y" m4 t# [" ?9 P) u8 m
我爱电脑技术论坛  |/ {8 f$ S( ~4 z
www.520diannao.com! F- v7 O0 w' a8 d* A
打造最好的电脑自学交流论坛7 [- W( y; g6 V5 J8 D! g

+ B$ w  w( \% W4 u9 C0 j&&www.520diannao.com  U6 u0 R$ W, W: o, L
||
, z# C' m+ ~' x: h& n5 w; `" H打造最好的电脑自学交流论坛电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站1 a6 ~3 D. H0 _$ K) F, C
其前后各接一逻辑值,返回两逻辑值之“与”运算逻辑值和“或”运算逻辑值。如:
5 j9 p+ {( d! a: E2 @" a8 z6 p" iwww.520diannao.com'A'&&34.3f的返回值是逻辑真,为1;34&&0的返回值是逻辑假,为0。电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站2 y2 T7 E# o, k7 N1 n' u+ y
0||'B'的返回值是逻辑真,为 1;0||0的返回值是逻辑假,为0。
: |. o* J; l( Y+ r0 w+ e我爱电脑技术社区--打造最好的电脑技术自学交流平台
, A& q2 z. o$ {/ Z) X, Z3 V
* j) S2 L+ x, Y( G) f1 H) U电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
% b1 h. w( V! X0 }www.520diannao.com
" l$ t) [0 W2 Q9 M6 D) x) D$ K&) C6 I( ~& R$ r# k3 `$ k! t/ `
|www.520diannao.com& t2 F# E. G( `7 K
^
' S8 ]& |5 R: f) Z) Twww.520diannao.com电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站0 I; M  s/ P$ v7 ^0 x5 Y6 `
其前后各接一数字,返回两数字之“与”运算、“或”运算、“异或”运算值。如前面所说,先将两侧的数字转成二进制数,然后对各位进行与、或、异或cao作。如:
/ `7 m4 p% _  Iwww.520diannao.com4&6的返回值是4,4转为00000100,6转为00000110各位相与得,00000100,为4。打造最好的电脑自学交流论坛* a. }# i* e1 G! E1 \- b9 @
4|6的返回值是6,4转为00000100,6转为00000110各位相或得,00000110,为6。电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站, p8 B" r+ x* S# j
4^6的返回值是2,4转为00000100,6转为00000110各位相异或得,00000010,为2。 www.520diannao.com; E/ D5 l2 q6 v* Z7 G8 q3 T# t( V
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站3 F# ^* r3 K+ `# \. m5 @

: g/ ]" v" Z6 u; S. Iwww.520diannao.com+ G( A% e- {- R# z2 O6 D

- \& ], h+ ?# y, s# Y打造最好的电脑自学交流论坛>
, C9 W% B; {9 c电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站<
; ]0 Q9 f* ~& _: I4 ]' c! K& Z7 r==
3 J5 u" D2 P. M我爱电脑技术论坛>=
( k  q: b# |- `$ s; }3 h$ ?我爱电脑技术论坛<=
2 O0 _1 d5 c0 C1 l( D$ m& o( P% M电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站!= 打造最好的电脑自学交流论坛& E* s- H5 \8 u0 w' I
我爱电脑技术论坛/ R# l# l4 f' u  T$ C$ a  W5 f
其前后各接一数字,根据两数字是否大于、小于、等于、大于等于、小于等于及不等于而返回相应的逻辑值。如:
1 k' k/ L  e) i9 B我爱电脑技术社区--打造最好的电脑技术自学交流平台34>34的返回值是0,为逻辑假;32<345的返回值为1,为逻辑真。打造最好的电脑自学交流论坛5 s* [( x3 [" J% [
23>=23和23>=14的返回值都是1,为逻辑真;54<=4的返回值为0,为逻辑假。
. f7 H0 \' E0 i7 P2 o# t9 j& i56==6的返回值是0,为逻辑假;45==45的返回值是1,为逻辑真。
( ^; D! _! {& T$ I2 S  J. B7 v5!=5的返回值是0,为逻辑假;5!=35的返回值是真,为逻辑真。 打造最好的电脑自学交流论坛" D/ o5 P8 B* c

6 {2 i2 C, W" o0 {. [  A我爱电脑技术社区--打造最好的电脑技术自学交流平台电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站& G' K$ g; |2 e

/ H9 q; W: i$ U  u( D$ W打造最好的电脑自学交流论坛
; s8 y3 p: B0 \9 p>>打造最好的电脑自学交流论坛- Q) Y: ~* |8 o4 i
<<
3 `2 H. }& B5 C  y7 Owww.520diannao.com
2 M. A( [/ E4 q# x; ^8 m电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站其前后各接一数字,将左侧数字右移或左移右侧数字指定的位数。与前面的 ~、&、|等cao作一样,之所以要提供左移、右移cao作主要是因为CPU提供了这些指令,主要用于编一些基于二进制数的算法。打造最好的电脑自学交流论坛, l- ]* S( ]) T" O
<<将左侧的数字转成二进制数,然后将各位向左移动右侧数值的位数,如:4,转为00000100,左移2位,则变成00010000,得16。
1 y$ c, i5 i8 a2 ^  v/ k7 [6 K>>与<<一样,只不过是向右移动罢了。如:6,转为00000110,右移1位,变成00000011,得3。如果移2位,则有一位超出,将截断,则6>>2的返回值就是00000001,为1。5 U) }, ?# H3 }! Q, ~# Q
左移和右移有什么用?用于一些基于二进制数的算法,不过还可以顺便作为一个简单的优化手段。考虑十进制数3524,我们将它左移2位,变成352400,比原数扩大了100倍,准确的说应该是扩大了10的2次方倍。如果将3524右移2位,变成35,相当于原数除以100的商。
3 x! Q# k1 z; S; G" K# N7 a我爱电脑技术社区--打造最好的电脑技术自学交流平台同样,前面4>>2,等效于4/4的商;32>>3相当于32/8,即相当于32除以2的3次方的商。而4<<2等效于4*4,相当于4乘以2的2次方。因此左移和右移相当于乘法和除法,只不过只能是乘或除相应进制数的次方罢了,但它的运行速度却远远高于乘法和除法,因此说它是一种简单的优化手段。 打造最好的电脑自学交流论坛; X+ v9 l# ]* }, a4 j: I! a0 |0 P
* r5 a' J! v) b! G4 r$ L3 O
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站* F! u8 |' F% m1 @7 t

, S5 o0 ~$ A" a5 G0 d; w: S电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站6 W5 s! o. d. e, P. {8 B( P
, ( u% C1 d7 x# `$ V- L' Z: y! D
; a& k9 l) e8 O' l3 X& l
其前后各接一数字,简单的返回其右侧的数字。如:我爱电脑技术社区--打造最好的电脑技术自学交流平台* L  C+ Z5 |4 f* j! p
34.45f,54的返回值是54;-324,4545f的返回值是4545f。
4 [0 Z+ b- L8 y打造最好的电脑自学交流论坛那它到底有什么用?用于将多个数字整和成一个数字,在《C++从零开始(四)》中将进一步说明。 我爱电脑技术论坛7 N( D9 C4 V$ x. ~  `& Y
关于其他的二元cao作符将在后续文章中陆续提到(但不一定全部提到)。
- m. ~7 X1 n7 Z) U/ C+ r6 F5 d我爱电脑技术社区--打造最好的电脑技术自学交流平台三元cao作符只有一个,为:,其格式为:<数字1><数字2>:<数字3>。它的返回值为:如果<数字1>是逻辑真,返回<数字2>,否则返回<数字3>。如:我爱电脑技术论坛1 j+ q  d2 ^5 ~' }4 ]! c& b
344:2的返回值就是4,因为34非零,为逻辑真,返回4。而04:2的返回值就是2,因为0为逻辑假,返回2。 www.520diannao.com" e4 G3 L- E/ T% P5 T2 P- E, l

' k- d% Q; r: h: n* o; D" Q5 q0 s. {我爱电脑技术论坛
! ?% l+ _$ ~* w0 B0 E7 Z电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站表达式 你应该发现前面的荒谬之处了——12>435返回值为0,那为什么不直接写0还吃饱了撑了写个12>435在那?这就是表达式的意义了。
7 D5 e8 k; S1 b, m5 Y打造最好的电脑自学交流论坛前面说“>”的前后各接一数字,但是cao作符是cao作数字并返回数字的符号,因为它返回数字,因此可以放在上面说的任何一个要求接数字的地方,也就形成了所谓的表达式。如:23*54/45>34的返回值就是0,因为23*54的返回值为1242;然后又将1242作为“/”的左接数字,得到新的返回值27.6;最后将27.6作为“>”的左接数字进而得到返回值0,为逻辑假。
! I1 _- k) ]+ |$ l因此表达式就是由一系列返回数字的东西和cao作符组合而成的一段代码,其由于是由cao作符组成的,故一定返回值。而前面说的“返回数字的东西”则可以是另一个表达式,或者一个变量,或者一个具有返回值的函数,或者具有数字类型cao作符重载的类的对象等,反正只要是能返回一个数字的东西。如果对于何谓变量、函数、类等这些名词感到陌生,不需要去管它们,在后继的文章中将会一一说明。6 ^) d  k( W. h. I; Q
因此34也是一个表达式,其返回值为34,只不过是没有cao作符的表达式罢了(在后面将会了解到34其实是一种cao作符)。故表达式的概念其实是很广的,只要有返回值的东西就可以称为表达式。
! C1 X; T4 c8 F9 a! ~7 N( o( \www.520diannao.com由于表达式里有很多cao作符,执行cao作符的顺序依赖于cao作符的优先级,就和数学中的一样,*、/的优先级大于+、-,而+、-又大于>、<等逻辑cao作符。不用去刻意记住cao作符的优先级,当不能确定cao作符的执行顺序时,可以使用小括号来进行指定。如:
; P, T1 i' [! u9 `6 _4 V) V# u, ?我爱电脑技术论坛((1+2)*3)+3)/4的返回值为3,而1+2*3+3/4的返回值为7。注意3/4为0,因为3/4的商是0。当希望进行浮点数除法或乘法时,只需让cao作数中的某一个为浮点数即可,如:3/4.0的返回值为0.75。
+ ~! N8 y2 R6 X/ V' e( x# r& | ^ ~等的应用电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站* O  A& f  I' H, p9 D' `5 H/ {

! G5 N# Q* ?3 E2 r我爱电脑技术社区--打造最好的电脑技术自学交流平台前面提过逻辑cao作符“&&”、“||”、“!”等,作为表示逻辑,其被C++提供一点都不值得惊奇。但是为什么要有一个将数字转成二进制数,然后对二进制数的各位进行逻辑cao作的这么一类cao作符呢?首先是CPU提供了相应的指令,并且其还有着下面这个非常有意义的应用。www.520diannao.com5 {/ U+ l2 g' V! b" V0 H- _
考虑一十字路口,每个路口有三盏红绿灯,分别指明能否左转、右转及直行。共有12盏,现在要为它编写一个控制程序,不管这程序的功能怎样,首先需要将红绿灯的状态转化为数字,因为电脑只知道数字。所以用3个数字分别表示某路口的三盏红绿灯,因此每个红绿灯的状态由一个数字来表示,假设红灯为0,绿灯为1(不考虑黄灯或其他情况)。www.520diannao.com0 U& ]9 p& B7 g- Y  ]9 v0 Z
后来忽然发现,其实也可以用一个数字表示一个路口的三盏红绿灯状态,如用110表示左转绿灯、直行绿灯而右转红灯。上面的110是一个十进制数字,它的每一位实际都可以为0~9十个数字,但是这里只应用到了两个:0和1,感觉很浪费。故选择二进制数来表示,还是110,但是是二进制数了,转成十进制数为6,即使当为111时转成十进制数也只是7,比前面的110这个十进制数小多了,节约了……??什么??
$ F# d- t. P9 u+ N打造最好的电脑自学交流论坛我们在纸上写数字235425234一定比写134这个数字要更多地占用纸张(假设字都一样大)。因此记录一个大的数比记录一个小的数要花费更多的资源。简直荒谬!不管是100还是1000,都只是一个数字,为什么记录大的数字就更费资源?因为电脑并不是数字计算机,而是电子计算机,它是基于状态而不是基于数字的,这在下篇会详细说明。电脑必须使用某种表示方式来代表一个数字,而那个表示方式和二进制很像,但并不是二进制数,故出现记录大的数较小的数更耗资源,这也就是为什么上面整型数要分什么长整型短整型的原因了。www.520diannao.com6 t8 n/ o% @6 d+ k, B6 F
下面继续上面的思考。使用了110这个二进制数来表示三盏红绿灯的状态,那么现在要知道110这个数字代表左转红绿灯的什么状态。以数字的第三位表示左转,不过电脑并不知道这个,因此如下:110&100。这个表达式的返回值是100,非零,逻辑真。假设某路口的状态为010,则同样的010&100,返回值为0,逻辑假。因此使用“&”cao作符可以将二进制数中的某一位或几位的状态提取出来。所以我们要了解一个数字代表的红绿灯状态中的左转红绿灯是否绿灯时,只需让它和100相与即可。
% Z0 m1 p! o0 h' }3 U; O现在要保持其他红绿灯的状态不变,仅仅使左转红绿灯为绿灯,如当前状态为010,为了使左转红绿灯为绿灯,值应该为110,这可以通过010|100做到。如果当前状态是001,则001|100为101,正确——直行和右转的红绿灯状态均没有发生变化。因此使用“|”cao作符可以给一个二进制数中的某一位或几位设置状态,但只能设置为1,如果想设置为0,如101,要关掉左转的绿灯,则101&~100,返回值为001。
2 j5 d7 n$ X+ K" f4 S打造最好的电脑自学交流论坛上面一直提到的路口红绿灯的状态实际编写时可以使用一个变量来表示,而上面的100也可以用一个标识符来表示,如state&TS_LEFT,就可以表示检查变量state所表示的状态中的左转红绿灯的状态。
" D+ I, B. B( b打造最好的电脑自学交流论坛上面的这种方法被大量地运用,如创建一个窗口,一个窗口可能有二三十个风格,则通过上面的方法,就可以只用一个32位长的二进制数字就表示了窗口的风格,而不用去弄二三十个数字来分别代表每种风格是否具有。

TOP

C++从零开始(三)——何谓变量我爱电脑技术论坛& |# C' Q5 n5 ?* K
本篇说明内容是C++中的关键,基本大部分人对于这些内容都是昏的,但这些内容又是编程的基础中的基础,必须详细说明。
2 V6 {. g% Q6 G8 T' q+ p数字表示 数学中,数只有数值大小的不同,绝不会有数值占用空间的区别,即数学中的数是逻辑上的一个概念,但电脑不是。考虑算盘,每个算盘上有很多列算子,每列都分成上下两排算子。上排算子有2个,每个代表5,下排算子有4个,每个代表1(这并不重要)。因此算盘上的每列共有6个算子,每列共可以表示0到14这15个数字(因为上排算子的可能状态有0到2个算子有效,而下排算子则可能有0到4个算子有效,故为3×5=15种组合方式)。
8 C. Q' c* @; ]上面的重点就是算盘的每列并没有表示0到14这15个数字,而是每列有15种状态,因此被人利用来表示数字而已(这很重要)。由于算盘的每列有15个状态,因此用两列算子就可以有15×15=225个状态,因此可以表示0到224。阿拉伯数字的每一位有0到9这10个图形符号,用两个阿拉伯数字图形符号时就能有10×10=100个状态,因此可以表示0到99这100个数。
3 |9 [' [+ Z8 j0 w0 d2 W+ \# N这里的算盘其实就是一个基于15进制的记数器(可以通过维持一列算子的状态来记录一位数字),它的一列算子就相当于一位阿拉伯数字,每列有15种状态,故能表示从0到14这15个数字,超出14后就必须通过进位来要求另一列算子的加入以表示数字。电脑与此一样,其并不是数字计算机,而是电子计算机,电脑中通过一根线的电位高低来表示数字。一根线中的电位规定只有两种状态——高电位和低电位,因此电脑的数字表示形式是二进制的。
9 b6 Q8 h& Q: [- @0 w) y打造最好的电脑自学交流论坛和上面的算盘一样,一根电线只有两个状态,当要表示超出1的数字时,就必须进位来要求另一根线的加入以表示数字。所谓的32位电脑就是提供了32根线(被称作数据总线)来表示数据,因此就有2的32次方那么多种状态。而16根线就能表示2的16次方那么多种状态。
8 H9 }% K* [8 }0 Z% Swww.520diannao.com所以,电脑并不是基于二进制数,而是基于状态的变化,只不过这个状态可以使用二进制数表示出来而已。即电脑并不认识二进制数,这是下面“类型”一节的基础。打造最好的电脑自学交流论坛/ c' b" i' R# ^& f0 C# P; y$ S
内存 内存就是电脑中能记录数字的硬件,但其存储速度很快(与硬盘等低速存储设备比较),又不能较长时间保存数据,所以经常被用做草稿纸,记录一些临时信息。
  z- F% A5 b7 |: L5 L# V打造最好的电脑自学交流论坛前面已经说过,32位计算机的数字是通过32根线上的电位状态的组合来表示的,因此内存能记录数字,也就是能维持32根线上各自的电位状态(就好象算盘的算子拨动后就不会改变位置,除非再次拨动它)。不过依旧考虑上面的算盘,假如一个算盘上有15列算子,则一个算盘能表示15的15次方个状态,是很大的数字,但经常实际是不会用到变化那么大的数字的,因此让一个算盘只有两列算子,则只能表示225个状态,当数字超出时就使用另一个或多个算盘来一起表示。
. y1 A* L8 c: k; @8 E1 K' q& e- U电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站上面不管是2列算子还是15列算子,都是算盘的粒度,粒度分得过大造成不必要的浪费(很多列算子都不使用),太小又很麻烦(需要多个算盘)。电脑与此一样。2的32次方可表示的数字很大,一般都不会用到,如果直接以32位存储在内存中势必造成相当大的资源浪费。于是如上,规定内存的粒度为8位二进制数,称为一个内存单元,而其大小称为一个字节(Byte)。就是说,内存存储数字,至少都会记录8根线上的电位状态,也就是2的8次方共256种状态。所以如果一个32位的二进制数要存储在内存中,就需要占据4个内存单元,也就是4个字节的内存空间。
) a' t9 f  p  v( ]' E- b2 _我们在纸上写字,是通过肉眼判断出字在纸上的相对横坐标和纵坐标以查找到要看的字或要写字的位置。同样,由于内存就相当于草稿纸,因此也需要某种定位方式来定位,在电脑中,就是通过一个数字来定位的。这就和旅馆的房间号一样,内存单元就相当于房间(假定每个房间只能住一个人),而前面说的那个数字就相当于房间号。为了向某块内存中写入数据(就是使用某块内存来记录数据总线上的电位状态),就必须知道这块内存对应的数字,而这个数字就被称为地址。而通过给定的地址找到对应的内存单元就称为寻址。
: s* F2 h( Z) W/ E  X" B1 j  D打造最好的电脑自学交流论坛因此地址就是一个数字,用以唯一标识某一特定内存单元。此数字一般是32位长的二进制数,也就可以表示4G个状态,也就是说一般的32位电脑都具有4G的内存空间寻址能力,即电脑最多装4G的内存,如果电脑有超过4G的内存,此时就需要增加地址的长度,如用40位长的二进制数来表示。
5 Q, B* ^' t/ `' s, m/ x3 R类型
, _2 p8 B7 L  a0 C9 d$ l2 O电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站在本系列最开头时已经说明了何谓编程,而刚才更进一步说明了电脑其实连数字都不认识,只是状态的记录,而所谓的加法也只是人为设计那个加法器以使得两个状态经过加法器的处理而生成的状态正好和数学上的加法的结果一样而已。这一切的一切都只说明一点:电脑所做的工作是什么,全视使用的人以为是什么。
* r' O( f! T0 D, [我爱电脑技术社区--打造最好的电脑技术自学交流平台因此为了利用电脑那很快的“计算”能力(实际是状态的变换能力),人为规定了如何解释那些状态。为了方便其间,对于前面提出的电位的状态,我们使用1位二进制数来表示,则上面提出的状态就可以使用一个二进制数来表示,而所谓的“如何解释那些状态”就变成了如何解释一个二进制数。
5 y. \. Z6 j; s6 G# b- W6 ?% [- j电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站C++是高级语言,为了帮助解释那些二进制数,提供了类型这个概念。类型就是人为制订的如何解释内存中的二进制数的协议。C++提供了下面的一些标准类型定义。
+ F- h/ y3 @/ f" z打造最好的电脑自学交流论坛www.520diannao.com, t. r8 f! J) i
" A; O* D7 n" D* R0 M+ x
我爱电脑技术论坛' e. o" n/ m  P% L1 i) y

# E' X' C8 d2 ?( ?# w; @www.520diannao.comsignedchar
" z4 A9 D+ y  a! s打造最好的电脑自学交流论坛表示所指向的内存中的数字使用补码形式,表示的数字为-128到+127,长度为1个字节 + M# h$ G4 m# j) X

, c2 ]- E2 g. Z+ Q0 k( [打造最好的电脑自学交流论坛1 V3 N0 o) H- b3 h* C$ ~
unsignedchar . Y& X4 {& o8 g4 y
表示所指向的内存中的数字使用原码形式,表示的数字为0到255,长度为1个字节 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站! v6 Q0 Z! C6 o- |$ n- J
) Q& L4 \: B/ [% `3 }

) H& _9 D& u+ twww.520diannao.comsignedshort 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站2 |. j& X! _! W% I7 l& b% g1 n
表示所指向的内存中的数字使用补码形式,表示的数字为–32768到+32767,长度为2个字节 打造最好的电脑自学交流论坛: s( f1 w0 l, p0 d: @
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站" j1 K+ L% G8 r+ J

8 F" J! L6 r4 I# [打造最好的电脑自学交流论坛unsignedshort 我爱电脑技术社区--打造最好的电脑技术自学交流平台2 V4 E! C1 N  n# ^/ b( ^& ]- T7 s8 r$ U
表示所指向的内存中的数字使用原码形式,表示的数字为0到65535,长度为2个字节
: P1 O9 v5 f2 Z: M6 B我爱电脑技术社区--打造最好的电脑技术自学交流平台
7 n8 [/ c% o- q4 [4 d打造最好的电脑自学交流论坛, U2 @( O& K8 e8 S
signedlong 我爱电脑技术论坛& C- Q7 E" B) G/ k; f
表示所指向的内存中的数字使用补码形式,表示的数字为-2147483648到+2147483647,长度为4个字节 打造最好的电脑自学交流论坛, W  d2 l% ?7 w3 g4 }, R$ n, G3 W# y
www.520diannao.com! S( w4 g: J. N3 w+ ~* _

7 @+ c* b' w, H" [打造最好的电脑自学交流论坛unsignedlong
& h0 N2 ?: ]' b1 P6 P2 b9 H打造最好的电脑自学交流论坛表示所指向的内存中的数字使用原码形式,表示的数字为0到4294967295,长度为4个字节 我爱电脑技术社区--打造最好的电脑技术自学交流平台# ~  O; |) o  P5 @$ d9 d

/ V" |7 V. {, ?. W" }/ d, G$ k我爱电脑技术论坛' _: t& g* P0 b, i5 V8 ^& K
signedint; o: t% O1 N0 U" C

! w5 n5 [: k) _) E( K+ Pwww.520diannao.com表示所指向的内存中的数字使用补码形式,表示的数字则视编译器。如果编译器编译时被指明编译为在16位cao作系统上运行,则等同于signedshort;如果是编译为32位的,则等同于signedlong;如果是编译为在64位cao作系统上运行,则为8个字节长,而范围则如上一样可以自行推算出来。 ' z: q7 k0 N) ~
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站* ^, @8 r& m' n4 ]/ j0 \/ S, X
www.520diannao.com9 q8 ~. G8 e3 ]) W) M! z: u. L
unsignedint 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站' P: D" P+ G* k1 a% C
表示所指向的内存中的数字使用原码形式,其余和signedint一样,表示的是无符号数。
* s. [! T$ ]9 d0 `" \+ n: f; H打造最好的电脑自学交流论坛
7 M6 S: v2 H% J" ]8 \$ T. ~我爱电脑技术论坛电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站8 m$ u: g* J3 L6 g& S, Q' I5 j) S
bool 我爱电脑技术社区--打造最好的电脑技术自学交流平台" t* w$ I# i% T4 V
表示所指向的内存中的数字为逻辑值,取值为false或true。长度为1个字节。
! I/ @- p* }( K  o1 Y0 y6 d我爱电脑技术社区--打造最好的电脑技术自学交流平台
7 C+ j  o' Q- [( `我爱电脑技术社区--打造最好的电脑技术自学交流平台
7 ?+ _9 Q4 E1 |0 k4 R电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站float 打造最好的电脑自学交流论坛3 {% `$ x5 X: S4 o
表示所指向的内存按IEEE标准进行解释,为real*4,占用4字节内存空间,等同于上篇中提到的单精度浮点数。
6 ?+ h1 O! a) l) [- C2 \1 B4 |( Z# i电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站我爱电脑技术社区--打造最好的电脑技术自学交流平台* V7 P7 w0 C2 y3 W7 R3 i! E5 b
我爱电脑技术社区--打造最好的电脑技术自学交流平台: H$ z; k3 ~# Z
double
# I1 A" y8 q  I$ D- A  H1 r+ E我爱电脑技术社区--打造最好的电脑技术自学交流平台表示所指向的内存按IEEE标准进行解释,为real*8,可表示数的精度较float高,占用8字节内存空间,等同于上篇提到的双精度浮点数。 打造最好的电脑自学交流论坛8 v6 K9 W- I- q: t. @' j

4 {( L8 t: n) {( f3 r我爱电脑技术论坛www.520diannao.com5 K) c/ v2 f9 m9 n
longdouble
5 Q2 e' G& C) v8 Dwww.520diannao.com表示所指向的内存按IEEE标准进行解释,为real*10,可表示数的精度较double高,但在为32位Windowscao作系统编写程序时,仍占用8字节内存空间,等效于double,只是如果CPU支持此类浮点类型则还是可以进行这个精度的计算。
# ?3 b( b( v1 Y, W- ?我爱电脑技术论坛标准类型不止上面的几个,后面还会陆续提到。
  k2 f1 d# a" U; a, y我爱电脑技术论坛上面的长度为2个字节也就是将两个连续的内存单元中的数字取出并合并在一起以表示一个数字,这和前面说的一个算盘表示不了的数字,就进位以加入另一个算盘帮助表示是同样的道理。我爱电脑技术论坛* d2 s* |3 U8 N9 }2 `5 T
上面的signed关键字是可以去掉的,即char等同于signed char,用以简化代码的编写。但也仅限于signed,如果是unsigned char,则在使用时依旧必须是unsigned char。
0 N5 l( z; a% l' X1 ?我爱电脑技术社区--打造最好的电脑技术自学交流平台现在应该已经了解上篇中为什么数字还要分什么有符号无符号、长整型短整型之类的了,而上面的short、char等也都只是长度不同,这就由程序员自己根据可能出现的数字变化幅度来进行选用了。打造最好的电脑自学交流论坛& }# B1 A* x% c! ]& `
类型只是对内存中的数字的解释,但上面的类型看起来相对简单了点,且语义并不是很强,即没有什么特殊意思。为此,C++提供了自定义类型,也就是后继文章中将要说明的结构、类等。 www.520diannao.com0 v$ c5 @9 }! O3 |; J' U
我爱电脑技术论坛( x2 P3 ~. V/ `5 d8 _, J
变量 在本系列的第一篇中已经说过,电脑编程的绝大部分工作就是cao作内存,而上面说了,为了cao作内存,需要使用地址来标识要cao作的内存块的首地址(上面的long表示连续的4个字节内存,其第一个内存单元的地址称作这连续4个字节内存块的首地址)。为此我们在编写程序时必须记下地址。电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站' z) e* W3 G. c5 i1 p( ]
做5+2/3-5*2的计算,先计算出2/3的值,写在草稿纸上,接着算出5*2的值,又写在草稿纸上。为了接下来的加法和减法运算,必须能够知道草稿纸上的两个数字哪个是2/3的值哪个是5*2的值。人就是通过记忆那两个数在纸上的位置来记忆的,而电脑就是通过地址来标识的。但电脑只会做加减乘除,不会去主动记那些2/3、5*2的中间值的位置,也就是地址。因此程序员必须完成这个工作,将那两个地址记下来。
+ U9 F; |" K' k" t' i) ~' E打造最好的电脑自学交流论坛问题就是这里只有两个值,也许好记一些,但如果多了,人是很难记住哪个地址对应哪个值的,但人对符号比对数字要敏感得多,即人很容易记下一个名字而不是一个数字。为此,程序员就自己写了一个表,表有两列,一列是“2/3的值”,一列是对应的地址。如果式子稍微复杂点,那么那个表可能就有个二三十行,而每写一行代码就要去翻查相应的地址,如果来个几万行代码那是人都不能忍受。
+ m5 x+ s: f* _9 ]. M2 r) _www.520diannao.comC++作为高级语言,很正常地提供了上面问题的解决之道,就是由编译器来帮程序员维护那个表,要查的时候是编译器去查,这也就是变量的功能。打造最好的电脑自学交流论坛3 M% f  B7 ]3 K( P2 ^# k' Q' f
变量是一个映射元素。上面提到的表由编译器维护,而表中的每一行都是这个表的一个元素(也称记录)。表有三列:变量名、对应地址和相应类型。变量名是一个标识符,因此其命名规则完全按照上一篇所说的来。当要对某块内存写入数据时,程序员使用相应的变量名进行内存的标识,而表中的对应地址就记录了这个地址,进而将程序员给出的变量名,一个标识符,映射成一个地址,因此变量是一个映射元素。而相应类型则告诉编译器应该如何解释此地址所指向的内存,是2个连续字节还是4个?是原码记录还是补码?而变量所对应的地址所标识的内存的内容叫做此变量的值。
6 p7 H3 p/ }$ o* x. I. ~有如下的变量解释:“可变的量,其相当于一个盒子,数字就装在盒子里,而变量名就写在盒子外面,这样电脑就知道我们要处理哪一个盒子,且不同的盒子装不同的东西,装字符串的盒子就不能装数字。”上面就是我第一次学习编程时,书上写的(是BASIC语言)。对于初学者也许很容易理解,也不能说错,但是造成的误解将导致以后的程序编写地千疮百孔。
% B2 [) `6 f" c" x5 w6 p8 x2 p电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站上面的解释隐含了一个意思——变量是一块内存。这是严重错误的!如果变量是一块内存,那么C++中著名的引用类型将被弃置荒野。变量实际并不是一块内存,只是一个映射元素,这是致关重要的。
3 G4 I- t  J& y7 F/ M0 M9 p. c内存的种类 前面已经说了内存是什么及其用处,但内存是不能随便使用的,因为cao作系统自己也要使用内存,而且现在的cao作系统正常情况下都是多任务cao作系统,即可同时执行多个程序,即使只有一个CPU。因此如果不对内存访问加以节制,可能会破坏另一个程序的运作。比如我在纸上写了2/3的值,而你未经我同意且未通知我就将那个值擦掉,并写上5*2的值,结果我后面的所有计算也就出错了。
' m1 l7 U8 F/ }& A& Z8 }电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站因此为了使用一块内存,需要向cao作系统申请,由cao作系统统一管理所有程序使用的内存。所以为了记录一个long类型的数字,先向cao作系统申请一块连续的4字节长的内存空间,然后cao作系统就会在内存中查看,看是否还有连续的4个字节长的内存,如果找到,则返回此4字节内存的首地址,然后编译器编译的指令将其记录在前面提到的变量表中,最后就可以用它记录一些临时计算结果了。www.520diannao.com, R' |/ f) q6 P. y% @
上面的过程称为要求cao作系统分配一块内存。这看起来很不错,但是如果只为了4个字节就要求cao作系统搜索一下内存状况,那么如果需要100个临时数据,就要求cao作系统分配内存100次,很明显地效率低下(无谓的99次查看内存状况)。因此C++发现了这个问题,并且cao作系统也提出了相应的解决方法,最后提出了如下的解决之道。
2 I# s0 d( _- w. W+ Z9 J0 i栈(Stack) 任何程序执行前,预先分配一固定长度的内存空间,这块内存空间被称作栈(这种说法并不准确,但由于实际涉及到线程,在此为了不将问题复杂化才这样说明),也被叫做堆栈。那么在要求一个4字节内存时,实际是在这个已分配好的内存空间中获取内存,即内存的维护工作由程序员自己来做,即程序员自己判断可以使用哪些内存,而不是cao作系统,直到已分配的内存用完。
3 G9 {& q7 P1 w- m7 l7 @我爱电脑技术论坛很明显,上面的工作是由编译器来做的,不用程序员cao心,因此就程序员的角度来看什么事情都没发生,还是需要像原来那样向cao作系统申请内存,然后再使用。我爱电脑技术社区--打造最好的电脑技术自学交流平台) q$ |: |1 ^; \0 c
但工作只是从cao作系统变到程序自己而已,要维护内存,依然要耗费CPU的时间,不过要简单多了,因为不用标记一块内存是否有人使用,而专门记录一个地址。此地址以上的内存空间就是有人正在使用的,而此地址以下的内存空间就是无人使用的。之所以是以下的空间为无人使用而不是以上,是当此地址减小到0时就可以知道堆栈溢出了(如果你已经有些基础,请不要把0认为是虚拟内存地址,关于虚拟内存将会在《C++从零开始(十八)》中进行说明,这里如此解释只是为了方便理解)。而且CPU还专门对此法提供了支持,给出了两条指令,转成汇编语言就是push和pop,表示压栈和出栈,分别减小和增大那个地址。
  C' M5 k; P" K7 L, }4 N  R! f电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站而最重要的好处就是由于程序一开始执行时就已经分配了一大块连续内存,用一个变量记录这块连续内存的首地址,然后程序中所有用到的,程序员以为是向cao作系统分配的内存都可以通过那个首地址加上相应偏移来得到正确位置,而这很明显地由编译器做了。因此实际上等同于在编译时期(即编译器编译程序的时候)就已经分配了内存(注意,实际编译时期是不能分配内存的,因为分配内存是指程序运行时向cao作系统申请内存,而这里由于使用堆栈,则编译器将生成一些指令,以使得程序一开始就向cao作系统申请内存,如果失败则立刻退出,而如果不退出就表示那些内存已经分配到了,进而代码中使用首地址加偏移来使用内存也就是有效的),但坏处也就是只能在编译时期分配内存。我爱电脑技术论坛; W! e* ~, K! K1 ?2 B3 ]
堆(Heap) 上面的工作是编译器做的,即程序员并不参与堆栈的维护。但上面已经说了,堆栈相当于在编译时期分配内存,因此一旦计算好某块内存的偏移,则这块内存就只能那么大,不能变化了(如果变化会导致其他内存块的偏移错误)。比如要求客户输入定单数据,可能有10份定单,也可能有100份定单,如果一开始就定好了内存大小,则可能造成不必要的浪费,又或者内存不够。打造最好的电脑自学交流论坛: w# C4 x9 i* G1 m6 Y7 W: a3 i% r
为了解决上面的问题,C++提供了另一个途径,即允许程序员有两种向cao作系统申请内存的方式。前一种就是在栈上分配,申请的内存大小固定不变。后一种是在堆上分配,申请的内存大小可以在运行的时候变化,不是固定不变的。
2 x( r7 u9 s% K3 d: i1 P5 R电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站那么什么叫堆?在Windowscao作系统下,由cao作系统分配的内存就叫做堆,而栈可以认为是在程序开始时就分配的堆(这并不准确,但为了不复杂化问题,故如此说明)。因此在堆上就可以分配大小变化的内存块,因为是运行时期即时分配的内存,而不是编译时期已计算好大小的内存块。www.520diannao.com  w" `4 ~8 z, B* A% |
变量的定义
" _( {  W% C' i  o) D  wwww.520diannao.com上面说了那么多,你可能看得很晕,毕竟连一个实例都没有,全是文字,下面就来帮助加深对上面的理解。
" A2 G5 R3 M0 Xwww.520diannao.com定义一个变量,就是向上面说的由编译器维护的变量表中添加元素,其语法如下:
  V% _; q  N# c3 f/ K我爱电脑技术社区--打造最好的电脑技术自学交流平台long a;
3 [0 d+ l* P, U# f, W+ J) R9 T5 ~  S" P我爱电脑技术社区--打造最好的电脑技术自学交流平台先写变量的类型,然后一个或多个空格或制表符(\t)或其它间隔符,接着变量的名字,最后用分号结束。要同时定义多个变量,则各变量间使用逗号隔开,如下:
2 y4 x. @( m7 j电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站long a, b, c; unsigned short e, a_34c;
$ I% f9 x" g% L+ e1 N$ Z  c# s我爱电脑技术论坛上面是两条变量定义语句,各语句间用分号隔开,而各同类型变量间用逗号隔开。而前面的式子5+2/3-5*2,则如下书写。打造最好的电脑自学交流论坛. S$ r1 ^, F8 z8 Y3 o) L0 q
long a = 2/3, b = 5*2; long c = 5 + a – b;
$ i/ ?. I% h0 v- ?' u+ |* a( r* b打造最好的电脑自学交流论坛可以不用再去记那烦人的地址了,只需记着a、b这种简单的标识符。当然,上面的式子不一定非要那么写,也可以写成:long c = 5 + 2 / 3 – 5 * 2; 而那些a、b等中间变量编译器会自动生成并使用(实际中编译器由于优化的原因将直接计算出结果,而不会生成实际的计算代码)。) }0 n7 |3 ]6 m6 c
下面就是问题的关键,定义变量就是添加一个映射。前面已经说了,这个映射是将变量名和一个地址关联,因此在定义一个变量时,编译器为了能将变量名和某个地址对应起来,帮程序员在前面提到的栈上分配了一块内存,大小就视这个变量类型的大小。如上面的a、b、c的大小都是4个字节,而e、a_34c的大小都是2个字节。
: i2 ~  [0 W- F1 h3 @) A打造最好的电脑自学交流论坛假设编译器分配的栈在一开始时的地址是1000,并假设变量a所对应的地址是1000-56,则b所对应的地址就是1000-60,而c所对应的就是1000-64,e对应的是1000-66,a_34c是1000-68。如果这时b突然不想是4字节了,而希望是8字节,则后续的c、e、a_34c都将由于还是原来的偏移位置而使用了错误的内存,这也就是为什么栈上分配的内存必须是固定大小。打造最好的电脑自学交流论坛! L# e0 P  x( u2 U" L9 e+ L
考虑前面说的红色文字:“变量实际并不是一块内存,只是一个映射元素”。可是只要定义一个变量,就会相应地得到一块内存,为什么不说变量就是一块内存?上面定义变量时之所以会分配一块内存是因为变量是一个映射元素,需要一个对应地址,因此才在栈上分配了一块内存,并将其地址记录到变量表中。但是变量是可以有别名的,即另一个名字。这个说法是不准确的,应该是变量所对应的内存块有另一个名字,而不止是这个变量的名字。
* a' V* P: g5 y. F打造最好的电脑自学交流论坛为什么要有别名?这是语义的需要,表示既是什么又是什么。比如一块内存,里面记录了老板的信息,因此起名为Boss,但是老板又是另一家公司的行政经理,故变量名应该为Manager,而在程序中有段代码是老板的公司相关的,而另一段是老板所在公司相关的,在这两段程序中都要使用到老板的信息,那到底是使用Boss还是Manager?其实使用什么都不会对最终生成的机器代码产生什么影响,但此处出于语义的需要就应该使用别名,以期从代码上表现出所编写程序的意思。
" Z, b  E5 t+ l& }( ?0 W* U打造最好的电脑自学交流论坛在C++中,为了支持变量别名,提供了引用变量这个概念。要定义一个引用变量,在定义变量时,在变量名的前面加一个“&”,如下书写:打造最好的电脑自学交流论坛$ B# N% P: z$ t4 f% a% e
long a; long &a1 = a, &a2 = a, &a3 = a2;我爱电脑技术论坛1 K1 Q4 w. z5 x+ K: Q
上面的a1、a2、a3都是a所对应的内存块的别名。这里在定义变量a时就在栈上分配了一块4字节内存,而在定义a1时却没有分配任何内存,直接将变量a所映射的地址作为变量a1的映射地址,进而形成对定义a时所分配的内存的别名。因此上面的Boss和Manager,应该如下(其中Person是一个结构或类或其他什么自定义类型,这将在后继的文章中陆续说明):
2 U0 l& Y! {! c+ E! ]我爱电脑技术论坛Person Boss; Person &Manager = Boss;
1 E% q' f% D3 |# a3 N5 o我爱电脑技术社区--打造最好的电脑技术自学交流平台由于变量一旦定义就不能改变(指前面说的变量表里的内容,不是变量的值),直到其被删除,所以上面在定义引用变量的时候必须给出欲别名的变量以初始化前面的变量表,否则编译器编译时将报错。电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站4 C6 H' J' F+ J# I
现在应该就更能理解前面关于变量的红字的意思了。并不是每个变量定义时都会分配内存空间的。而关于如何在堆上分配内存,将在介绍完指针后予以说明,并进而说明上一篇遗留下来的关于字符串的问题。