/* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */#include <iostream>#include <typeinfo>#include <string.h>void f(void) { struct A { short age; int money; char name[12]; }; // 12 + 2 + 4 = 18 但實際上是20,因為 結構體的長度以 4 * n std::cout << sizeof(struct A) << "\t" << typeid(struct A).name() << std::endl; union B { short age; int money; char name[12]; }; // 公用體的長度以 4 * n std::cout << sizeof(union B) << "\t" << typeid(union B).name() << std::endl;}/* * */int main(void) { f(); f(); f(); struct A {}; std::cout << typeid(struct A).name() << std::endl; std::cout << "---------------------------" << std::endl; union B { short age; int money; char name[12]; }; B b; b.age = 2; std::cout << b.age << std::endl; b.money = 999; std::cout << b.age << "\t" << b.money << std::endl; strcpy(b.name,"Jack"); std::cout << b.age << "\t" << b.money << "\t" << b.name << std::endl; return 0;}
執行:
20 Z1fvE1A
12 Z1fvE1B
20 Z1fvE1A
12 Z1fvE1B
20 Z1fvE1A
12 Z1fvE1B
Z4mainE1A
---------------------------
2
999 999
24906 1801675082 Jack
理解編譯期與運行期:
這裡主要討論的是struct 與 union 申明位置.這個執行個體中,同事聲明了2個struct A 以及 2個union B,分別在main()函數之外的函數體內申明以及main()函數之內申明.
需要注意的是,即便是在函數體中申明的結構體,也是在編譯期間就定義好的,也就是說,是靜態產生的,並非程式執行到申明結構體的代碼才動態產生的!這和全域變數,局部變數,全域函數,局部函數,以及全域#include,局部#include,全域using name namespace xxx.局部using namespace xxx是一樣的,都是靜態編譯期間就完工定義,並非動態時定義!不同之處就是限制了使用的範圍而已.本質上沒有任何區別,不會導致更多的效能消耗,這裡我們使用typeid來證明了並非程式執行到申明結構體的行才動態申明結構體,因為,他們typeid是相同的!!!
共用體,IO處理:
/* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */#include <iostream>#include <fstream> #include <sstream> #include <cstring> struct Animal { int kind; union { char human[10]; char bird[20]; char fish[30]; }; char* getName(void) { if (kind == 1) { return human; } else if (kind == 2) { return bird; } else { return fish; } } // 考慮IO處理 friend std::ostream& operator<<(std::ostream& os, const Animal& ref); friend std::istream& operator>>(std::istream& is, Animal& ref); };std::ostream& operator<<(std::ostream& os, const Animal& ref) { os << ref.kind << '\n' /**需要分行符號*/;// if (ref.kind == 1) {// os << ref.human;// } else if (ref.kind == 2) {// os << ref.bird;// } else {// os << ref.fish;// } os << ref.fish; return os; } std::istream& operator>>(std::istream& is, Animal& ref) { is >> ref.kind >> ref.fish; return is; } /* * */int main(void) { Animal human = {1,"Jack"}; std::cout << human.getName() << std::endl; std::ofstream ofs("./tmp.txt", std::ios::trunc | std::ios::binary); ofs << human; // 將對象輸入到檔案中 ofs.flush(); ofs.close(); std::ifstream ifs("./tmp.txt", std::ios::in | std::ios::binary); Animal a1; ifs >> a1; // 讀取檔案內容,將其轉換為對象 ifs.close(); std::cout << a1 << std::endl; std::cout << "---------------------------" << std::endl; Animal bird = {2,"Sparrow"}; std::cout << bird.getName() << std::endl; std::ofstream ofs2("./tmp2.txt", std::ios::trunc | std::ios::binary); ofs2 << bird; // 將對象輸入到檔案中 ofs2.flush(); ofs2.close(); std::ifstream ifs2("./tmp2.txt", std::ios::in | std::ios::binary); Animal a2; ifs2 >> a2; // 讀取檔案內容,將其轉換為對象 ifs2.close(); std::cout << a2 << std::endl; std::cout << "---------------------------" << std::endl; Animal fish = {3, "Dolphin"}; std::cout << fish.getName() << std::endl; std::ofstream ofs3("./tmp3.txt", std::ios::trunc | std::ios::binary); ofs3 << fish; // 將對象輸入到檔案中 ofs3.flush(); ofs3.close(); std::ifstream ifs3("./tmp3.txt", std::ios::in | std::ios::binary); Animal a3; ifs3 >> a3; // 讀取檔案內容,將其轉換為對象 ifs3.close(); std::cout << a3 << std::endl; return 0;}
運行:
Jack
1
Jack
---------------------------
Sparrow
2
Sparrow
---------------------------
Dolphin
3
Dolphin