Назначение многомерных массивов и несовместимых типов

Я пытался написать функцию, которая будет выводить значения от 0 до 1, которые, в свою очередь, будут использоваться для генерации шума Перлина. Всякий раз, когда я пытаюсь скомпилировать код, я получаю это: error: incompatible types when assigning to type ‘float[(sizetype)(width)][(sizetype)(height)]’ from type ‘float *’

Я пытался передать указатель многомерности на функцию, чтобы он мог быть заполнен значениями. Я читал, что вы должны сначала выделить память массива, прежде чем передавать его. Также я читал, что вы можете использовать двойной указатель в объявлении функции.

Я не знаю, что случилось, хотя. Кстати, я использую команду gcc -Wall file.c -o file для ее компиляции.

Изменить: извините за неясность. Я пытаюсь присвоить значения из двумерного массива «smoothNoise» трехмерному массиву «leNoise». Вот где всплывает проблема.

#include <math.h>
#include <stdio.h> 

/* This is a macro for determining the size of an array */
#define ARRAY_SIZE(x)  (sizeof(x) / sizeof(x[0]))

/* Now for some simple linear interpolation */
float Interpolate(float x0, float x1, float alpha)
{
   return x0 * (1 - alpha) + alpha * x1;
}

/*
 * Functions for generating Perlin Noise. */

void GeneratePerlinNoise(float **perlinNoise, int width, int height, int octave) {

  /* Initialize the array */
    float noise[width][height];

    int i,j;

    for (i = 0; i < width; i++)
   {
    for (j = 0; j < height; j++)
       {
        /* Return a random number between 0 and 1.
     * This code may not work.
         */
    noise[i][j] = random();
    }
 }

 float smoothNoise[width][height];

 int samplePeriod = 1 << octave; /* calculates 2 ^ k */
 float sampleFrequency = 1.0f / samplePeriod;

 for (i = 0; i < width; i++)
{
  /* calculate the horizontal sampling indices */
  int sample_i0 = (i / samplePeriod) * samplePeriod;
  int sample_i1 = (sample_i0 + samplePeriod) % width; /* wrap around */
  float horizontal_blend = (i - sample_i0) * sampleFrequency;

  for (j = 0; j < height; j++)
  {
     /* calculate the vertical sampling indices */
     int sample_j0 = (j / samplePeriod) * samplePeriod;
     int sample_j1 = (sample_j0 + samplePeriod) % height; /* wrap around */
     float vertical_blend = (j - sample_j0) * sampleFrequency;

     /* blend the top two corners */
     float top = Interpolate(noise[sample_i0][sample_j0],
        noise[sample_i1][sample_j0], horizontal_blend);

     /*blend the bottom two corners */
     float bottom = Interpolate(noise[sample_i0][sample_j1],
        noise[sample_i1][sample_j1], horizontal_blend);

     /* final blend */
     smoothNoise[i][j] = Interpolate(top, bottom, vertical_blend);
   }
}

float leNoise[octave][width][height];

float persistance = 0.5f;

for (i = 0; i < octave; i++)
{
   /* Big problem here: moving data from a two-dimensional array
* to a three-dimensional array */
    leNoise[i] = smoothNoise[i];
}

 float amplitude = 1.0f;
 float totalAmplitude = 0.0f;

 /*blend noise together */
 int octaveCount;
 for (octaveCount = octave - 1; octaveCount >= 0; octave--)
 {
    amplitude *= persistance;
    totalAmplitude += amplitude;

    for (i = 0; i < width; i++)
    {
       for (j = 0; j < height; j++)
       {
          perlinNoise[i][j] += leNoise[octave][i][j] * amplitude;
       }
    }
  }

  /*normalisation */
  for (i = 0; i < width; i++)
 {
   for (j = 0; j < height; j++)
    {
      perlinNoise[i][j] /= totalAmplitude;
    }
  }
}

  int main()
{
/* These are some variables which will be used in the 
 * Perlin Noise functions.  These may not work.
 */
   /* Make some space in the RAM for our big array. */
   float **leNoise = malloc( 500 * sizeof( float ) );
   int i;

   for (i=0; i < 500; i++) {
 leNoise[i] = malloc(500 * sizeof(float *) );
   }

   GeneratePerlinNoise(leNoise, 500, 500, 7); 

   return 0;
 }

person Ertain    schedule 08.05.2013    source источник
comment
Вы перепутали размеры при выделении leNoise, должно быть float ** leNoise = malloc(500 * sizeof (float*)); - или лучше 500 * sizeof *leNoise, а leNoise[i] = malloc(500 * sizeof (float)); - или лучше, leNoise[i] = malloc(500 * sizeof *leNoise[i]);.   -  person Daniel Fischer    schedule 09.05.2013
comment
Попробую вариант float ** leNoise = malloc(500 * sizeof (float*));.   -  person Ertain    schedule 09.05.2013


Ответы (3)


Это назначение является виновником, насколько я знаю.

for (i = 0; i < octave; i++)
{
   /* Big problem here: moving data from a two-dimensional array to a three-dimensional array */
   leNoise[i] = smoothNoise[i];
}

Потому что в C нет ничего, что называется копированием массива в массив. Вы должны вручную копировать отдельные элементы из источника в место назначения, тщательно перебирая массивы.

Ex, leNoise[x][y][z] = smoothNoise[i][j]
person VoidPointer    schedule 08.05.2013
comment
Спасибо за помощь, VoidPointer. Я пытаюсь скопировать все значения в smoothNoise в leNoise. Поскольку SmoothNoise представляет собой трехмерный массив, у меня возникли проблемы с копированием данных. Я посмотрю, сработает ли это. - person Ertain; 09.05.2013

сообщение об ошибке clang лучше:

error: array type 'float [width][height]' is not assignable

массивы не назначаются. Вы заявили

float leNoise[octave][width][height];

а затем попробуйте назначить двумерные массивы компонентов:

for (i = 0; i < octave; i++)
{
   /* Big problem here: moving data from a two-dimensional array
* to a three-dimensional array */
    leNoise[i] = smoothNoise[i];
}

Поскольку массивы нельзя назначать, вам придется копировать значения здесь одно за другим [напрямую или с помощью memcpy].

Но,

float smoothNoise[width][height];

smoothNoise - это массив width×height, а smoothNoise[i] - это float[height] (который затем преобразуется в указатель на его начальный элемент), поэтому у вас несоответствие размеров, я не знаю, что вы собираетесь здесь делать, поэтому я не могу предложить исправление.

person Daniel Fischer    schedule 08.05.2013

#include<stdlib.h>

Вы должны включить его, это удалит другое предупреждение. Что касается массива, я не знаю, возможна ли такая копия из 3D в 2D-массив, поэтому не могу помочь.

person Coffee_lover    schedule 08.05.2013