Обсуждение Программирование на C/C++

Все разобрался! Надо было значения передавать по ссылке)

Посмотрел на код, ужаснулся... Извините за прямоту.

Вопрос: Вы на С++ программируете или на С??? В коде всё перемешано в кашу. Вообще в кашу. Классы, глобальная переменная, глобальные функции...
С++ - это объектно-ориентированный язык! Три столпа ООП - наследование, инкапсуляция, полиморфизм!
В частностности в Вашем случае о базовом принципе инкапсуляции и речи нет. Тут два пути:
1. Использовать целиком и полностью процедурный стиль, и программировать на С, и компилировать как С-код
2. Программировать на С++, и целиком использовать все три принципа ООП.

Во втором случае Ваш класс должен быть примерно таким:
PHP:
#include <iostream>#include <conio.h>#include <stdlib.h>

using namespace std;

class tank{private:    int x,y;    char symbol;public:    tank(int a, int b, char c) : x(a), y(b), symbol(c) {}    void moveTank(int x, int y);
    void ai();

    int getXCoord();
    int getYCoord();};
char map[15][20];

Где, метод moveTank присваивает приватным свойствам x и y указанные значения из параметров (еще лучше сделать структуру из двух значений координат)
Метод ai рандомно устанавливает свойства x и y.

В main должна быть реализация switch-case, и там примерно так: case 72: t34->moveTank(t34->getXCoord() - 1, t34->getYCoord());

А еще лучше реализовать четыре метода, moveLeft(int step), moveRigth(int step), moveTop(int step), moveDown(int step); где step - кол-во клеток для движения.

В общем особо вникать не охота, но суть такая.

И еще, получение экземпляра объекта надо делать так: tank* t34 = new tank(0,0,'T');
Тогда движение танка будет таким:
map[t34->getXCoord()][t34->getYCoord()] = '';
case 72: t34->moveLeft(1); break;
case 80: t34->moveRight(1); break;
case 75: t34->moveDowd(1); break;
case 77: t34->moveUp(1); break;
после case-ов: map[t34->getXCoord()][t34->getYCoord()] = 'T';

В этом случае будет легко дополнять "игру". Например "прыжок" на две позиции вверх: t34->moveUp(2);
 
Блин, че-то я замарочился этими танками=))))

Итак, сидя на унитазе, в голову пришел алгоритм работы программы:

1. Мы имеем объект(класс) - танк. И имеем объект(класс) карта.
2. Танк умеет: двигаться вверх(moveTop), влево(moveLeft), вправо(moveRight), вниз(moveDown), двигаться случайным образом(moveAI), getType() - возвращает значение AI это или Player
3. Карта: имеет приватное свойство из массива структур формата(tank* current, tank* next, tank* previous), конструктор, render(), action()
3.1 В конструктор передается кол-во танков на карте, конструктор заполняет массив структур. Где current - указатель на текущий танк, next - на следующий, previous - предыдущий, зачем это надо? А вот зачем, будет переменная, которая будет хранить в себе указатель на текущий танк, после того, как танк совершит ход, указатель переходит по next. Последнее значение структуры next указывает на первое значение, а previous у первого указывает на последний. Таким образом мы замкнем кольцо совершения ходов танков.
4. Функция main имеет бесконечный массив, берет getCurrentType у карты, которая в свою очередь возвращает this.current->getType(), если это AI, то сразу вызывается map->action(), если это Player, то делается _getchar() и значение передается в map->Action(). После чего делается map->render() - отрисовка карты на экране.
map->Action() разбирает входящие параметры и делает this.struct[current]->move<Left|Right|Top|Down>, и вызывает this.current = this.struct[current] = next; Таким образом мы совершили ход, и передали управление следующему.

В общем как-то так.

ИТОГО:
1. Можно менять кол-во клеток для хода
2. Можно добавить метод shut() - выстрел
3. Можно в любой момент добавлять или убирать с поля танки в любой момент времени во время выполнения
4. добавить объект(класс) "препятствие" которое нельзя проехать, только либо объехать стороной, либо разрушить выстрелом
5. Менять размерность карты в любых пределах.
6. Самое главное: Таким образом будет полностью ООП-ный код, который будет крайне легко поддерживать, расширять, улучшать.

З.Ы. Я описал самую простую схему. Советую почитать Страуструпа, и ОБЯЗАТЕЛЬНО паттерны проектирования.
 
Пишу на си. Нужно сделать функцию с переменным количеством аргументов. Внутри этой функции эти аргументы должны принтфнуться. Как-то просто это можно сделать?
Знаю, что в случае макроса можно просто __VA_ARGS__ заюзать

