第2講 變量與數(shù)據(jù)_第1頁(yè)
第2講 變量與數(shù)據(jù)_第2頁(yè)
第2講 變量與數(shù)據(jù)_第3頁(yè)
第2講 變量與數(shù)據(jù)_第4頁(yè)
第2講 變量與數(shù)據(jù)_第5頁(yè)
已閱讀5頁(yè),還剩47頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

編程規(guī)范—第二講

變量與類(lèi)型軟件工程系變量和類(lèi)型是程序的基礎(chǔ),也是編程中容易忽視的地方。本節(jié)將學(xué)習(xí)變量和類(lèi)型的相關(guān)概念和編程陷阱。實(shí)用經(jīng)驗(yàn)5:計(jì)算機(jī)是怎么存儲(chǔ)變量的?實(shí)用經(jīng)驗(yàn)6:確保每個(gè)對(duì)象在使用前已被初始化。實(shí)用經(jīng)驗(yàn)7:掌握局部變量和全局變量的區(qū)別實(shí)用經(jīng)驗(yàn)8:掌握變量定義的位置與時(shí)機(jī)。實(shí)用經(jīng)驗(yàn)9:合理使用引用實(shí)用經(jīng)驗(yàn)13:typedef使用的陷阱實(shí)用經(jīng)驗(yàn)16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩實(shí)用經(jīng)驗(yàn)17:深刻理解void和void*實(shí)用經(jīng)驗(yàn)18:如何判定變量是否相等?5:計(jì)算機(jī)如何存儲(chǔ)變量數(shù)據(jù)在內(nèi)存中的放置包括兩個(gè)部分:一是數(shù)據(jù)放置的位置即數(shù)據(jù)存儲(chǔ)區(qū)域二是數(shù)據(jù)放置的格式。數(shù)據(jù)存儲(chǔ)區(qū)域可分為:只讀數(shù)據(jù)區(qū),全局靜態(tài)存儲(chǔ)區(qū),自由存儲(chǔ)區(qū),棧區(qū),堆區(qū)。(P23)只讀/靜態(tài)存儲(chǔ)區(qū):存儲(chǔ)常量和恒值;全局靜態(tài)存儲(chǔ)區(qū):全局變量和靜態(tài)變量自由存儲(chǔ)區(qū):CRT通過(guò)malloc\free函數(shù)管理的內(nèi)存。與堆區(qū)同一種管理方式,統(tǒng)稱為堆區(qū)。棧區(qū):數(shù)據(jù)由編譯器自動(dòng)分配釋放,主要存放函數(shù)的參數(shù)值、局部變量等。堆區(qū):存放new分配的內(nèi)存塊,編譯器不負(fù)責(zé)他們的釋放。堆區(qū)分配數(shù)據(jù)雖具有節(jié)省空間,使用方便。堆區(qū)分配和釋放內(nèi)存會(huì)造成內(nèi)存空間的不連續(xù),形成大量的碎片,程序效率降低。分配的數(shù)據(jù)如果沒(méi)有釋放,很容易造成內(nèi)存泄露。思考:什么情形應(yīng)該用到全局變量和靜態(tài)變量,兩者有什么區(qū)別

什么時(shí)候應(yīng)該用到new/delte?5:計(jì)算機(jī)如何存儲(chǔ)變量數(shù)據(jù)放置的格式:整型值整數(shù),Int\short\long類(lèi)型都表示整型值,不同之處是存儲(chǔ)變量所占的內(nèi)存空間大小不同,計(jì)算機(jī)按位序列存儲(chǔ)數(shù)據(jù),8位一個(gè)字節(jié),一個(gè)字節(jié)和一個(gè)稱為地址的數(shù)關(guān)聯(lián)起來(lái),并且需要知道存在該地址的值的類(lèi)型。字符型

char基本字符集;wchar_t擴(kuò)展字符集布爾值算術(shù)類(lèi)型。Bool類(lèi)型表示true(非0)和false(0)。浮點(diǎn)型單精度(32:1+8+23雙精度(64:1+11+52)兩類(lèi)三部分符號(hào)位、指數(shù)位、尾數(shù)部分。浮點(diǎn)計(jì)算,三部分必須是二進(jìn)制形式。5計(jì)算機(jī)如何存儲(chǔ)變量變量在不同語(yǔ)境下,其分配內(nèi)存區(qū)域是不同的。靜態(tài)變量和全局變量一般分布在全局/靜態(tài)存儲(chǔ)區(qū),函數(shù)的參數(shù)和變量一般分配在棧中,new和malloc申請(qǐng)的數(shù)據(jù)一般分配在堆中。變量在定義和初始化時(shí),一定要注意其取值范圍,以防出現(xiàn)數(shù)據(jù)截?cái)喈惓,F(xiàn)象。同樣數(shù)據(jù)在使用過(guò)程中應(yīng)禁止降級(jí)強(qiáng)制轉(zhuǎn)換,這種轉(zhuǎn)換一般會(huì)降低數(shù)據(jù)的精度,嚴(yán)重時(shí)會(huì)出現(xiàn)模棱兩可的問(wèn)題。6:確保每個(gè)對(duì)象在使用前已被初始化對(duì)象在使用前是否會(huì)被初始化是無(wú)法確定的如:Pt的成員變量有時(shí)會(huì)被初始化為0,有時(shí)不會(huì)最佳的處理方式就是:永遠(yuǎn)在變量被使用之前將它初始化

內(nèi)置數(shù)據(jù)類(lèi)型,必須手動(dòng)完成初始化。

如:Inti=5;char*pszString=“acstring”內(nèi)置類(lèi)型以外的其他成員,對(duì)象的構(gòu)造函數(shù)完成初始化classCPoint{public: intm_iX;intm_iY;};intmain(){CPointpt;cout<<pt.m_iX<<endl;return0;}讀取未初始化的對(duì)象會(huì)導(dǎo)致不確定的行為6確保每個(gè)對(duì)象在使用前已被初始化最佳的處理方式就是:永遠(yuǎn)在變量被使用之前將它初始化內(nèi)置類(lèi)型以外的其他成員,對(duì)象的構(gòu)造函數(shù)完成初始化

