Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по программированию на C/С++

Автор: panik1987
Дата сообщения: 17.07.2007 11:14
Помогите пожалуйста решить 3 задачи:
1.. Ввести “m”, “n” ( n<=200) и строку из “n” символов (строка оканчивается либо '.', либо ':', либо ';'). В строке среди знаков могут встречаться открывающиеся и закрывающиеся круглые, квадратные и фигурные скобки. Проверить, предшествует ли каждая открывающаяся скобка соответствующей закрывающейся, т. е. правильность расстановки скобок во всех “m” строках.
2.Имеется кольцо, а в нём – указатели на функции, которые при выборе данного элемента кольца могут быть выполнены. Предусмотреть возможность наращивания кольца. Двигаясь по кольцу, при нажатии любой клавиши нужно показать функции, которые могут быть выполнены.
3.4.3.6. В узлах бинарного дерева имеется элемент, определяющий частоту обращения к нему. В записях дерева хранятся следующие данные: фамилия, имя, отчество работника, его адрес, место работы, должность, дата рождения. Создать новое бинарное дерево. В качестве ключа использовать частоту обращения к нему, путь к узлам дерева должен быть оптимальным (наикратчайшим). Записи из старого дерева в новое дерево не перемещать. Рекурсии и библиотечные функции не использовать. В дереве не более пятисот узлов. Частоты в узлах дерева не совпадают.
Автор: Qraizer
Дата сообщения: 17.07.2007 12:26
Abs62
Давай я переведу твою цитату
Цитата:
Нестатические элементы данных класса (не являющегося объединением), объявленные без предшествующего спецификатора доступа, размещаются так, чтобы более поздние элементы имели более старшие адреса в объекте класса. Порядок размещения нестатических элементов данных, разделённых спецификатором доступа, неопределен (11.1). Требования выравнивания, обусловленные особенностями конкретных реализаций, могут быть причиной для двух смежных элементов не быть распределенными непосредственно друг за другом; так же это относится к пространству, требуемому для управления виртуальными функциями (10.3) и виртуальными базовыми классами.
Если перевод неверен - поправь, плз, если верен - то либо я не понял, о чём ты, либо ты не понял, о чём в этой цитате говориться.
Т.о. для того, чтобы гарантировано обеспечить чёткое распределение пространства в образе экземпляра, достаточно не использовать спецификаторов доступа. Требования выравнивания данных для элементов структур и классов в общем случае невозможно регулировать, ибо это ограничение аппаратной платформы, и перекрыть его невозможно (за исключением, если при невыровненном обращении генериться эксепшн, например). И оно же распространяется на вообще любое распределение данных, будь то локальные или глобальные переменные. Следовательно такие платформы априори не имеют упомянутой тобой проблемы. Таких архитектур, как интеловская x86, которой по большому счёту пофиг, как размещаются данные - подавляющее меньшинство, и как раз для них эта проблема встаёт в полный рост. Но как раз для них и существуют решения на основе расширения стандарта языка, наподобие #pragma pack(). Понятное дело, что стандартизировать такие вещи нельзя - у каждой платформы свои решения.
Автор: Abs62
Дата сообщения: 17.07.2007 16:18
Qraizer

Цитата:
Требования выравнивания данных для элементов структур и классов в общем случае невозможно регулировать, ибо это ограничение аппаратной платформы, и перекрыть его невозможно (за исключением, если при невыровненном обращении генериться эксепшн, например). И оно же распространяется на вообще любое распределение данных, будь то локальные или глобальные переменные.

Тем не менее, это распределение стандартно для каждой платформы и не является compiler-depended. Что, собственно, я и хотел сказать. То бишь ответ на вопрос "почему оно работает" должен звучать не как "потому, что повезло", а как "потому, что так реализуются требования стандарта на платформе x86".

Цитата:
Таких архитектур, как интеловская x86, которой по большому счёту пофиг, как размещаются данные - подавляющее меньшинство