Код:
void foo(const char* format, ...)
{
// some code
printf(format, ...)
// some code
}
 

Klick

Ословед
Пишу на си. Нужно сделать функцию с переменным количеством аргументов. Внутри этой функции эти аргументы должны принтфнуться. Как-то просто это можно сделать?
Знаю, что в случае макроса можно просто __VA_ARGS__ заюзать

Код:
void foo(const char* format, ...)
{
// some code
printf(format, ...)
// some code
}

Должно быть что-то вроде:
Код:
#include <stdarg.h>

void foo(const char* format, ...)
{
    // some code
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
    // some code
}
 

''EMERCOm''

Ословед
Прошу помощи с задачей. С++
Используя все цифры от 1 до 9 по одному разу и операции сложения и вычитания, получить в сумме 100, при условии, что цифры появляются в возрастающем или убывающем порядке.
Например,
123 + 4 - 5 + 67 - 89 = 100,
9 – 8 + 76 – 5 + 4 + 3 + 21 = 100.
 

    IvanGT

    очки: 1.642
    Привет :hi:
P

_Partizanka_

Уважаемые жители округа. Просьба не оффтопить. У меня еще карты не распакованы. Еще раз увижу - исправлю эту незадачу.
P.S.: Сообщения вида: "Иди поучись" так же считаются оффтопом.
 

Trial

Самец :)
Здравствуйте всем. Имеется вопрос о перезагрузке операторов на С++

Кароче динамически создаю массив типа стринг, далее необходимо с помощью цикла искать в этом массиве непустые ячейки, но компилятор выдаёт ошибку C2676, она говорит о том что оператор видимо не поддерживает сравнение в типе std::string.

Привожу пример кода:

Код:
std::string *str3 = new std::string[20];

//здесь идёт обычное заполнение массива

//далее вывод непустых ячеек:
for(int i=0;i<sl1+sl2;i++)
{
if(str3[i]!=NULL)
std::cout<<str3[i]<<", ";
}

Ругается на if(str3!=NULL)

Вот сама ошибка: error C2676: binary '!=' : 'std::string' does not define this operator or a conversion to a type acceptable to the predefined operator

И ещё одна ошибка имеется: error C2784: 'bool std::eek:perator !=(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::string'

В гугле копался довольно долго, находил как делать перезагрузку, но всё равно не могу понять как в моём случае сделать, подскажите пожалуйста, только не отправляйте в гугл, если не знаете, или знаете но лень расписывать, то лучше промолчите!
 

Trial

Самец :)
Видимо строку надо сравнивать с "", а не с NULL
Сравнивал, не в этом дело. Компилятор ясно пишет что не перезагружен оператор, только его надо както правильно перезагружать, как подпрограмма делается с возратом значений, не могу понять как в моём случае это делается.

Если я делаю тоже самое но создавая массив типа char то всё работает и компилятор не ругается, но программа работает не так как мне нужно.
 
Ты сравниваешь строку с указателем, поэтому компилятор и ругается. Чтобы проверить, пуста ли строка, нужно сравнивать ее с ""
 

    Trial

    очки: 46
    Нет комментариев
Форумчане, кто может помочь с задачей, не за бесплатно конечно
Задача:
Методические рекомендации по лабораторной работе №2

Процессы. Потоки.
Часть 1.
Задача: создать многопотоковое приложение, в котором можно менять приоритеты потоков. Программа DreadedSorts создает два потока. Один поток запускает пузырьковую сортировку (bubble sort), другой – быструю сортировку (quick sort). С помощью соответствующих ползунков на главной форме можно изменять приоритеты потоков, чтобы они получали разнойе количество тактовой частоты. При этом, можно так настроить приоритеты, чтобы более медленная сортировка выполнялась даже быстрее.
Ход работы.
1. Запустить Delphi. Открыть новое приложение командой File|New Application.
2. Сохраните проект, дав модулю имя main.pas, проекту – DreadedSorts.dpr.
2. Перенести на пустую форму, кнопку BitBtn со страницы Additional палитры компонентов, два компонент Label со страницы Standard, 2 компонента TrackBar со страницы Win32. Свойства Name компонентов TrackBar установите соответственно как BubbleTrackBar и QuickTrackBar.
Установите свойства компонентов формы:
object Form1: TForm1
Caption = 'Пример многопоточного приложения'
object Label1: TLabel
Left = 40
Top = 8
Width = 129
Height = 33
Alignment = taCenter
Caption = 'Приоритет пузырьковой сортировки'
WordWrap = True
end
object Label2: TLabel
Left = 232
Top = 8
Width = 129
Height = 39
Alignment = taCenter
Caption = 'Приоритет быстрой сортировки'
WordWrap = True
end
object BitBtn1: TBitBtn
Left = 136
Top = 88
Width = 153
Height = 25
Caption = 'Запустить сортировку'
end
object BubbleTrackBar: TTrackBar
Left = 32
Top = 40
Width = 150
Height = 45
Max = 2
Min = -2
end
object QuickTrackBar: TTrackBar
Left = 224
Top = 40
Width = 150
Height = 45
Max = 2
Min = -2
end
end
4. Форма должна приобрести вид указанный на рис. 1.

