C++ 程式初探 V 2015 暑期 ver. 1.0.1
C++ 程式語言 大綱 1. 大量檔案讀取 & 計算 2. 指標 3. 動態記憶體 & 動態陣列 4. 標準函式庫 (STL) vector, algorithm 5. 結構與類別 2
大量檔案讀取 & 計算 若目前有一個程式將讀取純文字文件 (.txt) 中的整數, 並將該文件中的整數有小到大排序後, 儲存到另外一個新的純文字件中 假設有 20 個純文字文件, 每個文件格式包含兩項資訊為 : 1. 整數數量大小 (size, 已知最大數量為 300) 2. 欲排序之整數 (data) 3
大量檔案讀取 & 計算 給定最大陣列 #include<iostream> #include<fstream> #include<algorithm> const int maxsize = 300; int size; int data[maxsize]; size maxsize 1 2 3 4 5 6 0 0 0 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[298] a[299] ifstream sinf("sdata\\sdata00000.txt"); sinf>>size; //dynamic size is determined by reading file for(int i=0; i<size; i++) sinf>>data[i]; //sorting sort(data, data+size); //output on the screen for(int i=0; i<size; i++) cout<<data[i]<<" "; 4
大量檔案讀取 & 計算 產生動態的檔名 #include<iostream> #include<fstream> #include<sstream> #include<iomanip> #include<algorithm> const int maxsize = 300; int size; int data[maxsize]; int filenum = 20; for(int n=0; n<filenum; n++) // set the name rule for reading file stringstream ifname; //give the path as "sdata\\sdata00000.txt" ifname<<"sdata\\sdata"<<setw(5)<<setfill('0')<<n<<".txt"; 引入標頭檔 #include<sstream> sstream 物件 stringstream sstream 物件使用 sstr; sstr<<"str"<<36<<var; //read file ifstream sinf(ifname.str().c_str()); sstream 物件轉換為 c style 字串 sstr.str().c_str(); 5
大量檔案讀取 & 計算 產生動態的檔名 #include<iostream> #include<fstream> #include<sstream> #include<iomanip> #include<algorithm> #include<direct.h> const int maxsize = 300; int size; int data[maxsize]; int filenum = 20; 引入標頭檔 VC++ #include<direct.h> mkdir 函式 mkdir("folder_name"); mkdir("result"); //create new folder for(int n=0; n<filenum; n++) // set the name rule for reading file stringstream ifname; //give the path as "sdata\\sdata00000.txt" ifname<<"sdata\\sdata"<<setw(5)<<setfill('0')<<n<<".txt"; //read file ifstream sinf(ifname.str().c_str()); // 接續下一頁... 6
大量檔案讀取 & 計算 產生動態的檔名 // 接續上一頁... sinf>>size; //dynamic size is determined by reading file for(int i=0; i<size; i++) sinf>>data[i]; sort(data, data+size); // give the name for output file stringstream ofname; ofname<<"result\\rsdata"<<setw(5)<<setfill('0')<<n<<".txt"; //output file for sorted data ofstream routf(ofname.str().c_str()); for(int i=0; i<size; i++) routf<<setw(5)<<data[i]; sinf.close(); routf.close(); 7
指標 (pointer) int var = 4; int* ptr = &var; cout<<&var<<endl; //12FF88 cout<<ptr<<endl; //12FF88 Cout<<*ptr<<endl; //4 name Cout<< var<<endl; //4 address value int* ptr2; name ptr2 = &var; address value 指標 int* ptr; int* ptr = &var; var 取址運算子 0012FF88 4 ptr 0012FF80 0012FF88 & 8
指標 int var = 4; int* ptr = &var; cout<<var<<endl; //4 *ptr = 5; cout<<var<<endl; //5 Var = 6; cout<<*ptr<<endl; //6 name address value name address value 指標 int* ptr; int* ptr = &var; var 取址運算子 0012FF88 4 ptr 0012FF80 0012FF88 & 取值運算子 * 9
問題 1 //*(&var) 等於 *(ptr) cout<<*&var<<endl; //4 cout<<&*var<<endl; //invalid cout<<*&ptr<<endl; //0012FF88 //&(*ptr) 等於 &(var) cout<<&*ptr<<endl; //0012FF88 name address value name address value var 0012FF88 4 ptr 0012FF80 0012FF88 10
指標 指標做為函式引數 (pointer as argument) void swap_ref(int& a, int& b) int temp = a; a = b; b= temp; void swap_ptr(int* a, int* b) int temp = *a; *a = *b; *b= temp; 11
指標 指標做為函式引數 #include<iostream> int a =3, b=5; cout<<a<<" "<<b<<endl; swap_ref(a,b); cout<<a<<" "<<b<<endl; swap_ptr(&a,&b); cout<<a<<" "<<b<<endl; 12
指標 指標運算 var int var = 4; 0012FF88 int* ptr = &var; 4 cout<<ptr<<endl; //12FF88 ptr cout<<--ptr<<endl; //12FF84 0012FF80 //(-4 因為 int 大小為 4bytes) 0012FF88 cout<<++ptr<<endl; //12FF8c //(+4 因為 int 大小為 4bytes) cout<<ptr-5<<endl; //12FF74 (-4) cout<<ptr+5<<endl; //12FF9c (+20) 指標運算 ptr=ptr+5; ptr=ptr-5; ptr+=5; Ptr-=5; ptr++; Ptr--; 13
指標 陣列與指標間的關係 #include<iostream> int a[]=1,2,3,4,5,6,7,8,9,10; cout<<*a<<endl; // 1 cout<<*(a+1)<<endl; // 2 cout<<*(a+2)<<endl; // 3 cout<<*a+1<<endl; // for(int i=0, i<9; i++) cout<<*(a+i); // 1 2 3 4 5 6 7 8 9 10 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 4 5 6 7 8 9 10 a a+1 a+2 a+3 a+4 a+5 a+6 a+7 a+8 a+9 14
動態記憶體 & 動態陣列 #include<iostream> // 動態記憶體 (new & delete) int *a = new int; // 配置記憶體 *a = 8; cout<<*a<<endl; // 8 delete a; // 釋放記憶體 address value name address value 0012FF88 8 a 0012FF80 0012FF88 15
動態記憶體 #include<iostream> void fun() int *a = new int; // 配置記憶體 *a = 8; cout<<*a<<endl; // 未釋放記憶體!!! fun(); address value name address value 0012FF88 8 a 0012FF80 0012FF88 16
動態陣列 一維陣列 #include<iostream> // 一維動態陣列 int N=10; // 不需為 const!!! int *a = new int [N]; // 配置記憶體 for(int i=0, i<9; i++) a[i]=i+1; 1 2 3 4 5 6 7 8 9 10 for(int i=0, i<9; i++) a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] cout<<a[i]<<endl; delete [] a; // 釋放記憶體 17
動態陣列 一維陣列 #include<iostream> // 一維動態陣列 int N; cin>>n; // 動態決定 int *a = new int [N]; // 配置記憶體 for(int i=0, i<n; i++) a[i]=i+1; for(int i=0, i<n; i++) cout<<a[i]<<endl; delete [] a; // 釋放記憶體 1 2 3 N-1 N a[0] a[1] a[2] a[n-2] a[n-1] 18
動態陣列 二維陣列 // 二維動態陣列 int N=5, M=3; int **a = new int* [N]; // 配置記憶體 for(int i=0, i<n; i++) a[i]= new int [M]; for(int i=0, i<n; i++) for(int i=0, i<m; i++) a[i][j] = i*m+j+1; for(int i=0, i<n; i++)// 釋放記憶體 delete [] a[i]; delete [] a; a[0] a[1] a[2] a[3] a[4] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 19
標準程式庫 (standard template library; STL) #include<iostream> #include<fstream> #include<string> STL 命名空間 cout<<"stl"<<endl; 20
標準程式庫 (STL) vector 動態陣列 #include<vector> vector<int> vct1(10); vector<int> vct2(10,2); vector<int> vct3; vct3.resize(10); vector 宣告 vector<type> var int size=10; vector<int> vct4(size); vct4.resize(12); 21
標準程式庫 (STL) vector 動態陣列 #include<vector> #include<iostream> vector<int> vct(10); int size = vct.size(); // 陣列大小 vct[0]=100; // 存入陣列 cout<<vct[0]<<endl; // 取得陣列數值 22
標準程式庫 (STL) vector 動態陣列 #include<vector> #include<iostream> vector<int> vct(3,2); vct.push_back(6); vct.insert(vct.begin()+3, 5); vct.erase(vct.begin()+4); 23
標準程式庫 (STL) 多維 vector 動態陣列 #include<vector> #include<iostream> // 宣告 3*4 的 vector 陣列 方法 1 vector<vector<int> > vec2d_1(3); for(int i=0; i<3; i++) vec2d_1[i] = vector<int>(4); // 宣告 3*4 的 vector 陣列 方法 2 vector<vector<int> > vec2d_2(3,vector<int>(4)); 24
標準程式庫 (STL) algorithm #include<algorithm> 方法 sort random_shuffle next_enumeration prev_enumeration find 說明排序亂數排序下一個列舉數上一個列舉數搜尋 25
結構 (structure) #include<iostream> struct customer double x; double y; int demand; ; void main(void) customer client; client.x = 10.5; client.y = 4.3; client.demand = 40; cout<<"the customer at ("<< client.x <<","<< client.y <<") " <<"has demand of "<< client.demand <<endl; 結構宣告 struct name... ; 26
結構 結構陣列 struct customer double x; double y; int demand; ; void main(void) customer client[5]; 27
結構與類別 (class) class customer public: double x; double y; int demand; ; // 兩者的宣告意義相同 struct customer double x; double y; int demand; ; 結構宣告 class name public:... protected:... private:... ; 28
練習 1 練習建構一個學生資料的類別 ( 結構 ), 包含 : 1. 學生學號 2. 學生姓名 3. 國文成績 4. 數學成績 29