По количеству или по распространённости? Просто мне как-то не довелось работать с другими архитектурами.
Автор: Antananarivu
Дата сообщения: 17.07.2007 16:31
Abs62
Я вижу, что тут уже пошел спор сишных гуру, но все же свои 5 копеек. Правильно я понимаю, даже если ты и прав про стандарт платформы, все равно такая реализация функции (которую я приводил выше) как минимум... ну рискована что ли, потому что кто-то (или даже сам программист) со временем может забытиь такие тонкости и добавить, скажем, виртуальную функцию или выравнивание и все... и потом будешь полгода искать причину, почему перестало работать как надо, разве не так?
Автор: Abs62
Дата сообщения: 17.07.2007 17:17
Antananarivu
Правильно. Qraizer уже сказал, как следует поступать с авторами подобного кода. И я с ним согласен.
Автор: Qraizer
Дата сообщения: 18.07.2007 13:17
Abs62

Цитата:
Тем не менее, это распределение стандартно для каждой платформы и не является compiler-depended. Что, собственно, я и хотел сказать.
Это-то да, но как сказано чуть ниже, для платформ, подобных x86, это перестаёт быть справедливым.
Цитата:
То бишь ответ на вопрос "почему оно работает" должен звучать не как "потому, что повезло", а как "потому, что так реализуются требования стандарта на платформе x86".
В общем-то, это вопрос терминологии, так что спорить не буду. Однако, "повезло" мне больше по душе по двум причинам: во-первых, чем меньше не достаточно опытных в программировании людей увидят такие вот хаки, тем меньшее из них количество извлечёт из этого крайне отрицательные уроки, ошибочно считая их вершиной "мастерства", так что раз уж такая информация попала в их поле зрения, запрет должен быть как можно более категоричным; во-вторых, требования стандарта - это закон, поэтому если стандарт говорит, что сие есть неопределённое поведение, значит это есть неопределенённое поведение, следовательно "повезло" тут уместнее, ибо ожидаемое поведение есть частный случай неопределённого.
Цитата:
По количеству или по распространённости?
Не скажу точно. Однакое я не слышал (впрочем, возможно, забыл) не x86, которые бы не требовали выравнивания в обязательном порядке. Получается, что x86 чуть ли не единственная в своём роде. Распространённость, я думаю, тут ни при чём, ибо стандарт по-любому обязан рассматривать все возможные варианты, без учёта распространённости.
Автор: BattleMage
Дата сообщения: 22.07.2007 19:10
Вот у меня есть ComboBox. Я его заполянил некоторыми строчками:
ComboBox1->Clear();
ComboBox1->Items->Add("Строка1");
ComboBox1->Items->Add("Строка2");
ComboBox1->Items->Add("Строка3");
ComboBox1->Items->Add("Строка4");

Потом есть процедура по нажатию на некоторую клавишу.
Вопрос: как определить что именно выбрал пользователь "Строка1" или "Строка3", к примеру

Заранее спасибо :)
Автор: Antananarivu
Дата сообщения: 23.07.2007 13:44
продолжаю серию ламерских вопросов... ))
функция fscanf...

FILE* Read;
int n;
fscanf(Read,"%d\n",&n);
cout << n << endl;

