如果我有一個原型,看起來像這樣:如何將一個常量數組文字傳遞給一個不帶變量C/C++的指針的函數?
function(float,float,float,float)
我可以通過數值是這樣的:
function(1,2,3,4);
所以,如果我的原型是這樣的:
function(float*);
有什麼我可以實現這樣的事情嗎?
function({1,2,3,4});
只是尋找一種懶惰的方式來做到這一點,而不創建一個臨時變量,但我似乎無法指定語法。
如果我有一個原型,看起來像這樣:如何將一個常量數組文字傳遞給一個不帶變量C/C++的指針的函數?
function(float,float,float,float)
我可以通過數值是這樣的:
function(1,2,3,4);
所以,如果我的原型是這樣的:
function(float*);
有什麼我可以實現這樣的事情嗎?
function({1,2,3,4});
只是尋找一種懶惰的方式來做到這一點,而不創建一個臨時變量,但我似乎無法指定語法。
你可以做到這一點在C99(但不ANSI C(C90)或任何CURR C++的變體)與複合文字。有關血淋淋的詳細信息,請參閱C99標準的第6.5.2.5節。這裏有一個例子:
// f is a static array of at least 4 floats
void foo(float f[static 4])
{
...
}
int main(void)
{
foo((float[4]){1.0f, 2.0f, 3.0f, 4.0f}); // OK
foo((float[5]){1.0f, 2.0f, 3.0f, 4.0f, 5.0f}); // also OK, fifth element is ignored
foo((float[3]){1.0f, 2.0f, 3.0f}); // error, although the GCC doesn't complain
return 0;
}
GCC也提供這個作爲C90的擴展。如果編譯時使用-std=gnu90
(默認值),-std=c99
或-std=gnu99
,則會編譯;如果使用-std=c90
進行編譯,則不會。
顯然也可以用'-std = gnu89'(但不是'-std = c89')編譯,因爲它與'-std = gnu90'同義(和'-std = c90')(我相信你知道這個亞當,對於其他人來說更是如此,以防他們沒有:P)。 – RastaJedi 2016-08-27 04:35:25
不,你不能那樣做。我沒有可用的標準在這裏,所以我不能給出一個確切的參考,但最接近你問什麼是字符串常量,即
function(char *);
function("mystring");
是由編譯器視爲
char * some_pointer = "mystring";
function(char *);
function(some_pointer);
用這種方法處理其他類型的變量是沒有辦法的。
您可以創建文字的化合物:
function ((float[2]){2.0, 4.0});
雖然,我不知道你爲什麼要經歷的麻煩。 ISO不允許這樣做。
一般而言,應該避免使用像這樣的快捷方式,以利於所有情況下的可讀性;懶惰是不是探索一個好習慣(個人意見,當然)
我同意可讀性,實際上這個特定的函數會傳遞一個內存地址並且很高興。但是,在測試期間,我經常想插入一些隨機值。你的代碼片斷會訣竅,更好或更糟:)謝謝! – sinoth 2009-08-13 01:42:12
這是在c99中有效,但沒有別的標準明智... – 2009-08-13 02:42:04
可悲的是,它僅適用於字符數組:
void func2(char arg[]) {
}
int main()
{
func2("hello");
return 0;
}
這標誌着C和C++,所以你會得到根本不同的答案。
如果你期待四個參數,你可以這樣做:
void foo(float f[])
{
float f0 = f[0];
float f1 = f[1];
float f2 = f[2];
float f3 = f[3];
}
int main(void)
{
float f[] = {1, 2, 3, 4};
foo(f);
}
但是,這是相當不安全的,因爲你可以通過事故做到這一點:
void foo(float f[])
{
float f0 = f[0];
float f1 = f[1];
float f2 = f[2];
float f3 = f[3];
}
int main(void)
{
float f[] = {1, 2}; // uh-oh
foo(f);
}
通常最好離開他們作爲個人參數。既然你不應該使用原始數組,你可以這樣做:
#include <cassert>
#include <vector>
void foo(std::vector<float> f)
{
assert(f.size() == 4);
float f0 = f[0];
float f1 = f[1];
float f2 = f[2];
float f3 = f[3];
}
int main(void)
{
float f[] = {1, 2, 3, 4};
foo(std::vector<float>(f, f + 4)); // be explicit about size
// assert says you cannot do this:
foo(std::vector<float>(f, f + 2));
}
一個改進,但沒有太大的一個。你可以使用boost::array
,但不是不匹配的大小錯誤,它們被初始化爲0:
#include <boost/array.hpp>
void foo(boost::array<float, 4> f)
{
float f0 = f[0];
float f1 = f[1];
float f2 = f[2];
float f3 = f[3];
}
int main(void)
{
boost::array<float, 4> f = {1, 2, 3, 4};
foo(f);
boost::array<float, 4> f2 = {1, 2}; // same as = {1, 2, 0, 0}
foo(f2);
}
這都將是固定的C++ 0x中,當初始化列表構造函數中添加:
#include <cassert>
#include <vector>
void foo(std::vector<float> f)
{
assert(f.size() == 4);
float f0 = f[0];
float f1 = f[1];
float f2 = f[2];
float f3 = f[3];
}
int main(void)
{
foo({1, 2, 3, 4}); // yay, construct vector from this
// assert says you cannot do this:
foo({1, 2});
}
,可能boost::array
還有:
#include <boost/array.hpp>
void foo(boost::array<float, 4> f)
{
float f0 = f[0];
float f1 = f[1];
float f2 = f[2];
float f3 = f[3];
}
int main(void)
{
foo({1, 2, 3, 4});
foo({1, 2}); // same as = {1, 2, 0, 0} ..? I'm not sure,
// I don't know if they will do the check, if possible.
}
你可以寫一個生成器類,將允許大約相同的語法
// roughly
template <typename C>
class Builder {
public:
template <typename T>
Builder(const T & _data) { C.push_back(_data); }
template <typename T>
Builder& operator()(const T & _data) {
C.push_back(_data);
return *this;
}
operator const C &() const { return data; }
private:
C data;
};
這樣,你就可以使用類作爲
富(常量的std ::向量& V);
foo(Builder < std :: vector>(1)(2)(3)(4));
你可以在技術上引用數組,但你仍然不能創建我認爲的匿名初始化列表。
void func(int (&bla)[4])
{
int count = sizeof(bla)/sizeof(bla[0]);
// count == 4
}
int bla[] = {1, 2, 3, 4};
func(bla);
int bla1[] = {1, 2};
func(bla1); // <-- fails
對於C++方式,請看boost::assign。填充STL容器的方式非常簡潔。
要增加樂趣,您可以使用模板使其長度可變。
template<std::size_t N>
int chars(const char(&r)[N]){
std::cout << N << ": " << r << std::endl;
return 0;
}
template<std::size_t N>
int floats(const float(&r)[N]){
std::cout << N << ":";
for(size_t i = 0; i < N; i++)
std::cout << " " << r[i];
std::cout << std::endl;
return 0;
}
int main(int argc, char ** argv) {
chars("test");
floats({1.0f, 2.0f, 3.0f, 4.0f});
return 0;
}
感謝您的建議。我想我預計一個快速和骯髒的問題的快速和骯髒的答案,但你的迴應探討了一些我沒有想到的替代風格。非常感激! – sinoth 2009-08-13 01:54:10