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

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


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

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

Выпуск № 852
от 18.09.2007, 23:35

Администратор:Калашников О.А.
В рассылке:Подписчиков: 491, Экспертов: 64
В номере:Вопросов: 6, Ответов: 14


Вопрос № 101839: Здравствуйте знатоки. Кто может помочь в таком вопросе: У меня есть два массива. Надо сделать третий из общих элементов этих двух массивов, а затем надо в другой массив собрать элементы первого массива, которые не включаются во второй . Заран...
Вопрос № 101887: Здраствуйте Уважаемые эксперты. Помогите мне решить следующую проблему. У меня есть файл 1.exe. К мне можно записать информацию в этот же файл о количестве запусков данной программы?...
Вопрос № 101893: Вопрос по использованию функции ScBinFromHexBounded. Имеется код : CString csnext("48656C6C6F2048657820262042696E"); for (x=0;x<csnext.GetLength();x=x+2) { BYTE bb=0; char buffer2[2]; buffer2[0...
Вопрос № 101926: Здравствуйте! Я программировал на Delphi около года и узнав что Widnows написан на Си решил изучить, если не си, то си++ и стал изучать (без книг!) и без книг (благо что с++ похож на дельфи) изучил основные конструкции (циклы, операторы выбора и ...
Вопрос № 101976: Здравствуйте глубокоуважаемые эксперты! Появилась следующая неясность. Имеется код: class MyClass{ int x,y; public: MyClass(int u=1,int v=1):x(u),y(v){...} inline MyClass operator+(const MyClass& ob) { r...
Вопрос № 101978: добрый вечер уважаемые эксперты. подскажите пожалуйста какие компиляторы для С++ можно использовать для КПК на Windows mobile 2005 СПАСИБО...

Вопрос № 101.839
Здравствуйте знатоки. Кто может помочь в таком вопросе:
У меня есть два массива. Надо сделать третий из общих элементов этих двух массивов, а затем надо в другой массив собрать элементы первого массива, которые не включаются во второй .
Заранее спасибо.
Отправлен: 13.09.2007, 00:38
Вопрос задала: Елена Стоилова (статус: Посетитель)
Всего ответов: 4
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Verena
Здравствуйте, Елена Стоилова!
Предлагаю такой вариант: для того, чтобы отметить повторяющиеся элементы заведём массив флажков размерности первого массива и поставим в нём значения true в тех элементах, что соответствуют по индексу элементам первого массива, повторяющимся во втором. Заодно подсчитаем их количество, чтобы знать, какой размерности создавать новый массив. Динамические массивы при желании можно заменить на обыкновенные, выделяя им памяти на N элементов - какая-то часть будет не занята. Выполняемую часть кода смотрите в приложении, define нужно поместить в разделе директив препроцессора (там же, где include), остальное - в теле функции main. Ввод и вывод не организован - оставляю это Вам.
Удачи!

Приложение:

---------
Эта история - не для истории, понимаешь?

Ответ отправила: Verena (статус: Студент)
Ответ отправлен: 13.09.2007, 01:15

Отвечает: Терсков Сергей
Здравствуйте, Елена Стоилова!
Вот вариант решения вашей задачи с использованием STL. Основа решения функция find(). Она ищет значение в заданном интервале и если находит, то возвращает итератор указывающий на данный элемент. Подробнее см. в приложении...

Приложение:

Ответ отправил: Терсков Сергей (статус: Студент)
Ответ отправлен: 13.09.2007, 07:23

Отвечает: Хватов Сергей
Здравствуйте, Елена Стоилова!

Это задача - на использование ассоциативных массивов. C/C++ их напрямую не поддерживают, но для C++ есть в stl абстрактный контейнер map который можно очень изящно использовать

Приложение:

Ответ отправил: Хватов Сергей (статус: Студент)
Ответ отправлен: 13.09.2007, 10:54

Отвечает: Rockie
Здравствуйте, Елена Стоилова!

У нас есть 2 массива a и b, размерностью N и M соответственно. Есть исходный массив c размерностью N+M. Для каждого элемента из массива N проверим, есть ли такой же в массиве b. Для этого используем флаг flag. Когда flag равен 1, в массиве b есть такой же элемент, когда flag==0, такого элемента в b нет.

На самом деле это далеко не лучший способ найти разность массивов, гораздо эффективнее изначально отсортировать массивы и затем сравнивать, но ведь ваша задача учебная. Код в приложении.

Приложение:

Ответ отправил: Rockie (статус: 3-ий класс)
Ответ отправлен: 13.09.2007, 11:10


Вопрос № 101.887
Здраствуйте Уважаемые эксперты.
Помогите мне решить следующую проблему.
У меня есть файл 1.exe. К мне можно записать информацию в этот же файл о количестве запусков данной программы?

Приложение:

Отправлен: 13.09.2007, 11:11
Вопрос задал: MARTALEX (статус: 4-ый класс)
Всего ответов: 2
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Sov
Здравствуйте, MARTALEX!
Можно записать данные в конец файла, в примере для хранения данных используется поле MinorImageVersion(ИМХО не очень нужное) структуры OPTIONAL_HEADER.
Проблема заключается в том что отредактировать файл, пока он выполняется, windows не дает
и приходится создавать копию программы, которая дожидается завершения работы исходной программы и редактирует файл.

Приложение:

Ответ отправил: Sov (статус: 7-ой класс)
Ответ отправлен: 13.09.2007, 19:21
Оценка за ответ: 5
Комментарий оценки:
Спасибо за помощь.

Отвечает: Shurka
Здравствуйте, MARTALEX!
Способы конечно есть. Во первых, можно просто дописать это количество в конец файла. Это не повредит программе. Во-вторых можно сделать так, что количество запусков будет одной из переменных программы файл1.exe (это уже далеко не просто). Ну и еще если записи должен делать сам файл1.exe, то Windows сделает все возможное чтобы помешать этому.
Ответ отправил: Shurka (статус: 3-ий класс)
Ответ отправлен: 14.09.2007, 06:50
Оценка за ответ: 4
Комментарий оценки:
Спасибо, но хотелось бы более поподробнее.


Вопрос № 101.893
Вопрос по использованию функции ScBinFromHexBounded.
Имеется код :
CString csnext("48656C6C6F2048657820262042696E");
for (x=0;x<csnext.GetLength();x=x+2)
{
BYTE bb=0;
char buffer2[2];

buffer2[0]=csnext[x];
buffer2[1]=csnext[x+1];
// memset(&buffer2[0],0,2);
ScBinFromHexBounded(&buffer2[0],&bb,static_cast<ULONG>(sizeof(bb)));
char cc=bb;
cout << cc;
}
cout << endl;

В момент вызова функции ScBinFromHexBounded выскакивает ошибка "Unhandlied exception in Mapi.exe (OLMAPI32.dll)".
Что здесь не так (или просто как правильно использовать эту функцию), подскажите.
(Использую VS-98)
Отправлен: 13.09.2007, 12:09
Вопрос задал: Vasvladal (статус: Посетитель)
Всего ответов: 2
Мини-форум вопроса >>> (сообщений: 3)

Отвечает: Sergey A. Wedensky
Здравствуйте, Vasvladal!

Судя по MSDN, в качестве первого аргумента функция ScBinFromHexBounded ожидает null-terminated строку. А Вы ей передаете адрес буфера, под который выделено всего 2 символа, ни один из них не 0, а что за ними - неизвестно. Функция ищет завершающий 0-символ, в процессе чего, естественно, лезет в невыделенную память.
Вариант:
...
char buffer2[3];
buffer2[2] = 0;
...
Ответ отправил: Sergey A. Wedensky (статус: Студент)
Ответ отправлен: 13.09.2007, 12:26

Отвечает: Aristos
Здравствуйте, Vasvladal!

У меня возникли те же проблемы. В документации по MAPI от 06/08/2004 сказано, что в будущих версиях библиотеки возможно будет отсутствовать поддержка ряда функций, в частности FBinFromHex и ScBinFromHexBounded. Видимо придется воспользоваться другими функциями или библиотекой.
У меня работает функция UlFromSzHex, преобразующая строковое шестнадцатиричное представление числа в ULONG. В приложении пример на основе вашего кода.

Приложение:

---------
нет ничего невозможного

Ответ отправил: Aristos (статус: 6-ой класс)
Ответ отправлен: 13.09.2007, 13:31


Вопрос № 101.926
Здравствуйте! Я программировал на Delphi около года и узнав что Widnows написан на Си решил изучить, если не си, то си++ и стал изучать (без книг!)
и без книг (благо что с++ похож на дельфи) изучил основные конструкции (циклы, операторы выбора и условия и пару простых программ написал) и теперь хочу изучить массивы, модульное программирование и работу с WinApi. Посоветуете книгу?
Отправлен: 13.09.2007, 14:17
Вопрос задал: Груздев Денис Андреевич (статус: Посетитель)
Всего ответов: 2
Мини-форум вопроса >>> (сообщений: 17)

Отвечает: Виктор Пырлик
Здравствуйте, Груздев Денис Андреевич!

Я бы рекомендовал по C/C++
Программирование на языке Си 2-е изд. В. В. Подбельский В. В.
Программирование на языке Си Подбельский В.В., Фомин С.С.
По WinAPI - пожалуй, "Системное программирование в среде Win32" Дж. Харт
ну и.. класика - Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows
Автор: Рихтер Дж.

А вот и ресурс с книгами…


---------
Если ничего не помогло - надо читать инструкцию
Ответ отправил: Виктор Пырлик (статус: Студент)
Ответ отправлен: 13.09.2007, 15:06
Оценка за ответ: 4

Отвечает: Терсков Сергей
Здравствуйте, Груздев Денис Андреевич!
Какой-то конкретный источник посоветовать сложно. Смотря что вы хотите изучать. Если С++, то лучше сначала изучить ООП (Гради Буч - Объектно ориентированное программирование), иначе вы будете думать, что С++ - это обычный структурный язык. А массивы, модульное программирование и работа с WinApi - это чистый С (не нужно путать его с С++). Разную литературу по С/С++ можно найти здесь:

http://forum.vingrad.ru/topic-33456.html

P.S. Не сравнивайте Delphi и C++ - это совершенно разные языки.
Ответ отправил: Терсков Сергей (статус: Студент)
Ответ отправлен: 14.09.2007, 03:37
Оценка за ответ: 4


Вопрос № 101.976
Здравствуйте глубокоуважаемые эксперты!

Появилась следующая неясность. Имеется код:

class MyClass{
int x,y;
public:
MyClass(int u=1,int v=1):x(u),y(v){...}
inline MyClass operator+(const MyClass& ob)
{
return MyClass(this->x+ob.x);
}
inline MyClass operator=(const MyClass& ob)
{
return MyClass(this->x=ob.x);
}
inline MyClass& operator++()
{
return MyClass(++((*this).x));
}
int show(){return x;}
~MyClass(){}
};
...............
int main(int argc, char* argv[])
{
int k=1;
MyClass tmp;
++tmp=tmp+tmp; (1)
++k=k+k; (2)
cout<<tmp.show()<<" "<<k<<" ";
}

Вопросы заключаются в следующем:

1)почему для стандартного типа операндов результат (в переменной k) будет равен 4, а для определённого мною классового типа (объект tmp) результат будет 2, если использовать указанную форму записи (для записи ...++tmp; tmp=tmp+tmp;... результат естественным образом будет как раз 4)?

2)Что необходимо сделать, чтобы, применяя формы записи (1) и (2), результаты были одинаковы?

Как всегда, заранее ОГРОМНОЕ СПАСИБО!
Отправлен: 13.09.2007, 21:38
Вопрос задал: VSP (статус: Посетитель)
Всего ответов: 3
Мини-форум вопроса >>> (сообщений: 4)

Отвечает: Mystic
Здравствуйте, VSP!
Дело в том, что для оператора ++ Вы возвращаете новый созданный объект, а в сумме участвует старый объект. Насчет возвращаемого значения в операторе ++: возвращайте ссылку на текущий объект, т.е. правильное определение выглядит так:
MyClass& operator++()
{
++x;
return *this;
}
Замечу, что если Вы определяете функцию в объявлении класса, идентификатор inline не обязателен. Еще скажу, что this->x писать не обязательно, можно просто x. Исправленный код в приложении.
В приведенном Вами коде tmp становится равным 2 не из-за суммы, а из-за оператора ++.

Приложение:

Ответ отправил: Mystic (статус: 6-ой класс)
Ответ отправлен: 13.09.2007, 22:04
Оценка за ответ: 4
Комментарий оценки:
Спасибо за столь скорый ответ. Однако, введя указанные изменения, результат остался прежним tmp=2, k=4. А хочется добиться результата tmp=4, k=4.

Отвечает: Ross
Здравствуйте, VSP!

Собсно вобщето и должно быть два... Потому что в таком выражении:
++tmp=tmp+tmp;
сначала вызывается оператор + (возвращаемый результат сохраняется во временной переменной (2))
потом оператор ++ (в tmp теперь 2)
потом оператор = (tmp присваевается опять же 2 ). все по правилам.

Другое дело, что встроенные типы ведут себя по-иному и вначале вычисляется значение слева от знака =. Причем результат скорее всего может меняться в зависимости от компилятора... :)
Вобщем лучше вообще не использовать такие конструкции, тем более, что они ухудшают читаемость кода.
---------
Доступно только то, что видимо (c) Б. Керниган
Ответ отправил: Ross (статус: Студент)
Ответ отправлен: 14.09.2007, 01:20
Оценка за ответ: 5
Комментарий оценки:
Спасибо!

Отвечает: Sergey A. Wedensky
Здравствуйте, VSP!

Когда Вы оперируете классами, компилятор создает временные объекты.
Сразу оговорюсь - речь идет о MSVS2005, см. P.S.

Рассмотрим ход выполнения Вашего кода:

MyClass tmp;
На этом этапе создается объект типа MyClass, вызывается конструктор по умолчанию, tmp = {x=1;....}.

++tmp=tmp+tmp;
Сначала компилятор вычисляет правую часть, т.е. вызывает оператор +, определенный Вами. В результате возвращается ВРЕМЕННЫЙ объект типа MyClass, равный = {x=2;...}. Вы ведь сами вызываете конструктор в теле оператора +, это должно было натолкнуть на мысль. На самом деле, даже если бы Вы определили оператор + так:
inline MyClass& operator++()
{
++x;
return *this;
},
это все равно не помогло бы, т.к. встретив конструкцию return *this компилятор сделает то же самое, что Вы сделали сами - создаст ВРЕМЕННЫЙ объект и вызовет его конструктор копирования (который Вы, кстати, не описали, но он есть! - сгенерирован компилятором, почленно копирует данные).

Затем компилятор вычисляет левую часть - вызывает Ваш оператор ++, в теле которого Вы увеличиваете на 1 x. tmp становится равным tmp = {x=2;...}.

Затем вызывается оператор =.. Он приравнивает член x объекта tmp члену x того самого ВРЕМЕННОГО объекта , который вернул оператор +. В результате:
tmp = ,
но = {x=2;...}, как мы уже выяснили.
Следовательно, tmp становится равным tmp = {x=2;...}.
Затем 2 раза вызывается деструктор, для созданных временных объектов ( и еще один, который создался при возврате из оператора ++).
Это все становится очевидным, если пройтись отладчиком, с заходом во все вызовы.

Для переменных интегральных типов компилятор ведет себя несколько иначе. Он не создает никаких временных объектов, работает над одной ячейкой памяти (т.е. четырьмя, конечно, если речь о типе int).
Если посмотреть на дизасемблированный код, сгенерированный MSVS2005:
mov eax,dword ptr [ebp-14h]
add eax,1
mov dword ptr [ebp-14h],eax
mov ecx,dword ptr [ebp-14h]
add ecx,dword ptr [ebp-14h]
mov dword ptr [ebp-14h],ecx
Т.е. он по каким-то причинам СНАЧАЛА вызывает оператор ++, после чего k становится равным 2, затем выполняет k=k+k, k становится равным 4.

P.S. Все это поведение вполне вероятно может зависить от конкретного компилятора и даже от его настроек. Ведь в стандарте языка полностью не регламентируется порядок вычислений в подобных случаях. Поэтому такие конструкции создавать и не рекомендуется - результат не очень предсказуем.

Ответ отправил: Sergey A. Wedensky (статус: Студент)
Ответ отправлен: 14.09.2007, 10:42
Оценка за ответ: 5
Комментарий оценки:
За такой ответ просто огромнейшее спасибо! Все разложено по полочкам и собрав воедино все детали поведения компилятора получено формализованное объяснение текущей проблемы. Теперь всё предельно ясно!!!


Вопрос № 101.978
добрый вечер уважаемые эксперты. подскажите пожалуйста какие компиляторы для С++ можно использовать для КПК на Windows mobile 2005
СПАСИБО
Отправлен: 13.09.2007, 21:46
Вопрос задал: Макс Коваленко Юрьевич (статус: 1-ый класс)
Всего ответов: 1
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Sergey A. Wedensky
Здравствуйте, Макс Коваленко Юрьевич!

MS Visual Studio!
В версии 2005 Professional полностью поддерживается компиляция для нескольких мобильных платформ как под .NET, так и для нативного кода. Насколько помню, в 2003 VS также была возможность создавать проекты для 'Smart Devices'.
Ответ отправил: Sergey A. Wedensky (статус: Студент)
Ответ отправлен: 14.09.2007, 10:45
Оценка за ответ: 5


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

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

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

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

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


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


© 2001-2007, Портал RusFAQ.ru, Россия, Москва.
Авторское право: ООО "Мастер-Эксперт Про"
Техподдержка портала, тел.: +7 (926) 535-23-31
Хостинг: "Московский хостер"
Поддержка: "Московский дизайнер"
Авторские права | Реклама на портале
Версия системы: 4.59 от 18.09.2007
Яндекс Rambler's Top100
RusFAQ.ru | MosHoster.ru | MosDesigner.ru | RusIRC.ru
Kalashnikoff.ru | RadioLeader.ru | RusFUCK.ru

В избранное