typedefenumtagsex{MALE_SEX=0,FEMALE_SEX=1,}Sex;classCPerson{public:stringm_strName;Sexm_sex;CPerson(stringstrName,Sexsex);};CPerson::CPerson(stringstrName,Sexsex){m_strName=strName;m_sex=sex;}intmain(){CPersonc1("lucy",MALE_SEX);cout<<c1.m_strName<<c1.m_sex<<endl;return0;}typedefenumtagsex{ MALE_SEX=0,FEMALE_SEX=1,}Sex;classCPerson{public:stringm_strName;Sexm_sex;CPerson(stringstrName,Sexsex);};CPerson::CPerson(stringstrName,Sexsex):m_strName(strName),m_sex(sex){}intmain(){CPersonc1("lucy",MALE_SEX);cout<<c1.m_strName<<c1.m_sex<<endl;return0;}復(fù)制初始化:之前需調(diào)用默認(rèn)構(gòu)造函數(shù),效率低列表初始化:無(wú)需調(diào)用默認(rèn)構(gòu)造函數(shù),效率高,且常成員只能用列表初始化聲明次序決定初始化新婚許列表次序應(yīng)與聲明次序一致6確保每個(gè)對(duì)象在使用前已被初始化Tips:為內(nèi)置類(lèi)型對(duì)象進(jìn)行手動(dòng)初始化,因?yàn)镃++不保證初始化它們。構(gòu)造函數(shù)最好使用成員初始化列表,而不是在構(gòu)造函數(shù)本體內(nèi)使用賦值操作。初值列表列出的成員變量,其排列順序應(yīng)和它們?cè)赾lass中的聲明次序相同。

7局部變量和全局變量的差別變量一般包括4種:全局變量,靜態(tài)全局變量,靜態(tài)局部變量,和局部變量。按照存儲(chǔ)區(qū)域分:全局變量,靜態(tài)全局變量,靜態(tài)局部變量都存放在內(nèi)存的靜態(tài)存儲(chǔ)區(qū),局部變量存放在內(nèi)存的棧區(qū)。按照作用域分:全局變量在整個(gè)工程文件內(nèi)都有效;靜態(tài)全局變量只在定義它的文件內(nèi)有效;靜態(tài)局部變量只在定義它的函數(shù)內(nèi)有效,只是程序分配一次內(nèi)存,函數(shù)返回后,該變量不會(huì)消失;局部變量在定義它的函數(shù)內(nèi)有效,函數(shù)返回后失效。注意:全局變量和靜態(tài)變量如果沒(méi)有手動(dòng)初始化,則由編譯器初始化為0.局部變量是編譯器永遠(yuǎn)不會(huì)初始化的變量。如果沒(méi)有手動(dòng)初始化,則為隨機(jī)值7局部變量和全局變量的差別局部變量也稱為內(nèi)部變量.局部變量是在函數(shù)內(nèi)說(shuō)明的,其作用域僅限于函數(shù)內(nèi),離開(kāi)該函數(shù)后再使用變量是非法的。右圖在函數(shù)f1內(nèi)定義了3個(gè)變量,a為形參,b,c為一般變量,abc的作用于僅限于函數(shù)f1。局部變量說(shuō)明主函數(shù)main定義的變量只在其中使用,不能用于其他函數(shù)。同時(shí)也不能使用其他函數(shù)的變量。C++語(yǔ)言應(yīng)注意。形參變量屬于被調(diào)函數(shù)的局部變量,實(shí)參屬于主調(diào)函數(shù)的局部變量。在復(fù)合語(yǔ)句中可定義變量,其作用域只在復(fù)合語(yǔ)句范圍內(nèi)。Intf1(inta){Intb,c;……}Main(){Intm,n;F1(m)}局部變量定義及特點(diǎn)局部變量例子7局部變量和全局變量的差別本程序在main中定義了i,j,k3個(gè)變量,其中k未賦初值。而在復(fù)合語(yǔ)句內(nèi)有定義了一個(gè)變量k,并賦初值為8.請(qǐng)問(wèn)兩個(gè)輸出語(yǔ)句的值分別是?Main(){Inti=2;j=3;k;k=i+j;{intk=8;If(i==3){printf(“%d\n”,k);}}Printf(“%d\n%d\n”,i,k)}7局部變量和全局變量的差別

全局變量也稱為外部變量,他是在函數(shù)外部定義的變量。他不屬于某一個(gè)函數(shù),屬于一個(gè)源文件。全局變量例子程序要求:函數(shù)vs完成求長(zhǎng)方形體積和3個(gè)面積,函數(shù)返回體積V。主函數(shù)完成長(zhǎng)寬高的輸入及體積及三個(gè)面積的輸出。矛盾分析:C語(yǔ)言規(guī)定函數(shù)返回值只有一個(gè),vs函數(shù)將體積返回給主函數(shù),其余三個(gè)面積值怎么傳遞給主函數(shù)解決方法:定義三個(gè)面積為外部變量s1,s2,s3,其作用域?yàn)檎麄€(gè)程序。主函函數(shù)也可以使用ints1,s2,s3;intvs(inta,intb,intc){intv;v=a*b*c;s1=a*b;s2=b*c;s3=a*c;returnv;}intmain(){intv,l,w,h;cout<<"inputlength,widthandheight\n";cin>>l>>w>>h;v=vs(l,w,h);cout<<v<<"\n"<<s1<<"\n"<<s2<<"\n"<<s3;}全局變量定義及特點(diǎn)函數(shù)的return語(yǔ)句只能返回一個(gè)值體積v需要輸出vs函數(shù)計(jì)算所得的四個(gè)值?聲明為全局變量,無(wú)需return語(yǔ)句傳回7局部變量和全局變量的差別全局變量說(shuō)明:對(duì)于外部變量的說(shuō)明和定義不是一回事。

外部變量定義:必須在所有函數(shù)之外,且只定義一次:[extern]inta,b;(可省略extern.)

外部變量說(shuō)明:出現(xiàn)在要使用該外部變量的各個(gè)函數(shù)中,