Вопрос, что дает \n ?
У меня что fscanf(Read,"%d\n",&n);
что fscanf(Read,"%d",&n);
работают идентично...
Я уже пытался разделить два числа символом новой строки и чего только не пытался... В книге написано (если я правильно понял), что по идее компилятор должен будет проигнорировать символ конца строки... но хоть убей у меня этого не получается...
P.S. Я даже не совсем понимаю, как он должен его проигнорировать? У меня файл, в файле 2 числа через пробел 1 и 2, в результате выполнения программы в n запишется число 1, теперь я в файле пишу 1, жму Enter и пишу 2, по логике вещей, если бы компилятор проигнорировал символ конца строки в n должно было бы записаться число 12, разве не так? Но на самом деле ничего не меняется... Где я глобально заблуждаюсь? Заранее спасибо!
Автор: Qraizer
Дата сообщения: 23.07.2007 22:58
Ты заблуждаешься в своём представлении того, как функции xxxscanf() обрабатывают форматную строку. Ты считаешь, что она вначале целиком разбирается по элементам, а потом уже на основе разбора выполняется чтение данных. На самом деле она обрабатывается последовательно, и все встреченные форматные спецификаторы обрабатываются сразу же, без заглядывания вперёд. Т.е. когда разбор дойдёт до %d, сразу же будет выполнена попытка ввести целое десятичное, которое и вводится как 1, т.к. ввод из потока остановится на первом разделителе, неважно, пробел ли это будет или \n. И только потом начнётся анализ дальнейшего содержимого форматной строки.
При вводе, каждый спецификатор формата может начинать разбор содержимого потока с последовательности разделителей, каковыми являются пробелы, табуляции и "новые строки". При этом все эти последовательные разделители пропускаются. (Исключение составляет только %c, который никогда не учитывает разделители и считает из обычными символами.) Если в форматной строке встречаются не только спецификаторы формата, считается, что в соответствующих позициях потока должны располагаться именно эти символы. При этом они благополучно вычитываются и отбрасываются. Т.о. scanf("%d%d", &n1, &n2) после ввода n1 будет ожидать в потоке хотя бы один разделитель (иначе два числа просто сольются), а следом значение n2, а scanf("%dи далее%d", &n1, &n2) после ввода n1 будет ожидать последовательности "и далее" и только потом n2; при этом разделители уже не обязательны, т.к. ввод n1 будет остановлен на символе "и" (ибо этот символ явно не относится к цифрам), а после "далее" сразу же ожидается новое число. Если же в потоке между значениями n1 и n2 будет что-то другое, отличное от "и далее", то ввод прекратится на несовпавшем символе, и будет зафиксирована ошибка. Например, если в потоке будет "1и далие2", то после выборки из потока символа "л" вычитается "и", а не "е", как указано в форматной строке, и это будет расценено как ошибка данных в потоке. В результате поток не дойдёт до "2", и n2 не будет введено.
Отсюда следует, что указывать сами разделители в форматной строке не имеет особого смысла (если только они не должны быть введены спецификатором %c). Фактически они могут рассматриваться как поясняющие. Смотри например, что произойдёт с scanf("%d\n%d", &n1, &n2).
Когда после %d обнаружится \n, то именно он и будет ожидаться после ввода n1. Если он в потоке и правда есть, то он благополучно вычитается и отбросится; если же вместо него там будет, например, какой-нибудь пробел, то произойдёт ошибка, и он не вычитается. Однако далее следует ещё один %d, поэтому дальше начнётся ввод ещё одного целого, и начнётся он с разделителя, того самого, который не вычитался, и который теперь благополучно пропустится как лидирующий. Так что действительно - никакой разницы.
Автор: Antananarivu
Дата сообщения: 23.07.2007 23:43
Qraizer
Очередное большое спасибо. Остался только один вопрос, чем же руководствовался программист описывая все именно так? Просто в том проекте, что я разбираю, это не единичный случай... Как вариант, действительно, как пояснение. Но все равно, как-то не очень понятно. Не хочется рассматривать вариант, что он сам толком не понимал работу функции...
Автор: Qraizer
Дата сообщения: 24.07.2007 14:00
Я в своё время интересовался вопросом, зачем вообще позволять указывать в форматных строках при вводе не спецификаторы формата. Однако потом до меня дошло, что в этом случае можно просто использовать те же самые строки, что и при выводе, один к одному. И при этом программа защищается от непреднамерянного искажения информации в потоке. Слабенько, конечно, но случайные ошибки выявляются. Кроме того, есть же ещё спецификатор %[].
Так что твой коллега вполне мог просто скопипастить форматную строку из fprintf().
Автор: Inspirit
Дата сообщения: 28.07.2007 15:05
У меня такая ситуация : я запускаю у себя игровой сервер World of WarCraft... Сервер состоит из 2х процессов : логин сервер, мир сервер, соответсвенно realmd.exe и mangosd.exe Вместе с ними работает также программа, которая в случае зависания самого игрового мира, перезапускает оба окна, realmd.exe и mangosd.exe ... Но иногда случайно очень гадкая штука : процесс сам зависает (не мир) , выскакиевает новое окно с сообщение об ошибке и собственно, пока не закроешь окно ошибки, сервер рестарнуться не сможет... Использовал множество рестартеров, но не один с данной проблемой не справляется.... Поэтому возник вопрос :

