C++中的复合类型
文章目錄
- 重溫C++ 復(fù)合類型
- 在程序中 使用結(jié)構(gòu)體
- 結(jié)構(gòu)體賦值
- 結(jié)構(gòu)體數(shù)組
- 結(jié)構(gòu)體中位字段
- 共用體
- 枚舉
- 指針
- 如何聲明一個指針
- 將指針初始化為一個地址
- 使用new來分配內(nèi)存
- 指針和數(shù)組之間的差別
- 指針、數(shù)組和指針?biāo)阈g(shù)
- 指針和字符串
- 使用new創(chuàng)建動態(tài)結(jié)構(gòu)
- delete使用示例
- 類型組合
- 數(shù)組的替代品
- 模板類vector
- 模板類array
重溫C++ 復(fù)合類型
在程序中 使用結(jié)構(gòu)體
// structur.cpp -- a simple structure #include <iostream> struct inflatable // structure declaration {char name[20];float volume;double price; };int main() {using namespace std;inflatable guest ={"Glorious Gloria", // name value1.88, // volume value29.99 // price value}; // guest is a structure variable of type inflatable // It's initialized to the indicated valuesinflatable pal ={"Audacious Arthur",3.12,32.99}; // pal is a second variable of type inflatable // NOTE: some implementations require using // static inflatable guest =cout << "Expand your guest list with " << guest.name;cout << " and " << pal.name << "!\n"; // pal.name is the name member of the pal variablecout << "You can have both for $";cout << guest.price + pal.price << "!\n";// cin.get();return 0; }結(jié)構(gòu)體賦值
// assgn_st.cpp -- assigning structures #include <iostream> struct inflatable {char name[20];float volume;double price; }; int main() {using namespace std;inflatable bouquet ={"sunflowers",0.20,12.49};inflatable choice;cout << "bouquet: " << bouquet.name << " for $";cout << bouquet.price << endl;//C++ 11中結(jié)構(gòu)體可以直接賦值choice = bouquet; // assign one structure to anothercout << "choice: " << choice.name << " for $";cout << choice.price << endl;// cin.get();return 0; }結(jié)構(gòu)體數(shù)組
// arrstruc.cpp -- an array of structures #include <iostream> struct inflatable {char name[20];float volume;double price; }; int main() {using namespace std;//< guests 是一個結(jié)構(gòu)體數(shù)組,類型是 inflatableinflatable guests[2] = // initializing an array of structs{{"Bambi", 0.5, 21.99}, // first structure in array{"Godzilla", 2000, 565.99} // next structure in array};//< guests可以使用據(jù)點(diǎn)訪問結(jié)構(gòu)體相應(yīng)的成員cout << "The guests " << guests[0].name << " and " << guests[1].name<< "\nhave a combined volume of "<< guests[0].volume + guests[1].volume << " cubic feet.\n";// cin.get();return 0; }結(jié)構(gòu)體中位字段
- 與C語言一樣C++也允許指定占用特定位數(shù)的結(jié)構(gòu)體成員,這使得創(chuàng)建與某個硬件設(shè)備上寄存器對應(yīng)的數(shù)據(jù)結(jié)構(gòu)非常方便,字段的類型為整數(shù)或者枚舉,接下來是冒號,冒號后面是一個數(shù)字,它指定使用的位數(shù),可以使用沒有名稱的字段來提供間距,每個成員都被稱為位字段(bit field)
共用體
- 共用體是一種數(shù)據(jù)格式,它能夠存儲不同的數(shù)據(jù)類型,但是只能同時存儲其中一種數(shù)據(jù)類型
- 可以采用共用提的特性,就能在傳參的時候既能傳入浮點(diǎn)型,也能傳入整形,或者字符串。
枚舉
- C++的enum工具提供了另一種創(chuàng)建符號常量的方式,這種方式可以代替const,它還允許定義新類型,但是必須安嚴(yán)格的限制進(jìn)行,使用enum的句法與使用結(jié)構(gòu)體相似。
這條語句完成了兩件事情
-
可以使用枚舉名來聲明這種類型的變量;
specrum band;// band a veriable of type spectrum
-
如果只是想使用枚舉型常量,而不想使用枚舉型變量,則可以按照下面這種形式定義
指針
// address.cpp -- using the & operator to find addresses #include <iostream> int main() {using namespace std;int donuts = 6;double cups = 4.5;cout << "donuts value = " << donuts;cout << " and donuts address = " << &donuts << endl; // NOTE: you may need to use unsigned (&donuts) // and unsigned (&cups)cout << "cups value = " << cups;cout << " and cups address = " << &cups << endl;// cin.get();return 0; }如何聲明一個指針
// pointer.cpp -- our first pointer variable #include <iostream> int main() {using namespace std;int updates = 6; // declare a variableint * p_updates; // declare pointer to an intp_updates = &updates; // assign address of int to pointer// express values two wayscout << "Values: updates = " << updates;cout << ", *p_updates = " << *p_updates << endl;// express address two wayscout << "Addresses: &updates = " << &updates;cout << ", p_updates = " << p_updates << endl;// use pointer to change value*p_updates = *p_updates + 1;cout << "Now updates = " << updates << endl;// cin.get();return 0; }$ ./a.out Values: updates = 6, *p_updates = 6 Addresses: &updates = 0x7fffbadc28dc, p_updates = 0x7fffbadc28dc Now updates = 7
將指針初始化為一個地址
// init_ptr.cpp -- initialize a pointer #include <iostream> int main() {using namespace std;int higgens = 5;int * pt = &higgens;cout << "Value of higgens = " << higgens<< "; Address of higgens = " << &higgens << endl;cout << "Value of *pt = " << *pt<< "; Value of pt = " << pt << endl;// cin.get();return 0; }警告
- 一定要在對指針應(yīng)用解除引用運(yùn)算符(*),之前,將指針初始化為一個確定的、適當(dāng)?shù)牡刂?#xff0c;這時關(guān)于使用指針的金科玉律
使用new來分配內(nèi)存
//< 運(yùn)行時分配內(nèi)存 int * pn = new int; typeName * Pointer_name = new typeName;- 將new用于兩種不同的類型
指針和數(shù)組之間的差別
// arraynew.cpp -- using the new operator for arrays //< c/C++中使用指針來處理數(shù)組,兩者基本上相同,但是還是由細(xì)微的差別 #include <iostream> int main() {using namespace std;double * p3 = new double [3]; // space for 3 doublesp3[0] = 0.2; // treat p3 like an array namep3[1] = 0.5;p3[2] = 0.8;cout << "p3[1] is " << p3[1] << ".\n";//< 指針可以進(jìn)行加減操作,但是數(shù)組不可以p3 = p3 + 1; // increment the pointercout << "Now p3[0] is " << p3[0] << " and ";cout << "p3[1] is " << p3[1] << ".\n";p3 = p3 - 1; // point back to beginningdelete [] p3; // free the memory// cin.get();return 0; }指針、數(shù)組和指針?biāo)阈g(shù)
指針和數(shù)組基本上等價的原因在于指針?biāo)阈g(shù)(pointer arithmetic)和C++內(nèi)部處理數(shù)組的方式,指針?biāo)阈g(shù)是按照步長進(jìn)行增減的,和數(shù)組的增減方式一樣,C++底層將數(shù)組解釋為地址:
// addpntrs.cpp -- pointer addition #include <iostream> int main() {using namespace std;double wages[3] = {10000.0, 20000.0, 30000.0};short stacks[3] = {3, 2, 1};// Here are two ways to get the address of an arraydouble * pw = wages; // name of an array = addressshort * ps = &stacks[0]; // or use address operator // with array elementcout << "pw = " << pw << ", *pw = " << *pw << endl;pw = pw + 1;cout << "add 1 to the pw pointer:\n";cout << "pw = " << pw << ", *pw = " << *pw << "\n\n";cout << "ps = " << ps << ", *ps = " << *ps << endl;ps = ps + 1;cout << "add 1 to the ps pointer:\n";cout << "ps = " << ps << ", *ps = " << *ps << "\n\n";cout << "access two elements with array notation\n";cout << "stacks[0] = " << stacks[0] << ", stacks[1] = " << stacks[1] << endl;cout << "access two elements with pointer notation\n";cout << "*stacks = " << *stacks<< ", *(stacks + 1) = " << *(stacks + 1) << endl;cout << sizeof(wages) << " = size of wages array\n";cout << sizeof(pw) << " = size of pw pointer\n";// cin.get();return 0; }程序輸出
pw = 0x7ffd05782530, *pw = 10000 add 1 to the pw pointer: pw = 0x7ffd05782538, *pw = 20000ps = 0x7ffd05782520, *ps = 3 add 1 to the ps pointer: ps = 0x7ffd05782522, *ps = 2access two elements with array notation stacks[0] = 3, stacks[1] = 2 access two elements with pointer notation *stacks = 3, *(stacks + 1) = 2 24 = size of wages array 8 = size of pw pointer- 程序解釋,在大多數(shù)情況下, C++將數(shù)組名解釋為數(shù)組的第一個元素的地址
指針和字符串
// ptrstr.cpp -- using pointers to strings #include <iostream> #include <cstring> // declare strlen(), strcpy() int main() {using namespace std;char animal[20] = "bear"; // animal holds bearconst char * bird = "wren"; // bird holds address of stringchar * ps; // uninitializedcout << animal << " and "; // display bearcout << bird << "\n"; // display wren// cout << ps << "\n"; //may display garbage, may cause a crashcout << "Enter a kind of animal: ";cin >> animal; // ok if input < 20 chars// cin >> ps; Too horrible a blunder to try; ps doesn't// point to allocated spaceps = animal; // set ps to point to stringcout << ps << "!\n"; // ok, same as using animalcout << "Before using strcpy():\n";//< 如果向cout提供的是一個字符串指針 cout將打印出字符串 如果向打印出地址必須強(qiáng)制轉(zhuǎn)換為 (int *)類型才行cout << animal << " at " << (int *) animal << endl;cout << ps << " at " << (int *) ps << endl;ps = new char[strlen(animal) + 1]; // get new storagestrcpy(ps, animal); // copy string to new storagecout << "After using strcpy():\n";cout << animal << " at " << (int *) animal << endl;cout << ps << " at " << (int *) ps << endl;delete [] ps;// cin.get();// cin.get();return 0; }使用new創(chuàng)建動態(tài)結(jié)構(gòu)
// newstrct.cpp -- using new with a structure #include <iostream> struct inflatable // structure definition {char name[20];float volume;double price; }; int main() {using namespace std;inflatable * ps = new inflatable; // allot memory for structurecout << "Enter name of inflatable item: ";//< 使用get函數(shù)獲取ps->name的值cin.get(ps->name, 20); // method 1 for member accesscout << "Enter volume in cubic feet: ";cin >> (*ps).volume; // method 2 for member accesscout << "Enter price: $";cin >> ps->price;cout << "Name: " << (*ps).name << endl; // method 2cout << "Volume: " << ps->volume << " cubic feet\n"; // method 1cout << "Price: $" << ps->price << endl; // method 1delete ps; // free memory used by structure// cin.get();// cin.get();return 0; }delete使用示例
// delete.cpp -- using the delete operator #include <iostream> #include <cstring> // or string.h using namespace std; char * getname(void); // function prototype int main() {char * name; // create pointer but no storagename = getname(); // assign address of string to namecout << name << " at " << (int *) name << "\n";delete [] name; // memory freedname = getname(); // reuse freed memorycout << name << " at " << (int *) name << "\n";delete [] name; // memory freed again// cin.get();// cin.get();return 0; }//< 申請內(nèi)存可以返回指針的形式,但是要是使用參數(shù)的形式就必須使用指向指針的指針 //< 因?yàn)镃++傳入的參數(shù)會使用臨時變量代替 char * getname() // return pointer to new string { //< 自動變量是局部變量,他的作用域就是它所包含的代碼塊//< 自動變量常存儲在棧中,這意味著執(zhí)行代碼塊時,其中的變量將依次添加到棧中,//< 離開代碼塊是將按照相反的順序釋放這些變量,這被稱為后進(jìn)先出的(LIFO),因此在程序執(zhí)行的過程中,棧將不//< 增大和縮小char temp[80]; // temporary storagecout << "Enter last name: ";cin >> temp;char * pn = new char[strlen(temp) + 1];strcpy(pn, temp); // copy string into smaller spacereturn pn; // temp lost when function ends }類型組合
// mixtypes.cpp --some type combinations #include <iostream>struct antarctica_years_end {int year;/* some really interesting data, etc. */ };int main() {antarctica_years_end s01, s02, s03; s01.year = 1998;antarctica_years_end * pa = &s02;pa->year = 1999;antarctica_years_end trio[3]; // array of 3 structurestrio[0].year = 2003;std::cout << trio->year << std::endl;const antarctica_years_end * arp[3] = {&s01, &s02, &s03};std::cout << arp[1]->year << std::endl;const antarctica_years_end ** ppa = arp; auto ppb = arp; // C++0x automatic type deduction // or else use const antarctica_years_end ** ppb = arp; std::cout << (*ppa)->year << std::endl;std::cout << (*(ppb+1))->year << std::endl;// std::cin.get();return 0; }數(shù)組的替代品
模板類vector
- 模板類類似于string類,也是一種動態(tài)數(shù)組,可以在運(yùn)行階段設(shè)置vector對象的長度,可以再末尾附加新數(shù)據(jù),還可以在中間插入新數(shù)據(jù),基本上它可以是使用new創(chuàng)建動態(tài)數(shù)組的替代品,實(shí)際上的vector確實(shí)是用new和delete來管理內(nèi)存,但是這種工作自動完成的。
vector<typeName> vt(n_elem)
vt為vector對象,它存儲n_elem個類型為 typeName的元素
模板類array
- 使用vector功能比數(shù)組強(qiáng)大,但是付出的代價就是效率稍低,鑒于此C++11提供與數(shù)組一樣的模板類,與數(shù)組一樣是固定長度的,也是使用棧而不是自由存儲區(qū)
對比數(shù)組vector和array的不同
// choices.cpp -- array variations #include <iostream> #include <vector> // STL C++98 #include <array> // C++0x int main() {using namespace std; // C, original C++double a1[4] = {1.2, 2.4, 3.6, 4.8}; // C++98 STLvector<double> a2(4); // create vector with 4 elements // no simple way to initialize in C98a2[0] = 1.0/3.0;a2[1] = 1.0/5.0;a2[2] = 1.0/7.0;a2[3] = 1.0/9.0; // C++0x -- create and initialize array objectarray<double, 4> a3 = {3.14, 2.72, 1.62, 1.41}; array<double, 4> a4;//< array 同樣大小的情況下可以直接進(jìn)行賦值 a4 = a3; // valid for array objects of same size // use array notationcout << "a1[2]: " << a1[2] << " at " << &a1[2] << endl;cout << "a2[2]: " << a2[2] << " at " << &a2[2] << endl;cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl;cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl; // misdeeda1[-2] = 20.2; //< 編譯沒有問題C++也不做數(shù)組超界限的處理cout << "a1[-2]: " << a1[-2] <<" at " << &a1[-2] << endl;cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl;cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl;// cin.get();return 0; }總結(jié)
- 上一篇: 【热烈祝贺】我刊主编郑纬民教授荣获中国存
- 下一篇: 朱兴杰(1986-),男,泰康保险集团股