嘿傢伙!當我嘗試在頭文件中執行以下操作時將靜態const char []設置爲預定義的靜態const char []失敗
static const char FOOT[] = "Foot";
static const char FEET[] = FOOT;
我收到編譯器錯誤error: initializer fails to determine size of FEET
。我想知道這是什麼原因,以及是否有辦法糾正它。謝謝!
嘿傢伙!當我嘗試在頭文件中執行以下操作時將靜態const char []設置爲預定義的靜態const char []失敗
static const char FOOT[] = "Foot";
static const char FEET[] = FOOT;
我收到編譯器錯誤error: initializer fails to determine size of FEET
。我想知道這是什麼原因,以及是否有辦法糾正它。謝謝!
即使你爲什麼得到這個錯誤已經回答了,還有更多的故事。如果你真的需要換腳是一個數組,那麼你可以把它的引用,而不是指針:(該inside-out rule的更多示例)
char const foot[] = "foot";
char const (&feet)[sizeof foot] = foot;
// reference to array (length 5) of constant char
// (read the declarations "from the inside-out")
char const* const smelly_feet = foot;
// constant pointer to const char
int main() {
cout << sizeof feet << ' ' << feet << '\n';
cout << sizeof smelly_feet << ' ' << smelly_feet << '\n';
cout << sizeof(void*) << " - compare to the above size\n";
return 0;
}
其次,static
在文件和命名空間範圍意味着內部聯繫;所以當你在標題中使用它時,你會在每個使用該標題的TU中獲得重複的對象。有些時候你想要這樣做,但是在你的代碼中沒有看到它的原因,這是一個常見的錯誤。
關於陣列尺寸:的sizeof
操作者返回一個類型的對象或實例的內存大小。對於數組來說,這意味着所有項目的總內存大小。由於C++保證sizeof(char)
爲1,因此char數組的內存大小與其長度相同。對於其他數組類型,你可以通過一個項目的內存大小劃分得到一個數組的長度:
void f() {
int array[5];
assert((sizeof array/sizeof *array) == 5);
}
而且你可以把它推廣到函數模板:
template<class T, int N>
int len(T (&)[N]) {
return N;
}
// use std::size_t instead of int if you prefer
這存在提升爲boost::size。
您可能會看到使用sizeof array/sizeof *array
的代碼,無論是通過宏還是直接使用,或者是因爲它過時或不想使事情複雜化。
原因是你說FEET []是一個字符數組,但是你將它初始化爲一個ptr; 要糾正,你可以改變從腳腳[]爲* FEET 也可以做同樣的FOOT
感謝您的解釋 – spbots 2009-11-18 20:52:18
一種方式是這個
static const char FOOT[] = "Foot";
static const char *FEET = FOOT;
有在C數組沒有「=」操作符++ ,你需要使用strcpy或類似的東西(你不能用靜態常量來做)。根據您的要求下面可能是有用的:
#define contentsOfFoot "FOOT"
static const char FOOT[5] = contentsOfFoot;
static const char FEET[5] = contentsOfFoot;
static const char *feeet = FOOT;
原代碼不使用'='運算符。原始代碼執行初始化。 '='在初始化時不是'='運算符。 – AnT 2009-11-18 21:42:41
不推薦使用static,而且命名空間範圍內的const變量實際上是靜態的。另外,請爲預處理器標識符保留ALL_CAPS。
更大的問題是你爲什麼要使用原始數組。你很可能需要更多的東西是這樣的:
std::string const foot = "foot";
std::string const feet = foot;
或者,更有可能:
#include <string>
namespace spbots {
typedef std::string string_t;
string_t const foot = "foot";
string_t const feet = foot;
}
我想強調的是,你不應該把這些東西在頭文件。變量只能放在頭文件中,如果你想使它們全局可見(通常不是一個好主意,但它是一種合法的技術)。
feet.h
extern char feet[];
feet.cpp
char feet[] = "FEET";
現在,當您在一個不同 .cpp文件feet.h,說leg.cpp,在feet.h的聲明意味着leg.cpp可以看到和使用feet.cpp
定義的陣列extern關鍵字與您使用的static關鍵字具有相反的含義。靜態的典型用法如下;
feet.cpp
static char feet[] = "FEET";
現在腳[]在feet.cpp之外明顯不可見。 static關鍵字負責這種缺乏可見性。所以靜態=本地,外部=全球和(可能不幸?)外部是默認的,所以如果你不使用任何關鍵字,你會得到外部不管你喜歡還是不喜歡。
因爲static = local,所以沒有什麼可以與其他模塊通信,所以不需要在頭文件中聲明其他模塊的聲明。一切都保存在feet.cpp中,可能比全局變量更好。
另一點我隱含地試圖解決這個問題,就是聲明進入頭文件,定義進入.cpp文件。在你的問題中你有一個頭文件的定義。不是非法的,但是如果你將它包含在多個文件中(如果你不這樣做,爲什麼要把它放在一個頭文件中?),你會得到多次定義的單個變量,這會給你一個鏈接錯誤。
所有這些實際上都是古老的C而不是現代意義上的C++。換句話說,你真的在寫C,但由於C(幾乎)是C++的一個子集,你仍然可以使用C++來完成這些工作。
+1,因爲它最接近聲明的要求,並且因爲引用/數組指針是鮮爲人知和理解的,它需要修復:)但是,我還使用'sizeof'而不是使用硬編碼大小來聲明'腳'。 – 2009-11-18 22:14:33
好的建議,修正。 – 2009-11-18 22:21:58
這是一個很好的答案,感謝所有的信息;每天都必須學習新的東西! – spbots 2009-11-19 15:51:15