在整個(gè)程序內(nèi)可能出現(xiàn)多次:externinta,b;外部變量在定義時(shí)就分配了內(nèi)存單元,外部變量定義可做初始賦值。外部變量說(shuō)明不再賦初始值,只是說(shuō)明。外部變量加強(qiáng)了函數(shù)模塊之間的聯(lián)系,同時(shí)使得函數(shù)依賴這些變量,因此導(dǎo)致函數(shù)獨(dú)立性低。基于模塊化程序設(shè)計(jì),在不必要的情況下盡可能少使用外部變量。同一源文件,允許全局變量和局部變量同名7局部變量和全局變量的差別變量特性

生存期靜態(tài)存儲(chǔ)變量變量定義就分配存儲(chǔ)單元直至整個(gè)程序結(jié)束。

靜態(tài)存儲(chǔ)變量有:extern全局變量靜態(tài)變量static

動(dòng)態(tài)存儲(chǔ)變量程序執(zhí)行過(guò)程才分配存儲(chǔ)單元,使用完畢立即釋放動(dòng)態(tài)存儲(chǔ)變量有:auto自動(dòng)變量register寄存器變量靜態(tài)存儲(chǔ)變量是一直存在的,而動(dòng)態(tài)存儲(chǔ)變量則時(shí)而存在時(shí)而消失。作用域全局作用域、局部作用域、語(yǔ)句作用域、類(lèi)作用域、命名空間作用域、文件作用域。全局變量具有全局作用域,可以作用于所有源文件。不包含全局變量定義的源文件只需要用extern關(guān)鍵字再次聲明。靜態(tài)局部變量具有局部作用域,他只被初始化一次,直到程序運(yùn)行結(jié)束都一直存在。只對(duì)定義自己的函數(shù)體始終可見(jiàn)。局部變量只有局部作用域,自動(dòng)對(duì)象,在程序運(yùn)行期間不是一直存在的,函數(shù)執(zhí)行期間存在,函數(shù)調(diào)用結(jié)束變量撤銷(xiāo)內(nèi)存收回。靜態(tài)全局變量具有全局作用域,他只作用于他的文件中,不作用于其他文件(區(qū)別于全局變量)。即被static關(guān)鍵字修飾過(guò)的變量具有文件作用域。7局部變量和全局變量的差別Tips:A.若全局變量?jī)H在單個(gè)C文件中訪問(wèn),則可以將這個(gè)變量修改為靜態(tài)全局變量,以降低模塊間的耦合度;B.若全局變量?jī)H由單個(gè)函數(shù)訪問(wèn),則可以將這個(gè)變量改為該函數(shù)的靜態(tài)局部變量,以降低模塊間的耦合度;C.設(shè)計(jì)和使用訪問(wèn)動(dòng)態(tài)全局變量、靜態(tài)全局變量、靜態(tài)局部變量的函數(shù)時(shí),需要考慮重入問(wèn)題,因?yàn)樗麄兌挤旁陟o態(tài)數(shù)據(jù)存儲(chǔ)區(qū),全局可見(jiàn);D.如果我們需要一個(gè)可重入的函數(shù),那么,我們一定要避免函數(shù)中使用static變量(這樣的函數(shù)被稱為:帶“內(nèi)部存儲(chǔ)器”功能的的函數(shù))E.函數(shù)中必須要使用static變量情況:比如當(dāng)某函數(shù)的返回值為指針類(lèi)型時(shí),則必須是static的局部變量的地址作為返回值,若為auto類(lèi)型,則返回為錯(cuò)指針。8:掌握變量定義的位置與時(shí)機(jī)tips:在定義變量時(shí),要三思而后行,掌握變量定義的時(shí)機(jī)與位置,在合適的時(shí)機(jī)與合適的位置上定義變量。盡可能推遲變量的定義,直到不得不需要該變量為止;同時(shí),為了減少變量名污染,提高程序可讀性,盡量縮小變量的作用域??偨Y(jié):變量定義離使用越遠(yuǎn)越好;盡量縮小變量作用域優(yōu)點(diǎn):

避免構(gòu)造和析構(gòu)非必要對(duì)象,甚至避免默認(rèn)構(gòu)造函數(shù)執(zhí)行

避免命名污染8掌握變量定義的位置與時(shí)機(jī)std::stringChangToUpper(conststd::string&str){usingnamespacestd;stringupperStr;if(str.length()<=0){throwerror("Stringtobechangedisnull");}...//將字符變?yōu)榇髮?xiě)

returnupperStr;

}結(jié)論:就算函數(shù)拋出了異常,因變量定義在先。仍然要為upperStr的構(gòu)造與析構(gòu)付出代價(jià)。所以變得精明些,把握變量定義的時(shí)機(jī):盡量晚地去定義變量,直到不得不定義時(shí)。過(guò)早定義upperstr對(duì)象如果輸入字符串為空,函數(shù)拋出異常,upperstr對(duì)象就不會(huì)被使用。掌握變量定義的位置與時(shí)機(jī)std::stringChangToUpper(conststd::string&str){usingnamespacestd;if(str.length()<=0){throwerror("Stringtobechangedisnull");}stringupperStr;...//將字符變?yōu)榇髮?xiě)

returnupperStr;}關(guān)于變量定義的位置,建議變量定義得越“l(fā)ocal”越好,盡量避免變量作用域的膨脹。這樣做不僅可以有效地減少變量名污染,還有利于代碼閱讀者盡快找到變量定義,獲悉變量類(lèi)型與初始值,使閱讀代碼更容易。8掌握變量定義的位置與時(shí)機(jī)#include<iostream>#include<string>usingnamespacestd;stringgetSubStr(conststring&str,size_tiPos){stringstrSubStr;if(str.size()<iPos){throwlogic_error("iPosistoolarge");}strSubStr=str.substr(iPos);returnstrSubStr;}intmain(){strings1("hello");cout<<getSubStr(s1,7);return0;}#include<iostream>#include<string>usingnamespacestd;stringgetSubStr(conststring&str,size_tiPos){if(str.size()<iPos){throwlogic_error("iPosistoolarge");}stringstrSubStr;strSubStr=str.substr(iPos);returnstrSubStr;}intmain(){strings1("hello");cout<<getSubStr(s1,7);return0;}該語(yǔ)句根本就不會(huì)執(zhí)行,字符串對(duì)象trSubStr也沒(méi)有聲明的必要Hello總共6位,獲取從第8位開(kāi)始的子字符串,一定出現(xiàn)異常推遲對(duì)象聲明,但是對(duì)象的默認(rèn)構(gòu)造函數(shù)仍會(huì)執(zhí)行#include<iostream>#include<string>usingnamespacestd;stringgetSubStr(conststring&str,size_tiPos){if(str.size()<iPos){throwlogic_error("iPosistoolarge");}stringstrSubStr(str.substr(iPos));returnstrSubStr;}intmain(){strings1("hello");cout<<getSubStr(s1,7);return0;}8掌握變量定義的位置與時(shí)機(jī)for(inti=0;i<N;i++){...//dosomething}...//somecodefor(inti=0;i<M;i++){...//doanotherthing}原因分析:這是因?yàn)樵赩C6.0中,i的作用域超出了本身的循環(huán)。存在變量名污染變量名污染著名例子明明兩個(gè)i都屬于各自for語(yǔ)句內(nèi)的局部變量作用域已經(jīng)足夠小上述代碼在VC6.0中是不能通過(guò)編譯的,編譯器會(huì)提示變量i重復(fù)定義。說(shuō)明:1.微軟意識(shí)到了這個(gè)問(wèn)題,在其后續(xù)的VC++系列產(chǎn)品中,i的作用域重新被限定在了for循環(huán)體2.變量名污染的本質(zhì)就是同一作用域下的命名沖突9:引用難道只是別人的替身引用的定義及特點(diǎn)引用只是默認(rèn)值的別名,對(duì)引用的唯一操作就是將其初始化。一旦引用初始化結(jié)束,引用就只是其默認(rèn)值的另一種寫(xiě)法。引用沒(méi)有地址,甚至不占用任何存儲(chǔ)空間。引用只可作為

