2013-01-21 3 views
1

У меня есть массив из 64 бит целых без знака. Можно ли назначить некоторые указатели массива в некоторых его положениях. Я имею в виду:Array с значениями и указателями

array [0] = Integer 
array [1] = Integer 
array [2] = Pointer to array 
array [3] = Pointer to array 
array [4] = Integer 

Может ли кто-нибудь помочь мне, как это сделать?

+0

Это очень уродливая практика (в C++ не в C) для интерпретации указателей как чисел (и наоборот). Это вообще, но, согласно вашему примеру, это уродливое^2, потому что - как бы вы переосмыслили их назад к указателям? Возможно, лучший способ - пересмотреть архитектуру. – borisbn

ответ

4

Один из способов превратить array в массив

union { 
    uint64_t intval; 
    uintptr_t ptrval; 
}; 

и работать с этим.

Вам, конечно, потребуется какой-то способ узнать, сохраняет ли конкретный элемент целое число или указатель.

3

Вы можете использовать reinterpret_cast:

array[3] = reinterpret_cast<std::uintptr_t>(pointer); 

(uintptr_t от <cstdint>)

Try, чтобы избежать этого, если это возможно, хотя. Можете ли вы переосмыслить свой дизайн?

+0

Спасибо, но будет «array [3] = reinterpret_cast (указатель);" он создает указатель на массив указанного типа и длины и как получить доступ к этому? Можете ли вы дать простой код, чтобы проиллюстрировать выше факт? – user1838343

+2

@ user1838343 вы теряете всю информацию о типе, когда вы это делаете, поэтому вы не можете получить ее длину. Вам просто нужно «reinterpret_cast» вернуть его в указатель ... Что вы пытаетесь сделать с этим? – Pubby

+0

Я хочу поместить целые числа в массивы. Если позиции имеют множество значений (массив значений), я хочу создать массив указателей и сохранить в нем значения. Тогда я должен получить доступ к этим значениям соответственно. – user1838343

-1

Да, мы можем сделать это,

а [3] = (неподписанных долго долго) и а; (В окнах)

и вернуть значение указателя, (без знака долго долго *) а [3]

+0

Почему вы указали «в окнах»? Этот код не будет работать в Linux или MacOS? – borisbn

1

Позвольте мне угадать: вы хотите иметь массив, каждый элемент которого может быть либо число или другой массив чисел? Если это так, сделайте массив из std::vector s и сохраните только одно значение, если вы хотите сохранить номер. Как это:

typedef std::vector< long long > I64Vector; 
std::vector<I64Vector> array; 
array.push_back(I64Vector({ 42 })); // store one integer (42) in array[ 0 ] 
array.push_back(I64Vector({ 1, 2, 3, 4, 5 })); // store 5 integers in array[ 1 ] 
//... etc. 
// accessing them 
long long num = array[ 0 ][ 0 ]; // 42 
const I64Vector & subarray = array[ 1 ]; 
long subNumber1 = subarray[ 0 ]; // 1 
long subNumber2 = subarray[ 1 ]; // 2 
//... etc. 
1

Вы должны изменить тип вашего array элемент к чему-то, что может хранить целые и указатели (или предпочтительно std::vector<std::uint64_t>). Подход типа безопасен в использовании boost::variant:

std::vector<boost::variant<std::uint64_t, std::vector<std::uint64_t>>> array; 
array.push_back(1); 
array.push_back(2); 
array.push_back(std::vector<std::uint64_t>{4,5,6}); 

if (int* x = boost::get<std::uint64_t>(array[0])) { ... } 
if (std::vector<std::uint64_t>* x 
     = boost::get<std::vector<std::uint64_t>>(array[2])) { ... } 

Если вы хотите использовать встроенные массивы вместо векторов можно использовать союзы вместо boost::variant:

struct IntOrArray 
{ 
    bool isInt; 
    union { 
    std::uint64_t int_value; 
    std::uint64_t* array_value; 
    } 
}; 

std::vector<IntOrArray> array; 
IntOrArray a1; 
IntOrArray a1.isInt = true; 
IntOrArray a1.int_value = 1; 
array.push_back(a1); 

IntOrArray a2; 
IntOrArray a2.isInt = false; 
IntOrArray a2.array_value = arrayYouGotElsewhere; 
array.push_back(a2); 

if (array[0].isInt) { ... } 

C++ 11 позволяет поместите std::vector в союзы, но это не поддерживается всеми компиляторами.

Смежные вопросы