Рис.1.
5. Теперь добавьте в проект две пустых формы, сохраните модули этих форм соответственно secform и thform.
6. Вернитесь к главной форме приложения и создайте обработчик события OnCreate:
procedure TForm1.FormCreate(Sender: TObject);
begin
// получить размер рабочего стола
ScreenWidth := GetSystemMetrics (SM_CXSCREEN);
ScreenHeight:= GetSystemMetrics (SM_CYSCREEN);
// переместить основную форму сверху центральной части рабочего стола
form1.top := 0;
form1.left := (ScreenWidth-form1.width) div 2;
// определить, сколько элементов можно отобразить в двух окнах
SortWindowSize := (ScreenHeight - form1.height) div 2;
if SortWindowSize > (ScreenWidth div 2) then
SortWindowSize := ScreenWidth div 2;
end;
7. Создайте обработчик события OnClick кнопки BitBtn1 главной формы:
// обработчик события щелчка мыши на кнопке - создает формы сортировки,
// генерирует данные сортировки и запускает потоки
procedure TForm1.BitBtn1Click(Sender: TObject);
var
i: integer;
ThreadID: dWord;
begin
// помещает форму пузырьковой сортировки на рабочий стол
form2.free;
form2 := TForm2.Create (self);
form2.top := form1.top + form1.Height+formgap;
form2.left := (ScreenWidth-(SortWindowSize*2)) div 2;
// помещает окно пузырьковой сортировки в левой половине экрана
form2.width := SortWindowSize;
form2.height := SortWindowSize;
form2.color := formcolor;
form2.caption := 'Bubble Sort';
form2.show;
// помещает форму быстрой сортировки на рабочем столе
form3.free;
form3 := TForm3.Create (self);
form3.top := form1.top + form1.Height+formgap;
form3.left := form2.left + form2.width;
// помещает окно пузырьковой сортировки в левой половине экрана
form3.width := SortWindowSize;
form3.height := SortWindowSize;
form3.color := formcolor;
form3.caption := 'Quick Sort';
form3.show;
// присваивает число элементов сортировки равным форме
NumItems := form2.ClientHeight - pixeloffset*2;
//выделение динамических массивов для хранения данных сортировки
SetLength (a, NumItems);
SetLength (b, NumItems);
// генерирование случайных чисел для сортировки
Randomize;
for i:=0 to NumItems-1 do
begin
a := random (NumItems);
b := a;
form2.canvas.pixels[a+pixeloffset,i+pixeloffset] := pixelcolor;
form3.canvas.pixels[b+pixeloffset,i+pixeloffset] := pixelcolor;
end;
// запуск потока пузырьковой сортировки
T1:= CreateThread (nil, 0, @BubbleThread, nil, 0, threadID);
// установка потока быстрой сортировки для отслеживания позитивного значения
setThreadPriority (T1, BubbleTrackBar.Position);
// запуск потока быстрой сортировки
T2:= CreateThread (nil, 0, @QuickThread, nil, 0, threadID);
// установка потока быстрой сортировки для отслеживания позитивного значения
setThreadPriority (T2, QuickTrackBar.Position);
// замечание: для просмотра рекурсивной быстрой сортировки в действии
// установите приоритет потока к значению -1 или -2. Для того,
// чтобы посмотреть может ли пузырьковая сортировка подавлять
// быструю сортировку, установите приоритет потока пузырьковой сортировки
// к значению +2, а быстрой сортировки к значению -2.
end;
8. Добавьте в раздел interface модуля main нижеследующий код:
8.1. описание констант
const
pixeloffset = 5; // смещение пикселов обеспечивает рамку внутри окон
formgap = 10; // количество пиксельных промежутков между основной формой
// и окнами сортировки
formcolor = clBlack; // цвет фона для формы сортировки окон
pixelcolor = clWhite; // цвет пикселов для элементов данных сортировки
8.2. в описание типа TForm1 код, выделеный жирным шрифтом.
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
BitBtn1: TBitBtn;
BubbleTrackBar: TTrackBar;
QuickTrackBar: TTrackBar;
procedure BitBtn1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
T1, T2: THandle;
ScreenWidth, ScreenHeight,
SortWindowSize : Word;
NumItems: Word;
a, b: array of integer;
public
{ Public declarations }
end;
9. Добавьте в раздел implementation модуля main нижеследующий код:
9.1. ссылки на модули других форм приложения
uses
secform, thform;
9.2. процедуру пузырьковой сортировки
// процедура пузырьковой сортировки - вызывается процедурой BubbleThread
procedure BubbleSort (var ia: array of integer; items: integer);
var
i, j, t: integer;
DC: HDC;
begin
DC := GetDC (Form2.Handle);
for i:= items downto 0 do
begin
for j:=0 to items -1 do
if ia[j] < ia[j+1] then
begin
t:= ia[j];
//
SetPixel (DC, ia[j+1]+pixeloffset, j+1+pixeloffset, formcolor);
SetPixel (DC, ia[j]+pixeloffset, j+pixeloffset, formcolor);
ia[j] := ia[j+1];
ia[j+1] := t;
SetPixel (DC, ia[j+1]+pixeloffset, j+1+pixeloffset, pixelcolor);
SetPixel (DC, ia[j]+pixeloffset, j+pixeloffset, pixelcolor);
end;
end;
ReleaseDC (Form2.Handle, DC);
end;
9.3. процедуру быстрой сортировки
// процедура быстрой сортировки - вызывается процедурой QuickThread
procedure QuickSort (var ia: array of integer; iLo, iHi: integer);
var
Lo, Hi, Mid, T: integer;
DC: HDC;
begin
Lo := iLo;
Hi := iHi;
mid := ia[(Lo+Hi) div 2];
DC := GetDC (Form3.Handle);
repeat
while ia[Lo] < mid do Inc(Lo);
while ia[Hi] > mid do Dec(Hi);
if Lo <= Hi then
begin
T:= ia[Lo];
//
SetPixel (DC, ia[Lo]+pixeloffset, Lo+pixeloffset, formcolor);
SetPixel (DC, ia[Hi]+pixeloffset, Hi+pixeloffset, formcolor);
ia[Lo] := ia[Hi];
ia[Hi] := T;
SetPixel (DC, ia[Lo]+pixeloffset, Lo+pixeloffset, pixelcolor);
SetPixel (DC, ia[Hi]+pixeloffset, Hi+pixeloffset, pixelcolor);
inc (Lo);
dec (Hi);
end;
until (Lo > Hi);
if Hi > iLo then QuickSort (ia, iLo, Hi);
if Lo < iHi then QuickSort (ia, Lo, iHi);
ReleaseDC (Form3.Handle, DC);
end;
9.4. две функции потоков
// функция потока пузырьковой сортировки
function BubbleThread (parms: pointer): LongInt; far;
begin
BubbleSort (form1.a, form1.numItems-1);
end;
// функция потока быстрой сортировки
function QuickThread (parms: pointer): LongInt; far;
begin
QuickSort (form1.b, 0, form1.numItems-1);
end;

