C++中的复合类型
文章目錄
- 重溫C++ 復合類型
- 在程序中 使用結構體
- 結構體賦值
- 結構體數組
- 結構體中位字段
- 共用體
- 枚舉
- 指針
- 如何聲明一個指針
- 將指針初始化為一個地址
- 使用new來分配內存
- 指針和數組之間的差別
- 指針、數組和指針算術
- 指針和字符串
- 使用new創建動態結構
- delete使用示例
- 類型組合
- 數組的替代品
- 模板類vector
- 模板類array
重溫C++ 復合類型
在程序中 使用結構體
// 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; }結構體賦值
// 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中結構體可以直接賦值choice = bouquet; // assign one structure to anothercout << "choice: " << choice.name << " for $";cout << choice.price << endl;// cin.get();return 0; }結構體數組
// arrstruc.cpp -- an array of structures #include <iostream> struct inflatable {char name[20];float volume;double price; }; int main() {using namespace std;//< guests 是一個結構體數組,類型是 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可以使用據點訪問結構體相應的成員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; }結構體中位字段
- 與C語言一樣C++也允許指定占用特定位數的結構體成員,這使得創建與某個硬件設備上寄存器對應的數據結構非常方便,字段的類型為整數或者枚舉,接下來是冒號,冒號后面是一個數字,它指定使用的位數,可以使用沒有名稱的字段來提供間距,每個成員都被稱為位字段(bit field)
共用體
- 共用體是一種數據格式,它能夠存儲不同的數據類型,但是只能同時存儲其中一種數據類型
- 可以采用共用提的特性,就能在傳參的時候既能傳入浮點型,也能傳入整形,或者字符串。
枚舉
- C++的enum工具提供了另一種創建符號常量的方式,這種方式可以代替const,它還允許定義新類型,但是必須安嚴格的限制進行,使用enum的句法與使用結構體相似。
這條語句完成了兩件事情
-
可以使用枚舉名來聲明這種類型的變量;
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; }警告
- 一定要在對指針應用解除引用運算符(*),之前,將指針初始化為一個確定的、適當的地址,這時關于使用指針的金科玉律
使用new來分配內存
//< 運行時分配內存 int * pn = new int; typeName * Pointer_name = new typeName;- 將new用于兩種不同的類型
指針和數組之間的差別
// arraynew.cpp -- using the new operator for arrays //< c/C++中使用指針來處理數組,兩者基本上相同,但是還是由細微的差別 #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";//< 指針可以進行加減操作,但是數組不可以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; }指針、數組和指針算術
指針和數組基本上等價的原因在于指針算術(pointer arithmetic)和C++內部處理數組的方式,指針算術是按照步長進行增減的,和數組的增減方式一樣,C++底層將數組解釋為地址:
// 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- 程序解釋,在大多數情況下, C++將數組名解釋為數組的第一個元素的地址
指針和字符串
// 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將打印出字符串 如果向打印出地址必須強制轉換為 (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創建動態結構
// 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函數獲取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; }//< 申請內存可以返回指針的形式,但是要是使用參數的形式就必須使用指向指針的指針 //< 因為C++傳入的參數會使用臨時變量代替 char * getname() // return pointer to new string { //< 自動變量是局部變量,他的作用域就是它所包含的代碼塊//< 自動變量常存儲在棧中,這意味著執行代碼塊時,其中的變量將依次添加到棧中,//< 離開代碼塊是將按照相反的順序釋放這些變量,這被稱為后進先出的(LIFO),因此在程序執行的過程中,棧將不//< 增大和縮小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; }數組的替代品
模板類vector
- 模板類類似于string類,也是一種動態數組,可以在運行階段設置vector對象的長度,可以再末尾附加新數據,還可以在中間插入新數據,基本上它可以是使用new創建動態數組的替代品,實際上的vector確實是用new和delete來管理內存,但是這種工作自動完成的。
vector<typeName> vt(n_elem)
vt為vector對象,它存儲n_elem個類型為 typeName的元素
模板類array
- 使用vector功能比數組強大,但是付出的代價就是效率稍低,鑒于此C++11提供與數組一樣的模板類,與數組一樣是固定長度的,也是使用棧而不是自由存儲區
對比數組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 同樣大小的情況下可以直接進行賦值 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++也不做數組超界限的處理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; }總結
- 上一篇: 【热烈祝贺】我刊主编郑纬民教授荣获中国存
- 下一篇: C/C++实现读取当前文件夹下的文件-p