C 将数组类型转换为指针?

C 将数组类型转换为指针?,c,arrays,pointers,C,Arrays,Pointers,是否可以键入一个数组 我有一组向量函数,它们都接受一个指向浮点的指针,浮点是由三个浮点组成的数组。我可以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);

是否可以键入一个数组

我有一组向量函数,它们都接受一个指向浮点的指针,浮点是由三个浮点组成的数组。我可以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

有人能解释一下为什么会这样吗?

指针和数组不是一回事。虽然它们的行为方式通常相同,但它们之间存在着重大差异,您刚刚发现了其中一个

你的代码实际上做了什么 为了使解释更清楚,我用实型替换了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;
如果执行此代码,会发生什么情况


现在您知道了编译器为什么禁止它了。

数组不是指针。数组有一个基指针。但无论如何,对于您要实现的目标,最适用的数据结构如下所示:

struct{
    float x;
    float y;
    float z;
} myFloat3;

数组对于可变长度的结构和东西来说很方便,但不是最有效的选择,因为你知道你有3个浮点数,你可以利用它。让编译器高效地打包你的很多结构,并从堆中分配你需要的东西。

你必须在代码中堆积许多不同的特性,所以这不是最有效的选择你所说的“为什么会这样”是什么意思?具体是什么意思

无论如何,为了“typedef一个数组”,你必须typedef一个数组,而不是指针

typedef float vec3_t[3];
之后你就可以

vec3_t a = { 1, 1, 1 };
代码的其余部分与数组的类型定义无关。您只是发现了复合文字语法,即
(非标量类型){initializers}
,并创建了给定类型的无名临时对象。
(非标量类型)
part是复合文字语法的重要组成部分,不能省略

因此,与其这样做

vec3_t a = { 1, 1, 1 };
f(a);
如果您不想拥有一个命名的数组对象
a
,您只需这样做即可

f((vec3_t) { 1, 1, 1 });


具有相同的效果。

注意
typedef float*vec3\u t
是指针,而不是数组。数组应该是
typedef float vec3\u t[3]
。数组不是指针。我认为它与浮点的字节长度有关。char*之所以有效,是因为一个字符是1个字节。但是1个浮点是…4个字节?不确定。我认为标题与您的实际问题没有太大关系。请重新表述。应该注意
(float[]){1,1,1}
是一个新的C99语法。他的问题似乎是他认为{1,1,1}是一个数组。
f((float [3]) { 1, 1, 1 });
f((float []) { 1, 1, 1 });