10. Приложение готово можно скомпилировать и выполнить его.

Задание: Задача выше - это указания, с помощью которых можно создать приложение, визуально демонстрирующее работу разных алгоритмов сортировки. нужно взяв код приложение на Делфи за основу, переписать его на С/С++ с возможностью задавать количество сортируемых элементов (менять NumItems). Сейчас, NumItems := form2.ClientHeight - pixeloffset*2. Если вместо этой строки написать, например, NumItems := 1000000, программа начинает глючить. Т.О. надо переписать код на С/С++ и устранить баг с NumItems.
Вопросы желательно в ЛС.
 
Работа.

Есть однократная работа для C++ программиста.

Кратко суть задачи. Есть DGN-файл (Microstation) в котором присутствуют ссылки на внешние документы и изображения. Необходимо написать консольную .NET программу, которая будет получать задание через командную строку и/или INI-файл, выполнять задание и возвращать результат. Это может быть одна из следующих операций:
1. Получить список ссылок на внешние документы и/или изображения (в виде XML документа с заданной структурой).
2. Изменить пути к внешним документам и/или изображениям на переданные.
3. Получить список текстовых блоков с их содержимым (в виде XML документа с заданной структурой).
4. Модифицировать конкретные текстовые блоки.

Для работы с DGN файлами будет выдана библиотека Teigha 3.8 или более новая от Open Design Alliance.

