柚子快報(bào)激活碼778899分享:開發(fā)語(yǔ)言 C++沖鴨~【高級(jí)】
柚子快報(bào)激活碼778899分享:開發(fā)語(yǔ)言 C++沖鴨~【高級(jí)】
C++文件和流
iostream庫(kù):cin cout 從標(biāo)準(zhǔn)輸入讀取流和向標(biāo)準(zhǔn)輸出寫入流。 fstream庫(kù):從文件讀取流和向文件寫入流。
ofstream:該數(shù)據(jù)類型表示輸出文件流,用于創(chuàng)建文件并向文件寫入信息;ifstream:該數(shù)據(jù)結(jié)構(gòu)表示輸入文件流,用于從文件讀取信息;fstream:文件流,同時(shí)具有ofstream和ifstream兩種功能。 要在C++中進(jìn)行文件處理,必須在C++源代碼中包含頭文件和。
打開文件
void open(const char *filename, ios::openmode mode);
ios::app 【追加模式,所有寫入都追加到文件末尾】ios::ate 【文件打開定位到文件末尾】ios::in 【打開文件用于讀取】ios::out 【打開文件用于寫入】ios::trunc 【如果文件已存在,其內(nèi)容將在打開文件之前被截?cái)?,即把文件長(zhǎng)度設(shè)為0?!?同時(shí)使用
ofstream outfile;
outfile.open("file.dat", ios::out | ios::trunc );
關(guān)閉文件
當(dāng) C++ 程序終止時(shí),它會(huì)自動(dòng)關(guān)閉刷新所有流,釋放所有分配的內(nèi)存,并關(guān)閉所有打開的文件。但程序員應(yīng)該養(yǎng)成一個(gè)好習(xí)慣,在程序終止前關(guān)閉所有打開的文件。
讀取&寫入實(shí)例
#include
#include
using namespace std;
int main(){
char data[100];
// 以寫模式打開文件
ofstream outfie;
outfile.open("afile.dat");
cout << "Writing to the file" < cout << "Enter your name: "; cin.getline(data, 100); // 向文件寫入用戶輸入的數(shù)據(jù) outfile << data < cout << "Enter your age: "; cin >> data; cin.ignore(); // 再次向文件寫入用戶輸入的數(shù)據(jù) outfile << data < // 以讀模式打開文件 ifstream infile; infile.open("afile.dat"); cout << "Readomg from the file" < infile >> data; // 在屏幕上寫入數(shù)據(jù) cout << data << endl; // 再次從文件讀取數(shù)據(jù),并顯示 infile >> data; cout << data < infile.close(); return 0; } 程序編譯運(yùn)行結(jié)果: $./a.out Writing to the file Enter your name: Zara Enter your age: 9 Reading from the file Zara 9 文件位置指針 // 定位到 fileObject 的第 n 個(gè)字節(jié)(假設(shè)是 ios::beg) fileObject.seekg( n ); // 把文件的讀指針從 fileObject 當(dāng)前位置向后移 n 個(gè)字節(jié) fileObject.seekg( n, ios::cur ); // 把文件的讀指針從 fileObject 末尾往回移 n 個(gè)字節(jié) fileObject.seekg( n, ios::end ); // 定位到 fileObject 的末尾 fileObject.seekg( 0, ios::end ); C++異常處理 異常時(shí)程序在執(zhí)行期間產(chǎn)生的問(wèn)題。C++異常是指在程序運(yùn)行時(shí)發(fā)生的特殊情況,比如嘗試除以零的操作。異常提供了一種轉(zhuǎn)移程序控制權(quán)的方式。C++異常處理設(shè)計(jì)三個(gè)關(guān)鍵字:try、catch、throw。 throw:當(dāng)問(wèn)題出現(xiàn)時(shí),程序會(huì)拋出一個(gè)異常。這是通過(guò)throw關(guān)鍵字完成的。catch:通過(guò)異常處理程序捕獲異常。catch關(guān)鍵字用于捕獲異常。try:try塊中的代碼標(biāo)識(shí)將被激活的特定異常。后面跟一個(gè)或多個(gè)catch塊。 try { // 保護(hù)代碼 }catch( ExceptionName e1 ) { // catch 塊 }catch( ExceptionName e2 ) { // catch 塊 }catch( ExceptionName eN ) { // catch 塊 } 拋出異常 double division(int a, int b) { if( b == 0 ) { throw "Division by zero condition!"; } return (a/b); } 捕獲異常 try { // 保護(hù)代碼 }catch( ExceptionName e ) { // 處理 ExceptionName 異常的代碼 } 實(shí)例: #include using namespace std; double division(int a, int b){ if (b == 0){ throw "Division by zero condition!"; } retnrn (a/b); } int main(){ int x = 50; int y = 0; double z = 0; try { z = division(x,y); cout << z < }catch (const char* msg){ cerr << msg < } return 0; } C++標(biāo)準(zhǔn)的異常 定義新的異常 通過(guò)繼承和重載exception類來(lái)定義新的異常。 #include #include using namespace std; struct MyException : public exception{ const char * what() const throw(){ return "C++ Exception"; } }; int main(){ try{ throw MyException(); } catch (MyException& e){ std::cout << "MyException caught" << std::endl; std::cout << e.what() << std::endl; } catch(std::exception& e){ //其他錯(cuò)誤 } return 0; } MyException caught C++ Exception C++動(dòng)態(tài)內(nèi)存 C++程序中的內(nèi)存分為兩個(gè)部分: 棧:在函數(shù)內(nèi)部聲明的所有變量都將占用棧內(nèi)存;堆:這是程序中未使用的內(nèi)存,在程序運(yùn)行時(shí)可用于動(dòng)態(tài)分配內(nèi)存。 很多時(shí)候,無(wú)法提前預(yù)知需要多少內(nèi)存來(lái)存儲(chǔ)某個(gè)定義變量中的特定信息,所需內(nèi)存的大小需要在運(yùn)行時(shí)才能確定。 在C++中,您可以使用特殊的運(yùn)算符為給定類型的變量在運(yùn)行時(shí)分配堆內(nèi)的內(nèi)存,這會(huì)返回所分配的空間地址。這種運(yùn)算符即new運(yùn)算符。 如果不再需要?jiǎng)討B(tài)分配的內(nèi)存空間,可以使用delete運(yùn)算符,刪除之前由new運(yùn)算符分配的內(nèi)存。 #include using namespace std; int main(){ double* pvalue = NULL; // 初始化為null的指針 pvalue = new double; // 為變量請(qǐng)求內(nèi)存 *pvalue = 1314.99; // 在分配的地址存儲(chǔ)值 cout << "Value of pvalue : " << *pvalue < delete pvalue; // 釋放內(nèi)存 return 0; } 數(shù)組的動(dòng)態(tài)內(nèi)存分配 假設(shè)要為一個(gè)字符數(shù)組(一個(gè)有20個(gè)字符的字符串)分配內(nèi)存,可以使用上面實(shí)例中的語(yǔ)法來(lái)為數(shù)組動(dòng)態(tài)的分配內(nèi)存: char* pvalue = NULL; // 初始化為null的指針 pvalue = new char[20]; // 為變量請(qǐng)求內(nèi)存 刪除剛剛創(chuàng)建的屬組: delete [] pvalue; // 刪除 pvalue 所指向的數(shù)組 一維數(shù)組 // 動(dòng)態(tài)分配,數(shù)組長(zhǎng)度為m int *array = new int[m]; // 釋放內(nèi)存 delete [] array; 二維數(shù)組 int **array; array = new int *[m]; for (int i=0; i array[i] = new int [n]; } // 釋放 for (int i=0; i delete [] array[i]; } delete [] array; 二維數(shù)組實(shí)例測(cè)試 #include using namespace std; int main(){ int **p; int i,j; p = new int *[4]; for (i=0; i<4; i++){ p[i] = new int [8]; } for (i=0; i<4; i+; i++){ for (j=; j<8; j++){ p[i][j] = j*i; } } for (i=0; i<4;i++){ for (j=0; j<8; j++){ if (j==0) cout < cout << p[i][j] <<"\t"; } } for (i=0; i<4; i++){ delete [] p[i]; } delete [] p; return 0; } 對(duì)象的動(dòng)態(tài)內(nèi)存分配 對(duì)象與簡(jiǎn)單的數(shù)據(jù)類型沒(méi)有什么不同。 #include using namespace std; class Box{ public: Box() { cout << "調(diào)用構(gòu)造函數(shù)!" < } ~Box(){ cout << "調(diào)用析構(gòu)函數(shù)!" < } }; int main(){ Box* myBoxArray = new Box[4]; delete [] myBoxArray; // 刪除數(shù)組 return 0; } C++命名空間 命名空間是專門用于解決不同庫(kù)中相同函數(shù)名調(diào)用問(wèn)題,它可以作為附加信息來(lái)區(qū)分不同庫(kù)中相同名稱的函數(shù)、類、變量等。使用了命名空間即定義了上下文。本質(zhì)上,命名空間就是定義了一個(gè)范圍。 #include using namespace std; namespace first_space{ void func(){ cout << "Inside first_sapce" < } } namespace second_space{ void func (){ cout << "Inside second_space" < } } int main(){ first_space::func(); second_space::func(); return 0; } using 指令 可以使用using namespace指令,這樣在使用命名空間時(shí)就可以不用再前面加上命名空間的名稱。這個(gè)指令會(huì)告訴編譯器,后續(xù)的代碼將使用指定的命名空間中的名稱。 #include using namespace std; namespace first_space{ void func(){ cout << "Inside first_space" < } } namespace second_space{ void func(){ cout << "Inside second_space" < } } using namespace first_space; int main(){ func(); return 0; } using 也可以用來(lái)指定命名空間中的特定項(xiàng)目。 using std::cout; 不連續(xù)的命名空間 命名空間可以定義在幾個(gè)不同的部分中,因此命名空間是由幾個(gè)單獨(dú)定義的部分組成的。一個(gè)命名空間的各個(gè)組成部分可以分散在多個(gè)文件中。 所以,如果命名空間中的某個(gè)組成部分需要請(qǐng)求定義在另一個(gè)文件中的名稱,則仍然需要聲明該名稱。下面的命名空間定義可以是定義一個(gè)新的命名空間,也可以是為已有的命名空間增加新的元素。 嵌套的命名空間 命名空間可以嵌套。 namespace namespace_name1{ namespace namesapce_name2{ } } 通過(guò)使用 :: 運(yùn)算符來(lái)訪問(wèn)嵌套的命名空間中的成員: // 訪問(wèn) namespace_name2 中的成員 using namespace namespace_name1::namespace_name2; // 訪問(wèn) namespace_name1 中的成員 using namespace namespace_name1; C++模板 模板是泛型編程的基礎(chǔ),泛型編程即以一種獨(dú)立于任何特定類型的方式編寫代碼。 模板是創(chuàng)建泛型類或函數(shù)的藍(lán)圖或公式。庫(kù)容器,比如迭代器和算法,都是泛型編程的例子,都使用了模板的概念。 每個(gè)容器都有一個(gè)單一的定義,比如向量,可以定義不同類型的向量,vector vector。 函數(shù)模板 // 一般形式 template // 函數(shù)主體 } type是函數(shù)所使用的數(shù)據(jù)類型的占位符名稱,這個(gè)名稱可以在函數(shù)定義中使用。 例子 #include #include using namespace std; template inline T const& Max (T const& a, T const& b){ return a < b? b:a; } int main(){ int i = 39; int j = 20; cout << "Max(i, j): " << Max(i, j) < double f1 = 13.5; double f2 = 20.7; coout << "Max(i, j): " << Max(f1, f2) < string s1 = "Hello"; string s2 = "World"; cout << "Max(s1, s2): " << Max(s1, s2) < return 0; } 編譯鏈接結(jié)果: Max(i, j): 39 Max(f1, f2): 20.7 Max(s1, s2): World 類模板 與函數(shù)模板一樣,也可以定義類模板。泛型類聲明的一般形式如下所示: template } type是占位符類型名稱,可以在類被實(shí)例化的時(shí)候進(jìn)行指定。 例子 #include #include #include #include #include using namespace std; template class Stack { private: vector public: void push(T const&); // 入棧 void pop(); // 出棧 T top() const; // 返回棧頂元素 bool empty() const{ // 如果為空返回真 return elems.empty(); } }; template void Stack elems.push_back(elem); } template void Stack if (elems.empty()) { throw out_of_range("Stack<>::pop(): empty stack"); } elems.pop_back(); } template T Stack if (elems.empty()){ throw out_of_range("Stack<>::top():empty stack"); } return elems.back(); // 返回最后一個(gè)元素的副本 } int main(){ try { Stack Stack intStack.push(7); cout << intStack.top() < stringStack.push("hello"); cout << stringStack.top() < stringStack.pop(); stringStack.pop(); } catch (exception const& ex) { cerr << "Exception: " << ex.what() < return -1; } } 編譯執(zhí)行結(jié)果: 7 hello Exception: Stack<>::pop(): empty stack C++預(yù)處理器 預(yù)處理器是一些指令,只是編譯器在實(shí)際編譯之前所需完成的預(yù)處理。 所有的預(yù)處理器指令都是以井號(hào)(#)開頭,只有空格字符可以出現(xiàn)在預(yù)處理指令之前。預(yù)處理指令不是C++語(yǔ)句,所以它們不會(huì)以分號(hào)結(jié)尾。 #include 指令,這個(gè)宏用于把頭文件包含到源文件中。 C++還支持很多預(yù)處理指令,比如 #include、#define、#if、#else、#line等,讓我們一起看看這些重要指令。 #define預(yù)處理 #define預(yù)處理指令用于創(chuàng)建符號(hào)常量。該符號(hào)常量通常稱為宏。 例子 #include using namespace std; #define PI 3.1415926 int main(){ cout << "Value of PI :" << PI << endl; return 0; } 參數(shù)宏 可以使用#define來(lái)定義一個(gè)帶有參數(shù)的宏,如下所示: #include using namespace std; #define MIN(a,b)(a int main(){ int i, j; i = 100; j = 30; cout << "較小的值為:" << MIN(i, j) < return 0; } 條件編譯 有幾個(gè)指令可以用來(lái)有選擇地對(duì)部分程序源代碼進(jìn)行編譯。這個(gè)過(guò)程被稱為條件編譯。 條件預(yù)處理器的結(jié)構(gòu)與if選擇結(jié)構(gòu)很像。 #ifdef NULL #define NULL 0 #endif 只在調(diào)試時(shí)編譯,調(diào)試開關(guān)可以使用一個(gè)宏來(lái)實(shí)現(xiàn): #ifdef DEBUG cerr << "Variable x = " << x < #endif 如果在指令 #ifdef DEBUG 之前已經(jīng)定義了符號(hào)常量DEBUG,則會(huì)對(duì)程序中的cerr語(yǔ)句進(jìn)行編譯。可以使用 #if 0 語(yǔ)句注釋掉程序的一部分: #if 0 不進(jìn)行編譯的代碼 #endif 例子 #include using namespace std; #define DEBUG #define MIN(a, b) (((a)<(b)) ? a : b) int main (){ int i, j; i = 100; j = 30; #ifdef DEBUG cerr << "Trace: Inside main function" < #endif #if 0 cout << MKSTR(HELLO C++) << endl; #endif cout << "The minimum is " << MIN(i, j) < #ifdef DEBUG cerr <<"Trace: Coming out of main function" < #endif return 0; } 編譯執(zhí)行結(jié)果: Trace: Inside main function The minimum is 30 Trace: Coming out of main function #和##運(yùn)算符 #和## 預(yù)處理運(yùn)算符在C++和ANSI/ISO C中都是可用的。 #運(yùn)算符會(huì)把 replacement-text 令牌轉(zhuǎn)換為用引號(hào)引起來(lái)的字符串。 #include using namespace std; #define MKSTR( x ) int main(){ cout << MKSTR(HELLO C++) < return 0; } 將 cout << MKSTR(HELLO C++) << endl; 轉(zhuǎn)換成 cout << “HELLO C++” << endl; ##運(yùn)算符用于連接兩個(gè)令牌。 #define CONCAT( x, y ) x ## y 例子 #include using namespace std; #define concat(a, b) a ## b int main(){ int xy = 100; cout << concat(x, y); return 0; } 將 cout << concat(x, y); 轉(zhuǎn)換為 cout << xy; C++中的預(yù)定義宏 __LINE__ 這會(huì)在程序編譯時(shí)包含當(dāng)前行號(hào); __FILE__ 這會(huì)在程序編譯時(shí)包含當(dāng)前文件名; __DATE__ 這會(huì)包含一個(gè)形式為 month/day/year 的字符串,它表示把源文件轉(zhuǎn)換為目標(biāo)代碼的日期。 __TIME__ 這會(huì)包含一個(gè)形式為 hour:minute:second 的字符串,它表示程序被編譯的時(shí)間。 C++信號(hào)處理 信號(hào)是由操作系統(tǒng)傳給進(jìn)程的中斷,會(huì)提早終止一個(gè)程序。在UNIX、LINUX、MacOSX或windows系統(tǒng)中,可以通過(guò)Ctrl+C產(chǎn)生中斷。 有些信號(hào)不能唄程序捕獲,但是下表所列信號(hào)可以在程序中捕獲,并可以基于信號(hào)采取適當(dāng)?shù)膭?dòng)作。這些信號(hào)是定義在C++頭文件 信號(hào)描述SIGABRT程序的異常終止,如調(diào)用abort。SIGFPE錯(cuò)誤的算術(shù)運(yùn)算,比如除以零或者導(dǎo)致溢出的操作。SIGILL檢測(cè)非法指令。SIGINT程序終止(interrupt)信號(hào)。SIGSEGV非法訪問(wèn)內(nèi)存。SIGTERM發(fā)送到程序的終止請(qǐng)求。 signal()函數(shù) C++信號(hào)處理庫(kù)提供了signal函數(shù),用來(lái)捕獲突發(fā)事件。 void (*signal (int sig, void (*func)(int)))(int); signal(registered signal, signal handler) 這個(gè)函數(shù)接收兩個(gè)參數(shù):第一個(gè)參數(shù)是要設(shè)置的信號(hào)的標(biāo)識(shí)符,第二個(gè)參數(shù)是指向信號(hào)處理函數(shù)的指針。函數(shù)返回值是一個(gè)指向先前信號(hào)處理函數(shù)的指針。如果先前沒(méi)有設(shè)置信號(hào)處理函數(shù),則返回值為 SIG_DFL。如果先前設(shè)置的信號(hào)處理函數(shù)為 SIG_IGN,則返回值為 SIG_IGN。 例子 #include #include #include using namespace std; void signalHandler( int signum ){ cout << "Interrupt signal (" << signum << ") received.\n"; // 清理并關(guān)閉 // 終止程序 exit(signum); } int main (){ // 注冊(cè)信號(hào) SIGINT 和信號(hào)處理程序 signal(SIGINT, signalHandler); while(1){ cout << "Going to sleep..." < sleep(1); } return 0; } 編譯執(zhí)行結(jié)果: Going to sleep… Going to sleep… Going to sleep… 按下Ctrl+C中斷程序: Going to sleep… Going to sleep… Going to sleep… Interrupt signal (2) received. raise()函數(shù) 可以使用 raise() 生成信號(hào),該函數(shù)帶有一個(gè)整數(shù)信號(hào)編號(hào)作為參數(shù): int raise (signal sig); 在這里, sig是要發(fā)送的信號(hào)的編號(hào),這些信號(hào)包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。 例子 #include #include #include using namespace std; void signalHandler( int signum ){ cout << "Interrupt signal (" << signum << ") received.\n"; // 清理并關(guān)閉 // 終止程序 exit(signum); } int main(){ int i=0; signal (SIGINT, signalHandler); while(++i){ cout << "Going to sleep..." < if(i == 3){ raise( SIGINT ); } sleep(1); } return 0; } 編譯執(zhí)行結(jié)果: Going to sleep… Going to sleep… Going to sleep… Interrupt signal (2) received. note: sleep函數(shù) 功能:執(zhí)行掛起一段時(shí)間,也就是等待一段時(shí)間再繼續(xù)執(zhí)行; 用法:sleep(時(shí)間) sleep是區(qū)分大小寫的,有的編譯器是大寫,有的是小寫; sleep括號(hào)里的時(shí)間,在windows下是以毫秒為單位,而Linux是以秒為單位。 C++多線程 多線程是多任務(wù)處理的一種特殊形式,多任務(wù)處理允許讓電腦同時(shí)運(yùn)行兩個(gè)或兩個(gè)以上的程序。一般情況下,兩種類型的多任務(wù)處理:基于進(jìn)程和基于線程。 基于進(jìn)程的多任務(wù)處理是程序的并發(fā)執(zhí)行;基于線程的多任務(wù)處理是同一程序的片段的并發(fā)執(zhí)行。 多線程程序包含可以同時(shí)運(yùn)行的兩個(gè)或多個(gè)部分。這樣的程序中的每個(gè)部分稱為一個(gè)線程,每個(gè)線程定義了一個(gè)單獨(dú)的執(zhí)行路徑。 本教程假設(shè)您使用的是 Linux 操作系統(tǒng),我們要使用 POSIX 編寫多線程 C++ 程序。POSIX Threads 或 Pthreads 提供的 API 可在多種類 Unix POSIX 系統(tǒng)上可用,比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Solaris。 創(chuàng)建線程 #include pthread_create (thread, attr, start_routine, arg) pthread_create 創(chuàng)建一個(gè)新的線程,并讓它可執(zhí)行。關(guān)于參數(shù): 參數(shù)描述thread指向線程標(biāo)識(shí)符指針attr一個(gè)不透明的屬性對(duì)象,可以被用來(lái)設(shè)置線程屬性??梢灾付ň€程屬性對(duì)象,也可以使用默認(rèn)值 NULLstart_routine線程運(yùn)行函數(shù)起始地址,一旦線程被創(chuàng)建就會(huì)執(zhí)行arg運(yùn)行函數(shù)的參數(shù)。它必須通過(guò)把引用作為指針強(qiáng)制轉(zhuǎn)換為void類型進(jìn)行傳遞。如果沒(méi)有傳遞參數(shù),則使用NULL。創(chuàng)建線程成功時(shí),返回0,若返回值不為0,則說(shuō)明創(chuàng)建失敗。 終止線程 #include pthread_exit (status) pthread_exit 用于顯式地退出一個(gè)線程。通常情況下,pthread_exit() 函數(shù)是在線程完成工作后無(wú)需繼續(xù)存在時(shí)被調(diào)用。 如果 main() 是在它所創(chuàng)建的線程之前結(jié)束,并通過(guò) pthread_exit() 退出,那么其他線程將繼續(xù)執(zhí)行。否則,它們將在 main() 結(jié)束時(shí)自動(dòng)被終止。 例子 #include #include using namespace std; #define NUNM_THREADS 5 // 線程的運(yùn)行函數(shù) void* say_hello(void* args){ cout << "Hello CPP!" < return 0; } int main (){ pthread_t tids[NUM_THREADS]; for(int i=0; i int ret = pthread_create(&tids[i], NULL, say_hello, NULL); if (ret != 0){ cout << "pthread_create error: error_code=" << ret < } } // 等各個(gè)線程退出后,進(jìn)程才結(jié)束,否則進(jìn)程強(qiáng)制結(jié)束了,線程可能還沒(méi)反應(yīng)過(guò)來(lái); pthread_exit(NULL); } 使用 -lpthread 庫(kù)編譯程序: $ g++ test.cpp -lpthread -o test.o 執(zhí)行程序: $ ./test.o Hello CPP! Hello CPP! Hello CPP! Hello CPP! Hello CPP! 使用pthread_create()函數(shù)創(chuàng)建了5個(gè)線程,并接收傳入的參數(shù)。每個(gè)線程打印一個(gè)“Hello CPP!”消息,并輸出接收的參數(shù),然后調(diào)用pthread_exit()終止線程。 #include #include #include using namespace std; #define NUM_THREADS 5 void *PrintHello(void *threadid){ // 對(duì)傳入的參數(shù)進(jìn)行強(qiáng)制類型轉(zhuǎn)換,由無(wú)類型指針變?yōu)檎蛿?shù)指針,然后再讀取 int tid = *((int*)threadid); cout << "Hello CPP! 線程ID, " << tid < pthread_exit(NULL); } int main(){ pthread_t threads[NUM_THREADS]; int indexes[NUM_THREADS]; // 用數(shù)組保存i的值 int rc; int i; for (i=0; i cout << "main() : 創(chuàng)建線程, " << i < indexes[i] = i; // 先保存i的值 rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&(indexes[i])); if (rc) { cout << "Error: 無(wú)法創(chuàng)建線程, " << rc < exit(-1); } } pthread_exit(NULL); } 編譯執(zhí)行結(jié)果: $ g++ test.cpp -lpthread -o test.o $ ./test.o main() : 創(chuàng)建線程, 0 main() : 創(chuàng)建線程, 1 Hello Runoob! 線程 ID, 0 main() : 創(chuàng)建線程, Hello Runoob! 線程 ID, 21 main() : 創(chuàng)建線程, 3 Hello Runoob! 線程 ID, 2 main() : 創(chuàng)建線程, 4 Hello Runoob! 線程 ID, 3 Hello Runoob! 線程 ID, 4 向線程傳遞參數(shù) 這個(gè)實(shí)例演示了如何通過(guò)結(jié)構(gòu)傳遞多個(gè)參數(shù)。 #include #include #include using namespace std; #define NUNM_THREADS 5 struct thread_data{ int thread_id; char *message; }; void *PrintHello(void *threadarg){ struct thread_data *my_data; my_data = (struct thread_data *) threadarg; cout << "Thread ID : " << my_data->thread_id; cout << " Message : " << my_data->message << endl; pthread_exit(NULL); } int main(){ pthread_t threads[NUM_THREADS]; struct thread_data td[NUM_THREADS]; int rc; int i; for( i=0; i cout << "main() : creating thread, " << i << endl; td[i].thread_id = i; td[i].message = (char*)"This is message"; rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]); if (rc){ cout << "Eror: unable to create thread, " << rc < exit(-1); } } pthread_exit(NULL); } 編譯執(zhí)行結(jié)果: $ g++ -Wno-write-strings test.cpp -lpthread -o test.o $ ./test.o main() : creating thread, 0 main() : creating thread, 1 Thread ID : 0 Message : This is message main() : creating thread, Thread ID : 21 Message : This is message main() : creating thread, 3 Thread ID : 2 Message : This is message main() : creating thread, 4 Thread ID : 3 Message : This is message Thread ID : 4 Message : This is message 連接和分離線程 使用以下兩個(gè)函數(shù)連接或分離線程: pthread_join(threadid, status) pthread_detach(threadid) pthread_join() 子程序阻礙調(diào)用程序,直到指定的 threadid線程終止為止。當(dāng)創(chuàng)建一個(gè)線程時(shí),它的某個(gè)屬性會(huì)定義它是否是可連接的(joinable)或可分離的(detached)。只有創(chuàng)建時(shí)定義為可連接的線程才可以被連接。如果線程創(chuàng)建時(shí)被定義為可分離的,則它永遠(yuǎn)也不能被連接。 例子 #include #include #include #include using namespace std; #define NUM_THREADS 5 void *wait(void *t){ int i; long tid; tid = (long)t; sleep(1); cout << "Sleeping in thread " < cout << "Thread with id : " << tid << " ...exiting" < pthread_exit(NULL); } int main(){ int rc; int i; pthread_t threads[NUM_THREADS]; pthread_attr_t attr; void *status; // 初始化并設(shè)置線程為可連接的(joinable) pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for (i=0; i cout << "main() : creating thread, " << i < rc = pthread_create(&threads[i], NULL, wait, (void *)&i); if (rc) { cout << "Error:unable to create thread, " << rc < exit(-1); } } // 刪除屬性,并等待其他線程 pthread_attr_destroy(&attr); for(i=0; i rc = pthread_join(threads[i], &status); if(rc){ couot << "Error:unable to join," << rc < exit(-1); } cout << "Main: completed thread id :" << i; cout << " exiting with status :" < } cout << "Main: program exiting." < pthread_exit(NULL); } 編譯執(zhí)行結(jié)果: main() : creating thread, 0 main() : creating thread, 1 main() : creating thread, 2 main() : creating thread, 3 main() : creating thread, 4 Sleeping in thread Thread with id : 4 ...exiting Sleeping in thread Thread with id : 3 ...exiting Sleeping in thread Thread with id : 2 ...exiting Sleeping in thread Thread with id : 1 ...exiting Sleeping in thread Thread with id : 0 ...exiting Main: completed thread id :0 exiting with status :0 Main: completed thread id :1 exiting with status :0 Main: completed thread id :2 exiting with status :0 Main: completed thread id :3 exiting with status :0 Main: completed thread id :4 exiting with status :0 Main: program exiting. std::thread C++ 11 之后添加了新的標(biāo)準(zhǔn)線程庫(kù) std::thread , std::thread 在 頭文件中聲明,因此使用 std::thread 時(shí)需要包含在 頭文件。 一些編譯器使用C++的編譯參數(shù)是 -std=c++ g++ -std=c++ test.cpp std::thread 默認(rèn)構(gòu)造函數(shù),創(chuàng)建一個(gè)空的std::thread執(zhí)行對(duì)象。 #include std::thread thread_object(callable) 一個(gè)可調(diào)用對(duì)象可以是以下三個(gè)中的任何一個(gè): 函數(shù)指針函數(shù)對(duì)象lambda表達(dá)式 定義 callable 后,將其傳遞給 std::thread 構(gòu)造函數(shù) thread_object 。 例子 // 演示多線程的CPP程序 // 使用三個(gè)不同的可調(diào)用對(duì)象 #include #include using namespace std; // 一個(gè)虛擬函數(shù) void foo(int Z){ for (int i=0; i < Z; i++){ cout << "線程使用函數(shù)指針作為可調(diào)用參數(shù)\n"; } } // 可調(diào)用對(duì)象 class thread_obj { public: void operator()(int x){ for (int i=0; i cout << "線程使用函數(shù)作為可調(diào)用參數(shù)\n"; } } }; int main(){ cout << "線程 1、2、3 " "獨(dú)立運(yùn)行" < // 函數(shù)指針 thread th1(foo, 3); // 函數(shù)對(duì)象 thread th2(thread_obj(), 3); // 定義 Lambda 表達(dá)式 auto f = [](int x) { for (int i=0; i cout << "線程使用lambda 表達(dá)式作為可調(diào)用參數(shù)\n"; } }; thread th3(f, 3); th1.join(); th2.join(); th3.join(); return 0; } 使用C++ 11 的編譯參數(shù) -std=c++11: g++ -std=c++11 test.cpp 編譯執(zhí)行結(jié)果: 線程 1 、2 、3 獨(dú)立運(yùn)行 線程使用函數(shù)指針作為可調(diào)用參數(shù) 線程使用函數(shù)指針作為可調(diào)用參數(shù) 線程使用函數(shù)指針作為可調(diào)用參數(shù) 線程使用函數(shù)對(duì)象作為可調(diào)用參數(shù) 線程使用函數(shù)對(duì)象作為可調(diào)用參數(shù) 線程使用函數(shù)對(duì)象作為可調(diào)用參數(shù) 線程使用 lambda 表達(dá)式作為可調(diào)用參數(shù) 線程使用 lambda 表達(dá)式作為可調(diào)用參數(shù) 線程使用 lambda 表達(dá)式作為可調(diào)用參數(shù) C++web編程 什么是CGI? 公共網(wǎng)關(guān)接口(CGI),是一套標(biāo)準(zhǔn),定義了信息時(shí)如何在Web服務(wù)器和客戶端腳本之間進(jìn)行交換的;CGI規(guī)范目前是由NCSA維護(hù)的,NCSA定義CGI如下:公共網(wǎng)關(guān)接口(CGI),是一種用于外部網(wǎng)關(guān)程序與信息服務(wù)器(如HTTP服務(wù)器)對(duì)接的接口標(biāo)準(zhǔn)。 Web瀏覽 當(dāng)我們點(diǎn)擊一個(gè)超鏈接,瀏覽一個(gè)特定的網(wǎng)頁(yè)或URL,會(huì)發(fā)生什么? 瀏覽器聯(lián)系上HTTP Web服務(wù)器,并請(qǐng)求URL,即文件名;Web服務(wù)器將解析URL,并查找文件名。如果找到請(qǐng)求的文件,Web服務(wù)器會(huì)把文件發(fā)送回瀏覽器,否則發(fā)送一條錯(cuò)誤信息,表明請(qǐng)求了一個(gè)錯(cuò)誤的文件;Web瀏覽器從Web服務(wù)器獲取響應(yīng),并根據(jù)接收到的響應(yīng)來(lái)顯示文件或錯(cuò)誤消息。 然而,以這種方式搭建起來(lái)的HTTP服務(wù)器,不管何時(shí)請(qǐng)求目錄中的某個(gè)文件,HTTP服務(wù)器發(fā)送回來(lái)的不是該文件,而是以程序形式執(zhí)行,并把執(zhí)行產(chǎn)生的輸出發(fā)送回瀏覽器顯示出來(lái)。 公共網(wǎng)關(guān)協(xié)議(CGI),是使得應(yīng)用程序(稱為CGI程序或CGI腳本)能夠與Web服務(wù)器以及客戶端進(jìn)行交互的標(biāo)準(zhǔn)協(xié)議。這些CGI程序可以用Python、PERL、shell、C或C++等進(jìn)行編寫。 CGI架構(gòu)圖 Web服務(wù)器配置 在進(jìn)行CGI編程之前,請(qǐng)確保Web服務(wù)器支持CGI,并已配置成可以處理CGI程序。所有由HTTP服務(wù)器執(zhí)行的CGI程序,都必須在預(yù)配置的目錄中。該目錄就是CGI目錄,按照慣例命名為 /var/www/cgi-bin 。雖然CGI文件是C++可執(zhí)行文件,但是按照慣例它的擴(kuò)展名是 .cgi。 默認(rèn)情況喜愛(ài),Apache Web 服務(wù)器回配置在 /var/www/cgi-bin 中運(yùn)行CGI程序。如果想指定其他目錄來(lái)運(yùn)行CGI腳本,在httpd.conf中修改: AllowOverride None Options ExecCGI Order allow,deny Allow from all Options All 第一個(gè)CGI程序 #include using namespace std; int main(){ cout << "Content -type:text/html\r\n\r\n"; cout << "\n"; cout << " cout << " cout << "\n"; cout << " cout << " cout << " cout << "\n"; return 0; } 編譯之后,把可執(zhí)行文件命名為 cplusplus.cgi ,并把這個(gè)文件保存在 /var/www/cgi-bin 中。 執(zhí)行結(jié)果: 柚子快報(bào)激活碼778899分享:開發(fā)語(yǔ)言 C++沖鴨~【高級(jí)】 相關(guān)閱讀Hello World! 這是我的第一個(gè) CGI 程序
\n";
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。