можно ли написать на С++ простенькую программу, состоящую допустим из самого экзешника и файла конфигурации к примеру setup.conf. Итак идея такая : программа должна контролировать количество открытых окон. Тоесть в файле setup.conf мы закладываем значения : количество допустимых открытых окон (выставляем сами), частота проверки в секундах. Принцип таков : программа сверяется через определенные промежутки времени и если окон становится больше\меньше, тоесть изменяется заданное программе число, она закрывает все активные окна, а т.к. авторестартер ВоВ находится в панели задач, то закрытие на него не действует .. окна падают... авторестартер получает информацию, что процессы обрушены и делает перезагрузку.

Вот может кто-нибудь написать что-то подобное?
Автор: Terran888
Дата сообщения: 03.08.2007 23:10
Вполне можно, тебе надо только перехватывать события в системе вроде CreateWindow и реагировать на них закрытием созданного окна.
Автор: bgukov
Дата сообщения: 04.08.2007 09:14
Жалко вас ребята.
Вы плохо понимаете суть вещей, увлёкшись формами.
Языки типа C(??,++,--,#,...) страдают позорной болезнью - многословием.
(Компилятор реализовать большая проблема.)
Они синтаксически (см. формы X++,X--,...) убоги и уродливы.
Про семантику вобще говорить нет смысла. Программист слева не поймёт
программиста справа. Каждый рисует как желает.
У Component Pascal (реализация Oberona-2) 20 страниц определений с
описанием синтаксиса и семантики. у C++ 150 страниц. И это только синтаксис.
Описание семантики составляют талмуды авторов, кои множатся.
Да что говорить ..? Накипело...
Автор: TeXpert
Дата сообщения: 04.08.2007 12:22
Inspirit
По-моему, не свосем по теме, надо было в другом топике, посвящённом WinAPI.

Terran888
Есть способы и попроще.

bgukov
Тебе что, флеймить негде? Проблемы своего роста (застоя?) и ещё какие-то свои комплексы обсуждай в других форумах, здесь ты вообще ни к чему. То что ты новичок, не освобождает тебя от обязанности чтения правил.
Автор: Qraizer
Дата сообщения: 04.08.2007 15:15
bgukov Ух ты! А я-то думаю, в чём причина. Спасибо, объяснил.
Друзья! Следуя выраженной идее, я призываю вас всех отказаться от великого и могучего русского и общаться исключительно на эсперанто. Не страшно, что выразительность и смысловое богатство от этого пострадает, главное, что не придётся проводить в школе за партой многие годы, да ещё и без гарантий успеха.

P.S. Я восторгаюсь тобой, bgukov. Не суметь осилить 19 - а отнюдь не 150 - страниц синтаксиса C++ и продолжать попытки заниматься программированием... это нужно иметь большую волю. Наверное, для воспитания воли очень важно, чтобы то, что в C++ можно записывать одной строкой, на Обероне описывать циклом с парой временных переменных.

P.S.S. Прошу прощения у админов, больше не буду.
Автор: TeXpert
Дата сообщения: 04.08.2007 16:19
Qraizer
Ну не дорос товарищ, что поделаешь). Не стоило поддаваться на провокацию.

P. S. Извинения за офтоп.
Автор: veronica b
Дата сообщения: 05.08.2007 07:26
bgukov

Цитата:
Да что говорить ..? Накипело...

Как я понимаю, ну не удается понять синтаксись Си и Си++. Не дано. Ещё давным давно Эзоп написал свою басню "Лиса и виноград".
Автор: akaGM
Дата сообщения: 05.08.2007 08:30
прошу всех меня простить...
Автор: Terran888
Дата сообщения: 05.08.2007 20:23
Подскажите: tcnmkb способ хранения настроек порграммы в своем exe модуле? Поменял настройки, скинул на флешку и на другом компьютере эти настройки остались как я выставил. Без использования реестра и всяких доп. файлов.
Автор: TeXpert
Дата сообщения: 05.08.2007 22:01
Terran888
Самомодифицирующиеся exe-файлы легко пишутся под Win16 (если у тебя есть компилятор), и под win32 работать будут. А под win32 писать такое -- морока.
Только это опять не по теме.
Автор: Terran888
Дата сообщения: 05.08.2007 22:05
Я бы не назвал это морокой. Надо всего-то немного текста менять в exe. Мне бы пример такой функции...
Автор: TeXpert
Дата сообщения: 06.08.2007 07:40
Terran888
Ты не понял. win32 не позволяет средствами WinAPI редактировать дисковый образ запущенного exe-файла.
Автор: Terran888
Дата сообщения: 06.08.2007 11:52
А если сделать копию файла, подправить его и сохранить, а исходный удалить. Так получится?
Автор: rain87
Дата сообщения: 06.08.2007 12:24
Terran888
при желании всё получится, но это таки морока и изврат. реестр рулет