變量的別名復(fù)雜的左值(有內(nèi)存地址)表達(dá)式的別名引用的用途如果一個(gè)函數(shù)返回一個(gè)引用,這說(shuō)明此函數(shù)的返回值可重新賦值引用的另一個(gè)用途即讓函數(shù)在其返回值之外傳遞幾個(gè)值。另外,指向數(shù)組的引用保留了數(shù)組的長(zhǎng)度信息,而指針不會(huì)保留數(shù)組的長(zhǎng)度信息。常量值不能給普通引用初始化,但是可以給const引用初始化:

constint&rInt=12;//正常通過(guò);

int&rInt=12//錯(cuò)誤9:引用難道只是別人的替身引用的用途int&put(intn);intvals[10];interror=-1;voidmain(){put(0)=10;put(9)=20;cout<<vals[0];cout<<vals[9];}int&put(intn){if(n>=0&&n<=9)returnvals[n];else{cout<<"subscripterror";returnerror;}}#include<iostream>#include<string>usingnamespacestd;intvs(inta,intb,intc,int&s1,int&s2,int&s3){intv;v=a*b*c;

s1=a*b;

s2=b*c;

s3=a*c;returnv;}intmain(){intl,w,h,v,s1,s2,s3;cout<<"inputlength,widthandheight\n";cin>>l>>w>>h;v=vs(l,w,h,s1,s2,s3);cout<<v<<"\n"<<s1<<"\n"<<s2<<"\n"<<s3;}只能返回體積,其余的三個(gè)面的面積怎么傳遞回主函數(shù)說(shuō)明:如果一個(gè)函數(shù)返回一個(gè)引用,這說(shuō)明此函數(shù)的返回值可重新賦值說(shuō)明:引用的另一個(gè)用途即讓函數(shù)在其返回值之外傳遞幾個(gè)值。9:引用難道只是別人的替身引用的用途#include<iostream>#include<string>usingnamespacestd;voidArray_test1(int(&array)[3]){array[2]=3;}voidArray_test2(intarray[3]){array[2]=3;}intmain(){intn3[2]={2,4};Array_test1(n3);Array_test2(n3);}編譯不能通過(guò)編譯能通過(guò)指向數(shù)組的引用,保留數(shù)組的長(zhǎng)度為3,卻傳來(lái)一個(gè)長(zhǎng)度為3的數(shù)組指向數(shù)組的指針,只記住數(shù)組的首地址說(shuō)明:指向數(shù)組的引用,可以保留數(shù)組長(zhǎng)度9:引用難道只是別人的替身引用的用途#include<iostream>#include<iomanip>usingnamespacestd;intmain(){inta;int&b=a;constint&c=12.3;cout<<c;shorts=123;constint&rIntegrate=s;s=321;constint*ip=&rIntegrate;cout<<"rIntegrate="<<rIntegrate<<",s="<<s<<endl;cout<<"ip="<<ip<<",&s="<<&s;return0;引用初始化值為左值沒(méi)問(wèn)題引用默認(rèn)值不是左值,必須前面加constrInte與s值并不相同,說(shuō)明rInte默認(rèn)值并不是s,而是一個(gè)臨時(shí)對(duì)象說(shuō)明:常量引用與臨時(shí)變量共存亡9引用難道只是別人的替身小心陷阱:如果初始化值是一個(gè)左值(可以取得地址),則可以初始化引用。如果初始化值不是一個(gè)左值,則只能對(duì)constT&(常量引用)賦值,且賦值過(guò)程包括3階段:首先將值隱式轉(zhuǎn)換到類(lèi)型T,然后將這個(gè)轉(zhuǎn)換結(jié)果存放在一個(gè)臨時(shí)對(duì)象中,最后用這個(gè)臨時(shí)對(duì)象來(lái)初始化這個(gè)引用變量。constT&(常量引用)過(guò)程中使用的臨時(shí)變量會(huì)和constT&共“存亡”。constint&rInt=12;//對(duì)變量引用的任何操作都會(huì)影響匿名臨時(shí)變量,而不會(huì)影響常量12.并且編譯器會(huì)保證臨時(shí)對(duì)象生命期擴(kuò)展到初始化后的引用存在的全部時(shí)域。Tips:若非必要請(qǐng)不要使用const引用,因?yàn)橐糜袝r(shí)會(huì)伴隨著臨時(shí)對(duì)象的產(chǎn)生。在函數(shù)生命中,請(qǐng)盡量避免const引用形參聲明,使用非const引用形參替代以防因返回const引用生成的臨時(shí)變量而導(dǎo)致程序執(zhí)行錯(cuò)誤。a=b+100;a就是左值,b+25就是一個(gè)右值。兩邊不可互換。13:typedef使用的陷阱Typydef與宏的混用陷阱#include<iostream>#definePSTR_MACROchar*typedefchar*PSTR;usingnamespacestd;intmain(intargc,char*argv[]){PSTRpiVar1,piVar2;PSTR_MACROpiVar3,piVar4;chariVar=100;piVar1=&iVar;piVar2=&iVar;piVar3=&iVar;piVar4=iVar;cout<<(void*)piVar1<<endl;cout<<(void*)piVar2<<endl;cout<<(void*)piVar3<<endl;cout<<piVar4<<endl;return0;}Typedef是給數(shù)據(jù)類(lèi)型定義一個(gè)別名宏定義只是簡(jiǎn)單的字符串替換13:typedef使用的陷阱typedef

