Я конвертирую часть кода FORTRAN 77 в C ++
DIMENSION ARRAY(513),JRRAY(2,513)
EQUIVALENCE (ARRAY(1),JRRAY(1,1))
Это неявный код, где каждое имя переменной, начинающееся с I, J, K, L, M, N, O, P, неявно принимается как целочисленный тип. Таким образом, здесь мы имеем массив двойной точности с именем ARRAY и целочисленный массив с именем JRRAY.
Операторы эквивалентности указывают начало обоих массивов в одной и той же ячейке памяти. Однако почему-то байты по-разному интерпретируются как двойные, когда вызывается ARRAY (I), или как целые числа, когда вызывается JRRAY (I, J) (по крайней мере, я так думаю, что происходит).
Есть ли подобный способ в C ++, где одно и то же место в памяти можно интерпретировать как другой тип?
Или что-то, что делает то же самое, что и EQUIVALENCE в FORTRAN, но затем в C ++.
Аналогичная особенность union
:
union {
double array[513];
int jrray[513][2];
} equiv;
Вы можете получить доступ equiv.array[i]
или же equiv.jrray[i][j]
,
Однако обратите внимание, что доступ к члену объединения, отличному от того, который вы в последний раз написали, приводит к неопределенному поведению в C ++. Увидеть Союзы и типовые удары. Если вы хотите переинтерпретировать данные как другой тип данных, вы должны использовать reinterpret_cast<>
не типа врезать
C union
часто используется для этой цели, как в Бармаре ответ. Тем не менее, вы можете использовать приведение типов для ссылки на массив с плавающей запятой в виде целочисленного массива.
Рассмотрим следующую декларацию array
и определение jrray
:
double array[513];
int (*jrray)[2] = reinterpret_cast<int (*)[2]>(array);
Мы можем проверить, что это объявление работает, как ожидалось, например, посмотрев на экспоненту. У нас будет показатель степени array[k]
в битах 20-30 jrray[k][1]
,
Например, проверьте, что если теперь мы инициализируем элементы массива как
array[0] = 1.23*2; // exponent is 1
array[1] = 1.23*4; // exponent is 2
array[2] = 1.23*8; // exponent is 3
Мы будем иметь
((jrray[0][1] >> 20) & 0x7FF) - 1023 == 1
((jrray[1][1] >> 20) & 0x7FF) - 1023 == 2
((jrray[2][1] >> 20) & 0x7FF) - 1023 == 3
В любом случае это нарушает строгое правило псевдонимов C ++ и может привести к неопределенному поведению.