2009-06-17 8 views

ответ

4

Это то, что вы могли бы использовать союз для:

union { 
    UINT64 ui64; 
    struct { 
     DWORD d0; 
     DWORD d1; 
    } y; 
} un; 

un.ui64 = 27; 
// Use un.y.d0 and un.y.d1 

пример (при Linix так с использованием различных типов):

#include <stdio.h> 
union { 
    long ui64; 
    struct { 
     int d0; 
     int d1; 
    } y; 
} un; 
int main (void) { 
    un.ui64 = 27; 
    printf ("%d %d\n", un.y.d0, un.y.d1); 
    return 0; 
} 

Это дает:

27 0 
+0

Или просто используйте встроенный союз ULARGE_INTEGER, см. Http://msdn.microsoft.com/en-us/library/aa383742(VS.85).aspx – eran

+0

Да, я знаю, что вопрос указан Win32, но я по-прежнему предпочитаю, чтобы мой код был переносимым (не зависящим от платформы). – paxdiablo

+0

Pax, ваш код также не переносится - заметьте, ширина int и long отличается между платформами и может даже быть одинаковой. –

0

Keep в виду, что 64-битные целые числа имеют ограничения на выравнивание, по крайней мере, до 32-битных целых чисел на всех платформах. Поэтому совершенно безопасно указывать указатель на 64-битное целое число как указатель на 32-разрядный.

ULONGLONG largeInt; 
printf("%u %u\n", ((DWORD *)&largeInt)[ 0 ], ((DWORD *)&largeInt)[ 1 ]); 

Очевидно, что решение Pax является намного чище, но это технически более эффективным, поскольку он не требует никакого копирования данных.

1

Думал, что я приведу пример использования LARGE_INTEGER Для платформы Windows. Если у меня есть переменная «значение», которое 64 бит, то я:

LARGE_INTEGER li; 
li.QuadPart = value; 
DWORD low = li.LowPart; 
DWORD high = li.HighPart; 

Да, это копии, но мне нравится читаемость него.