string

NAME;

typedef

int

AGE;#define

MAC_NAME

string

#define

MAC_AGE

int

typedef

int*

PTR_INT1;

#define

int*

PTR_INT2

int

main()

{

PTR_INT1

pNum1,

pNum2;

PTR_INT2

pNum3,

pNum4;

int

year

=

2011;

pNum1

=

&year;

pNum2

=

&year;

pNum3

=

&year;

pNum4

=

&year;

cout<<pNum1<<"

"<<pNum2<<"

"<<pNum3<<"

"<<pNum4;

return

0;

}

Typydef與宏的混用陷阱stringa,b;intc,d;

stringa,b;intc,d;

MAC_NAMEa,b;MAC_AGEc,d;

stringa,b;intc,d;

PTR_INT1

pNum1,

pNum2;

PTR_INT2

pNum3,

pNum4;

int*pNum1,

*pNum2;int*pNum3,

pNum4;13:typedef使用的陷阱Typedef其他多種用途:(1)簡(jiǎn)化代碼在部分較老的C代碼中,聲明struct對(duì)象時(shí),必須帶上struct關(guān)鍵字,即采用“struct結(jié)構(gòu)體類(lèi)型結(jié)構(gòu)體對(duì)象”的聲明格式。

為了在結(jié)構(gòu)體使用過(guò)程中,少寫(xiě)聲明頭部的struct,于是就有人使用了typedef:struct

tagRect

{

int

width;

int

length;

};

strcut

tagRect

rect;

typedef

struct

tagRect

{

int

width;

int

length;

}RECT;

RECT

rect;

說(shuō)明:在現(xiàn)在的C++代碼中,這種方式已經(jīng)不常見(jiàn),因?yàn)閷?duì)于結(jié)構(gòu)體對(duì)象的聲明已經(jīng)不需要使用struct了,可以采用“結(jié)構(gòu)體類(lèi)型結(jié)構(gòu)體對(duì)象”的形式。13:typedef使用的陷阱(2)用typedef定義一些與平臺(tái)無(wú)關(guān)的類(lèi)型。例如在標(biāo)準(zhǔn)庫(kù)中廣泛使用的size_t的定義:(3)為復(fù)雜的聲明定義一個(gè)簡(jiǎn)單的別名。它可以增強(qiáng)程序的可讀性和標(biāo)識(shí)符的靈活性,這也是它最突出的作用。說(shuō)明:在typedef的使用過(guò)程中,還必須記?。簍ypedef在語(yǔ)法上是一個(gè)存儲(chǔ)類(lèi)的關(guān)鍵字,類(lèi)似于auto、extern、mutable、static、register等,雖然它并不會(huì)真正影響對(duì)象的存儲(chǔ)特性,#ifndef

_SIZE_T_DEFINED

#ifdef

_WIN64

typedef

unsigned

__int64

size_t;

#else

typedef

_W64

unsigned

int

size_t

#endif

#define

_SIZE_T_DEFINED

#endif

typedef

static

int

INT2;

//不可行,編譯將失敗

聲明:int*(*a[5])(int,char*);變量名為a,直接用一個(gè)新別名pFun替換a就可以了:

typedefint*(*pFun)(int,char*);

原聲明的最簡(jiǎn)化版:pFuna[5];13:typedef使用的陷阱用途一:定義一種類(lèi)型的別名,而不只是簡(jiǎn)單的宏替換。可以用作同時(shí)聲明指針型的多個(gè)對(duì)象。用途二:用在舊的C的代碼中(具體多舊沒(méi)有查),幫助struct。以前的代碼中,聲明struct新對(duì)象時(shí),必須要帶上struct,即形式為:struct結(jié)構(gòu)名對(duì)象名。用途三:用typedef來(lái)定義與平臺(tái)無(wú)關(guān)的類(lèi)型。用途四:為復(fù)雜的聲明定義一個(gè)新的簡(jiǎn)單的別名。Tips:區(qū)分typedef與#define之間的不同;不要用理解宏的思維方式對(duì)待typedef,typedef聲明的新名稱具有一定的封裝性,更易定義變量,而#define宏只是簡(jiǎn)單的自讀替換。盡量用typedef實(shí)現(xiàn)那些復(fù)雜的聲明形式,以保證代碼清晰,易于閱讀。16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩在C/C++中,類(lèi)型轉(zhuǎn)換發(fā)生在這種情況下:為了實(shí)現(xiàn)不同類(lèi)型的數(shù)據(jù)之間進(jìn)行某一操作或混合運(yùn)算,編譯器必須把數(shù)據(jù)轉(zhuǎn)換成為相同的數(shù)據(jù)類(lèi)型。C/C++語(yǔ)言中的類(lèi)型轉(zhuǎn)換可以分為兩種,一種為隱式轉(zhuǎn)換,特指編譯器完成的類(lèi)型轉(zhuǎn)換;而另一種則為顯式強(qiáng)制轉(zhuǎn)型特指由開(kāi)發(fā)人員顯式進(jìn)行的數(shù)據(jù)類(lèi)型轉(zhuǎn)換。顯式強(qiáng)制轉(zhuǎn)型在某種程度上還有一定的優(yōu)點(diǎn),對(duì)于編寫(xiě)代碼的人來(lái)說(shuō)使用它能夠很容易地獲得所需類(lèi)型的數(shù)據(jù),對(duì)于閱讀代碼的人來(lái)說(shuō)可以從代碼中獲知作者的意圖。而隱式轉(zhuǎn)換則不然,它讓發(fā)生的一切變得悄無(wú)聲息,在編譯時(shí)這一切由編譯程序按照一定規(guī)則自動(dòng)完成,不需任何的人為干預(yù)。16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩隱式轉(zhuǎn)換雖然帶來(lái)了一定的便利,使編碼更加簡(jiǎn)潔,減少了冗余,但是這些并不足以讓我們完全接受它,因?yàn)殡[式轉(zhuǎn)換所帶來(lái)的副作用不可小覷,它通常會(huì)使我們?cè)谡{(diào)試程序時(shí)毫無(wú)頭緒。上述代碼片段中的函數(shù)調(diào)用不會(huì)出現(xiàn)任何錯(cuò)誤,編譯器給出的僅僅是一個(gè)警告??墒羌?xì)心的程序員一眼就能看出問(wèn)題:函數(shù)Function(charc)的參數(shù)c是一個(gè)char型,256絕不會(huì)出現(xiàn)在其取值區(qū)間內(nèi)。但是編譯器會(huì)自動(dòng)地完成數(shù)據(jù)截?cái)嗵幚?。編譯器悄悄完成的這種轉(zhuǎn)換存在著很大的不確定性:一方面它可能是合理的,因?yàn)楸M管類(lèi)型long大于char,但para中很可能存放著char類(lèi)型范圍內(nèi)的數(shù)值;另一方面para的值的確可能是char無(wú)法容納的數(shù)據(jù),這樣一不小心便會(huì)造成一個(gè)非常隱蔽、難以捉摸的錯(cuò)誤。void

