版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第5章指針、數(shù)組和結(jié)構(gòu)
5.1指針5.2數(shù)組5.3指向數(shù)組的指針5.4指向函數(shù)的指針5.5指向void*的指針5.6常量5.7引用5.8結(jié)構(gòu)小結(jié)練習(xí)題
5.1指針
5.1.1指針與指針變量
所謂指針,即一個(gè)變量的內(nèi)存存儲(chǔ)地址。假設(shè)變量v的地址是0x06AF(十六進(jìn)制),我們就說(shuō)v的指針(或稱指針值)是0x06AF。
對(duì)于類型T(T為基本類型或?yàn)樽远x類型),指針類型(表示為T(mén)*)是“指向T類型對(duì)象的指針”,即一個(gè)T*?類型的指針變量只能存放一個(gè)類型為T(mén)的對(duì)象的地址。例如:
charc=‘a(chǎn)’;圖5.1char*類型的變量pv中存放char類型變量c的地址
char*pv=&c;//取變量c的地址,并賦給指針char*類型的變量pv用圖5.1表示如下。引入指針類型的目的是用某個(gè)指針變量中的值間接地存/取它所指的對(duì)象的內(nèi)容。
大部分教科書(shū)及專業(yè)書(shū)籍都把指針和指針變量統(tǒng)稱為指針,因此,到底是指針還是指針變量,讀者在學(xué)習(xí)與閱讀時(shí)一定要注意其上下文環(huán)境,并根據(jù)上下文來(lái)進(jìn)行判斷。5.1.2為什么要使用指針變量
通常,我們是用某種類型的變量去存儲(chǔ)相應(yīng)類型的值,然后,通過(guò)變量名去存/取(注意:計(jì)算機(jī)的動(dòng)作是在內(nèi)存中存/取)其中的值。既然能用變量名(與某塊內(nèi)存綁定)直接存/取內(nèi)存中的值,那么為什么還要用指針來(lái)間接存/取內(nèi)存中所存儲(chǔ)的值呢?
應(yīng)用中,以下幾種情況必須使用指針:
(1)如果在起始地址為Av的存儲(chǔ)空間Sv中存儲(chǔ)的值是在運(yùn)行時(shí)根據(jù)運(yùn)行情況才寫(xiě)入的,不能事先規(guī)定所寫(xiě)入的是哪個(gè)變量的值,能夠保證的只是所寫(xiě)入的一定是類型為T(mén)的值,這時(shí)應(yīng)該采用指針。例如,多進(jìn)程之間利用一塊共享內(nèi)存進(jìn)行通信時(shí),其底層實(shí)現(xiàn)采用的就是指針,如圖5.2所示。圖5.2多進(jìn)程之間的通信
(2)如果需要同時(shí)對(duì)一組同類型的數(shù)據(jù)進(jìn)行多個(gè)側(cè)面或角度的組織,以有效地支持多種不同性質(zhì)的操作(源數(shù)據(jù)要求不動(dòng)),這時(shí)亦應(yīng)該使用指針。例如,某應(yīng)用欲實(shí)現(xiàn)一批整型數(shù)同時(shí)進(jìn)行遞增和遞減排序,并要求源數(shù)據(jù)保持不動(dòng),這時(shí)就需要采用指針,如圖5.3所示。圖5.3源數(shù)據(jù)要求不動(dòng)的一批同類型數(shù)據(jù)的遞增、遞減排序
(3)對(duì)于連續(xù)存儲(chǔ)著類型為T(mén)的許多個(gè)值(例如數(shù)組)的情況,當(dāng)需要依次進(jìn)行某種處理時(shí),可以在不需要知道數(shù)組下標(biāo)(或數(shù)組的界)的情況下,用改變一個(gè)指針變量的值的方式來(lái)依次進(jìn)行這一批同類型量的訪問(wèn),如圖5.4所示。
此外,指針還有其它的一些應(yīng)用場(chǎng)合,此處不一一介紹。圖5.4用指針對(duì)一批連續(xù)存放的同類型值的處理5.1.3指針變量的聲明與定義
與指針相關(guān)的聲明共分兩類,即定義聲明和非定義聲明。
1.定義聲明
(1)定義聲明與數(shù)據(jù)相關(guān)的指針,例如:
char*pc; //pc:指向char類型值的指針變量
int*pi; //pi:指向int類型值的指針變量
char**ppc; //ppc:指向“指向char類型值的指針”的
指針變量
int*ap[15]; //ap:由15個(gè)指向int類型值的指針變量
構(gòu)成的指針數(shù)組
(2)定義聲明與函數(shù)相關(guān)的指針,例如:
int(*fp)(char*);
//fp:指向參數(shù)為char*類型、返回值為int類型的函數(shù)指針
2.非定義聲明
例如:
int*f(char*); //參數(shù)為char*類型、返回值為int*類型
的函數(shù)聲明
C++的語(yǔ)法并不限定多級(jí)指針的定義,例如我們可定義一個(gè)二級(jí)指針:
char**ppc;
則ppc指針變量中就可存放指向char類型的指針變量的地址,如圖5.5所示。圖5.5二級(jí)指針變量中的內(nèi)容我們亦可定義一個(gè)三級(jí)指針(或更多級(jí)的指針),例如:
int***ppi;
但實(shí)際應(yīng)用中,應(yīng)避免定義復(fù)雜的多級(jí)指針,二級(jí)指針變量足矣!5.1.4指針變量的操作
設(shè)T為任意類型(基本類型或用戶自定義類型),則T類型指針變量的類型為T(mén)*。與指針類型相關(guān)的操作如下。
1.取地址
操作符:&,一元前綴運(yùn)算符,采用右結(jié)合律。
語(yǔ)義:取某個(gè)T類型變量的地址并返回之。
例如:
charc=‘a(chǎn)’;
char*p=&c;//取c變量的地址并賦給指針變量p
2.求內(nèi)容(內(nèi)容解析)
操作符:*,一元前綴運(yùn)算符,采用右結(jié)合律。
語(yǔ)義:以相應(yīng)指針變量中的值為地址,求出該地址中存儲(chǔ)的值并返回之。
例如:
charc=‘a(chǎn)’;
char*p=&c;
charc2=*p; //c2=‘a(chǎn)’
注意:&
和
*
二者互為逆操作。若定義
charc;
char*p=&c;
則*(&c)==c,&(*p)==p。
3.指針變量的自增(減)操作
指針變量可進(jìn)行前綴/后綴的自增(減)操作。例如:
charc=‘a(chǎn)’;
char*pc=&a;
pc++;
//等價(jià)于pc+sizeof(char);
--pc;//等價(jià)于pc-sizeof(char);
簡(jiǎn)言之,對(duì)于一個(gè)T*類型的指針變量pt:
pt++; //等價(jià)于pt=pt+sizeof(T);
++pt; //等價(jià)于pt=pt+sizeof(T);
pt--;//等價(jià)于pt=pt-sizeof(T);
--pt;//等價(jià)于pt=pt-sizeof(T);
4.指針變量的加(減)操作
指針變量可與一個(gè)整數(shù)常量進(jìn)行加、減操作。設(shè)N為一整型常量,則
pt+N; //等價(jià)于pt=pt+N*sizeof(T)
pt-N;//等價(jià)于pt=pt-N*sizeof(T)
5.指向同一數(shù)組的指針變量的相減操作
當(dāng)兩個(gè)同類型的指針變量指向同一數(shù)組時(shí),兩指針變量可進(jìn)行相減操作。相加操作沒(méi)有定義,被認(rèn)為是非法操作。例如:
inta[]={1,2,3,4,5,6};
int*pa1,pa2;
pa1=a; //pa1指向數(shù)組首元素a[0]
pa2=&a[4]; //pa2指向數(shù)組元素a[4]
intn=pa2-pa1;//n=4,表示二指針?biāo)冈匚恢弥g
的差
n=pa1+pa2;//錯(cuò)誤!沒(méi)有定義
由于指針變量的自增(減)操作、加(減)操作是直接針對(duì)內(nèi)存地址的操作,所以在進(jìn)行這些操作時(shí),一定要注意指針的越界問(wèn)題。關(guān)于此問(wèn)題的討論與處理詳見(jiàn)下文。
T*類型指針變量的取值范圍為T(mén)類型變量的所有的合法地址。5.1.5常量零(0)
一般而言,數(shù)字字面值0的類型為整型。由于C++中允許各種基本類型的相互轉(zhuǎn)換,因此,數(shù)字0廣義地說(shuō),可作為任意整型、浮點(diǎn)型、指針、指向成員的指針變量的字面值常量。因此,在上述情況下,數(shù)學(xué)0的類型就與上下文環(huán)境相關(guān),并由其上下文環(huán)境所決定。
因計(jì)算機(jī)內(nèi)存地址為0的單元一直保留未用,即沒(méi)有任何對(duì)象會(huì)被分配到內(nèi)存地址為0的地方,故0可用作一個(gè)指針變量的字面值常量。當(dāng)一個(gè)指針變量初始化為0時(shí),表示它此刻沒(méi)有指向任何對(duì)象。在C中流行用宏NULL表示0。由于C++不同的實(shí)現(xiàn)可能對(duì)NULL的定義不同,所以,直接采用0而非NULL會(huì)使得指針的初始化更可靠、安全。如果你非常熟悉C,且習(xí)慣于采用C的宏NULL,建議在編寫(xiě)C++程序時(shí)可先定義:
constintNULL=0;//定義NULL是一個(gè)表示0的字符常量
然后在程序中再采用符號(hào)常量NULL。
5.2數(shù)組
對(duì)于類型T,一個(gè)數(shù)組類型T[size](size表示數(shù)組中元素的個(gè)數(shù),一般為整型常量)是類型為T(mén)的size個(gè)元素的有序集合,數(shù)組中的元素可用下標(biāo)訪問(wèn),其下標(biāo)范圍為[0~size-1]。
數(shù)組類型屬于構(gòu)造類型,即一個(gè)數(shù)組類型是由兩個(gè)類型構(gòu)造而成的:一個(gè)是數(shù)組元素的類型(如T類型),另一個(gè)是索引(或稱下標(biāo))類型(如{0,1,…,size-1},即對(duì)應(yīng)索引類型的值集)。標(biāo)準(zhǔn)C++規(guī)定:數(shù)組元素的類型可為任意數(shù)據(jù)類型(包括另一個(gè)數(shù)組類型,但必須保證其元素的類型是同質(zhì)的),而索引(下標(biāo))類型要求其值集上的元素要有偏序(順序)關(guān)系(一般為整型或枚舉類型)。5.2.1數(shù)組的定義與初始化
在C++中,可定義一維數(shù)組和多維數(shù)組,定義方式如下例所示:
inta[10];
//定義一個(gè)元素類型為int,元素個(gè)數(shù)為
10的一維整型數(shù)組a
intb[2][3]; //定義一個(gè)元素類型為int,元素個(gè)數(shù)
(2行3列)為6的二維數(shù)組b
定義數(shù)組時(shí),其數(shù)組類型和數(shù)組類型的變量(后者通常簡(jiǎn)稱為數(shù)組)一般在定義聲明中是同時(shí)聲明的。例:
floatv[3]; //float[3]v;
char*a[32]; //(char*)[32]a;
intd2[10][7]; //(int[10])[7]d2;
上述第一條語(yǔ)句定義了一個(gè)元素類型為float,元素個(gè)數(shù)為3的數(shù)組類型,并定義了這種數(shù)組類型的一個(gè)變量為v,數(shù)組類型與其類型的變量二者在定義時(shí)同時(shí)聲明。
第二條語(yǔ)句定義了一個(gè)元素類型為char*,元素個(gè)數(shù)為32的數(shù)組類型(即字符指針數(shù)組),并定義了該數(shù)組類型的一個(gè)變量a,數(shù)組類型與其類型的變量二者在定義時(shí)同時(shí)聲明。第三條語(yǔ)句定義了一個(gè)元素類型為int[10](一維整型數(shù)組,元素個(gè)數(shù)為10),元素個(gè)數(shù)為7的數(shù)組類型(即數(shù)組中的數(shù)組),并定義了該數(shù)組類型的變量d2,數(shù)組類型與其類型的變量d2二者在定義時(shí)同時(shí)聲明。
一旦定義聲明了某個(gè)數(shù)組類型T[size](size為常量)的變量a,編譯器在編譯時(shí)會(huì)根據(jù)數(shù)組的定義給這個(gè)變量a連續(xù)分配一塊大小為sizeof(T)*size的內(nèi)存空間,并將這塊內(nèi)存空間的首地址裝入數(shù)組名中。因此,C++中的數(shù)組是靜態(tài)的并具有固定尺寸的一種數(shù)據(jù)結(jié)構(gòu),它常用于對(duì)一批同類型量的組織與操作。
C++只允許定義大小固定的靜態(tài)、矩形的一維或多維數(shù)組(注意:數(shù)組尺寸不允許在運(yùn)行時(shí)改變)。若需要?jiǎng)討B(tài)數(shù)組(即數(shù)組尺寸在運(yùn)行時(shí)可變),請(qǐng)用C++標(biāo)準(zhǔn)類庫(kù)中的vector類(vector類的詳細(xì)內(nèi)容見(jiàn)本書(shū)第三部分)。
定義數(shù)組時(shí),數(shù)組類型定義中的size(數(shù)組元素的個(gè)數(shù)或稱數(shù)組的尺寸)可以不給出,而交由編譯程序推斷出來(lái),但此時(shí)必須在定義聲明中對(duì)數(shù)組進(jìn)行初始化,初始值的個(gè)數(shù)即為數(shù)組的size。例如:
int v1[]={1,2,3,4};//int[4]v1;
char v2[]={‘a(chǎn)’,‘b’,‘c’,0};
//char[4]v2;
int i,j,k;
int* v3[]={&i,&j,&k,0};//int*[4]v3;
在定義多維數(shù)組時(shí),語(yǔ)法上規(guī)定:其第一維的大小可以不給出,但除第一維以外的維數(shù)大小在定義時(shí)一定要給出。因?yàn)镃++對(duì)多維數(shù)組的內(nèi)存分配仍然是一塊連續(xù)的內(nèi)存空間,但C++是“按行”進(jìn)行內(nèi)存分配的(某些語(yǔ)言是“按列”進(jìn)行分配的,如Fortran語(yǔ)言)。以二維數(shù)組為例,若不指定第二維的尺寸,編譯器將無(wú)法推斷和檢查所分配的內(nèi)存。例如:
float f[][3]={{1,2,3},{4,5,6}}; //正確!編譯器推斷為2行3列的float型數(shù)組
int a[][4]={1,2,3,4,5,6,7,8}; //正確!編譯器推斷為2行4列的int型數(shù)組
double d[2][]={2,4,6,8,10}; //錯(cuò)誤!編譯器無(wú)法推斷內(nèi)存分配量
數(shù)組類型定義時(shí)可給出size(整數(shù)常量/整型常量表達(dá)式),進(jìn)而在定義聲明中對(duì)數(shù)組進(jìn)行初始化;初始化的元素個(gè)數(shù)不能大于size,但可以小于size(C++自動(dòng)地對(duì)未給出初值的元素賦0)。例如:
int?v1[4]={1,2,3,4}; //正確!int[4]v1;
charv2[2]={‘a(chǎn)’,‘b’,‘c’,0}; //錯(cuò)誤!初始值的個(gè)數(shù)4大于數(shù)組尺寸2
inti,j,k;
int*v3[8]={&i,&j,&k,0}; //int*[8]v3;
//相當(dāng)于int*v3[8]={&i,&j,&k,0,0,0,0,0};如前所述,字面值0在不同的上下文環(huán)境中具有不同的類型,而不同類型的0在不同的上下文環(huán)境中又有不同的語(yǔ)義。例如,0對(duì)于整型而言,就是0;對(duì)于指針T*而言,它表示空指針;對(duì)于字符串char*而言,它是串結(jié)束符。因此,采用系統(tǒng)默認(rèn)的0賦值,在某些情況下可能偏離編程者的本意,有時(shí)是十分危險(xiǎn)的!
在C++中,對(duì)于全局或靜態(tài)的(static)數(shù)組變量,當(dāng)用戶不賦初值時(shí),系統(tǒng)自動(dòng)賦初值0,局部數(shù)組系統(tǒng)不賦初值。5.2.2字符串字面值
由于應(yīng)用中常常采用char*的變量或char[]數(shù)組變量存儲(chǔ)一字符串常量,故在此引入字符串字面值的概念。
一個(gè)字符串字面值是由一對(duì)雙引號(hào)括起來(lái)的一串字符。例如,“Iamastudent.”?就是一個(gè)合法的C++字符串字面值。
一個(gè)字符串字面值的長(zhǎng)度等于其中所包含的字符個(gè)數(shù)加1(串結(jié)束符‘\0’);每個(gè)字符串字面值以字符‘\0’(值等于0)作為串結(jié)束符。因此有:
sizeof(“Teacher”)=8個(gè)字節(jié)//假定某平臺(tái)上sizeof(char)=1字符串字面值的類型為具有確定數(shù)目的const字符數(shù)組,即為constchar[]類型(注意:用const定義(或稱約束)的量只能讀而不能寫(xiě))。
為了繼承和兼容大量原有的C/C++代碼,C++標(biāo)準(zhǔn)規(guī)定:一個(gè)字符串字面值可以賦給一個(gè)char*的變量(在原有的C/C++定義中,字符串字面值的類型為char*)。由于C++標(biāo)準(zhǔn)規(guī)定字符串字面值是constchar[]類型,所以對(duì)字符串字面值只能讀而不能寫(xiě)。例如:
char*pc=“Teacher”;
*pc='B'; //錯(cuò)誤!試圖修改常量的值欲修改字符串字面值中的字符,可采取如下方式:
charc[]=“Teacher”;//數(shù)組的尺寸為sizeof(Teachar)+1=8
//一個(gè)常量字符串字面值賦值拷貝到一個(gè)字符數(shù)組變量中
c[0]=‘B’;//將?“Teacher”?中的首字符?‘T’?改為?‘B’
系統(tǒng)為字符串字面值靜態(tài)地分配了一塊連續(xù)的內(nèi)存空間以存放之。程序中若存在兩個(gè)或兩個(gè)以上相同的字符串字面值,系統(tǒng)是在內(nèi)存中存放該字符串的一個(gè)副本還是存放該字符串的多個(gè)副本將依具體的實(shí)現(xiàn)而定。字符串字面值中可以有帶轉(zhuǎn)義符的字符(EscapeCharacter),如‘\n’(換行)。在程序中,一個(gè)字符串字面值不能跨行定義。
字符串字面值中若有字符?‘?“?’?或?‘?’?‘?或?’\‘,要前加轉(zhuǎn)義符?’\‘。
在程序中可以將一個(gè)字符串字面值寫(xiě)成用whitespace分隔開(kāi)的多個(gè)字符串字面值,C++會(huì)將它們自動(dòng)接續(xù)成一個(gè)字符串字面值,這對(duì)在程序中書(shū)寫(xiě)較長(zhǎng)的字符串字面值提供了方便。whitespace包括:space(空格)、tab、newline(新行)、formfeed(走紙)、carriagereturn(回車)。例如:
chara1[]=“Thisisa\”string\“.\n*******************\n”;
//字符串字面值在程序中不允許跨行定義
chara2[]=“Thisisa\”string\“.
*******************”; //語(yǔ)法錯(cuò)誤!
//用whitespace分隔開(kāi)的字符串字面值將被自動(dòng)續(xù)接
chara3[]=“Thisisa\”string\“.\n”
“*******************\n”;
//定義效果與a1相同
5.3指向數(shù)組的指針
5.3.1指向一維數(shù)組的指針
指針與數(shù)組有著密切的關(guān)系。數(shù)組名本身就是一個(gè)指針,它代表數(shù)組元素的首地址,因此,我們常常利用指向數(shù)組的指針變量操作數(shù)組中的元素。
值得注意的是,程序中數(shù)組名擔(dān)當(dāng)著如下兩種角色:
(1)代表某個(gè)數(shù)組類型的變量名。因此,我們可用數(shù)組名求其數(shù)組的存儲(chǔ)空間分配量。例如:上述結(jié)果是在VC.net2005下運(yùn)行的,在此平臺(tái)上,sizeof(int)=4。因a數(shù)組的元素個(gè)數(shù)為4,故其存儲(chǔ)分配量為4×4=16。
(2)代表著存放該數(shù)組元素的首地址,注意:數(shù)組名是一個(gè)常量。因此,我們可以將數(shù)組名賦給一個(gè)與其數(shù)組元素類型一致的指針變量,之后,用其指針變量操作數(shù)組中的元素。語(yǔ)法上數(shù)組指針變量不拒絕指向數(shù)組以外的元素,但其后果自負(fù)。例如:
intv[]={1,2,3,4}; //int[4],其元素為v[0]~v[3]
int*p1=v; //被隱式轉(zhuǎn)換成int*p1=&v[0];
int*p2=&v[0];
int*p3=&v[4];//允許指針指向數(shù)組以外的元素,后果自負(fù)!
在C++中,char[](字符類型的數(shù)組)類型和char*(指向字符的指針類型)類型不同,但允許char[]到char*的轉(zhuǎn)換。對(duì)于字符數(shù)組而言,將數(shù)組名隱式轉(zhuǎn)換成字符指針?lè)奖阌谑褂脴?biāo)準(zhǔn)庫(kù)中的庫(kù)函數(shù)。char*到char[]的轉(zhuǎn)換被認(rèn)為是違法的。該類型轉(zhuǎn)換規(guī)則保證了不允許將一個(gè)char*值賦給數(shù)組名(常量)。例如:
intstrlen(constchar*);
//strlen:C標(biāo)準(zhǔn)庫(kù)函數(shù),在<cstring>中定義,求char*所指的字符串的長(zhǎng)度
voidf()
{
charv[]=“Annemarie”;
char*p=v; //隱式類型轉(zhuǎn)換,char[]→char*
intn1=strlen(p);
//函數(shù)調(diào)用時(shí)類型匹配
intn2=strlen(v);
//隱式類型轉(zhuǎn)換,char[]→char*
v=p;
//錯(cuò)誤!不允許char*→char[]以保證
數(shù)組名常量不被修改
}5.3.2指向多維數(shù)組的指針
C++的多維數(shù)組被看成是數(shù)組中的數(shù)組。以二維數(shù)組為例,C++將二維數(shù)組定義為其元素類型為一維數(shù)組的數(shù)組。應(yīng)用中,一般較少使用二維以上的數(shù)組。在此以二維數(shù)組示例,指向多維數(shù)組的指針概念和用法與二維數(shù)組類同。
在二維數(shù)組中,數(shù)組名仍然代表著數(shù)組的首地址,但它是一個(gè)行地址。例如:
inta[2][3]={1,2,3,4,5,6};
int(*pa)[3]; //pa定義為指向一個(gè)尺寸為3的一維數(shù)組的行指針
pa=a+1;
/*
pa=a+1等價(jià)于pa=&a[0][0]+3*sizeof(int),
即pa指向a數(shù)組中第二行首元素
*/
int*pa1
pa1=a[0]+1;
//pa1=&a[0][0],a[0]是數(shù)組a第一行的首地址,它為一列地址,pa1=a[0]+1=&a[0][1]
所謂行指針,即指針加1跳一行(所指的)數(shù)組元素,列指針加1跳一個(gè)(所指的)數(shù)組元素。
在上例中,數(shù)組名為行地址,而a[0](其地址等于&a[0][0])和a[1](其地址等于&a[1][0])分別為列地址。行地址的定義形式如下:數(shù)組元素類型T(*行指針名)[size];
該語(yǔ)句定義聲明了一個(gè)指向T[size]類型的指針類型,其中size為一維數(shù)組的大小。
行、列指針以上例代碼為例,其進(jìn)行增減操作后的結(jié)果如圖5.6所示。
若定義了一個(gè)指向二維數(shù)組的行指針:
inta[2][3]={{1,2,3},{4,5,6}};
int(*q)[3]=a;
我們可用如圖5.7所示的形式來(lái)表示上述二維數(shù)組中的各元素。
一個(gè)行指針進(jìn)行*運(yùn)算后(如*pa)即可轉(zhuǎn)換成一個(gè)列指針。圖5.6行、列指針示意圖圖5.7用行指針q表示2行3列數(shù)組中的各元素5.3.3取數(shù)組元素及數(shù)組的遍歷
兩個(gè)同類型的(數(shù)組元素類型相同,數(shù)組大小相同)數(shù)組可進(jìn)行元素對(duì)元素的整體賦值。例如:
inta[4]={10,20,30,40},
b[4];
b=a;
//a數(shù)組元素對(duì)b數(shù)組元素依次拷貝賦值
但除此之外,對(duì)數(shù)組的所有操作只能針對(duì)其元素進(jìn)行。因此,取數(shù)組中的某個(gè)元素或在數(shù)組中進(jìn)行遍歷是其它一切數(shù)組操作的基礎(chǔ)。通常采用數(shù)組名和下標(biāo)運(yùn)算符及索引(下標(biāo))來(lái)取數(shù)組中的某個(gè)元素(如a[i])或?qū)ζ溥M(jìn)行依次遍歷;另一種方式是利用指向數(shù)組的指針加索引進(jìn)行取元素或遍歷操作,其具體用法如下例所示。
//此函數(shù)是對(duì)指針使用數(shù)組操作
voidfi(char*v)
{
for(inti=0;v[i]!=0;i++)
use(v[i]);//use假定為已定義的操作數(shù)組元素的函數(shù)
}
//此函數(shù)是對(duì)數(shù)組使用指針操作
voidfp(charv[])
{
for(char*p=v;*p!=0;p++)
use(*p);
}
在應(yīng)用中需要注意如下幾點(diǎn):
(1)在多維數(shù)組(包括二維)中進(jìn)行取元素或遍歷操作時(shí)要注意是利用行指針還是列指針。
(2)?C++的數(shù)組不具有自描述性,即數(shù)組變量中不存放其實(shí)際存放的元素個(gè)數(shù)的信息。因此,在遍歷一個(gè)數(shù)組時(shí),必須以某種方式提供它的實(shí)際元素個(gè)數(shù)(字符串?dāng)?shù)組中包含一個(gè)串結(jié)束符?‘\0’,據(jù)此可推斷出其實(shí)際的元素個(gè)數(shù)),以供操作數(shù)組和進(jìn)行數(shù)組的越界檢查。
例如:
//函數(shù)fp:對(duì)傳遞的數(shù)組進(jìn)行某種操作
voidfp(charv[],unsignedintsize) //傳遞時(shí)須同時(shí)傳遞數(shù)組其及大小
{
for(inti=0;i<size;i++)
use(v[i]);
//...
}
(3)?C++語(yǔ)法上允許數(shù)組的越界操作,并且編譯器忽略此類錯(cuò)誤。因此,對(duì)數(shù)組進(jìn)行操作時(shí),一定要注意數(shù)組的越界問(wèn)題。一個(gè)好的C/C++程序員,應(yīng)將對(duì)數(shù)組的越界檢查及處理作為其基本本能。
(4)用指針和數(shù)組形式進(jìn)行數(shù)組的操作,在許多情況下是等效的,但還是應(yīng)當(dāng)加以約束,以避免平臺(tái)不同帶來(lái)的影響。請(qǐng)看下面一實(shí)際應(yīng)用中的程序片斷:
constunsignedshortID;
//數(shù)據(jù)庫(kù)表的數(shù)據(jù)項(xiàng)描述
structTB_col{
ID col_id;
char col_name[19];
short col_type;
short col_length;
};
//取指定數(shù)據(jù)項(xiàng)的物理名
char*TB_GetColName(IDtab_id,IDcol_id)
{staticstructTB_col*cp;
if(!TB_GetColInf(tab_id,col_id,&cp))
//根據(jù)表名tab_id和列名col_id及cp指針取列的相應(yīng)信息
returnNULL;
returncp->col_name;
}
上述代碼片斷中的retuencp->col_name;?語(yǔ)句是用指針取col_name(char*類型)中的字符串(表列名)。在Windows平臺(tái)上,無(wú)論col_name中的字符串非空/空,returncp->col_name;語(yǔ)句都將如實(shí)地返回col_name中的內(nèi)容;但在UNIX平臺(tái)上,若col_name為空串,則語(yǔ)句不返回任何值,這導(dǎo)致了程序錯(cuò)誤。因此,上述的returncp->col_name;語(yǔ)句應(yīng)改為
return(cp->col_name[0]=='\0')?0:cp->col_name;
這樣將會(huì)更安全、可靠地實(shí)現(xiàn)跨平臺(tái)使用程序。下面給出對(duì)數(shù)組進(jìn)行取元素或遍歷操作的示例程序。
例1打印輸出數(shù)組中的元素值并用直方圖的形式表示之(若干*號(hào)個(gè)數(shù)的條形圖)。
(*q)[1]is2
(*q+1)[1]is3
*(*(z+1)+2)is-33
*(z[1]+2)is-33
5.4指向函數(shù)的指針
C++允許定義指向某種類型函數(shù)的指針變量。例如下述語(yǔ)句:
int(*fp)(int);
即定義了一個(gè)指向其函數(shù)返回類型為int、參數(shù)為int型的該類函數(shù)的指針變量fp。這類指針變量可存放該類函數(shù)的地址,即所定義的fp中可存放上述類別的函數(shù)的地址(或稱函數(shù)代碼的首地址)。
函數(shù)指針的定義方式如下:
函數(shù)返回類型(*函數(shù)指針名)(函數(shù)參數(shù)表列);函數(shù)指針的一個(gè)主要目的是讓用戶編寫(xiě)更為靈活、用數(shù)據(jù)實(shí)現(xiàn)控制的程序。假定應(yīng)用中我們需編寫(xiě)計(jì)算如下積分的程序:經(jīng)過(guò)分析可看出:y1、y2和y3的被積函數(shù)雖然形式不同,但具有共性,即被積函數(shù)都只有一個(gè)自變量x,且被積函數(shù)都是x的一元某次方程。根據(jù)其共性,可編寫(xiě)適合這一類被積函數(shù)的積分程序。若用函數(shù)實(shí)現(xiàn),則解決方案如下:
floatintegral(fp,a,b);//計(jì)算某類函數(shù)積分的通用函數(shù)接口
//fp為指向該類被積函數(shù)的指針,a、b為積分的上、下限
上述函數(shù)的具體實(shí)現(xiàn)請(qǐng)參閱后續(xù)函數(shù)一章的相應(yīng)內(nèi)容。
5.5指向void*的指針
若定義了一個(gè)void*的指針變量,就意味著可將一個(gè)指向任意類型對(duì)象的指針賦給它。
一個(gè)void*類型的變量所能進(jìn)行的操作是:
將一個(gè)void*類型的變量賦給另一個(gè)void*類型的變量;
兩個(gè)void*的相等與不相等比較;
一個(gè)void*可以顯式地轉(zhuǎn)換成另一個(gè)任意類型的指針類型(注意謹(jǐn)慎使用!)。
void*類型的變量不能進(jìn)行的操作是:
將函數(shù)指針賦給void*;
將指向成員的指針賦給void*。
void*最重要的用途是需要向函數(shù)傳遞一個(gè)指針,而向函數(shù)傳遞時(shí),又不能對(duì)指針?biāo)笇?duì)象的類型做任何假設(shè),即利用void*可向函數(shù)傳遞任意類型的對(duì)象。其另外一個(gè)主要用途就是從函數(shù)返回一個(gè)無(wú)類型(Untype,即可為任意類型)的對(duì)象。因此,被定義成void*類型的量所提供的信息是:由于不可能事先約定,所以允許任意的指針類型與之對(duì)應(yīng)(通常是函數(shù)的形參或返回值)。這是C++為程序員提供的一種可傳遞/處理任何類型對(duì)象的機(jī)制。
這樣做的可行性在于:在同一平臺(tái)上任何指針類型的存儲(chǔ)空間分配量是一致的。在C++標(biāo)準(zhǔn)庫(kù)函數(shù)的一些實(shí)現(xiàn)中,void*機(jī)制的使用使得該函數(shù)具有較強(qiáng)的通用性,請(qǐng)看在C標(biāo)準(zhǔn)庫(kù)中的一個(gè)典型應(yīng)用:
//C標(biāo)準(zhǔn)庫(kù)函數(shù)——快速排序qsort函數(shù)的接口定義
intqsort(void*,int,intsize_t,(int(*fp)(constvoid*,constvoid*)));
/*函數(shù)中各參數(shù)的含義如下:
被排序的數(shù)組的起始地址,由于是void*?類型,則可接受任何類型的數(shù)組;
(數(shù)組中存放欲排序的數(shù)據(jù))
數(shù)組中有效元素個(gè)數(shù);數(shù)組尺寸的大小;
指定的比較函數(shù)的指針。由于函數(shù)的兩個(gè)參數(shù)的類型為void*?類型,故函數(shù)可進(jìn)行
任何類型的兩個(gè)量的比較
*/
下面我們利用C標(biāo)準(zhǔn)庫(kù)函數(shù)qsort高度抽象的接口與實(shí)現(xiàn)的定義來(lái)實(shí)現(xiàn)任意類型量的排序。
假定應(yīng)用中我們需對(duì)一批字符串進(jìn)行排序,代碼如下:
constintTABLE_SIZE=1000;
char*ourTable[TABLE_SIZE];
//…向ourTable輸入欲排序的數(shù)據(jù)
5.6常量
C++允許用戶定義字符常量(也稱符號(hào)常量)。C++用關(guān)鍵字const來(lái)定義符號(hào)常量,const用來(lái)直接表達(dá)“不變化的值”這一概念。例如,我們欲定義PI這一符號(hào)常量,可寫(xiě)為
constfloatPI=3.15159;
C++仍兼容C的常量定義方式(采用宏),例如:
#definePI3.14159
//PI為一字符常量,代表3.14159
比較C和C++的兩種常量定義方法,我們可看到:C++的常量定義方式不僅含義更加明確,最重要的是該常量定義給編譯器和運(yùn)行環(huán)境提供了被定義者是常量及所具有的類型這些重要的信息,以供編譯器和運(yùn)行環(huán)境進(jìn)行編譯時(shí)和運(yùn)行時(shí)的類型檢查!?這在應(yīng)用中是十分重要的。
(2)采用符號(hào)常量而不是將常量字面值直接寫(xiě)入代碼中,將使得程序更易于擴(kuò)充、維護(hù)與修改。例如:若需修改數(shù)組的尺寸,只需修改常量STRL的定義(一處)即可,以防止大范圍地在每一個(gè)出現(xiàn)STRL的地方修改程序代碼(大范圍地修改代碼很難保證修改的一致性與正確性)。
(3)通常是用指針讀而不是寫(xiě)。例如:
constintSTRL=40;
charbuf[STRL*10+STRL];
char*conststr1=&buf;//定義str1為一常量字符
指針
char*conststr2=&buf[STRL+1]; //定義str2為一常
量字符指針
}
voidf()
{
g(“Thisisatest”);//用一個(gè)常量字符串對(duì)constchar*p賦初值
}
(2)指針常量的定義方式為
指針類型T*const常量名=初值;
注意:
①常量若以函數(shù)的形參方式出現(xiàn),則沒(méi)有初值部分,對(duì)應(yīng)的實(shí)參即為常量的初值。②當(dāng)常量的類型是一個(gè)T*時(shí),即為指針常量,不允許修改的是指針常量本身的值,而不是指針常量所指對(duì)象的值;若指針?biāo)傅膶?duì)象為const,即為指向常量的指針,則不允許修改的是*常量名或常量名[下標(biāo)]對(duì)應(yīng)的值。例如:
//cpc是一個(gè)指向一個(gè)常量字符串的常量指針
constchar*constcpc=s;
*cpc=‘g’; //錯(cuò)誤!?試圖修改cpc所指的內(nèi)容
cpc=p; //錯(cuò)誤!?試圖修改cpc的內(nèi)容
}
由于談到指針時(shí)總涉及兩個(gè)對(duì)象——指針變量本身與指針?biāo)傅膶?duì)象,而C++又允許對(duì)這二者都可進(jìn)行const約束,因此,是指針常量(不允許修改指針本身的值),還是指向常量的指針(指針?biāo)傅膶?duì)象不允許修改)就難以辨別。如何有效地辨別、定義這兩種類型的量呢?BjarneStrostrup給出了一個(gè)有效的方法,即當(dāng)從右至左讀常量定義式時(shí),即可解析其類別。例如:
語(yǔ)句:char*constcp=s;從右至左可讀成cp是一個(gè)指向char類型(變量)的const指針(*讀為指針pointer)。
語(yǔ)句:constchar*pc=s;
從右至左可讀成pc是一個(gè)指向常量字符串的指針變量。
語(yǔ)句:constchar*constcpc=s;
從右至左可讀成cpc是一個(gè)指向常量字符串的常量指針。
C++語(yǔ)法規(guī)定:可將一個(gè)變量的地址賦給一個(gè)常量指針,因?yàn)檫@樣做不會(huì)造成任何傷害;但不允許將一個(gè)常量的地址賦給一個(gè)未加限制的指針(即指針變量),以防止用戶不經(jīng)意/試圖通過(guò)該指針修改常量的值。例如:
5.7引用
引用即為一個(gè)變量的別名。引用的主要用途是向函數(shù)直接傳遞變量(C/C++是值傳遞,稱為CallbyValue)或從函數(shù)返回變量。特別是在實(shí)現(xiàn)大型對(duì)象的傳遞與操作符的重載(OperatorOverloading,詳見(jiàn)第二部分的內(nèi)容)時(shí),引用更是扮演著不可或缺的角色。
引用用符號(hào)X&表示,它表示對(duì)某個(gè)X類型變量的引用。
為了保證引用確實(shí)是對(duì)某個(gè)量的引用(即用引用名綁定所引用的對(duì)象),在定義引用時(shí)一定要對(duì)其進(jìn)行初始化。由于一個(gè)引用所表示的是一個(gè)對(duì)象的別名,所以它不能獨(dú)立存在,必然要關(guān)聯(lián)于某個(gè)已定義的名字,它們對(duì)應(yīng)于同一個(gè)對(duì)象。
關(guān)聯(lián)的方式是:①在定義該引用時(shí)所聲明的初始化值;②對(duì)于被定義為函數(shù)的形參(或返回值)的引用,由實(shí)參(或返回值表達(dá)式)給出對(duì)應(yīng)值。例如:
voidg()
{
intii=0;
int&rr=ii; //rr為ii的引用,rr即為ii的別名
rr++; //等價(jià)于ii++;
int*pp=&rr; //pp==ⅈ*pp==ii;
}
形象地說(shuō),一個(gè)引用好比總是用*(取內(nèi)容)操作的一個(gè)指針常量。
應(yīng)用中,我們有時(shí)可能需要向函數(shù)傳遞/從函數(shù)返回某個(gè)對(duì)象(稱為CallbyReference)而非對(duì)象的值,這時(shí)可采用引用類型。因此,當(dāng)參數(shù)類型為引用類型時(shí),函數(shù)體內(nèi)對(duì)形參的修改實(shí)際上就是對(duì)實(shí)參的修改,這類似于Pascal函數(shù)或過(guò)程用var聲明的形參。例如:
voidswap(int&a,int&b)//在函數(shù)內(nèi)部交換a,b
{
inttemp;
temp=a;
a=b;
b=temp;
}當(dāng)然,我們亦可用指針的方式完成同樣的功能。代碼如下:
voidswap(int*a,int*b)
{
int*temp=0;
*temp=*a;
*a=*b;
*b=*temp;
}引用最主要的應(yīng)用場(chǎng)合是:①傳遞/返回大型對(duì)象;②實(shí)現(xiàn)操作符的重載(本書(shū)第二部分將會(huì)詳細(xì)講述)。其它情況下一般不宜采用引用類型。當(dāng)需要向函數(shù)傳遞/從函數(shù)返回某個(gè)對(duì)象而非對(duì)象的值時(shí),采用指針更易于理解。例如:
//使用引用,不易理解的方式
voidinc(int&aa)
{aa++;} //aa自增1
voidf()
{
intx=1;
inc(x);
//aa、x對(duì)應(yīng)同一對(duì)象,用戶可能不清楚x已改變其值
}
//使用指針,易于理解的方式
voidinc(int*p)
{(*p)++;}
voidf()
{
intx=1;
inc(&x);
//用戶非常清楚x已改變其值并等于2
}
當(dāng)一個(gè)函數(shù)的返回類型為引用時(shí),該函數(shù)的調(diào)用結(jié)果既可作為右值(原意為賦值表達(dá)式的右部,即代表一個(gè)值),亦可作為一個(gè)左值(原意為賦值表達(dá)式的左部,此處代表一個(gè)對(duì)象的存儲(chǔ)空間)。引用的基本用法及應(yīng)用示例如下所示。
例3
用戶從鍵盤(pán)上輸入若干個(gè)token,每個(gè)token用空格相隔,統(tǒng)計(jì)輸出用戶輸入的token及相應(yīng)的次數(shù)。當(dāng)用戶輸入“stringstudentstringasbcuiasas”時(shí),程序運(yùn)行輸出結(jié)果為
string:2
student:1
as:3
bc:1
ui:1
5.8結(jié)構(gòu)
一個(gè)結(jié)構(gòu)是其元素類型為任意類型的若干個(gè)元素的集合,即一個(gè)元素類型可以各不相同的數(shù)組,我們常稱其為異質(zhì)(Heterogeneous)數(shù)組。
相比之下,我們稱數(shù)組為一個(gè)同質(zhì)(Homogeneous)元素的集合。
構(gòu)成一個(gè)結(jié)構(gòu)類型的那些元素稱為它的成員(Member)。
結(jié)構(gòu)類型用來(lái)定義具有多種不同類型(當(dāng)然亦可具有相同的類型)的屬性(Attribute)的客觀事物,而這樣的事物在現(xiàn)實(shí)中是大量存在的。從上例可看出,在結(jié)構(gòu)類型中,每個(gè)成員都有相應(yīng)的類型,各成員的類型可相同亦可不相同。
一個(gè)結(jié)構(gòu)類型看上去只是定義了一種事物的一個(gè)實(shí)例的各個(gè)屬性(用成員表示),但根據(jù)各成員類型的值集可以直接構(gòu)造出這個(gè)結(jié)構(gòu)類型的值集,即可根據(jù)定義的這種結(jié)構(gòu)類型,定義出(實(shí)例化出)具有這種結(jié)構(gòu)的和具有該結(jié)構(gòu)類型值集元素個(gè)數(shù)的同類事物的實(shí)例,這是一種典型的共性抽象。
例如,在上面address結(jié)構(gòu)類型的定義中,實(shí)際上定義了由如下集合構(gòu)造的可具有
個(gè)值的結(jié)構(gòu)類型變量。
用結(jié)構(gòu)類型可以構(gòu)造對(duì)應(yīng)的數(shù)組類型(結(jié)構(gòu)數(shù)組,即數(shù)組的元素為結(jié)構(gòu))、指針類型(指向結(jié)構(gòu)的指針)、引用類型(結(jié)構(gòu)的引用)和結(jié)構(gòu)類型(結(jié)構(gòu)嵌套結(jié)構(gòu))。
結(jié)構(gòu)定義中,其成員類型不能是它自身,否則會(huì)使得編譯器無(wú)法推斷該類型量的存儲(chǔ)分配量而無(wú)法進(jìn)行內(nèi)存分配。例如,我們不能進(jìn)行如下定義:
structNo_good{
No_goodmember;
};
/*存在無(wú)終止條件的遞歸,無(wú)法確定對(duì)應(yīng)的存儲(chǔ)空間的大小*/
而可以進(jìn)行如下的定義:
structLink{
Link*previous;
Link*successor;
};
/*指針類型變量的存儲(chǔ)空間大小不依賴于對(duì)應(yīng)類型*/
C++為任意結(jié)構(gòu)類型提供了一個(gè)對(duì)象的整體賦值操作(二進(jìn)制復(fù)制),但不提供與結(jié)構(gòu)類型變量相關(guān)的其它整體操作(例如比較操作),這些操作可由用戶自己定義(在本書(shū)第二部分會(huì)看到,這些操作所使用的操作符可以與基本類型相同)。例如,對(duì)結(jié)構(gòu)類型address變量可進(jìn)行如下的整體賦值操作:
addresscurrent;
addressset_current(addressnext)
{
staticaddressprev=current; //結(jié)構(gòu)變量的整體賦值
current=next; //結(jié)構(gòu)變量的整體賦值
returnprev;
}
C++提供了取結(jié)構(gòu)類型指定成員值的兩個(gè)操作:
(1)取結(jié)構(gòu)成員操作符·?。
語(yǔ)法:結(jié)構(gòu)變量名·成員名
語(yǔ)義:返回第一操作數(shù)中成員名字與第二操作數(shù)相同的成員的值。
(2)用指針取結(jié)構(gòu)成員操作符->。
語(yǔ)法:指向結(jié)構(gòu)變量的指針變量->成員名
語(yǔ)義:返回第一操作數(shù)所指向的那個(gè)對(duì)象中成員名字與第二操作數(shù)相同的成員的值。
定義結(jié)構(gòu)類型變量時(shí)可進(jìn)行初始化,其方式與數(shù)組類似(用初始化表的方式)。例如:
structstudent //結(jié)構(gòu)類型student的定義
{
stringname;
unsignedintid;
chargender;
}s1={“LiXiaohong”,0304214,‘F’};
//結(jié)構(gòu)類型與結(jié)構(gòu)變量s1同時(shí)定義,并對(duì)s1進(jìn)行初始化
C++為結(jié)構(gòu)類型的對(duì)象分配一塊連續(xù)的存儲(chǔ)空間,并按該結(jié)構(gòu)類型各成員的聲明順序和對(duì)應(yīng)類型對(duì)該空間進(jìn)行劃分,但在分配和劃分時(shí)遵循“字對(duì)準(zhǔn)”原則(即每個(gè)成員的起始地址是一個(gè)字,字的大小與平臺(tái)相關(guān),常見(jiàn)的是2字節(jié)或4字節(jié)),因此,對(duì)一個(gè)結(jié)構(gòu)類型量所實(shí)際分配的空間存儲(chǔ)量可能大于各成員類型對(duì)應(yīng)空間之和。例如,對(duì)以下的address變量jd而言,其內(nèi)存分配示意圖如圖5.8所示。
addressjd={
“JimDandy”, //的初始值
61,
//jd.number的初始值
“SouthSt”,
//jd.street的初始值
“NewProvidence”, //jd.town的初始值
{‘N’,‘J’}, //jd.state的初始值
7974
//jd.zip的初始值
};圖5.8結(jié)構(gòu)類型address變量所分配的存儲(chǔ)空間假定在某一平臺(tái)上,sizeof(char)=1,sizeof(longint)=8,sizeof(char*)=4,根據(jù)adrress的定義,jd的實(shí)際內(nèi)存分配量為
sizeof(jd)=sizeof(char*)+sizeof(longint)+sizeof(char*)
+sizeof(char*)+2*sizeof(char)+2+sizeof(long)
=32字節(jié)
而非成員實(shí)際應(yīng)有的內(nèi)存量30字節(jié)。注意上式中的+2
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版機(jī)床進(jìn)出口買(mǎi)賣合同范本詳析2篇
- 2024年禁牧區(qū)水資源保護(hù)與管理合同
- 專業(yè)化油漆施工協(xié)議(2024年版)版B版
- 二零二五年高性能環(huán)保材料供應(yīng)與技術(shù)研發(fā)協(xié)議2篇
- 天府新區(qū)職業(yè)學(xué)院《信息內(nèi)容安全的理論與應(yīng)用》2023-2024學(xué)年第一學(xué)期期末試卷
- 二零二五版快遞行業(yè)專用包裝材料供應(yīng)協(xié)議2篇
- 2024版股權(quán)投資協(xié)議(投資金額和股權(quán)比例)3篇
- 2024運(yùn)輸管理實(shí)訓(xùn)機(jī)構(gòu)運(yùn)營(yíng)合作協(xié)議3篇
- 天津商業(yè)大學(xué)寶德學(xué)院《圖像處理與機(jī)器視覺(jué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 二零二五年高端混凝土預(yù)制構(gòu)件委托加工合同3篇
- 2024年江蘇省《輔警招聘考試必刷500題》考試題庫(kù)帶答案(達(dá)標(biāo)題)
- 高中家長(zhǎng)會(huì) 高三上學(xué)期期末家長(zhǎng)會(huì)
- 深圳南山區(qū)2024-2025上學(xué)期小學(xué)四年級(jí)數(shù)學(xué)期末試卷
- 藥店員工培訓(xùn)
- 環(huán)衛(wèi)工節(jié)前安全培訓(xùn)
- 李四光《看看我們的地球》原文閱讀
- 2024年全國(guó)“紀(jì)檢監(jiān)察”業(yè)務(wù)相關(guān)知識(shí)考試題庫(kù)(附含答案)
- DB32T 2305-2013 內(nèi)陸水域魚(yú)類資源調(diào)查規(guī)范
- 《陋室銘》(過(guò)關(guān)檢測(cè))(原卷版)-2024年中考語(yǔ)文課內(nèi)39篇文言文閱讀
- 福建省福州市2023-2024學(xué)年高一上學(xué)期期末考試物理試卷 附答案
- 2024-2030年中國(guó)IT運(yùn)營(yíng)管理(ITOM)軟件行業(yè)市場(chǎng)發(fā)展趨勢(shì)與前景展望戰(zhàn)略研究報(bào)告
評(píng)論
0/150
提交評(píng)論