可以输入一个数组吗?
我有一组向量函数,它都接受指向浮点的指针,浮点数是一个由三个浮点数组成的数组。我可以使用typedef float * vec3_t,但是它不会让我通过简单地将它设置为括号中的数组来创建一个对象。
typedef float* vec3_t;
vec3_t a = {1,1,1}; // Does not work
vec3_t b = (float[]){1,1,1}; // Works
float c[] = {1,1,1}; // Works
void f(vec3_t x);
f({1,1,1}); // Error
f((float[]){1,1,1}; // OK
有人可以解释一下为什么会这样吗?
答案 0 :(得分:7)
指针和数组不是一回事。虽然它们通常以相同的方式表现,但存在重大差异,其中一个是您刚刚发现的。
我已将typedefed类型替换为真实类型,以使解释更清晰。
float c[] = {1,1,1};
您只是创建并初始化了一个数组
f({1,1,1});
上面的代码既不是左值也不是右值。 {val1,...,valn}
语法仅仅是初始化程序,不能在其他地方使用。
float* b = (float[]){1,1,1};
在这里,您创建并初始化了一个数组,然后将其存储在指针中。
f((float[]){1,1,1};
这种情况与上面的情况相同,但不是存储指针,而是将其作为参数传递给函数。
float* a = {1,1,1};
您正在尝试将三个变量写入尚未分配的内存位置。
通常,{valn,...,valn}
是初始化程序。此时你无需初始化。因此,此语法无效。您正试图将气体倒入尚未制造的罐中。
虽然我理解你想要实现的目标,但你似乎错误地理解了内存和指针的整个概念。想象一下这段代码(在某些肮脏的逻辑中)与您尝试做的相同:
float* a = NULL;
a[0] = 1;
a[1] = 1;
a[2] = 1;
如果您执行此代码会发生什么?
所以现在你知道为什么编译器会禁止它。
答案 1 :(得分:2)
你的代码中有许多不同的功能,所以“为什么这样工作”并不清楚你的意思。具体是什么“这个”?
无论如何,为了“typedef一个数组”,你必须输入一个数组,而不是指针
typedef float vec3_t[3];
之后你就可以了
vec3_t a = { 1, 1, 1 };
其余代码与typedefing数组无关。您只需发现复合文字语法,该语法为(non-scalar-type) { initializers }
并创建给定类型的无名临时对象。 (non-scalar-type)
部分是复合文字语法的重要组成部分。你不能省略它。
所以,而不是做
vec3_t a = { 1, 1, 1 };
f(a);
如果您不关心命名数组对象a
,则只需执行
f((vec3_t) { 1, 1, 1 });
或
f((float [3]) { 1, 1, 1 });
或
f((float []) { 1, 1, 1 });
具有相同的效果。
答案 2 :(得分:1)
数组不是指针。数组具有基指针。但无论如何,您尝试实现的最适用的数据结构将是:
struct{
float x;
float y;
float z;
} myFloat3;
阵列对于可变长度结构和东西很方便,但不是最有效的选择,因为你知道你有3个浮点数,你可以利用它。让编译器有效地打包你的大量结构,并从堆中分配你需要的东西。