[問題] UVA 10189

看板C_and_CPP (C/C++)作者 (我想考試)時間9年前 (2015/04/06 21:06), 9年前編輯推噓7(7092)
留言99則, 9人參與, 最新討論串1/1
開發平台(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

04/06 21:40, , 1F
這寫法錯得離譜
04/06 21:40, 1F

04/06 21:41, , 2F
我貼到我之前打錯的版本= = 請問一要怎樣修改文章?
04/06 21:41, 2F
※ 編輯: ssadd502227 (36.233.66.79), 04/06/2015 21:48:04

04/06 21:45, , 3F
在文章列表 自己的文章前大寫 E
04/06 21:45, 3F

04/06 21:48, , 4F
改好了感恩
04/06 21:48, 4F

04/06 21:55, , 5F
你把它取代一下不就知道了... 不過這用了C++一個漏洞
04/06 21:55, 5F

04/06 21:55, , 6F
boolean是會被當成int 1的 這個應該很多編譯器都會
04/06 21:55, 6F

04/06 21:55, , 7F
給你警告吧(?)
04/06 21:55, 7F

04/06 21:56, , 8F
上面打錯 是boolean的true被當1 false被當0
04/06 21:56, 8F

04/06 22:11, , 9F
所以這算很爛的寫法?
04/06 22:11, 9F

04/06 22:19, , 10F
這是啥漏洞@@
04/06 22:19, 10F

04/06 22:20, , 11F
不是標準規定的轉型嗎?
04/06 22:20, 11F

04/06 22:25, , 12F
0可以表為false待無疑義,但是true可以表為1 2 3 4 5
04/06 22:25, 12F

04/06 22:25, , 13F
不過我用詞的確不好,與其說漏洞,還不如說陋習....
04/06 22:25, 13F

04/06 22:25, , 14F
跟const char* a = "12345abcde";一樣不太建議的寫法
04/06 22:25, 14F

04/06 23:21, , 15F
@@ 為什麼不太建議?
04/06 23:21, 15F

04/07 00:15, , 16F
不特別講我還真不知道 true + true 是啥…
04/07 00:15, 16F

04/07 02:13, , 17F
這性質的濫用法多的咧, 例如 #1FMBb9lE (Programming)
04/07 02:13, 17F

04/07 09:37, , 18F
因為true只代表不是零 只是這樣寫通常都是1
04/07 09:37, 18F

04/07 09:37, , 19F
但規定裡面並沒有提到true=1 所以並不是很安全
04/07 09:37, 19F

04/07 09:38, , 20F
把A(x,y) 改寫成function就很安全了
04/07 09:38, 20F

04/07 09:49, , 21F
true 跟 1 的關係有點複雜. C++ 裡 true 運算時就是 1
04/07 09:49, 21F

04/07 09:50, , 22F
詳情可參閱 #1J0fVosb
04/07 09:50, 22F

04/07 09:52, , 23F
而在 C99, true 就真的是整數 1
04/07 09:52, 23F

04/07 11:40, , 24F
@steve1012: 不對, C++ 裡的 bool 轉成 int 一定是 true
04/07 11:40, 24F

04/07 11:41, , 25F
轉成 1, false 轉成 0; 反過來是非零轉成 true, 零轉成
04/07 11:41, 25F

04/07 11:41, , 26F
false
04/07 11:41, 26F

04/07 12:45, , 27F
那這樣應該蠻安全的吧?
04/07 12:45, 27F

04/07 15:54, , 28F
算安全,Spec 4.7裡面有提到這件事
04/07 15:54, 28F

04/07 15:54, , 29F
但是很爛,你一連串int算式夾個boolean 只會迷惑人
04/07 15:54, 29F

04/07 15:55, , 30F
而且你沒辦法反過來推這個算式
04/07 15:55, 30F

04/07 15:55, , 31F
我可以換句話說,C- string也是安全的啊... XD
04/07 15:55, 31F

04/07 15:56, , 32F
但是const char *a = "12345abcde";真的不是很建議
04/07 15:56, 32F

04/07 15:58, , 33F
不過就跟x^=y^=x^=y一樣 總會有人用的... XD
04/07 15:58, 33F

04/07 15:59, , 34F
p.s. 上面那個算是也是spec safe
04/07 15:59, 34F

04/07 16:00, , 35F
x^=y^=x^=y 安全? 我錯過甚麼了?
04/07 16:00, 35F

04/07 16:01, , 36F
如果 C string 不能用. 那你在 C 裡面推薦怎麼作字串?
04/07 16:01, 36F

04/07 16:32, , 37F
x ^= y ^= x ^= y 是 undefined behavior.......
04/07 16:32, 37F

04/07 17:15, , 38F
我當然說是在C++裡面啦...
04/07 17:15, 38F
還有 21 則推文
04/07 21:43, , 60F
到底拿到的是什麼(你還需要知道長度或者「他是\0字」)
04/07 21:43, 60F

04/07 21:44, , 61F
不像拿到int*就知道「指向一個長度sizeof(int)的整數」
04/07 21:44, 61F

04/07 21:45, , 62F
更不用講很多人還拿char*去接,維護這種很頭大的
04/07 21:45, 62F

04/07 21:45, , 63F
當然也可以理直氣壯的說「看到const char*就該想到啊」
04/07 21:45, 63F

04/07 21:45, , 64F
這我就真的沒意見了,碰到就知道痛 :P
04/07 21:45, 64F

04/07 22:05, , 65F
這些寫C的就會碰到阿QQ 不過如果compiler的選項有開
04/07 22:05, 65F

04/07 22:06, , 66F
是會有warning 提醒的(char*的話) 不過pointer的話
04/07 22:06, 66F

04/07 22:08, , 67F
void* 是會更難理解吧0_0
04/07 22:08, 67F

04/07 22:17, , 68F
你沒有隱性轉型是不可能用 std::string 去接 string literal
04/07 22:17, 68F

04/07 22:17, , 69F
這不是慣例的問題. 是語言本身特性.
04/07 22:17, 69F

04/07 22:18, , 70F
你可以說 std::string 相對包裝得比較好. 但是跟 string
04/07 22:18, 70F

04/07 22:18, , 71F
literal 轉型的問題沒關係
04/07 22:18, 71F

04/07 22:34, , 72F
更不幸地是 C++11 的 std::string 後面還是有 '\0'
04/07 22:34, 72F

04/08 00:35, , 73F
std::string至少你不用思考「他到底是三小」
04/08 00:35, 73F

04/08 00:36, , 74F
他就只是個string,既不偉大也不卑微(誒)
04/08 00:36, 74F

04/08 00:36, , 75F
接到個const char*(更甚者, char*)你要煩惱的可多了...
04/08 00:36, 75F

04/08 00:37, , 76F
有看過function傳char* 有時是ascii有時是binary的嗎XD
04/08 00:37, 76F

04/08 00:37, , 77F
不過也因為如此 我專案都要求用vector<unsigned char>
04/08 00:37, 77F

04/08 00:37, , 78F
來當作binary的載體而非char*就是...有點矯枉過正哩...
04/08 00:37, 78F

04/08 00:38, , 79F
總覺得binary用char*其實就夠了 XD
04/08 00:38, 79F

04/08 00:38, , 80F
(以上都是實際碰過的心得分享而已)
04/08 00:38, 80F

04/08 00:46, , 81F
你後面這段話跟我要解釋的沒關係~ 所以我想可能誤解了甚麼
04/08 00:46, 81F

04/08 00:47, , 82F
我也認為在 "一般情況" 下, "C++" 裡用 std::string 會比較
04/08 00:47, 82F

04/08 00:48, , 83F
好, 但是 這跟 string literal 會隱性轉型沒關係
04/08 00:48, 83F

04/08 00:48, , 84F
std::string 無法解決 string literal 會隱性轉型的問題
04/08 00:48, 84F

04/08 01:07, , 85F
順帶一提, 用 vector<unsigned char> 作為字串運算可能不是
04/08 01:07, 85F

04/08 01:07, , 86F
個好主意..
04/08 01:07, 86F

04/08 01:08, , 87F
阿. 上面這句是我誤會XD 抱歉 Orz
04/08 01:08, 87F

04/08 09:30, , 88F
其實主要是在解釋為什麼const char*接字串不好
04/08 09:30, 88F

04/08 09:31, , 89F
主要就是因為意義不明(因為他意義在於兩個慣例之上)
04/08 09:31, 89F

04/08 09:32, , 90F
能work嘛?可。合理嗎?也許。這樣好嗎..?不太好
04/08 09:32, 90F

04/08 09:33, , 91F
string literal 在 C 用 const char * 之類的是 Spec 設計的
04/08 09:33, 91F

04/08 09:34, , 92F
我不確定用慣例這個名詞是否合理
04/08 09:34, 92F

04/08 09:34, , 93F
"他不合理的地方是隱式轉換" 是你說的. 我只是要解釋這點
04/08 09:34, 93F

04/08 09:34, , 94F
std::string a = "Hello world"; 不只隱性轉型還做了兩次
04/08 09:34, 94F

04/08 09:35, , 95F
C++ 沒有把 C 的 string literal 打掉重練反而後來有點妥協
04/08 09:35, 95F

04/08 09:41, , 96F
就好像我常常希望能跟別人說 : 忘了 const char * 吧
04/08 09:41, 96F

04/08 09:41, , 97F
但是 std::string 的建構式最常用的參數就是 const char *
04/08 09:41, 97F

04/08 13:20, , 98F
er...我通常寫std::string a("Hello World");椰 XD
04/08 13:20, 98F

04/08 13:20, , 99F
不過這純粹是習慣不同就是
04/08 13:20, 99F
文章代碼(AID): #1L8eJKSa (C_and_CPP)
文章代碼(AID): #1L8eJKSa (C_and_CPP)