Function(char

c);

int

main()

{

long

para

=

256;

Function(para);

return

0;

}

16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩C/C++隱式轉(zhuǎn)換主要發(fā)生在以下幾種情形。1、內(nèi)置類(lèi)型間的隱式轉(zhuǎn)換在混合類(lèi)型的表達(dá)式中,操作數(shù)轉(zhuǎn)換成相同的類(lèi)型;用作if語(yǔ)句或循環(huán)語(yǔ)句的條件時(shí),被轉(zhuǎn)換為bool類(lèi)型;用于switch語(yǔ)句時(shí),被轉(zhuǎn)換為整數(shù)類(lèi)型;用來(lái)初始化某個(gè)變量(函數(shù)實(shí)參、return語(yǔ)句)時(shí),被轉(zhuǎn)換為變量的類(lèi)型。內(nèi)置類(lèi)型的轉(zhuǎn)換級(jí)別:Double>float>longlong/unsignedlonglong>long/unsignedlong>int/unsignedint>short/unsignedshort>char/unsignedchar16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩在編譯這段代碼時(shí),編譯器會(huì)按照規(guī)則自動(dòng)地將ival轉(zhuǎn)換為與dval相同的double類(lèi)型。C語(yǔ)言規(guī)定的轉(zhuǎn)換規(guī)則是由低級(jí)向高級(jí)轉(zhuǎn)換。兩個(gè)通用的轉(zhuǎn)換原則是:(1)為防止精度損失,類(lèi)型總是被提升為較寬的類(lèi)型。(2)所有含有小于整型類(lèi)型的算術(shù)表達(dá)式在計(jì)算之前其類(lèi)型都會(huì)被轉(zhuǎn)換成整型。它最直接的害處就是有可能導(dǎo)致重載函數(shù)產(chǎn)生二義性。(右圖)參數(shù)0.5應(yīng)該轉(zhuǎn)換為ival還是fval?這是編譯器沒(méi)法搞明白的一個(gè)問(wèn)題。int

ival

=

3;

double

dval

=

3.1415

cout<<(ival

+

dval)<<endl;

//ival被提升為double類(lèi)型:3.0

extern

double

sqrt(double);

sqrt(2);

//2被提升為double類(lèi)型:

2.0void

Print(int

ival);

void

Print(float

fval);

int

ival

=

2;

float

fval

=

2.0f;

Print(ival);

//

OK,

int-version

Print(fval);

//

OK,

float-version

Print(1);

//

OK,

int-version

Print(0.5);

//

ERROR!!

