看板 C_and_CPP 關於我們 聯絡資訊
增加VLA跟std::array/std::vector的部份... =============================================================== 03. 你不可以提取(dereference)不知指向何方的指標(包含 null 指標)。 錯誤例子: char *pc1; /* 未給予初值,不知指向何方 */ char *pc2 = NULL; /* pc2 起始化為 null pointer */ *pc1 = 'a'; /* 將 'a' 寫到不知何方,錯誤 */ *pc2 = 'b'; /* 將 'b' 寫到「位址0」,錯誤 */ 正確例子: char c; /* c 的內容尚未起始化 */ char *pc1 = &c; /* pc1 指向字元變數 c */ *pc1 = 'a'; /* c 的內容變為 'a' */ /* 動態分配 10 個 char(其值未定),並將第一個char的位址賦值給 pc2 */ char *pc2 = (char *) malloc(10); pc2[0] = 'b'; /* 動態配置來的第 0 個字元,內容變為 'b' free(pc2); 說明:指標變數必需先指向某個可以合法操作的空間,才能進行操作。 ( 使用者記得要檢查 malloc 回傳是否為 NULL, 礙於篇幅本文假定使用上皆合法,也有正確歸還記憶體 ) 錯誤例子: char *name; /* name 尚未指向有效的空間 */ printf("Your name, please: "); fgets(name,20,stdin); /* 您確定要寫入的那塊空間合法嗎??? */ printf("Hello, %s\n", name); 正確例子: /* 如果編譯期就能決定字串的最大空間,那就不要宣告成 char* 改用 char[] */ char name[21]; /* 可讀入字串最長 20 個字元,保留一格空間放 '\0' */ printf("Your name, please: "); fgets(name,20,stdin); printf("Hello, %s\n", name); 正確例子(2): 若是在執行時期才能決定字串的最大空間,C提供兩種作法: a. 利用 malloc() 函式來動態分配空間,用malloc宣告的陣列會被存在heap 須注意:若是宣告較大陣列,要確認malloc的回傳值是否為NULL size_t length; printf("請輸入字串的最大長度(含null字元): "); scanf("%u", &length); name = (char *)malloc(length); if (name) { // name != NULL printf("您輸入的是 %u\n", length); } else { // name == NULL puts("輸入值太大或系統已無足夠空間"); } /* 最後記得 free() 掉 malloc() 所分配的空間 */ free(name); name = NULL; //(註1) b. C99開始可使用variable-length array (VLA) 須注意: - 因為VLA是被存放在stack裡,使用前要確認array size不能太大 - 不是每個compiler都支援VLA(註2) - C++ Standard不支援(雖然有些compiler支援) float read_and_process(int n) { float vals[n]; for (int i = 0; i < n; i++) vals[i] = read_val(); return process(vals, n); } 正確例子(3): C++的使用者也有兩種作法: a. std::vector (不管你的陣列大小會不會變都可用) std::vector<int> v1; v1.resize(10); // 重新設定vector size b. C++11以後,若是確定陣列大小不會變,可以用std::array 須注意:一般使用下(存在stack)一樣要確認array size不能太大 std::array<int, 5> a = { 1, 2, 3 }; // a[0]~a[2] = 1,2,3; a[3]之後為0; a[a.size() - 1] = 5; // a[4] = 0; 備註: 註1. C++的使用者,C++03或之前請用0代替NULL,C++11開始請改用nullptr 註2. gcc和clang支援VLA,Visual C++不支援 補充資料: http://www.cplusplus.com/reference/vector/vector/resize/ -- 個人網頁:http://gnitnaw.github.io/ 以後在C_and_CPP或LinuxDev發表的文章都會放一份在這邊。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 86.209.153.222 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1463129454.A.687.html ※ 編輯: wtchen (86.209.153.222), 05/13/2016 18:46:01
Caesar08: c++11後,可以用std::array 05/13 19:01
wtchen: 我都忘了還有這個,馬上加 05/13 19:11
※ 編輯: wtchen (86.209.153.222), 05/13/2016 19:18:23 ※ 編輯: wtchen (86.209.153.222), 05/13/2016 19:18:37
wtchen: 對了,請問std::array是存在stack裡嗎? 05/13 19:24
Caesar08: std::array就是一個C形式的array 05/13 19:30
wtchen: 所以一樣不能宣告太大? 05/13 19:31
Caesar08: 對 05/13 19:34
※ 編輯: wtchen (86.209.153.222), 05/13/2016 19:40:38 ※ 編輯: wtchen (86.209.153.222), 05/13/2016 19:40:56
wtchen: 寫到現在總覺得C跟C++5年內一定會分家... 05/13 19:46
Caesar08: 最好快點分... 05/13 19:59
wtchen: C++就像變心的女友一樣回不來了.... 05/13 20:14
tinlans: 永遠檢查 malloc 的傳回值不是更好? XD 05/17 02:40
wtchen: 我還真的很想在十三誡加這條 05/19 07:00