Консультация № 161600
28.02.2009, 11:14
0.00 руб.
0 7 2
Здравствуйте эксперты, подскажите как можно сделать следующее:
пишу в codeblocks
записал в переменную типа INT число и хочу каждый его бит считать в переменную типа CHAR
Через указатели не смог сделать, если указатель сделать на тип INT то если к адресу добавлять единицу то к адресу добавиться 4 байта, пробовал присвоить адрес переменной типа INT в указатель на CHAR так ошибка получается, не дает компилятор.
Как можно сделать это? вообще как можно независимо от типа получиться адрес чего-либо как просто обычное число, и обычное число превратить в адрес и работать с этим адресом?

Обсуждение

давно
Академик
20764
1861
28.02.2009, 11:26
общий
Вас биты или байты интересуют.?
Распаковать по битам можно только с помощью сдвигов.
Преобразовывать из типа в тип - с помощью cast-преобразований:
unsigned addr = (unsigned)&var;
char *ptr = (char *)&var;
Неизвестный
28.02.2009, 11:28
общий
это ответ
Здравствуйте, Tribak!
В таких случаях необходимо выполнять операцию явного приведения:
Код:

#include <iostream>

using namespace std;

int main()
{
int number=0x12345678;
char *chArr=(char*)&number;
for(unsigned i=0;i<4;i++)
{
cout<<"offset="<<i<<" value="<<hex<<(int)chArr[i]<<endl;
}
system("PAUSE");
return 0;
}

Результат работы:
Код:

offset=0 value=78
offset=1 value=56
offset=2 value=34
offset=3 value=12
Неизвестный
28.02.2009, 11:37
общий
Вообще то указатель это и есть простое обычное число, с которым можно работать соответствующим образом. А то, что операции инкремента и декремента изменяют значение указателя на величину равную размеру объекта им адресуемого это как раз очень удобно.
Неизвестный
28.02.2009, 11:42
общий
это ответ
Здравствуйте, Tribak!
Вот еще как можно получить значения ВСЕХ битов какого-либо типа. Делается это с помощью объединений и полей.
Код снабжён комментариями, мало того, я его оттестил в Code::Blocks, наслаждайтесь.

Приложение:
#include <iostream>

using namespace std;

struct BYTES4
{
union //Объединение. Всё, что в нём, хранится в одной памяти, т.е. наша структура и переменная типа int
{
struct //Все поля имеют размер в 1 бит. Всего их 32, как и положено
{
unsigned _b00:1;unsigned _b01:1;unsigned _b02:1;unsigned _b03:1;unsigned _b04:1;unsigned _b05:1;unsigned _b06:1;unsigned _b07:1;
unsigned _b10:1;unsigned _b11:1;unsigned _b12:1;unsigned _b13:1;unsigned _b14:1;unsigned _b15:1;unsigned _b16:1;unsigned _b17:1;
unsigned _b20:1;unsigned _b21:1;unsigned _b22:1;unsigned _b23:1;unsigned _b24:1;unsigned _b25:1;unsigned _b26:1;unsigned _b27:1;
unsigned _b30:1;unsigned _b31:1;unsigned _b32:1;unsigned _b33:1;unsigned _b34:1;unsigned _b35:1;unsigned _b36:1;unsigned _b37:1;
};
int i; //Переменная
};
};

int main()
{
int i = -8; //Присваиваем любое число...
BYTES4 myBytes; //Объевляем нашу структуру...
myBytes.i = i; //Передаём структуре значение....
cout << (int) myBytes._b34 << endl; //Выводим значение последнего байта (4-ый бит), например..
cin>> i; //Ждём нажатия клавиши
return 0;
}
Неизвестный
28.02.2009, 11:59
общий
Если же речь идет именно о битах, то для таких операций лучше подходят битовые операции:
Код:

#include <iostream>
#include <exception>

using namespace std;

int BitValue(int value,int bit)
{
if(bit<0||bit>31)throw exception("BitValue:Argument "bit" out of range(0..31)");
else
{
unsigned int mask=1<<bit;
return value&mask?1:0;
}
}

int main()
{
int number=0x12345678;
cout.setf(ios::showbase);
cout<<"number="<<hex<<number<<endl;
cout.unsetf(ios::showbase);
for(unsigned i=0;i<32;i++)
{
cout<<"bit="<<dec<<i<<" value="<<BitValue(number,i)<<endl;
}
system("PAUSE");
return 0;
}

Результат:
Код:

number=0x12345678
bit=0 value=0
bit=1 value=0
bit=2 value=0
bit=3 value=1
bit=4 value=1
bit=5 value=1
bit=6 value=1
bit=7 value=0
bit=8 value=0
bit=9 value=1
bit=10 value=1
bit=11 value=0
bit=12 value=1
bit=13 value=0
bit=14 value=1
bit=15 value=0
bit=16 value=0
bit=17 value=0
bit=18 value=1
bit=19 value=0
bit=20 value=1
bit=21 value=1
bit=22 value=0
bit=23 value=0
bit=24 value=0
bit=25 value=1
bit=26 value=0
bit=27 value=0
bit=28 value=1
bit=29 value=0
bit=30 value=0
bit=31 value=0


Хоть мои примеры тестировались в VC++ суть остается неизменной для любого компилятора C/C++.
Неизвестный
28.02.2009, 22:11
общий
я так и не понял, можно кратко как то прописать по какому физическому адресу я хочу что то записать, присвоить адрес указателю на какой нить байт и записать в него, число число (адрес) вбить куда в памяти я хочу записать байт информации и все. И точно так же получить адрес какого-либа обьекта(1ый байт, или любой другой, чтобы физический найти его в памяти, и работать с этим адресом), чтобы это было чисто число, и работать с этим числом, а затем писать в этот адрес или читать оттуда?
Неизвестный
28.02.2009, 22:54
общий
Немного прокомментировал код. Возможно Вам надо почитать немного теории.
Код:

#include <iostream>

using namespace std;

int main()
{
// Целое число
int number=0x12345678;
// Получаем адрес number и приводим его к указателю на unsigned char
unsigned char *chArr=(unsigned char*)&number;
cout.setf(ios::showbase);
// Выводим number
cout<<"number="<<hex<<number<<endl;
// Выводим ардес сохраненный в chArr(фактически адрес number)
cout<<"Adress="<<hex<<(int)chArr<<endl;
// Пишем в chArr(фактически в number)
chArr[0]=0xff;
chArr[1]=0xaa;
chArr[2]=0x66;
chArr[3]=0x11;
// Выводим number после этого
cout<<"number="<<hex<<number<<endl;
system("PAUSE");
return 0;
}


Код:

number=0x12345678
Adress=0x2efb10
number=0x1166aaff

Ну а чем Вам этот адрес не число? В примерах есть и получение адреса и ответы на все остальные Ваши вопросы.
Но не забывайте, что писать в любой адрес(какой вам вздумается) в защищенном режиме Вы не сможете.
Форма ответа