Требования к кандидатам.
1. Знание английского технического.
2. Способность быстро и без головняков разбираться с документацией и незнакомым продуктом коим для вас будут скорее всего сама Teigha и Microstation (который необязателен но полезен и который скорее всего придётся где-нибудь скачать :) ). Предполагается что с INI и XML файлами вы уже умеете работать.
3. Способность писать грамотный код, который потом не придётся переписывать чуть менее чем полностью. Чтобы убедиться что вы не транжирите моё время желательно предъявить пример какой-нибудь софтины написанной вами с фрагментами исходников.
4. Наличие банковского счёта в нормальном банке, принимающем международные платежи без тупых вопросов о их происхождении (hint: Сбербанк), или PayPal куда можно перевести деньги.

Условия сотрудничества.
1. Вам направляется спецификация о том что надо сделать.
2. Вы её анализируете и говорите за какие сроки и деньги вы готовы это сделать.
3. Если компанию ваши требования удовлетворяют, то считается что мы договорились.
4. Делаете, укладываясь в сроки, ну или не сильно их нарушая.
5. Компания проверяет вашу работу, если всё ok, то деньги выплачиваются. Если есть какие-то недочёты, ошибки, то исправляете.
6. Если вы существенно запарываете сроки или сделанный продукт полон багов так что на их исправление требуются существенные ресурсы, то деньги не выплачиваются и все оказываются в убытке, потеряв своё время.

Заказчик - австралийская компания на которую я работаю.

В случае успешного сотрудничества могут быть и другие задачи.

Если у вас есть интерес к подобной работе, то пишите в личку. Я вышлю спецификацию.
 

TAPAHOB_Х@й

Ословед
Нужнен кому последний труд Страуструпа? (С++ Programming Language 4th Edition. Мягкий переплет, английский язык)
Мне 2 экземпляра пришло (думал первый потерялся на почте, а он нашелся). Посылка не открывалась. Мне обошлась 57 евро (~2500p), отдам за 2000р.
О книге можно почитать тут http://www.stroustrup.com/4th.html
 

DIY

Самец :)
Среда разработки - Visual C++, без .NET
Пишем плагин для одной программы

В бэкграунде выполняем скачивание больших файлов.
Задача: как вернуться в главный поток (Main/GUI thread), чтобы обновить прогрессбар новыми данными?

Есть какая-нибудь функция выполнения функций из главного потока типа runFunctionInMainThread()? Хочу поставить функцию в очередь на выполнение в main event loop.

Что пробовал: QueueUserAPC, ждущие таймеры - всё это не подходит, потому что у меня нет прямого доступа к main() программы, и вводя где-либо SleepEX(), я блокирую интерфейс программы. Смысл асинхронной закачки тогда теряется вообще.
 
Задача: как вернуться в главный поток (Main/GUI thread), чтобы обновить прогрессбар новыми данными?
Задача поставлена некорректно. Фоновый поток должен потокобезопасным образом выставлять "наружу" состояние о том сколько информации он обработал, а другой (главный) поток по таймеру должен должен эту информацию считывать и отображать когда ему это будет нужно. Все иные способы ведут к покаранию богами многпоточности.
 

DIY

Самец :)
Задача: как вернуться в главный поток (Main/GUI thread), чтобы обновить прогрессбар новыми данными?
Задача поставлена некорректно. Фоновый поток должен потокобезопасным образом выставлять "наружу" состояние о том сколько информации он обработал, а другой (главный) поток по таймеру должен должен эту информацию считывать и отображать когда ему это будет нужно. Все иные способы ведут к покаранию богами многпоточности.

тогда следующий вопрос
как таймер организовать, если у меня нет доступа к main() программы? Потому что пишу плагин
 

    MK

    очки: 9.999
    Нет комментариев
тогда следующий вопрос
как таймер организовать, если у меня нет доступа к main() программы? Потому что пишу плагин
Если ситуация обстоит таким образом, и программа не даёт никакого API для плагинов чтобы отображать всякие прогрессбары и т.п. то я бы тогда не пытался бы заработать гемор со стабильностью на свою голову а вынес бы всю фоновую загрузку и отображение прогресса оной в отдельный процесс/исполняемый модуль - exe, а плагином бы дёргал его как заблагорассудится, благо возможности IPC в виндах богатые.

Заодно и отлаживаться будет легче.

P.S. А... ещё немного и тебе не придётся изобретать велосипед. STFW, curl, wget и что-то подобное.
 

    MK

    очки: 9.999
    Нет комментариев
Сверху