版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++簡單程式設計1.1C++語言概述
1.1.1從C到C++C++語言是從C語言發展演變而來的,因此在介紹C++語言之前,我們首先介紹一下C語言。C語言最初是美國貝爾實驗室的戴尼斯·M·利奇(Dennis.M.Ritchie)在B語言基礎上開發出來的,並於1972年在一臺PDP-11電腦上實現了最初的C語言。目前,比較流行的C語言版本基本上都是以ANSIC為基礎的。C語言具有以下優點:
①語言簡潔靈活。
②運算符和數據結構豐富,具有結構化控制語句,程式執行效率高。
③與高級語言相比,具有可以直接訪問物理地址,能進行位運算的優點。
④與組合語言相比,又具有良好的可讀性和可移植性。
儘管如此,C語言畢竟是一個面向過程的編程語言,因此與其它面向過程的編程語言一樣,已經不能滿足運用面向對象方法開發軟體的需要。C++語言便是在C語言基礎上為支持面向對象的程式設計而研製的一個通用的程式設計語言,它是在1980年由貝爾實驗室的BjarneStroustrup博士創建的。C++包含了整個C,C是建立C++的基礎。C++包括C的全部特徵、屬性和優點,同時,C++添加了對面向對象編程的完全支持。1.1.2一個簡單的C++程式現在,我們來看一個簡單的程式實例。例1-1是一個面向過程的程式,我們只是通過這個程式看一看,電腦程式是個什麼樣子,人們如何通過程式來控制電腦的操作。【例1-1】一個簡單的C++程式例題。
#include<iostream.h>voidmain(void){ cout<<"hello!\n"; cout<<"Iamastudent.\n";}
這裏main是主函數名,函數體用一對大括弧括住。C++程式由函數構成。在C++程式中,必須有且只能有一個名為main()的函數,因為程式總是從main()開始執行的。main()函數之前的void表示main()函數沒有返回值(關於函數的返回值將在第2章介紹)。程式由語句組成,每條語句由分號“;”作為結束符。cout是一個輸出流對象,它是C++系統預定義的對象,其中包含了許多有用的輸出功能。輸出操作由操作符“<<”來表達,其功能是將緊隨其後的雙引號中的字串輸出到標準輸出設備(顯示器)上。在第9章中將對輸出流做詳細介紹,在這裏,讀者只要知道這段程式可以實現在顯示器上輸出hello!Iamastudent.
就可以了。程式中的#include<iostream.h>的作用是在編譯之前,將檔iostream.h中的代碼嵌入到程式中該指令所在的地方。作為程式的一部分,iostream.h檔中聲明了程式所需要的輸入和輸出操作的有關資訊。cout和“<<”操作的有關資訊就是在該檔中聲明的。由於這類檔常被嵌入在程式的開始處,所以稱之為頭檔。在C++程式中如果使用了系統中提供的一些功能,就必須嵌入相關的頭檔。
當我們編寫完程式文本後,要將它存儲為尾碼為.cpp的檔,此檔稱為C++原始檔案,再經過編譯系統的編譯、連接後,最後產生出尾碼為.exe的可執行檔。通過以上程式可以看出,C++的程式結構由編譯預處理、程式主體和注釋組成,其特點如下:
①每個以符號“#”開頭的行,稱為編譯預處理語句。編譯預處理是C++組織程式的工具。有關#include語句的作用及其使用方法,將在第5章進行詳細介紹。②一個C++程式可以由一個或多個函數組成。任何一個完整的C++程式,都必須包含一個且只能包含一個名為main()的函數,程式總是從main()函數開始執行,而不管main()函數處於程式的什麼位置。
③函數體應由“{}”括起來。函數體一般包括變數的定義部分和執行部分。所有的變數要先定義後使用。
④注釋是程式員為讀者寫的說明,是提高程式可讀性的一種手段。一般可將注釋分為兩種:序言注釋和注解注釋。前者用於程式開頭,說明程式或檔的名稱、用途、編寫時間、編寫人以及輸入、輸出等,後者用於程式難懂的地方。C++的注釋為“//”之後的內容,直到換行。注釋僅供閱讀程式使用,是程式的可選部分。在生成可執行程式之前,C++忽略注釋,並把每個注釋都視為一個空格。另外,C++還相容了C語言的注釋。
⑤每個語句和數據定義的後面都要有一個分號。這一點初學者尤其要注意。
⑥main函數名和關鍵字(如void、int、float等)都是小寫字母構成。C++程式中的識別字是大小寫“敏感”的,所以,在書寫識別字的時候要注意其大小寫。1.1.3字元集
C++語言的字元集由下述字元構成:①英文字母:A~Z,a~z②數字字元:0~9③特殊字元:空格 ! # % ^ & * _(下劃線)+ = : - ~ < > / \? 〝 ; .(){}[] 1.1.4詞法記號詞法(語句)記號是構成語句的最小單元,這裏我們介紹C++的識別字、關鍵字、文字、運算符、分隔符號和空白符。
1.識別字識別字是程式員聲明的字元序列,它命名程式正文中的一些實體,如函數名、變數名、類名、對象名等。C++識別字的構成規則如下:①以大寫字母、小寫字母或下劃線(_)開始。
②可以由大寫字母、小寫字母、下劃線(_)或數字0~9組成。
③大寫字母和小寫字母代表不同的識別字。
④不能是C++關鍵字。例如,Richad、red_line、_Nol都是合法的識別字,而No.1、1st則是不合法的識別字。在識別字的命名中要特別注意:C++是大小寫敏感的,即大寫和小寫字母被認為是不同的字母。例如,識別字something、Something、SOMETHING、SomeThing都被視為不同的名字。2.關鍵字關鍵字是C++預定義好的識別字,這些識別字對C++編譯系統有著特殊的含義。如例1-1中的void,後面將逐步介紹到的數據定義語句int、float、long及double等等,它們都是C++的關鍵字。
3.文字文字是在程式中直接使用符號表示的數據,包括數字、字元、字串和布爾文字。在本章1.2節中將詳細介紹各種文字。
4.操作符(運算符)
操作符是用於實現各種運算的符號,例如+、-、*、/等。在本章1.2節及後續章節中將詳細介紹各種操作符。5.分隔符號分隔符號用於分隔各個詞法記號或程式正文。C++的分隔符號如下:
(){} , : ;
這些分隔符號不表示任何實際的操作,僅用於構造程式。例如,“{}”用於分隔函數體,“;”作為語句的分隔符號,其他分隔符號的具體用法會在以後相應的章節仲介紹。
6.空白符在程式編譯時的詞法分析階段將程式正文分解為詞法記號和空白。空白是空格、跳位字元(TAB鍵產生的字元)、換行符(Enter鍵所產生的字元)和注釋的總稱。
空白符用於指示詞法記號的開始和結束位置,但除了這一功能之外,其餘的空白將被忽略。因此,C++程式可以不必嚴格地按行書寫,凡是可以出現空格的地方,都可以出現換行。例如:
intj;與
intj;或與
intj
;
是等價的。但是儘管如此,我們在書寫程式時,仍要力求清晰、易讀。因為一個程式不僅要讓機器執行,還要讓人閱讀的同時便於修改、維護。1.2基本數據類型和運算式
程式處理的對象是數據。數據有許多種類,例如數值數據、文字數據、圖像數據以及聲音數據等,但其中最基本也是最常用的是數值數據和文字數據。無論什麼數據,在對其進行處理時都要先存放在記憶體中。顯然,不同類型的數據在內存中的存放格式也不相同,甚至同一類數據,為了處理方便,也可以使用不同的存儲格式。例如,數值數據其存儲格式又可以分為整型、長整型、浮點型和雙精度型等幾種類型;文字數據也可以分為單個字元和字串。
我們編寫電腦程式的目的,就是為了解決客觀世界中的現實問題。所以,高級語言中提供了豐富的數據類型和運算符。C++中的數據類型分為基本類型和非基本類型,見圖1-1。基本類型是C++編譯系統內置的,非基本類型也稱為用戶定義數據類型,即用戶自己定義的數據類型,本節我們首先介紹基本數據類型。圖1-1C++的數據類型1.2.1基本數據類型一個程式要運行,就要先描述演算法。描述一個演算法應先說明演算法要用的數據,數據以變數或常量的形式來描述。每個變數或常量都有數據類型。變數是存儲資訊的單元,它對應於某個記憶體空間。為了便於描述,電腦高級語言中都用變數名來表示其記憶體空間,所以,程式能在變數中存儲值和取出值。
在定義變數時,說明變數名和數據類型(如int、float)就是告訴編譯器要為變數分配多少空間,以及變數中要存儲什麼類型的值。數據類型的定義確定了其記憶體所占空間大小,也確定了其表示範圍。表1-1列出了基本數據類型的取值範圍。在不同的系統中,每個變數類型所占的位元組數目可能有所不同,表1-1裏列出的是在VC++6.0編譯環境中的情況(也是目前大多數編譯環境中的情況)。表1-1常用基本數據類型描述類型說明長度表示範圍備注bool邏輯型1false,true
char字元型1-128~127-27~(27-1)unsignedchar無符號字元型10~2550~(28-1)short短整形2-32768~32767-215~(215-1)unsignedshort無符號短整型20~655350~(216-1)int整型4-2147483648~2147483647-231~(231-1)unsignedint無符號整型40~42949672950~(232-1)long長整型4-2147483648~2147483647-231~(231-1)unsignedlong無符號長整型40~42949672950~(232-1)float浮點型4-3.4×1038~3.4×10387位有效位double雙精度8-1.7×10308~1.7×1030815位有效位longdouble長雙精度8-1.7×10308~1.7×1030815位有效位1.2.2常量所謂常量,是指在程式運行的整個過程中其值始終不可改變的量。例如,68、3.5、'A'、"hello!"都是常量。常量有以下幾種。
1.整型常量整型常量即以數碼形式出現的整數,包括正整數、負整數和零。整型常量的表示形式有十進位、八進制和十六進制。十進位整型常量的一般形式與數學中我們所熟悉的表示形式是一樣的:[±]若干個0~9的數字即符號加若干個0~9的數字,但數字部分不能以0開頭,正數前邊的正號可以省略。
八進制整型常量的數字部分要以數字0開頭,一般形式為
[±]0若干個0~7的數字十六進制整型常量的數字部分要以ox開頭,一般形式為
[±]ox若干個0~9的數字及A~F的字母(大小寫均可)
整型常量可以用尾碼字母L(或l)表示長整型,用尾碼字母U(或u)表示無符號型,也可同時使用尾碼L和U(大小寫無關)。例如,123、0123、-ox5af都是合法的常量形式2.實型常量實型常量又稱浮點小數。在C++語言中,實型常量只使用十進位表示,有兩種表示形式:一般形式和指數形式。一般形式:例如,16.5、-13.5等。指數形式:例如,0.565E+2表示0.565×102,-34.4E-3表示-34.4×10-3,其中,字母E可以大寫或小寫。當以指數形式表示一個實數時,整數部分和小數部分可以省略其一,但不能都省略。例如,.234E-1和12.E2都是正確的,但不能寫成E-3這種形式。實型常量默認為double型,如果尾碼為F(或f)則為float型。3.字元常量字元常量是單引號括起來的一個字元,如'a'、'G'、'?'、'$'等。另外,還有一些字元是不可顯示字元,也無法通過鍵盤輸入,例如響鈴、換行、跳位字元、回車等等。這樣的字元常量該如何寫到程式中呢?C++提供了一種稱為轉義序列的表示方法來表示這些字元,表1-2列出了C++預定義的轉義序列。表1-2C++預定義的轉義序列字元形式ASCII碼(十六進制)功
能\n0A換行\t09橫向跳格(即跳到下一個輸出區)\v0B豎向跳格\b08退格\r0D回車\a07響鈴\\5C反斜杠字元“\”\'27單引號\"22雙引號\dddddd(八進制)1到3位八進制數所代表的字元\xhhHh1到2位十六進制數所代表的字元4.字串常量字串常量簡稱字串,是用一對雙引號括起來的字元序列。例如,''China''、''1234''都是字串常量。字串與字元是不同的,字串在內存中的存放形式是:按串中字元的排列次序順序存放對應字元的ASCII碼,每個字元占一個位元組,並在字串末尾添加'\0'作為結束標記。圖1-2是字元數據及其存儲形式(十六進制)的舉例。從圖1-2中可以看出,字串''a''與字元'a'是不同的。
5.布爾型常量布爾型常量只有兩個:false(假)和true(真)。圖1-2字元數據的存儲形式1.2.3變數在程式的執行過程中其值可以變化的量稱為變數,變數需要用識別字來命名。就像常量具有各種類型一樣,變數也具有相應的類型。變數在使用之前需要首先聲明其類型和名稱。在同一語句中可以聲明同一類型的多個變數。變數聲明的形式如下:
<類型識別字>變數名1,變數名2,…,變數名n;
在程式運行時系統會給每一個聲明過的變數分配記憶體空間,用於存放對應類型的數據,因而變數名也就是對相應記憶體單元的命名。在聲明一個變數的同時,也可以給它賦以初值,而這實質上就是給對應的記憶體單元賦值。例如:
inta=3;
floatf=3.45; charc='b';
有一點值得注意,雖然C++中有字串常量,卻沒有字串變數。那麼,用什麼類型的變數來存放字串呢?在後面的章節,我們會介紹用字符數組來存儲字串常量。1.2.4引用程式設計語言的進化使用戶從被迫解決細節問題中解脫出來,而轉向允許用戶花更多的時間來考慮“大的藍圖”。根據這種精神,C++包含了一個稱為引用的特性。本小節僅僅介紹了引用的基本概念,有關更詳細的內容在後面章節會陸續介紹,到時讀者就會掌握引用的使用方法。
引用是個別名,當建立引用時,程式用另一個變數或對象(目標)的名字來對其進行初始化。自此,引用作為目標的別名而使用,對引用的改動實際是對目標的改動。引用的聲明形式為
<類型識別字>&引用名=目標名或
<類型識別字>&引用名=目標名
其中:
①引用名是為引用型變數所起的名字,它必須遵循變數的命名規則。
②前面的數據類型就是它所引用目標的數據類型。在此要特別說明的是,引用在聲明時必須進行初始化,即指出該引用是哪一個對象的別名。這裏的目標名可以是變數名,也可以是以後將要介紹的對象名。而且引用一旦聲明,就以對應目標的記憶體單元地址作為自己的地址,並且不再改變,從一而終。
例如,引用一個整型變數:
intsomeInt;
int&rInt=someInt;
聲明rInt是對整數的引用,初始化為引用someInt。在這裏,要求someInt已經聲明或定義。引用不是值,不占存儲空間。聲明引用時,目標的存儲狀態不會改變。【例1-2】建立和使用引用例題。#include<iostream.h>voidmain(){ intsomeInt; int&rInt=someInt;
someInt=6; cout<<"someInt:"<<someInt<<endl; cout<<"rInt:"<<rInt<<endl;rInt=7; cout<<"someInt:"<<someInt<<endl; cout<<"rInt:"<<rInt<<endl;}程式運行結果為someInt:6rInt:6someInt:7rInt:7
在上述程式中,引用rInt用someInt來初始化。以後,無論改變someInt或rInt,實際上都是指someInt,兩個的值都一樣。對引用的理解可以見圖1-3。圖1-3引用與變數的關係6omeIntrInt1.2.5運算符與運算式在任何高級程式設計語言中,運算式都是最基本的組成部分,也就是說,程式中的大部分語句是由運算式構成的。通常,當我們要進行某種計算時,都要首先列出算式,然後求解其值。利用C++語言編寫程式求解問題時也是這樣。可以簡單地將運算式理解為用於計算的公式,它由運算符(例如+、-、*、/)、運算對象(也稱運算元,可以是常量、變數等等)和括弧組成。執行運算式所規定的運算,所得到的結果值便是運算式的值。例如,a+b、x/y都是運算式。
運算式在使用時要注意以下幾點:
①一個常量或標識對象的識別字是一個最簡單的運算式,其值是常量或對象的值。
②一個運算式的值可以用來參與其他操作,即用作其他運算符的運算元,這就形成了更複雜的運算式。
③包含在括弧中的運算式仍是一個運算式,其類型和值與未加括弧時的運算式相同。
C++語言中定義了豐富的運算符,如算術運算符、關係運算符、邏輯運算符等等,有些運算符需要兩個運算元,使用形式為
<運算元1>運算符<運算元2>
運算符具有優先順序與結合性。當一個運算式包含多個運算符時,先進行優先順序高的運算,再進行優先順序低的運算。如果運算式中出現了多個相同優先順序的運算,運算順序就要看運算符的結合性了。所謂結合性,是指當一個運算元左右兩邊的運算符優先順序相同時,按什麼樣的順序進行運算,是自左向右,還是自右向左。例如,我們熟悉的算術運算式6+5-2中,“+”、“-”是同級運算符,那麼是先算5-2,還是先算6+5?這就取決於算術運算符的結合性。由於算術運算符的結合性為自左向右,所以應先算6+5,然後再算11-2。1.算術運算符與算術運算式
C++中的算術運算符包括基本的算術運算符和自增、自減運算符。由算術運算符、運算元和括弧構成的運算式稱為算術運算式。基本算術運算符有:+(加)、-(減或負號)、*(乘)、/(除)、%(取餘)。其中“-”作為負號時為一元運算符,其餘都為二元運算符。這些基本算術運算符的意義與數學中相應符號的意義是一致的。它們之間的相對優先順序關係與數學中的也是一致的,即先乘除、後加減,同級運算自左向右進行。使用算術運算符要注意以下幾點:①“%”是取餘運算,只能用於整型運算元。運算式a%b的結果為a/b的餘數。“%”的優先順序與“/”相同。
②當“/”用於兩整型運算元相除時,其結果取商的整數部分,小數部分被自動捨棄。因此,運算式1/2的結果為0,這一點需要特別注意。
③C++中的“++”(自增)、“--”(自減)運算符是使用方便且效率很高的兩個運算符,它們都是一元運算符。這兩個運算符都有前置和後置兩種使用形式(例如++i與i--)。
無論寫成前置或後置的形式,它們的作用都是將運算元的值增1(減1)後,重新寫回該運算元在內存中的原有位置。所以,如果變數i原來的值是1,計算運算式i++後,運算式的結果為2,並且i的值也被改變為2。但是,當自增、自減運算的結果要被用於繼續參與其他操作時,前置與後置時的情況就完全不同了。例如,如果i的值為1,則下列兩條語句的執行結果是不一樣的:
cout<<i++; cout<<++i;2.賦值運算符與賦值運算式
C++提供了幾個賦值運算符,最簡單的賦值運算符就是“=”。帶有賦值運算符的運算式被稱為賦值運算式。例如,m=m+6就是一個賦值運算式。賦值運算式的作用就是將等號右邊運算式的值賦給等號左邊的對象。賦值運算式的類型為等號左邊對象的類型,運算式的結果為等號左邊對象被賦值後的值,運算的結合性為自右向左。請看下列賦值運算式的例子。
n=1
運算式值為1。
a=b=c=2
這個運算式從右向左運算,在c被更新為2後,運算式c=2的值為2,接著b的值被更新為2,最後a被賦值為2。
a=3+(c=4)運算式值為7,a的值為7,c為4。
a=(b=5)+(c=6)運算式值為11,a為11,b為5,c為6。
除了“=”以外,C++還提供了10種複合的賦值運算符:+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=。其中,前五個運算符是賦值運算符與算術運算符複合而成的,後五個是賦值運算符與位運算符複合而成的。關於位運算,稍後再做介紹。這裏10種運算符的優先順序與“=”相同,結合性也是自右向左。現在舉例說明複合賦值運算符的功能。
b+=2 //等價於b=b+2 x*=y+3 //等價於x=x*(y+3)
x+=x-=x*x //等價於x=x+(x=x-x*x)
如果在賦值運算式後面加上分號,便成為了賦值語句。例如:
b=b+2;便是一個賦值語句,它實現的功能與賦值運算式相同。賦值運算式與賦值語句的不同點在於:賦值運算式可以作為一個更複雜運算式的一部分,繼續參與運算;而賦值語句不能。3.逗號運算符與逗號運算式在C++中,逗號也是一個運算符,它的使用形式為
<運算式1>,<運算式2>,…,<運算式n>
求解順序為,先求解運算式1,再求解運算式2,最後求解運算式n的值。逗號運算式的最終結果為運算式n的值。例如:
x=2*5,x*4
運算式的結果為40。
4.關係運算符和關係運算式關係運算符即比較符。關係運算符及其優先次序為<(小於)、<=(小於等於)、>(大於)、>=(大於等於)、==(等於)、!=(不等於)
優先順序相同(較高)
優先順序相同(較低)
用關係運算符將兩個運算式連接起來就是關係運算式。關係運算式是一種最簡單的邏輯運算式。例如:x>5x+y<=20c==a+b
都是關係運算式。注意,“==”(等於)是連續的兩個等號,不要誤寫為賦值運算符“=”。5.邏輯運算與邏輯運算式只有簡單的關係比較是遠不能滿足編程需要的,我們還需要用邏輯運算符將簡單的關係運算式連接起來構成較複雜的邏輯運算式。邏輯運算式的結果類型也為bool,值只能為true或false。C++中的邏輯運算符及其優先次序為
“!”是一元運算符,使用形式是:!運算元。非運算的作用是對運算元取反。如果運算元a的值為true,則運算式!a的值為false;如果運算元a的值為false,則運算式!a的值為true。“&&”是二元運算符。“&&”運算的作用是求兩個運算元的邏輯與。只有當兩個運算元的值都為true時,與運算的結果才為true,其他情況下與運算的結果均為false。
“||”也是二元運算符。“||”運算的作用是求兩個運算元的邏輯或。只有當兩個運算元的值都為false時,或運算的結果才為false,其他情況下或運算的結果均為true。邏輯運算符的運算規則可以用真值表來說明。表1-3給出了運算元a和b值的各種組合以及邏輯運算的結果。
例如,假設a=7,b=5,x=20,y=30,則邏輯運算式(a>b)&&(x>y)的值為false。表1-3邏輯運算符的真值表ab!aa&&ba||btruetruefalsetruetruetruefalsefalsefalsetruefalsetruetruefalsetruefalsefalsetruefalsefalse6.條件運算符與條件運算式條件運算符“?”是C++中唯一的三元運算符,它能夠實現簡單的選擇功能。條件運算式的形式為
<運算式1>?<運算式2>:<運算式3>
其中,運算式1的值必須是bool類型,運算式2和運算式3的值可以是任何類型。條件運算式的執行順序是:先求解運算式1。若運算式1的值為true,則求解運算式2,運算式2的值為條件運算式的結果;若運算式1的值為false,則求解運算式3,運算式3的值為條件運算式的結果。
注意:條件運算符的優先順序高於賦值運算符,低於邏輯運算符;結合方向為自右向左。例如,設x、a和b是整型變數,則語句
x=(a<b)?a:b;的功能是先求出整數a和b中較小數的值後,賦給變數x。7.sizeof操作符
sizeof運算符是用來計算某種數據類型在內存中所占的位元組數。該操作符使用的語法形式為
sizeof(類型名)
或
sizeof(運算式)
注意:sizeof(運算式)僅僅計算“運算式”的結果類型所占的位元組數,並不對括弧中的運算式本身求值。8.位運算一般的高級語言處理數據的最小單位只能是位元組,C++語言卻能對數據按二進位位進行操作。在C++中提供了六個位運算符,可以對整數進行位操作。
1)按位與(&)
按位與操作的作用是將兩個運算元對應的每一位分別進行邏輯與操作。例如,計算3&5:
3:00000011 5:(&)00000101 3&5:000000018.位運算一般的高級語言處理數據的最小單位只能是位元組,C++語言卻能對數據按二進位位進行操作。在C++中提供了六個位運算符,可以對整數進行位操作。
1)按位與(&)
按位與操作的作用是將兩個運算元對應的每一位分別進行邏輯與操作。例如,計算3&5:
3:00000011 5:(&)00000101 3&5:000000013)按位異或(^)
按位異或操作的作用是將兩個運算元對應的每一位進行異或。具體運算規則是:若對應位相同,則該位的運算結果為0;若對應位不同,則該位的運算結果為1。例如,計算071^052:
071: 00111001052:(^) 00101010071^052: 00010011
可以看出:與“1”相異或,具有取反的作用;與“0”相異或,維持不變。使用按位異或操作可以將運算元中的若干指定位取反。如果使某位與0異或,結果是該位的原值;如果使某位與1異或,則結果與該位原來的值相反。例如,要使01111010低四位翻轉,可以與00001111進行異或:
01111010
(^)00001111011101014)按位取反(~)
按位取反是一個單目運算符,其作用是對一個二進位數的每一位取反。例如:
025:00010101~025:111010105)移位
C++中有兩個移位運算符——左移運算(<<)和右移運算(>>),都是二元運算符。移位運算符左邊的運算元是需要移位的數值,右邊的運算元是左移或右移的位數。左移是按照指定的位數將一個數的二進位值向左移位。
左移後,低位補0,移出的高位捨棄。右移是按照指定的位數將一個數的二進位值向右移位。右移後移出的低位捨棄。如果是無符號數則高位補0;如果是有符號數,則高位補符號位。下麵我們看兩個例子。
①如果有char型變數a的值為-8,則a在內存中的二進位補數值為11111000,於是運算式a>>2的值為-2。圖1-4說明了移位操作的過程。
②運算式2<<l的值為4。圖1-5說明了移位操作的過程。
圖1-4a>>2的移位操作過程11111000
1111100011111110
值得注意的是:移位運算的結果是位運算運算式(a>>2和2<<1)的值,移位運算符左邊運算式的變數值本身並不會被改變。圖1-52<<1的移位操作過程
0000001000000010
0000001009.運算符優先順序表1-4中列出了C++中全部運算符的優先順序與結合性,除·*、->*運算符外,其餘的都在本章介紹。表1-4C++中運算符的優先順序與結合性優先順序運算符結合性1[ ]( ).->後置++後置--左→右2前置++前置--sizeof&*+(正號)-(負號)~!右→左3(強制轉換類型)右→左4·*->*左→右5*/%左→右6+-左→右7<<>>左→右8<><=>=左→右9==!=左→右10&左→右11^左→右12|左→右13&&左→右14||左→右15?:右→左16=*=/=%=+=- =<<=>>=&=^=|=右→左17,左→右1.2.6數據類型轉換當運算式中出現了多種類型數據的混合運算時,首先需要進行類型轉換,其次再計算運算式的值。運算式中的類型轉換分為兩種:隱含轉換和強制轉換。
1.隱含轉換在混合運算時,對於二元運算符要求兩個運算元的類型一致。若參加運算的運算元類型不一致,系統自動對數據進行轉換(即隱含轉換)。具體的規則如下。①算術運算和關係運算轉換的基本原則是將低類型數據轉換為高類型數據。類型越高數據的表示範圍越大,精度也越高,所以這種轉換是安全的。各種類型的高低順序如下:
charshortintunsignedlongunsigned-longfloatdouble
低高
②邏輯運算符要求參與運算的運算元必須是bool型,如果運算元是其他類型,則系統自動將其轉換為bool型。轉換方法是:非0數據轉換為true,0轉換為false。③位運算的運算元必須是整數。當二元位運算的運算元是不同類型的整數時,編譯系統會自動進行類型轉換。
④賦值運算要求左值(賦值運算符左邊的值)與右值(賦值運算符右邊的值)的類型相同。若類型不同,系統會自動進行類型轉換。但這時的轉換不適用上述的轉換規則,而是一律將右值類型轉換為左值類型。下麵的程式段說明了類型轉換的規則:floatfVal;doubledVal;intiVa1unsignedlongulVal;dVal=iVal*ulVal; //iVal被轉換為unsignedlong //乘法運算的結果被轉換為doubledVal=ulVal+fVal; //ulVal被轉換為float //加法運算的結果被轉換為double2.強制類型轉換強制類型轉換又稱為顯式轉換,是通過類型識別字和括弧來實現的,其語法形式有兩種:
<類型識別字>(運算式)
或(類型識別字)<運算式>
強制類型轉換的作用是將運算式的結果類型轉換為類型識別字所指定的類型。例如:floatz=9.74,fraction_part;intwhole_part;whole_part=int(z);//將float型轉換為int型時,取整數部分,捨棄小數部分fraction_part=z-int(z) //用z減去其整數部分,得到小數部分使用強制類型轉換時,應該注意:①從上面的例子中可以看到,將高類型數據轉換為低類型數據時,數據精度會受到損失。
②這種轉換是暫時的、一次性的。例如,int(z)只是將float型變數z的值取出來,臨時轉換為int型,然後賦給whole_part。而變數z仍是原來的浮點類型值。1.3數據的輸入與輸出1.3.1I/O的書寫格式
C++數據的輸入與輸出是通過I/O流來實現的,I/O流輸入或輸出的是一系列位元組。當程式需要在螢幕上顯示輸出時,可以使用插入符“<<”向cout輸出流中插入字元。cout是預定義的流類對象,“<<”是預定義的插入符,格式如下:
cout<<運算式<<運算式…
例如,語句
cout<<"\"Thisisasample.\",hesaid.\n";
的輸出結果為
"Thisisasample.",hesaid.
當程式需要執行鍵盤輸入時,可以使用提取操作符“>>”從cin輸入流中抽取字元,格式如下:
cin>>運算式>>運算式…cin是預定義的流類對象,“>>”是預定義的提取符。例如:
inta;
charc;
cin>>a>>c;
要求從鍵盤上輸入兩個變數的值,兩數之間以空格分隔。若輸入
48↙
這時,變數a獲取值為4,變數b獲取值為8的ASCII值38(十六進制)。因為變數c的數據類型為char,cin能夠知道輸入的變數類型。1.3.2簡單的I/O格式控制從上面的介紹中可以看出,當我們用cin、cout進行數據的輸入和輸出時,無論處理的是什麼類型的數據,都能夠自動按照默認格式處理。但這還是不夠,我們仍經常需要設置特殊的格式。設置格式有很多方法,有關內容將在第9章做詳細介紹,本節只介紹最簡單的格式控制。
C++的I/O流類庫提供了一些控制符,可以直接嵌入到輸入/輸出語句中來實現I/O格式控制。使用格式控制符首先必須在根源程式的開頭包含iomanip.h。表1-5中列出了幾個常用的I/O流類庫格式控制符。表1-5常用的I/O流控制符控制符含義Dec數值數據採用十進位Hex數值數據採用十六進制Oct數值數據採用八進制Ws提取空白符Endl插入換行符,並刷新流Ends插入空字元setprecision(int)設置浮點數的小數位數(包括小數點)setw(int)設置域寬
在使用setw(n)時要注意:
①如果一個輸出量需要比setw(n)確定的字元數更多的字元,則該輸出量將使用它所需要的寬度。例如:
floatamount=3.14159;cout<<setw(4)<<amount<<endl;
其運行結果為3.14159。它並不按4位寬度,而是按實際寬度輸出。②setw(n)僅僅影響下一個數值輸出,換句話說,使用setw設置的間隔方式並不保留其效力。例如:
cout<<setw(8)<<10<<20<<endl;
運行結果為
------1020
運行結果中的下劃線表示空格整數20並沒有按寬度8輸出。setw()的默認寬度為0,意思是按輸出數值表示的寬度輸出,所以20就緊挨10了。
【例1-3】I/O格式控制例題。按十六進制、八進制和十進位的格式輸出數據例題。這三個控制符都是在iostream.h定義的,所以無需加入頭檔iomanip.h。
#include<iostream.h>voidmain(){ intnumber=1001;cout<<"\tDecimal:"<<dec<<number<<endl <<"\tHexadecimal:"<<hex<<number<<endl <<"\tOctal:"<<oct<<number<<endl;}程式運行結果為Decimal:1001Hexadecimal:3e9Octal:17511.4程式的基本控制結構
學習了數據類型、運算式、賦值語句和數據的輸入與輸出後,就可以編寫程式完成一些簡單的功能了。但是,我們現在寫的程式還只是一些順序執行的語句。實際上,我們所面對的客觀世界遠不是這麼簡單,我們通常解決問題的方法也不是用這樣的順序步驟就可以描述清楚的。例如,有一分段函數如下,輸入一個x值,求出y值:
這個問題由人來判斷並不複雜,但是如何將這一計算方法用電腦來完成?顯然,用順序執行的語句序列是無法描述的,這裏必須進行選擇判斷,需要用選擇型控制結構。
再舉一個簡單的例子,比如統計某一個年級某門課程的平均成績。這個問題人工計算起來方法很簡單,但是當統計數據量非常大的時候我們就不得不借助於電腦了。但是計算方法卻必須由我們為它準確地描述清楚。這個演算法中的一個主要部分就是進行累加,這種大量重複的相同動作顯然不適宜由順序執行的語句來羅列,需要用迴圈型控制結構。
程式的基本控制結構有三種:順序結構、選擇結構和迴圈結構。其中順序結構的程式是最簡單的。下麵我們將詳細介紹C++中的選擇結構和迴圈結構控制語句。在此之前,為了便於描述演算法,我們先介紹一種常用演算法表示工具——程式流程圖。流程圖是用一些圖框表示各種操作的。用圖框表示演算法,具有簡潔、直觀、易於理解等優點。流程圖中常用的符號如圖1-6所示。圖1-6流程圖的常用符號1.4.1簡單選擇結構用if語句可以實現簡單選擇結構。if語句的語法形式如下:
if(運算式)語句1else語句2if語句的執行順序是:首先計算運算式的值。若運算式值為true,則執行語句1;否則執行語句2。執行流程如圖1-7所示。其中語句1和語句2不僅可以是一條語句,而且可以是大括弧括起來的多條語句(稱為複合語句)。圖1-7if-else語句流程圖
例如:
if(x>y)cout<<x; else cout<<y;
實現了從x和y中選擇較大的一個輸出。if語句中的語句2可以為空。當語句2為空時,else可以省略,成為如下形式:
if(運算式)語句1
例如,若ch字元等於字元b,則響鈴:
if(ch=='b') cout<<'\a';
【例1-4】輸入一個年份,判斷是否閏年。分析:閏年的年份可以被4整除而不能被100整除,或者能被400整除。因此,首先輸入年份存放到變數year中,如果運算式((year%4==0&&year%100!=0)||(yeax%400==0))的值為true,則為閏年;否則就不是閏年。根源程式:
#include<iostream.h>voidmain(){intyear; boolIsLeapYear; cout<<"Entertheyear:"; cin>>year; IsLeapYear=((year%4==0&&year%100!=0)||(year%400==0)); if(IsLeapYear) cout<<year<<"isaleapyear"<<endl; else cout<<year<<"isnotaleapyear"<<endl;}
程式運行結果為
Entertheyear:20002000isaleapyear1.4.2多重選擇結構有很多問題是一次簡單的判斷所解決不了的,需要進行多次判斷選擇。這可以有以下幾種方法。
1.嵌套的if語句形式1:if(運算式1) if(運算式2)語句1 else 語句2elseif(運算式3)語句3 else語句4
形式2:
if(運算式1)語句1 else if(運算式2)語句2else if(運算式3)語句3
else 語句n+1
可以看出,形式1的嵌套發生在if及else分支,形式2的嵌套僅發生在else分支。形式2的if…elseif語句的執行順序如圖1-8所示。圖1-8if…elseif語句流程圖
無論是何種形式,應當注意:
①if與else的配對關係。else總是與它上面最近的if配對。
②語句1、2、3、4、…、n+1可以是複合語句。
③如果省略某一個else,if與else的數目不一樣,為實現程式設計者的意圖,便要用{}括起該層的if語句來確定層次關係。
例如:
if() {if()語句1}else語句2
這時,{}確定了內嵌if語句的範圍,因此else與第一個if配對。【例1-5】本章開始舉例中,有一函數:
-1 (x<0) Y=0 (x=0)1 (x>0)
輸入一個x的值,輸出y的值。分析:通過鍵盤輸入一個數,這個數有三種可能:x=0,x>0,x<0。因此需要進行多次判斷,要用多重選擇結構。這裏我們選用嵌套的if…elseif語句。#include<iostream.h>voidmain(){ intx,y; cin>>x; if(x<0)y=-1; elseif(x==0)y=0; elsey=1; cout<<y<<endl;}
程式運行結果為輸入:4
螢幕顯示:12.switch語句如果在演算法中,雖然需要進行多次判斷選擇,但都是判斷同一個運算式的值,這樣就沒有必要在每一個嵌套的if語句中都計算一次運算式的值,為此,C++中有switch語句專門來解決這類問題。switch語句的語法形式如下:switch(運算式) { case常量運算式1:語句1case常量運算式2:語句2
case常量運算式n:語句n default:語句n+1} switch語句的執行順序是:首先計算switch語句中的運算式的值,然後在case語句中尋找值相等的常量運算式,並以此為入口標號,由此開始順序執行。如果沒有找到相等的常量運算式,則從“default:”開始執行。使用switch語句應注意下列問題:①switch後面括弧內的運算式的值只能是整型、字元型、枚舉型。例如,下麵的代碼錯誤地用浮點型作switch的運算式,它會引起編譯錯誤:floatf=4.0switch(f) //error{//...}②各常量運算式的值不能相同,且次序不影響執行結果。例如,下麵的代碼中出現相同的常量值:case'A':cout<<''thisisA\n'';csae65:cout<<''thisis65\n''; //error:'A'等值於65③每個case分支可以有多條語句,但不必用{}。
④每個case語句只是一個入口標號,通常我們只需執行一個case後的語句,因此,每個case分支的最後應該加break語句,用來結束整個switch結構,否則從入口點開始一直執行到switch結構的結束點。
⑤當若干分支需要執行相同操作時,可以使多個case分支共用一組語句。
【例1-6】輸入一個1~3的整數,來計算相應圖形的面積(1-圓形,2-長方形,3-正方形)。分析:本題需要根據輸入的數字決定相應面積的計算,由於數字1~3分別對應圓形、長方形和正方形,因此需要運用多重分支結構。但是每次判斷的都是輸入的整數,所以選用switch語句最為適宜。
#include<iostream.h>constdoublePI=3.1416;voidmain(){intiType; doubleradius,a,b,area; cout<<"圖形的類型為?(1-圓形,2-長方形,3-正方形):"; cin>>iType; switch(iType) { case1: cout<<"圓的半徑為:"; cin>>radius; area=PI*radius*radius; cout<<"面積為:"<<area<<endl; break;case2: cout<<"矩形的長為:"; cin>>a; cout<<"矩形的寬為:"; cin>>b; area=a*b; cout<<"面積為:"<<area<<endl; break;case3: cout<<"正方形的邊長為:"; cin>>a; area=a*a; cout<<"面積為:"<<area<<endl; break; default: cout<<"不是合法的輸入值!"<<endl; }}程式運行結果為圖形的類型為?(1-圓形,2-長方形,3-正方形):1圓的半徑為?:2面積為12.56641.4.3迴圈結構在C++中有三種迴圈控制語句。
1.while語句
while語句的語法形式如下:
while(運算式)語句
while語句的執行順序是:判斷一個條件運算式(迴圈控制條件),以便決定是否應當進入和執行循環體(語句)。當條件滿足時進入迴圈,不滿足時則不再執行迴圈。圖1-9是while語句的流程圖。
應用while語句時應該注意,一般來說在循環體中,應該包含改變迴圈條件運算式值的語句,否則便會造成死迴圈。【例1-7】求自然數1~100之和。分析:本題需要用累加演算法。累加過程是一個迴圈過程,可以用while語句實現。
#include<iostream.h>voidmain(){ inti=1,sum=0;while(i<=100) { sum+=i; i++; } cout<<"sum="<<sum<<endl;}程式運行結果為sum=50502.do-whil語句
do-whil語句的語法形式如下:
do語句
while(運算式);dowhile語句的執行順序是:當流程執行到do後,立即執行循環體語句,然後再判斷迴圈條件運算式的值。運算式為true時,繼續執行循環體;運算式為false則結束迴圈。圖1-10是do-while語句的流程圖。該語句結構使迴圈至少執行一次。【例1-8】用do-while語句編程,求自然數1~100之和。
#include<iostream.h>voidmain(){ inti(1),sum(0); do{ sum+=i++; }while(i<=100); cout<<"sum="<<sum<<endl;}do-while與while語句都是實現迴圈結構的,兩者的區別是:while語句先判斷運算式的值,當值為true時,再執行循環體;而do-while語句是先執行循環體,再判斷運算式的值。在大多數情況下,如果迴圈控制條件和循環體中的語句都相同,while迴圈和do-while迴圈的結果是相同的。但是如果一開始迴圈控制條件就為假,這兩種迴圈的執行結果就不同了,do-while迴圈至少執行一次循環體,while迴圈卻一次都不執行。現在我們將例1-7的題目稍作修改,改為從鍵盤輸入整數i,請讀者分析在輸入的i值大於10和不大於10的情況下,下麵兩個
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 小学信息技术第三册 第19课带变量的过程教学实录 北京版
- 2023九年级历史下册 第一单元 殖民地人民的反抗与资本主义制度的扩展第4课 日本明治维新教学实录 新人教版
- 六年级儿童节讲话稿10篇
- 银行的实习报告模板集锦五篇
- 2024六年级英语上册 Unit 2 School in Canada Lesson 11 Always Do Your Homework教学实录 冀教版(三起)
- 异位妊娠说课-教学课件
- 老师道歉信范文集合五篇
- 第3课 突破封锁线(教学实录)-教学实录2023-2024学年粤教版(B版)小学信息技术六年级下册
- 驾驶员工作述职报告6篇
- 教师学期个人总结2021汇报【10篇】
- 辽宁省2024年中考物理试题【附真题答案】
- 2024年部编新改版语文小学一年级上册第六单元复习课教案
- 竣工决算工作底稿
- 炉省煤器改造更换施工方案
- DB5334 T 12.3-2024《地理标志证明商标 香格里拉藏香猪》的第3部分饲养管理
- 佛山市2022-2023学年七年级上学期期末考试数学试题
- 信访工作条例应知应会考试题库300题(含答案)
- 公司和酒店住宿协议合同
- 2024-2030年中国布拉迪酵母行业市场发展趋势与前景展望战略分析报告
- 供应链管理部年终总结报告
- 2024年重庆空港贵宾服务限公司社会招聘20人公开引进高层次人才和急需紧缺人才笔试参考题库(共500题)答案详解版
评论
0/150
提交评论