Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на C / C++


РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / C/C++

Выпуск № 530
от 21.09.2006, 17:35

Администратор:Калашников О.А.
В рассылке:Подписчиков: 387, Экспертов: 53
В номере:Вопросов: 2, Ответов: 5


Вопрос № 55588: Доброго времени суток. Имею небольшую проблему: нужно поменять местами значение двух указателей. Сишными средствами это не удаётся ( авторы кода постарались :-) ). Короче говоря пока вижу только один выход - создать ассемблерную вставку, что-то типа ...
Вопрос № 55603: Здравствуйте, у меня такой вопрос: Я обращаюсь к ком порту стандартным кодом через функции CreatFile и читаю из него ReadFile. По докуметации моя железочка должна выдать мне сообщение что в ней вшито такая-то версия ПО, она мне отвечает но вместо тек...

Вопрос № 55.588
Доброго времени суток. Имею небольшую проблему: нужно поменять местами значение двух указателей. Сишными средствами это не удаётся ( авторы кода постарались :-) ). Короче говоря пока вижу только один выход - создать ассемблерную вставку, что-то типа функции
void ChangeValuePtr( int nAdrPtrFirst, int nAdrPtrSecond ){
__asm{
...
}
}

которая принимает в качестве параметров адреса указателей (увы, это - единственное что можно с ними сделать) и переписывает-меняет местами значения в ячейках по переданным адресам.
Вопрос - какой ассемблерный код надо написать? Адрес я получаю как обычно :
int nAdrPtr = (int)&MyPtr;
Типы указателей - одинаковые, так что дальнейших проблем с ними быть не должно.
Отправлен: 16.09.2006, 02:09
Вопрос задал: Kometa (статус: Посетитель)
Всего ответов: 2
Мини-форум вопроса >>> (сообщений: 2)

Отвечает: ADSota
Здравствуйте, Kometa!

И на Си можно сделать то-же:

int tmp=(int)nAdrPtrFirst;
(int)nAdrPtrFirst=(int)nAdrPtrSecond;
(int)nAdrPtrSecond=(int)tmp;

Главное, чтобы указатели не были константными...
---------
Открыть глаза навстречу солнцу
Ответ отправил: ADSota (статус: Специалист)
Ответ отправлен: 16.09.2006, 10:23
Оценка за ответ: 5
Комментарий оценки:
Отлично! Только что делает этот код ?
Зачем такие операции с адресами ?В действительности - я всего-лишь поменяю местами значения nAdrPtrFirst и nAdrPtrSecond.
Может Вы хотели написать такое:
int *temp = ptr1;
ptr1 = ptr2;
ptr2 = temp;
???
Но я же упомянул в скобках, что единственная операция, которую позволяет сделать компилер - это взятие адреса. Ничего другого - не допускается!

Отвечает: C4tnt
Здравствуйте, Kometa!

Если у вас действительно два указателя, то менять их местами правильнее всего так:

MyObject* tmp;
MyObject* A;
MyObject* B;

tmp = A;
A = B;
B = tmp;
//ну вот и поменяли A и B

Если у вас используются не указатели, а сами объекты, проще всего дописать к ним
конструктор копирования.
Если этого сделать нельзя, попробуйте так (это видимо то, что вас интересует, только без ASM):

void* tmp;
MyObject A;
MyObject B;
DWORD Size = sizeof(A);

tmp = new unsigned char[Size];
memcpy(&tmp,&A,Size);
memcpy(&A,&B,Size);
memcpy(&B,&tmp,Size);
delete [] tmp;

//ну вот и поменяли A и B (или обрушили программу/систему)
Лучше пишите конструктор копирования.

Пример конструктора копирования:

class ComplexClass
{
public:
ComplexClass(); //Конструктор обыкновенный
ComplexClass(const &ComplexClass source); //Конструктор копирования
protected:
int a;
int b;
}
ComplexClass::ComplexClass()
{
a=0;
b=0;
}
ComplexClass::ComplexClass(const ComplexClass& source)
{
a=source.a;// Копируем значения из старого класса в новый
b=sourrce.b;
}

После того, как вы допишите этот конструктор, объекты можно будет возвращать
из вункций и передавать в них, приравнивать (с нормальным результатом) и много чего ещё. Если вдруг понадобится особый способ приравнивания ваших классов -
- добавьте ComplexClass& operator= (const ComplexClass& source)
---------
Теперь к нашим ответам осталось лишь найти вопросы
Ответ отправил: C4tnt (статус: 3-ий класс)
Ответ отправлен: 16.09.2006, 10:52