по сабжу всё же - настройки хранить в ресурсах (винапи позволяет ковыряться в ресурсах), при сохранении настроек создавать свою копию, менять в ней ресурсы, а потом каким-нить образом завершиться, и сделать так, чтоб новая копия переписала старую прогу. например - батником, который потом и сам себя удалит
Автор: TeXpert
Дата сообщения: 06.08.2007 14:28
Terran888
Цитата:
А если сделать копию файла, подправить его и сохранить, а исходный удалить. Так получится?
Это да. Мне лично Рихтер так советовал -- работающий exe-файл переименовываешь, создаешь копию этого же exe-файла опять с оригинальным именем, правишь его и после завершения работы удаляешь переименованный образ. Полурешение, но получше пока не придумано.
rain87
Цитата:
реестр рулет
В топку реестр, это вообще дурной вкус. Хорошие программы не должны от реестра зависеть.
Автор: Terran888
Дата сообщения: 06.08.2007 15:36
TeXpert
Вы Рихтера знаете? Или это про его книгу?
А дело вот в чем: нужно чтобы пограмма "ходила по рукам" и работа каждого пользователя оставалась в программе. Например результаты некоторого психологического теста. Если это дело хранить где-то кроме exe то получается что либо пользователь может передать программу дальше без своих результатов (файл настроек удалить с флешки) либо эти все результаты останутся на его компютере. Вот на VisualBasik можно делать такие контейнеры в exe? причем всего 2 функциями. А неужели в С++ все так плохо? Я пока нашел только 1 другой выход: Флешку форматирую в NTFS и создаю NTFS поток этого exe файла, который и будет хранить настройки. При копировании впринципе (если у человека не FAT) настройки незаметно для него перекопируются вместе с фалом. Да и пожалуй не каждый опытный пользователь сразу додумается как это настройки сохранились. Но всеже хотелось бы всетаки выяснить как с exe орудовать. Всем Спасибо.
Автор: rain87
Дата сообщения: 06.08.2007 16:05

Цитата:
Хорошие программы не должны от реестра зависеть.
мало ж под винду хороших программ, оказывается
Автор: TeXpert
Дата сообщения: 06.08.2007 16:06
Terran888
Цитата:
Вы Рихтера знаете?
Лично нет. Но однажды написав письмо, датированное 21-м числом (месяц и год уже не помню), был удивлён тем, что ответ был 20-м. Потом дошло, насчёт разницы во времени. Тем не менее, был приятно удивлён тем, что такой занятой человек ответил так оперативно.
Цитата:
Вот на VisualBasik можно делать такие контейнеры в exe? причем всего 2 функциями. А неужели в С++ все так плохо?
Тут дело не в языке, а в платформе -- см. выше.
Цитата:
Я пока нашел только 1 другой выход: Флешку форматирую в NTFS
А как насчёт Win98?
Цитата:
Но всеже хотелось бы всетаки выяснить как с exe орудовать
Совет всё тот же -- добыть Win16 компилятор (Visual C++ 1, например, или 4, на худой конец -- Delphi 1), в этом случае делай с exe-шником что хочешь. Я, например, написал несложную игру, которая все результаты "носит с собой".





Добавлено:
rain87
Цитата:
мало ж под винду хороших программ, оказывается
Microsoft успел так основательно деформировать сознание многих -- к слову, ты не замечал, что уже так часто там, где следует писать "/", уже пишут "\" (Добавить/удалить)?
Автор: Terran888
Дата сообщения: 06.08.2007 17:18
Вот на VisualBasik можно делать такие контейнеры в exe. Я опечатался, это утверждение было. Тогда вот вопросик: Как написать что-то нормальное для Win16? А windows 98 уже можно забыть как страшный сон.

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193

Предыдущая тема: не знаю как назвать тему :-)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.