[問題] 使用全域變數的權衡

看板C_and_CPP作者 (好噁)時間12年前 (2013/03/25 08:39), 編輯推噓6(6028)
留言34則, 11人參與, 最新討論串1/1
問題(Question): 在寫acm題目的時候,常常遇到好像用全域變數會比較容易處理的情況? 以101 The block problem來說,我的寫法是用一個二維的vector來當作方塊, 一些動作則寫在function中。 我的問題是,如果不用全域變數,function的參數就都要加上這個vector。 但是大家又說盡量不要用全域變數,哪麼有什麼其它的寫法嗎? 謝謝 程式碼(Code):(請善用置底文網頁, 記得排版) #include <iostream> #include <string> #include <vector> #include <algorithm> #include <stack> using namespace std; void reset_desk(vector<vector<int> > &desk, int n) { desk.clear(); desk.resize(n); for (int i=0; i<n; i++) desk[i].push_back(i); } int find_block(const vector<vector<int> > &desk, const int block ) { for (int i = 0; i < desk.size(); ++i) { vector<int>::const_iterator it = find(desk[i].begin(), desk[i].end(), block); if (it != desk[i].end()) { return i; } } } void print_desk(const vector<vector<int> > &desk) { for (int i = 0; i < desk.size(); ++i) { cout << i << ":"; for (vector<int>::const_iterator it=desk[i].begin(); it != desk[i].end(); ++it) { cout <<" " << *it; } cout << endl; } } void clean_top(vector<vector<int> > &desk, const int block) { int temp; int pos = find_block(desk, block); while (desk[pos].back() != block) { temp = desk[pos].back(); desk[temp].push_back(temp); desk[pos].pop_back(); } } void move(vector<vector<int> > &desk, const int from_block, const int to_block) { stack<int> temp; int from = find_block(desk, from_block); while (desk[from].back() != from_block) { temp.push( desk[from].back() ); desk[from].pop_back(); } temp.push(desk[from].back()); desk[from].pop_back(); int to = find_block(desk, to_block); while( !temp.empty() ) { desk[to].push_back( temp.top() ); temp.pop(); } //print_desk(desk); //cout << endl; } void execute (vector<vector<int> > &desk, const string cmd1, const int a, const string cmd2, const int b) { //cout << cmd1 << " " << a << " " << cmd2 << " " << b << endl; if (cmd1 == "move") clean_top(desk, a); if (cmd2 == "onto") clean_top(desk, b); move (desk, a, b); } bool invalid_command(const vector<vector<int> > desk, const int a, const int b) { int pos_a, pos_b; pos_a = find_block( desk, a ); pos_b = find_block( desk, b ); return (a == b || pos_a == pos_b); } int main() { int n, a, b; int pos_a, pos_b; //position for a and b string cmd1, cmd2; vector< vector<int> > desk; //----------testing------------ freopen ("101.in", "r", stdin); freopen ("101.out", "w", stdout); while (cin >> n) { reset_desk(desk, n); while (1) { cin >> cmd1; if (cmd1 == "quit") break; cin >> a >> cmd2 >> b; if (invalid_command(desk, a, b)) continue; execute(desk, cmd1, a, cmd2, b); } print_desk(desk); } return 0; } 補充說明(Supplement): 我是用C++寫的~~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.32.170.48 ※ 編輯: howardxu 來自: 114.32.170.48 (03/25 08:42)

03/25 09:45, , 1F
放在 class 的 member ?
03/25 09:45, 1F

03/25 12:49, , 2F
將你的東西包成class,在裡面直接提供move之類的fun
03/25 12:49, 2F

03/25 12:50, , 3F
ction,這樣就能互相分享變數,而且又不需要全域
03/25 12:50, 3F

03/25 13:15, , 4F
一二樓的作法是對的
03/25 13:15, 4F

03/25 13:26, , 5F
那用static呢?
03/25 13:26, 5F

03/25 13:58, , 6F
全域比較好處理就用全域不會怎樣
03/25 13:58, 6F

03/25 13:59, , 7F
特別是這種單檔程式全域幾乎不會有什麼壞處
03/25 13:59, 7F

03/25 14:07, , 9F
不要聽人說不要用就不要用,弄清楚為何不要用
03/25 14:07, 9F

03/25 14:08, , 10F
還有什麼時候不要用
03/25 14:08, 10F

03/25 17:04, , 11F
也可以放在 unnamed namespace, 我個人幾乎是不用
03/25 17:04, 11F

03/25 17:09, , 12F
不是數仟上萬行的程式 用不用全域變數 其實無關緊要
03/25 17:09, 12F

03/25 17:09, , 13F
如果還是想避免的話 用namespace是一個可以考慮的做法
03/25 17:09, 13F

03/25 17:41, , 14F
瞭解了! 謝謝各位的回答!!!
03/25 17:41, 14F

03/25 18:27, , 15F
看你什麼事情要用static做 沒事誰會弄個static
03/25 18:27, 15F

03/25 18:28, , 16F
就像你平常不會一直戴著保險套是一樣的道理
03/25 18:28, 16F

03/25 23:30, , 17F
最好是比較好處理就用全域, 你寫 code 難道就只看好不
03/25 23:30, 17F

03/25 23:33, , 18F
好寫嗎? 像這種參數列中有交集就應該好好分析將處理的
03/25 23:33, 18F

03/25 23:34, , 19F
對象跟狀態封裝起來, non-static method在 signature
03/25 23:34, 19F

03/25 23:35, , 20F
直接就說明清楚操作對象為何, 用全域變數還要掃過函式
03/25 23:35, 20F

03/25 23:36, , 21F
body蒐集所有operation才能知道你幹了哪些髒事, 閱讀
03/25 23:36, 21F

03/25 23:36, , 22F
性差很多... C 語言就有 struct 在幹這種事偏偏有人拿
03/25 23:36, 22F

03/25 23:36, , 23F
來寫組語...
03/25 23:36, 23F

03/25 23:44, , 24F
因為ACM這種寫完就丟的東西沒有閱讀性等需求
03/25 23:44, 24F

03/25 23:45, , 25F
相對的大型軟體開發為了閱讀性全域就會變得"不好處理"
03/25 23:45, 25F

03/25 23:45, , 26F
也對啦, 因為樓上都不用偵錯的, submit 之後一段日子
03/25 23:45, 26F

03/25 23:46, , 27F
也不需要回來 turn 的
03/25 23:46, 27F

03/25 23:55, , 28F
處理不是打字而已,那些都是"處理"的一部分
03/25 23:55, 28F

03/26 00:27, , 29F
我現在接觸的firmware C code就是滿滿的global varible
03/26 00:27, 29F

03/26 00:28, , 30F
因為不少變數在polling function各地會用到 非得宣告成全域
03/26 00:28, 30F

03/26 00:29, , 31F
要是先人命名的詭異點再加上沒有註解 trace起來都想哭
03/26 00:29, 31F

03/26 00:31, , 32F
要不是editor有ctag, cscope這種便利的工具 不然會超沒效率
03/26 00:31, 32F

03/26 07:51, , 33F
ACM是看邏輯跟思維 不是看code寫的乾不乾淨啊 orz
03/26 07:51, 33F

03/26 19:42, , 34F
code寫乾淨是基本啊...好習慣從小地方做起
03/26 19:42, 34F
文章代碼(AID): #1HJvozq0 (C_and_CPP)