16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩non-explicitconstructor接受一個(gè)參數(shù)的用戶定義類(lèi)對(duì)象之間隱式轉(zhuǎn)換。在上面的代碼(右圖)中,調(diào)用DoSomething()函數(shù)時(shí)會(huì)發(fā)現(xiàn)實(shí)參與形參類(lèi)型不一致,但是因?yàn)轭?lèi)A的構(gòu)造函數(shù)只含有一個(gè)int類(lèi)型的參數(shù),所以編譯器會(huì)以20為參數(shù)調(diào)用A的構(gòu)造函數(shù),以便構(gòu)造臨時(shí)對(duì)象,然后傳給DoSomething()函數(shù)。不要為此而感到驚訝,其實(shí)編譯器比想像的還要聰明:當(dāng)無(wú)法完成直接隱式轉(zhuǎn)換的時(shí)候,它不會(huì)罷休,它會(huì)嘗試使用間接的方式。所以,下面的代碼也是可以被編譯器接受的:classA{public:A(intx):m_data(x){}private:intm_data;}voidDoSomething(AaObject);DoSomething(20);voidDoSomething(AaObject);floatfval=20.0;DoSomething(fval);16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩控制隱式轉(zhuǎn)換的兩條有效途徑之一:使用具名轉(zhuǎn)換函數(shù)為了避免該問(wèn)題出現(xiàn),建議使用自定義轉(zhuǎn)換具名函數(shù)代替轉(zhuǎn)換操作符ClassString{pubic:operatorconstchar*();//在需要時(shí),string對(duì)象可以轉(zhuǎn)換成constchar*指針};//假設(shè)s1s2均是string類(lèi)型的字符串Intx=s1-s2;//可編譯,單行為不確定Constchar*p=s1-5;//可編譯,但行為不確定P=s1+‘0’//可編譯,單不是開(kāi)發(fā)人員期望的結(jié)果If(s1==“0”){……}’//可編譯,單不是開(kāi)發(fā)人員期望的結(jié)果ClassString{pubic:constchar*as_char_pointer()const;//string對(duì)象轉(zhuǎn)換成constchar*指針};//假設(shè)s1s2均是string類(lèi)型的字符串Intx=s1-s2;//編譯錯(cuò)誤Constchar*p=s1-5;//編譯錯(cuò)誤P=s1+‘0’//編譯錯(cuò)誤If(s1==“0”){……}’//編譯錯(cuò)誤16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩控制隱式轉(zhuǎn)換的兩條有效途徑之二:使用explicit限制的構(gòu)造函數(shù)這種方式針對(duì)的是具有一個(gè)單參數(shù)構(gòu)造函數(shù)的用戶自定義類(lèi)型。上述代碼片段(右圖)中,用戶自定義類(lèi)型Widget的構(gòu)造函數(shù)可以是一個(gè)參數(shù),也可以是兩個(gè)參數(shù)。具有一個(gè)參數(shù)時(shí),其參數(shù)類(lèi)型可以是unsignedint,亦可以是char*。所以這兩種類(lèi)型的數(shù)據(jù)均可以隱式地轉(zhuǎn)換為Widget類(lèi)型??刂七@種隱式轉(zhuǎn)換的方法很簡(jiǎn)單:為構(gòu)造函數(shù)加上explicit關(guān)鍵字:class

Widget

{

public:

Widget(

unsigned

int

factor);

Widget(

const

char*

name,

const

Widget*

other

=

NULL);

};

Widgetwidget1=100;//可通過(guò)編譯Widgetwidget1=“mywindow”//可通過(guò)編譯class

Widget

{

explicit

Widget(unsigned

int

factor);

explicit

Widget(const

char*

name,

const

Widget*

other

=

NULL);

};

Widgetwidget1=100;//編譯錯(cuò)誤Widgetwidget1=“mywindow”//編譯錯(cuò)誤16:提防隱式轉(zhuǎn)換帶來(lái)的麻煩提防隱式轉(zhuǎn)換所帶來(lái)的微妙問(wèn)題,盡量控制隱式轉(zhuǎn)換的發(fā)生;通常采用的方式包括:(1)使用非C/C++關(guān)鍵字的具名函數(shù),用operatoras_T()替換operatoT()(T為C++數(shù)據(jù)類(lèi)型)。(2)為單參數(shù)的構(gòu)造函數(shù)加上explicit關(guān)鍵字。在隱式轉(zhuǎn)換中,轉(zhuǎn)型并非僅僅將一種類(lèi)型轉(zhuǎn)換為另外一種,參看p71實(shí)例1、實(shí)例2。Tips:在使用編譯器隱式類(lèi)型轉(zhuǎn)換時(shí),一定要注意,能減少隱式轉(zhuǎn)換使用時(shí)盡量減少隱式轉(zhuǎn)換的使用;除非明確知道隱式轉(zhuǎn)換時(shí)編譯器發(fā)生了什么,否則在編譯時(shí)不要對(duì)編譯器隱式轉(zhuǎn)換進(jìn)行假設(shè)。17:正確區(qū)分void與void*void是“無(wú)類(lèi)型”,所以它不是一種數(shù)據(jù)類(lèi)型;void*則為“無(wú)類(lèi)型指針”,即它是指向無(wú)類(lèi)型數(shù)據(jù)的指針,也就是說(shuō)它可以指向任何類(lèi)型的數(shù)據(jù)。從來(lái)沒(méi)有人會(huì)定義一個(gè)void變量,如果真的這么做了,編譯器會(huì)在編譯階段清晰地提示,“illegaluseoftype‘void’”。void體現(xiàn)的是“有與無(wú)”的問(wèn)題,要先“有”了,在非void的前提下才能去討論這個(gè)變量是什么類(lèi)型的。void發(fā)揮的真正作用是限制程序的參數(shù)與函數(shù)返回值。voida;//定義無(wú)類(lèi)型變量,無(wú)意義

void*p;//定義無(wú)類(lèi)型指針,會(huì)有意義intb;p=&b;inta;(void)a;//強(qiáng)制轉(zhuǎn)換變量類(lèi)型char*p;(void*)p//強(qiáng)制轉(zhuǎn)換指針類(lèi)型17:正確區(qū)分void與void*在C/C++語(yǔ)言中,對(duì)void關(guān)鍵字的使用做了如下規(guī)定:(1)如果函數(shù)沒(méi)有返回值,那么應(yīng)將其聲明為void類(lèi)型。在C語(yǔ)言中,凡不加返回值類(lèi)型限定的函數(shù),就會(huì)被編譯器作為返回整型值處理。程序運(yùn)行的結(jié)果為:2+3=5。這個(gè)結(jié)果更加明確地說(shuō)明了函數(shù)返回值為int類(lèi)型,而非void。為了避免出現(xiàn)混亂,在編寫(xiě)C/C++程序時(shí),必須對(duì)任何函數(shù)都指定其返回值類(lèi)型。如果函數(shù)沒(méi)有返回值,則要聲明為void。這既保證了程序良好的可讀性,也滿足了編程規(guī)范性的要求。Add

(

int

a,

int

b

);

int

main()

{

printf

(

“2

+

3

=

%d",

Add

(

2,

3)

);

return

0;

}

Add

(

int

a,

int

b

)

{

return

a

+

b;

}

17:正確區(qū)分void與void*(2)如果函數(shù)無(wú)參數(shù),那么聲明函數(shù)參數(shù)為void。如右圖代碼段,在C++編譯器中編譯代碼時(shí)則會(huì)出錯(cuò),提示“'TestFunction':functiondoesnottake1parameters”。在C/C++中,若函數(shù)不接受任何參數(shù),一定要指明參數(shù)為void。int

TestFunction(void)int

TestFunction()//

{

return

1;

}

int

main()

{

int

thisYear

=

TestFunction(2);

//

processing

code

return

0;

}

17:正確區(qū)分void與void*(3)特殊指針類(lèi)型void*。按照ANSI標(biāo)準(zhǔn),對(duì)void指針進(jìn)行算術(shù)操作是不合法的:ANSI標(biāo)準(zhǔn)之所以這樣認(rèn)定,是因?yàn)橹挥性诖_定了指針指向數(shù)據(jù)類(lèi)型的大小之后,才能進(jìn)行算術(shù)操作。但是大名鼎鼎的GNU則有不同的規(guī)定,它指定void*的算法操作與char*一致。所以在上面代碼片段中出現(xiàn)錯(cuò)誤的代碼在GNU編譯器中能順利通過(guò)編譯,并且能正確執(zhí)行。雖然GNU較ANSI更開(kāi)放,提供了對(duì)更多語(yǔ)法的支持,但是ANSI標(biāo)準(zhǔn)更加通用,更加“標(biāo)準(zhǔn)”,所以在實(shí)際設(shè)計(jì)中,還是應(yīng)該盡可能地迎合ANSI標(biāo)準(zhǔn)。void

