Индекс массива в C, это должно быть целое число?Может ли это быть плавающей точкой? - PullRequest
2 голосов
/ 02 февраля 2011

, как следует из названия ... Мне нужно использовать числа с плавающей запятой в качестве индексов массива, но компилятор GCC выдает сообщение об ошибке.

В основном у меня есть математическая функция, скажем F (x, t), где у функции есть переменные x и t. Проблема, с которой я столкнулся, заключается в том, что я пытаюсь увеличить x и t в типе float, чтобы я мог вычислить разные значения для функции с разными x и t. Естественно, у меня было бы два цикла:

for (x = x_min; x < x_max; x += dx) {
    for (t = t_min; t < t_min; t += dt) {
        f[x][t] = 10*x + 10*t; // Over simplified.. but you get the idea
    }
}

// And then perform some fourier transform
fft(f[x][t], 256, 1);

Так что да, вот почему мне было интересно, возможно ли получить плавающие точки в качестве индекса массива.

Ответы [ 6 ]

5 голосов
/ 02 февраля 2011

Если вы просто храните целые числа в переменных с плавающей запятой, приведение или иное преобразование значений в целочисленный тип должно работать очень хорошо.Например:

array[(int)x] = y;

Если вы действительно хотите индексировать массив с нецелыми индексами, вам придется спроектировать структуру данных более высокого уровня, и, вероятно, это не будет "массив "в смысле его эффективности по времени.

4 голосов
/ 02 февраля 2011

Да. Из стандарта C99 §6.5.2.1 (подписка на массив):

Одно из выражений должно иметь указатель типа '' на объект тип '', другое выражение должно иметь целочисленный тип, а результат имеет тип '' type ''.

Если вы хотите использовать число с плавающей точкой в ​​качестве индекса массива, вам нужно привести его к целому числу. Это часто плохая идея, потому что любые незначительные ошибки округления во время ваших вычислений могут легко привести к отключению индекса массива на 1 после усечения.

4 голосов
/ 02 февраля 2011

Да, это должно быть целое число, потому что вы по существу выполняете арифметику указателя, где &array[0] - указатель на начало массива (ну, технически это должно быть целым числом, потому чтоспецификация говорит, но это почему).

В этом контексте нет смысла перемещаться от базового указателя вверх к некоторой доле размера объекта.Вы в значительной степени гарантируете, что не будете указывать на начало элемента.

Посмотрите на это так:

int array[10] = { 0 };

// analagous to *(array + 5), where '5' is 
// offsetting the pointer by sizeof(int) * 5 bytes   
// If you were able to add 5.5 to the base address 
// the value assigned to 'i' below would be interpreted as
// the four bytes following *(array + 5.5), i.e., garbage data.
int i = array[5];  

Так как это кажется мне странным вопросом для началас, возможно, вы могли бы дать нам больше информации о том, что вы на самом деле пытаетесь достичь, а не о вашем предлагаемом решении?Возможно, в этом случае мы можем дать вам более полезные ответы.

2 голосов
/ 02 февраля 2011

Как вы обнаружили, индексы массивов должны быть целочисленными типами.Для достижения желаемого эффекта вы можете масштабировать и смещать целочисленный индекс с помощью дельты с плавающей запятой:

double x, t;
int x_i, t_i;

for (x_i = 0; x_i < NX; x_i ++) {
    x = x_min + x_i * dx;
    for (t_i = 0; t_i < NT, t_i++) {
        t = t_min + t_i * dt;
        f[x_i][t_i] = 10*x + 10*t;
    }
}
0 голосов
/ 02 февраля 2011

В зависимости от того, что вы действительно хотите сделать, вы можете иметь возможность использовать масштабированную смещенную версию вашего float в качестве "индекса":

#define arraySize 100
Entry array[arraySize];
float scaleFactor = 10;
float base = 0.1;
float value = 0.3;
// This truncation is where we have a many to one mapping.
index = (int)( (value - base) * scaleFactor);
if (index >=0 && index < arraySize)
    Entry* entry = array + index;
0 голосов
/ 02 февраля 2011

Индексы массива в C должны быть целыми

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...