Вопрос № 55.603
Здравствуйте, у меня такой вопрос: Я обращаюсь к ком порту стандартным кодом через функции CreatFile и читаю из него ReadFile. По докуметации моя железочка должна выдать мне сообщение что в ней вшито такая-то версия ПО, она мне отвечает но вместо текста я вижу 8 цифр!! Данные получаемые с железа пишу в переменную типа char и вывожу их printf("%d",text); Подскажите мне пожаста в чём дело ... Может у кого-то была аналогичная проблема... Заранее спасибо.
Отправлен: 16.09.2006, 10:48
Вопрос задала: Koran (статус: Посетитель)
Всего ответов: 3
Мини-форум вопроса >>> (сообщений: 1)

Отвечает: C4tnt
Здравствуйте, Koran!

А разве printf("%d",...) выводит не цифры?
Скорее всего вам нужен %s (если железячка возвращает C-строку).

На всякий случай полный список констант для printf:

c int or wint_t

When used with printf functions, specifies a single-byte character; when used with wprintf functions, specifies a wide character.

C int or wint_t

When used with printf functions, specifies a wide character; when used with wprintf functions, specifies a single-byte character.

d int Signed decimal integer.

i int Signed decimal integer.

o int Unsigned octal integer.

u int Unsigned decimal integer.

x int Unsigned hexadecimal integer, using "abcdef."

X int Unsigned hexadecimal integer, using "ABCDEF."

e double

Signed value having the form [ – ]d.dddd e [sign]ddd where d is a single decimal
digit, dddd is one or more decimal digits, ddd is exactly three decimal digits, and sign is + or –.

E double

Identical to the e format except that E rather than e introduces the exponent.

f double

Signed value having the form [ – ]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision.

g double

Signed value printed in f or e format, whichever is more compact for the given value and precision. The e format is used only when the exponent of the value is less than –4 or greater than or equal to the precision argument. Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.

G double

Identical to the g format, except that E, rather than e, introduces the exponent (where appropriate).

n

Pointer to integer Number of characters successfully written so far to the stream or buffer; this value is stored in the integer whose address is given as the argument.

p

Pointer to void Prints the address of the argument in hexadecimal digits.

s String

When used with printf functions, specifies a single-byte–character string; when used with wprintf functions, specifies a wide-character string. Characters are printed up to the first null character or until the precision value is reached.

S String

When used with printf functions, specifies a wide-character string; when used with wprintf functions, specifies a single-byte–character string. Characters are printed up to the first null character or until the precision value is reached.


---------
Теперь к нашим ответам осталось лишь найти вопросы
Ответ отправил: C4tnt (статус: 3-ий класс)
Ответ отправлен: 16.09.2006, 11:28

Отвечает: Сухомлин Кирилл Владимирович
Здравствуйте, Koran!
А как вы вообще читаете? Если уж вы char передаете ф-ии printf и ставите ей %d, что означает число. Причем размера не 1 байт, а больше. А char занимает обычно 1 байт. По идее, на вас очень сильно должен ругаться компилятор. Ну хотя бы предупреждение выдавать. Можно, конечно, читать через char в цикле, но такой способ по-моему, неудобен и не быстр.
В общем, либо читаете сразу все в char* text и выводите с помощью printf("%s", text), либо по одному символу через char text и выводите с помощью printf("%c", text).

Приложение:

---------
Не узнаешь - не попробуешь.

Ответ отправил: Сухомлин Кирилл Владимирович (статус: Практикант)
Ответ отправлен: 16.09.2006, 15:00
Оценка за ответ: 5

Отвечает: AlexKlaip
Здравствуйте, Koran!

Попробуйте с Вашим кодом, но обратите внимание на то что цикл у Вас
бесконечный, надо организовать выход.
Например, если нет данных в приемном буфере, или считано нужное Вам количество байт, или исползовать тайм-ауты
(см. BOOL SetCommTimeouts( HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeout):

DWORD iSize;
char text;
while(true)
{
if( ReadFile(hCom,&text,1,&iSize,0) && iSize > 0 )
printf("%c",text);
}

Можно так попробовать:

char buf[128];
DWORD iSize;

while ( ReadFile(hCom, buf, 127, &iSize, NULL) && (iSize > 0) )
{
//добавим признак конца строки, на всякий случай ;)
text[iSize] = 0;
printf ("%s", text);
}
printf (" End of message. ");

До начала цикла в порт уже должны поступить данные,
а то сразу проскочит ничего не приняв.

Возмжно поздновато отвечаю, но только сегодня поучил вопрос.
Удачи.
Ответ отправил: AlexKlaip (статус: 2-ой класс)
Ответ отправлен: 19.09.2006, 10:26


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2006, Портал RusFAQ.ru, Россия, Москва.
Идея, дизайн, программирование: Калашников О.А.
Email: adm@rusfaq.ru, Тел.: +7 (926) 535-23-31
Авторские права | Реклама на портале
Версия системы: 4.36 от 06.09.2006
Яндекс Rambler's Top100

В избранное