看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) 踩地雷簡單題,因為懶得用二維陣列去做就去網路上找用map寫法的 看到有一個是寫成以下這樣 #include<iostream> #include<map> using namespace std; int n1,n2,h=1; int main(){ while(cin>>n1>>n2&&n1!=0&&n2!=0) { if(h>1){cout<<endl;} map<int,map<int,char> >a; for(int i=0;i<n1;i++) { for(int ii=0;ii<n2;ii++) { cin>>a[i][ii]; } } cout<<"Field #"<<h<<":"<<endl; for(int i=0;i<n1;i++,cout<<endl) { for(int ii=0;ii<n2;ii++) { if(a[i][ii]=='*'){cout<<"*"; continue;} #define A(R,C) (a[R][C]=='*') int ans=A(i-1,ii-1)+A(i-1,ii)+A(i-1,ii+1) +A(i,ii-1)+A(i,ii)+A(i,ii+1) +A(i+1,ii-1)+A(i+1,ii)+A(i+1,ii+1); cout<<ans; } } h++; } } 想請問 #define A(R,C) (a[R][C]=='*') int ans=A(i-1,ii-1)+A(i-1,ii)+A(i-1,ii+1) +A(i,ii-1)+A(i,ii)+A(i,ii+1) +A(i+1,ii-1)+A(i+1,ii)+A(i+1,ii+1); 這一整段是啥意思? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.233.66.79 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1428325588.A.724.html
LPH66: 這寫法錯得離譜 04/06 21:40
ssadd502227: 我貼到我之前打錯的版本= = 請問一要怎樣修改文章? 04/06 21:41
※ 編輯: ssadd502227 (36.233.66.79), 04/06/2015 21:48:04
suhorng: 在文章列表 自己的文章前大寫 E 04/06 21:45
ssadd502227: 改好了感恩 04/06 21:48
Killercat: 你把它取代一下不就知道了... 不過這用了C++一個漏洞 04/06 21:55
Killercat: boolean是會被當成int 1的 這個應該很多編譯器都會 04/06 21:55
Killercat: 給你警告吧(?) 04/06 21:55
Killercat: 上面打錯 是boolean的true被當1 false被當0 04/06 21:56
ssadd502227: 所以這算很爛的寫法? 04/06 22:11
suhorng: 這是啥漏洞@@ 04/06 22:19
suhorng: 不是標準規定的轉型嗎? 04/06 22:20
Killercat: 0可以表為false待無疑義,但是true可以表為1 2 3 4 5 04/06 22:25
Killercat: 不過我用詞的確不好,與其說漏洞,還不如說陋習.... 04/06 22:25
Killercat: 跟const char* a = "12345abcde";一樣不太建議的寫法 04/06 22:25
bibo9901: @@ 為什麼不太建議? 04/06 23:21
Frozenmouse: 不特別講我還真不知道 true + true 是啥… 04/07 00:15
LPH66: 這性質的濫用法多的咧, 例如 #1FMBb9lE (Programming) 04/07 02:13
steve1012: 因為true只代表不是零 只是這樣寫通常都是1 04/07 09:37
steve1012: 但規定裡面並沒有提到true=1 所以並不是很安全 04/07 09:37
steve1012: 把A(x,y) 改寫成function就很安全了 04/07 09:38
Feis: true 跟 1 的關係有點複雜. C++ 裡 true 運算時就是 1 04/07 09:49
Feis: 詳情可參閱 #1J0fVosb 04/07 09:50
Feis: 而在 C99, true 就真的是整數 1 04/07 09:52
suhorng: @steve1012: 不對, C++ 裡的 bool 轉成 int 一定是 true 04/07 11:40
suhorng: 轉成 1, false 轉成 0; 反過來是非零轉成 true, 零轉成 04/07 11:41
suhorng: false 04/07 11:41
steve1012: 那這樣應該蠻安全的吧? 04/07 12:45
Killercat: 算安全,Spec 4.7裡面有提到這件事 04/07 15:54
Killercat: 但是很爛,你一連串int算式夾個boolean 只會迷惑人 04/07 15:54
Killercat: 而且你沒辦法反過來推這個算式 04/07 15:55
Killercat: 我可以換句話說,C- string也是安全的啊... XD 04/07 15:55
Killercat: 但是const char *a = "12345abcde";真的不是很建議 04/07 15:56
Killercat: 不過就跟x^=y^=x^=y一樣 總會有人用的... XD 04/07 15:58
Killercat: p.s. 上面那個算是也是spec safe 04/07 15:59
Feis: x^=y^=x^=y 安全? 我錯過甚麼了? 04/07 16:00
Feis: 如果 C string 不能用. 那你在 C 裡面推薦怎麼作字串? 04/07 16:01
suhorng: x ^= y ^= x ^= y 是 undefined behavior....... 04/07 16:32
Killercat: 我當然說是在C++裡面啦... 04/07 17:15
Killercat: 誒 我一直以為是spec safe,看來我一直印象錯誤了 04/07 17:16
firejox: const char *的問題是什麼? 04/07 17:57
Killercat: 一個指標指向string literal是個慣例,但是不合理 04/07 18:38
Killercat: 他把string literal隱式轉型成const char*了 04/07 18:38
bibo9901: 可是 string literal 實實在在地存在 .rodata 裡啊 04/07 19:01
bibo9901: 既然如此用 const char * 去存一個 static const char[] 04/07 19:04
bibo9901: 哪裡不合理? 又不像 integer literal 很可能跟本不在記 04/07 19:06
bibo9901: 憶體裡面 04/07 19:07
Killercat: 他不合理的地方是隱式轉換 而非存取方式 04/07 20:57
Killercat: 拿一個const char*存一個string literal是非常合理的 04/07 20:57
Feis: 樓上這論點蠻有趣的. 請教一下怎麼不做任何隱性轉換用 04/07 21:11
Feis: string literal ? (當然我講的是當作字串在 "用") 04/07 21:11
Feis: 例如把 "Hello world" 印出來~ 04/07 21:11
Feis: 阿. 是改成顯性轉換? 04/07 21:13
Killercat: 這其實就是靠慣例去做的,版上討論也不只一次啦... 04/07 21:37
Killercat: 不然這個從語法上看起來lhs跟rhs根本是不同的東西 04/07 21:38
Killercat: 不是說這個不好,但是有std::string了,我個人會比較 04/07 21:39
Killercat: 建議就多用點std::string,少用點C- string吧 04/07 21:39
Killercat: const char*能被string literal賦值靠的是兩個慣例 04/07 21:41
Killercat: 一個是我剛前面提的隱式轉換,另外一個則是隱含的\0 04/07 21:42
Killercat: 前者其實是很迷惑的,因為你無法從const char*得知你 04/07 21:43
Killercat: 到底拿到的是什麼(你還需要知道長度或者「他是\0字」) 04/07 21:43
Killercat: 不像拿到int*就知道「指向一個長度sizeof(int)的整數」 04/07 21:44
Killercat: 更不用講很多人還拿char*去接,維護這種很頭大的 04/07 21:45
Killercat: 當然也可以理直氣壯的說「看到const char*就該想到啊」 04/07 21:45
Killercat: 這我就真的沒意見了,碰到就知道痛 :P 04/07 21:45
firejox: 這些寫C的就會碰到阿QQ 不過如果compiler的選項有開 04/07 22:05
firejox: 是會有warning 提醒的(char*的話) 不過pointer的話 04/07 22:06
firejox: void* 是會更難理解吧0_0 04/07 22:08
Feis: 你沒有隱性轉型是不可能用 std::string 去接 string literal 04/07 22:17
Feis: 這不是慣例的問題. 是語言本身特性. 04/07 22:17
Feis: 你可以說 std::string 相對包裝得比較好. 但是跟 string 04/07 22:18
Feis: literal 轉型的問題沒關係 04/07 22:18
Feis: 更不幸地是 C++11 的 std::string 後面還是有 '\0' 04/07 22:34
Killercat: std::string至少你不用思考「他到底是三小」 04/08 00:35
Killercat: 他就只是個string,既不偉大也不卑微(誒) 04/08 00:36
Killercat: 接到個const char*(更甚者, char*)你要煩惱的可多了... 04/08 00:36
Killercat: 有看過function傳char* 有時是ascii有時是binary的嗎XD 04/08 00:37
Killercat: 不過也因為如此 我專案都要求用vector<unsigned char> 04/08 00:37
Killercat: 來當作binary的載體而非char*就是...有點矯枉過正哩... 04/08 00:37
Killercat: 總覺得binary用char*其實就夠了 XD 04/08 00:38
Killercat: (以上都是實際碰過的心得分享而已) 04/08 00:38
Feis: 你後面這段話跟我要解釋的沒關係~ 所以我想可能誤解了甚麼 04/08 00:46
Feis: 我也認為在 "一般情況" 下, "C++" 裡用 std::string 會比較 04/08 00:47
Feis: 好, 但是 這跟 string literal 會隱性轉型沒關係 04/08 00:48
Feis: std::string 無法解決 string literal 會隱性轉型的問題 04/08 00:48
Feis: 順帶一提, 用 vector<unsigned char> 作為字串運算可能不是 04/08 01:07
Feis: 個好主意.. 04/08 01:07
Feis: 阿. 上面這句是我誤會XD 抱歉 Orz 04/08 01:08
Killercat: 其實主要是在解釋為什麼const char*接字串不好 04/08 09:30
Killercat: 主要就是因為意義不明(因為他意義在於兩個慣例之上) 04/08 09:31
Killercat: 能work嘛?可。合理嗎?也許。這樣好嗎..?不太好 04/08 09:32
Feis: string literal 在 C 用 const char * 之類的是 Spec 設計的 04/08 09:33
Feis: 我不確定用慣例這個名詞是否合理 04/08 09:34
Feis: "他不合理的地方是隱式轉換" 是你說的. 我只是要解釋這點 04/08 09:34
Feis: std::string a = "Hello world"; 不只隱性轉型還做了兩次 04/08 09:34
Feis: C++ 沒有把 C 的 string literal 打掉重練反而後來有點妥協 04/08 09:35
Feis: 就好像我常常希望能跟別人說 : 忘了 const char * 吧 04/08 09:41
Feis: 但是 std::string 的建構式最常用的參數就是 const char * 04/08 09:41
Killercat: er...我通常寫std::string a("Hello World");椰 XD 04/08 13:20
Killercat: 不過這純粹是習慣不同就是 04/08 13:20