*

pVoid;

pVoid

++;

//

VC++錯(cuò)誤,error

C2036:

“pVoid*”:

未知的大小(GNU,正確)

pVoid

+=

1;

//

VC++錯(cuò)誤

(GNU,正確)

int

*

pInt;

pInt

++;

//

正確,pInt指針增大sizeof(int)

pInt

+=

2;

//正確,

pInt指針增大2*sizeof(int)17:正確區(qū)分void與void*(3)特殊指針類(lèi)型void*。在實(shí)際的程序設(shè)計(jì)中,為迎合ANSI標(biāo)準(zhǔn),并提高程序的可移植性,可以采用以下方式進(jìn)行代碼設(shè)計(jì):(4)如果函數(shù)的參數(shù)可以是任意類(lèi)型指針,那么應(yīng)聲明其參數(shù)為void*.最典型的例子就是我們熟知的內(nèi)存操作函數(shù)memcpy和memset的原型:任何類(lèi)型的指針都可以傳入memcpy和memset中,傳出的則是一塊沒(méi)有具體數(shù)據(jù)類(lèi)型規(guī)定的內(nèi)存,這也真實(shí)地體現(xiàn)了內(nèi)存操作函數(shù)的意義。如果類(lèi)型不是void*,而是char*,那么這樣的memcpy和memset函數(shù)就會(huì)與數(shù)據(jù)類(lèi)型產(chǎn)生明顯聯(lián)系,糾纏不清。void

*

pVoid;

(char

*)pVoid

++;

//

ANSI:正確;GNU:正確

(char

*)pVoid

+=

2;

//

ANSI:錯(cuò)誤;GNU:正確

void

*

memcpy(void

*dest,

const

void

*src,

size_t

len);

void

*

memset

(

void

*

buffer,

int

c,

size_t

num

);

17:正確區(qū)分void與void*(5)void不能代表一個(gè)真實(shí)的變量。Void體現(xiàn)了一種抽象,他的出現(xiàn)只是因?yàn)橐环N抽象的需要,如果你正確的理解了面向?qū)ο蟮某橄蠡?lèi)的概念,也就很容易理解void數(shù)據(jù)類(lèi)型。正如不能給一個(gè)抽象基類(lèi)定義實(shí)例一樣,我們不能定義void變量。void與void*是一對(duì)極易混淆的雙胞胎兄弟,但是它們?cè)诠亲永飬s存在著質(zhì)的不同,區(qū)分它們,按照一定的規(guī)則使用它們,可以提高程序的可讀性、可移植性。void

a;

Function(voida)

//

錯(cuò)誤

18:如何判定變量是否相等判斷兩個(gè)變量是否相等,有兩點(diǎn)非常重要:一是兩個(gè)變量分別都是什么類(lèi)型。首先兩個(gè)變量的類(lèi)型應(yīng)該是一致的,如果不一致,那么判定其是否相等則無(wú)疑義。二是變量相等的判斷依據(jù)是什么?判斷兩個(gè)變量是否相等時(shí),兩個(gè)變量類(lèi)型必須相同。每種類(lèi)型的變量,其判定依據(jù)各不相同,有些可判斷,有些無(wú)法判斷是否相等。只有那些允許判定是否相等的變量才可以判斷是否相等。變量類(lèi)型:布爾變量、整型變量、浮點(diǎn)型變量、字符型變量、指針變量。18:如何判定變量是否相等Bool變量一般描述某一操作執(zhí)行成功與否,成功返回true,否則返回false。布爾類(lèi)型的變量一般無(wú)法判定是否相等,判斷兩個(gè)布爾變量是否相等沒(méi)有意義。整形值包括(unsigned)char,short,int這幾種數(shù)據(jù)類(lèi)型。判定兩個(gè)整型變量是否相等,一般包括以下兩個(gè)步驟:1、應(yīng)保證兩個(gè)整型值為同一類(lèi)型,如果不同,C++編譯器會(huì)默認(rèn)將類(lèi)型階低的變量轉(zhuǎn)換為階高的變量。即存在潛在的隱式轉(zhuǎn)換,會(huì)帶來(lái)意想不到的麻煩。(p78)而顯示轉(zhuǎn)換更不可取。2、如果類(lèi)型同,通過(guò)“==”操作符即可進(jìn)行兩個(gè)整型變量是否相等的判定。18:如何判定變量是否相等浮點(diǎn)型變量包括單精度浮點(diǎn)型和雙精度浮點(diǎn)型。浮點(diǎn)型的比較不能通過(guò)簡(jiǎn)單的“==”進(jìn)行判定,必須通過(guò)差值的絕對(duì)值的精度判定。這是由浮點(diǎn)數(shù)據(jù)在內(nèi)存中存放的格式?jīng)Q定的。一個(gè)字符一般由多個(gè)字符組成。兩個(gè)字符串相等要滿足兩個(gè)條件:一是字符串的長(zhǎng)度必須相等;而是兩個(gè)字符串的每個(gè)字符必須相等。18:如何判定變量是否相等C語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供幾個(gè)標(biāo)準(zhǔn)函數(shù),可比較兩個(gè)字符串是否相等,它們是strmp和strmpi.。strcmp對(duì)兩個(gè)字符串進(jìn)行大小寫(xiě)敏感的比較,strcmpi對(duì)兩個(gè)字符串進(jìn)行大小寫(xiě)不敏感的比較。指針變量是C++中功能最強(qiáng)大,也是出現(xiàn)問(wèn)題最多的地方,比較時(shí),必須保證是同一類(lèi)型的指針變量。且無(wú)法進(jìn)行大于小于的比較。18:如何判定變量是否相等#include<iostream>usingnamespacestd;intmain(){char

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論