【问题标题】:ANSI C: Assigning arrays and pointers to arraysANSI C:分配数组和指向数组的指针
【发布时间】:2010-09-25 23:51:45
【问题描述】:

以下是我正在尝试做的简化版本,因为我确定您不想涉足粒子系统的一整套结构和函数原型。

float const materials[24][4][4] = {{{...}}};
typedef struct EmitterStruct  { float *material[4][4]; } Emitter;
typedef struct ParticleStruct { float material[4][4]; } Particle;
Emitter *myEmitter;

Emitter * createEmitter(float *material[4][4])
{
    Emitter * newEmitter;
    newEmitter = (Emitter *)malloc(sizeof(Emitter));
    newEmitter->material = materal; /* Returns "incompatable types in assignment" */
    return newEmitter;              /* I also tried newEmitter->material = &material */
}

int main(char *argv, int argc)
{
    myEmitter = createEmitter(materials[0]);
}

本质上,正如评论所示,我得到了一个编译错误。我已经尝试了几种不同的方法,甚至在 Emitter 结构中使用“float material[4][4]”和 createEmitter 的签名。但是,稍后当我尝试将值复制到粒子中以进行修改时,使用:

for (i=0; i++; i<4)
{
    for (j=0; j++; j<4)
    {
        particle->material[i][j] = emitter->material[i][j];
    }
}

我在复制时得到另一个类型不匹配,即使 everything 被声明为类型 float[4][4]。本质上,我想从 4x4 数组的数组中得到一个 4x4 数组,在发射器结构中记下它,然后将其复制到粒子结构中。但我只想实际复制一次值。

【问题讨论】:

  • 我将标签从 ansi-c 更改为 c,因为这是 stackoverflow 中的通用名称。我希望你不介意。不喜欢就改回来:)

标签: c performance arrays pointers


【解决方案1】:

我正在回答您更新的问题(出现在您自己的答案中)。首先是您的代码:

float const materials[24][4][4] = {{{...}}};
typedef struct EmitterStruct  { float *material; } Emitter; /*Use just a plain pointer*/
typedef struct ParticleStruct { float material[4][4]; } Particle;
Emitter *myEmitter;

Emitter * createEmitter(float *material) /*Use a plain pointer here*/
{
    Emitter * newEmitter;
    newEmitter = (Emitter *)malloc(sizeof(Emitter));
    newEmitter->material = material; 
    return newEmitter;               
}

int main(char *argv, int argc)
{
    myEmitter = createEmitter(materials[0]);/*This decays into a pointer*/
}

不!那不是正确的方法。它衰减为指针 - 是的,但不是指向浮点数的指针!如果您传递材料[0],您将得到一个float const[4][4],它衰减为float const(*)[4](指向其第一个元素的指针),而该指针就是传递的内容。因此,您想将其更改为:

float const materials[24][4][4] = {{{...}}};
/*Use just a plain pointer to an array */
typedef struct EmitterStruct  { float const (*material)[4]; } Emitter; 
typedef struct ParticleStruct { float material[4][4]; } Particle;
Emitter *myEmitter;

/*Use a plain pointer here. Bet keep it float const, not only float!*/
Emitter * createEmitter(float const (*material)[4])
{
    Emitter * newEmitter;
    newEmitter = (Emitter *)malloc(sizeof(Emitter));
    newEmitter->material = material; 
    return newEmitter;               
}

int main(int argc, char ** argv) /* you swapped args here */
{
    myEmitter = createEmitter(materials[0]); /* This decays into a pointer */
}

在此处阅读:what is `int *userMask[3][4]` pointing to?。在此处阅读有关如何正确传递数组的信息:C++ strings: [] vs. *。我会推荐你​​一个好的 C 或 C++ 书友:)

【讨论】:

  • 当然,我还没有运行代码,但你确定它在传递给 createEmitter 函数时不会变成浮点指针吗?当然,它是糟糕的 C,但我也有预感它可能会起作用。
  • 它不会在我的一生中变成 float* :) 我的意思是你期望做什么材料 [1] ?您最终会跳过 sizeof(float[4]) 个字节的材料 [0][1]。如果它是一个 float*,做材料 [1],你只会跳过 sizeof(float) 个字节,因此最终会在维度之间的某个地方结束。外星时间!
  • 是的,指针的大小将关闭,但我在代码中看不到任何相关的地方。我可能是错的,因为我没有仔细观察。
  • 好吧。如果他不关心类型,他可以使用 void*。所有其他类型,如 float* 都不起作用。但我看不出有任何理由使用 void* 引入不安全性。只需使用正确的 :)
【解决方案2】:

关于第一个 sn-p,您会收到该错误,因为 C 中的数组不可分配。您必须执行memcpy 才能复制数组。

关于第二个 sn-p,您对以下行有疑问:

particle->material[i][j] = emitter->material[i][j];

Emitter 中的成员material 是一个float* 类型的二维数组。 Particle 中的成员 material 的类型为 float。请注意,一个是指针,一个不是,这就是它们不可分配的原因。

你可以这样写:

particle->material[i][j] = *(emitter->material[i][j]);

但这是假设您已将这些指针分配给 point 某物。或者,您可以将Emitter 中的material 更改为非指针。我无法确定你应该做什么,因为我很难根据你提供的代码来解读你的确切意图。

【讨论】:

  • 我知道我做错了什么。我承认,这相当令人困惑。但是,剪切和粘贴完整的代码将是 3 个文件的价值,甚至更令人困惑。不过,谢谢。
【解决方案3】:

当然,在我寻求帮助的那一刻,我就清楚自己需要做什么。

float const materials[24][4][4] = {{{...}}};
typedef struct EmitterStruct  { float *material; } Emitter; /*Use just a plain pointer*/
typedef struct ParticleStruct { float material[4][4]; } Particle;
Emitter *myEmitter;

Emitter * createEmitter(float *material) /*Use a plain pointer here*/
{
    Emitter * newEmitter;
    newEmitter = (Emitter *)malloc(sizeof(Emitter));
    newEmitter->material = material; 
    return newEmitter;               
}

int main(char *argv, int argc)
{
    myEmitter = createEmitter(materials[0]);/*This decays into a pointer*/
}

然后是副本:

for (i=0; i++; i<4)
{
    for (j=0; j++; j<4)
    {
        particle->material[i][j] = *(emitter->material[i * 4 + j];
    }
}

哎呀……

【讨论】:

    【解决方案4】:

    我曾经是这方面的专家。不幸的是,我已经离开它太久了。所以这是我大约 6 年前写的一个工作代码 sn-p。我认为它可能会为您指明正确的方向。

    // get a color histogram of an image
    int ***colorHistogram(PIXEL *inputImage, HEADER *imageHeader)
    {
        int x, y, z;
    
        // a color histogram
        int ***histo;
    
        // allocate space for the histogram
        histo = (int ***)malloc(256 * sizeof(int**));
        for(x=0; x<256; x++)
        {
            histo[x]=(int **)malloc(256 * sizeof(int*));
            for(y=0; y<256; y++)
            {
                histo[x][y]=(int *)malloc(256 * sizeof(int));
    
                // initialize the histogram
                for(z=0; z<256; z++)
                    histo[x][y][z] = 0;
            }
        }
    
        // fill the histogram
        for (x = 0; x < imageHeader->width * imageHeader->height; x++)
        {
            histo[((int) inputImage[x].r)][((int) inputImage[x].g)][((int) inputImage[x].b)]++;
        }
    
    return histo;
    

    }

    无论如何,我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 2017-08-25
      相关资源
      最近更新 更多