標籤:

C++ 用輸入的變數作為數組長度是壞習慣嗎?

今天寫了個根據用戶輸入進行冒泡排序的程序,想到用輸入的變數作為數組的長度。看到一些書上說數組長度應當是 「常量或常量表達式」,想知道這樣寫的兼容性如何?如果是 OI 評測會不會炸……

代碼確認在以下編譯器和操作系統上編譯通過:

  • Apple LLVM version 9.0.0 (clang-900.0.39.2) OS: macOS High Sierra 10.13.2
  • g++ (GCC) 4.7.2 (MinGW 32 Dev-C++ 5.4.2) OS: Windows 10 x86_64
  • g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 OS: NOI Linux 32-bit

代碼如下:

#include &
using std::cin;
using std::cout;
using std::endl;

int main() {
int N = 0;
cin &>&> N;
int a[N];
for (int i = 0; i &< N; i++) cin &>&> a[i];
int tmpVar = 0;
for (int i = 0; i &< N; i++) for (int j = N - 1; j &>= 0; j--) {
if (a[j - 1] &> a[j]) {
tmpVar = a[j];
a[j] = a[j - 1];
a[j - 1] = tmpVar;
}
}
for (int i = 0; i &< N; i++) { cout &<&< a[i] &<&< " "; } cout &<&< endl; return 0; }


首先,這不是 C++ 標準。

所以你要先問自己一個問題:我需要讓我的代碼符合標準嗎

並非所有代碼都需在所有編譯器下工作,如果你使用的編譯器實現了這個功能,那盡可以放心使用。如果你在做工程開發,那麼編寫符合標準的代碼更利於其他人閱讀、修改和使用你的代碼。

演算法競賽評測會提供編譯器版本,請先測試能否在評測用編譯器下正常工作。

其次,一個實踐中的問題:這樣定義的數組,它的空間在棧上(也就是 NiroBC 所提到的,但她沒有解釋這樣可能帶來的問題)。

舉個例子,Linux 系統的默認棧大小只有幾 MB,這表明你不能在這裡定義過大的數組。請先測試你的演算法能接受的最大數據範圍是否會導致運行是錯誤,如果是,你可能需要調整棧空間或者改用其它內存分配方式(static 並用常數大小,或 std::vector)。

演算法競賽評測中,一般會將棧空間限制設置為用內存限制的大小(請留意比賽的注意事項),這種情況下無需擔心棧溢出的問題。

其他回答中所說的一定會炸、不可能實現、不能用的都是錯的。實踐是檢驗真理的唯一標準。


VLA 不是 C++規範內容,C++ 里這樣幹事壞習慣。VLA一般的實現是分配在棧上的,如果數組大小可能很大,那就容易炸了。


聲明在函數體裡面的變數佔用的是棧空間哦。


按照標準是的,你這麼寫是得要填一個constexpr。

但是話說……

為什麼你不把它new(或者如果你堅持malloc……)到堆上……


我記得我在烏班圖下gcc和g++都不能編譯通過。。。


c艹里想用vla...


推薦這樣

std::vector& mukyu(len, initial_value);

沒有多花幾個字元,還可以一口氣初始化成同個東西。


變長數組屬於c99標準,號稱兼容c的c++不支持這個特性,這一腔悲憤向誰說。

g++有擴展支持這個特性,所以c++委員會就類似聯合國,有點地盤實力的都不鳥他。

類似冒泡排序這種通用演算法,肯定是不建議用變長數組,因為棧空間很容易溢出。適用的情況只有在實際工程中,有些地方知道大小範圍,肯定不會棧溢出,這時候才可以放心大膽地使用vla。唯一的作用也就是減小延遲。所以如果用在對性能不是很敏感的關鍵路徑上,實際意義不大。


有malloc你不用。。。


我曹輸入的變數都能當數組長度了!你這是怎麼做到的!當年我想做個變長數組只能new


C++是不支持VLA的…這是c99開始有的c語言的特性,能編譯過的話應該是編譯器自己的擴展。c++中像題目中那樣在棧上開數組,數組的大小應該是一個編譯期的就確定的值。

所以還是開一個全局大數組(不初始化的話,數組元素還都會都是0,有些時候還能帶來點方便…)。或者用array、vector,不過考慮到刷題可能會被拖慢速度…


如果你是做像codeforces網站這樣的注重構造的題目,你用vector、deque,甚至用java python都沒關係。如果你是在做演算法題,用全局大數組代替就可以了。

變長數組是C99的特性,GNU G++編譯器有提供C++對C99的兼容


推薦閱讀:

在oi/acm中,有什麼冷門但好用的stl函數?
如何向完全不懂編程的小夥伴解釋「程序寫死」?
為什麼 C++ 只比 VBA 快 4倍?
正在學c++但是越學越覺得自己還有好多東西不知道?
為什麼現代CFD和PIC模擬大量採用C++編寫?針對這些模擬C++相對於C的優勢在哪?

TAG:C | OI |