• Какие есть проекты на Си, которые можно использовать для изучения языка?

    Если захочется чего "покрупнее", чем предложил terrier, посмотрите SQLite - тоже проект написанный далеко не дураками).
    Ответ написан
    Комментировать
  • Почему функция "cpy" работает со строками?

    Nipheris
    @Nipheris Куратор тега C++
    String(const char *str);//конструктор по принимаемой строке

    вот и ответ. (конструктор неявного преобразования).

    Если хотите проверить - поставьте перед этим конструктором кейворд explicit - и строка
    a.cpy("rap").print();

    должна перестать компилироваться.
    Ответ написан
    1 комментарий
  • Как показать сообщение после завершения всех webClient.DownloadFileAsync?

    Nipheris
    @Nipheris Куратор тега C#
    Почему бы в download_completed не уменьшать счетчик оставшихся загрузок и дожидаться, пока не он станет равным нулю?
    Ответ написан
    3 комментария
  • OVPN TLS Error: TLS key negotiation failed. - уже после проверки сертификата сервера. Why?!?!?

    Советую проверить, правильно ли сгенерены клиентские сертификаты, одинаковые ли используются ca.cert на обоих концах. Попробовать перегенерить все, если это не слишком сложно.
    Ответ написан
  • Где найти БД города с улицами и домами и координатами домов в OSM?

    download.geofabrik.de

    Определяете регион, в котором находится ваш город, качаете файл (немаленький), затем выковыриваете геометрию домов и их адреса.

    Кстати, эта фишка (маппинг человеческих адресов на фичи) называется геокодинг.
    Ответ написан
    Комментировать
  • Где логическая ошибка?

    Nipheris
    @Nipheris Куратор тега C++
    > (a-b)/2
    Проверьте, не случилось ли у вас тут целочисленного деления
    Ответ написан
    Комментировать
  • Где найти работу junior unix администратору?

    > я никогда не смогу быть unix only специалистом, из-за того что microsoft здесь доминирует.
    не совсем согласен. Да, стек MS еще доминирует, но с другой стороны, околосетевое оборудование (сервера VPN-доступа, сетевые шлюзы) или отдельные сервисы - почта, NAS - вполне могут быть не на винде. И если ОДНОМУ админу сложно быть unix-only, то В ПАРЕ с виндовым админом - вполне, почему нет? В нормальном предприятии > 2 админов нормальная ситуация, потому что некоторые работы нужно проводить ночью + иногда дежурить или выезжать. Чтобы работать в рамках ТК, два админа - вполне адекватное решение. В штатных ситуациях один вполне может специализироваться на *nix.
    Вообще, вам правильно советуют подучить еще какой-нибудь софт. Люди любят более-менее законченные решения, логично что директору хочется, чтобы вы смогли хотя бы почту поднять и админить ее, или поддерживать внутренний сайт.
    Вот кстати, корпоративного софта сейчас намного меньше под .NET, Python и Ruby имеют хорошую долю во внутрикорпоративных приложениях, да и сам .NET уже поддерживается гораздо лучше самим MS на unix системах. Следовательно, сейчас > 80% серверов - это про *nix (в IT-специлизированных компаниях еще больше). Огромное количество софта на платформе java куда чаще запускают на linux машинах. Так что учитесь так, чтобы сказать "Здравствуйте. Я могу поддерживать почту/NAS/JIRA/Redmine/Jenkins/Samba, если у вас нет, могу и поднять". И во многих случаях у вас либо уже будет unix, либо (набравшись опыта) вы сами сможете все настроить. О, а DBA это отдельная история. Если совладаете с PostgreSQL, а то и с Oracle, вам будут давать неплохие деньги.
    И в конце концов, потеря данных сейчас фатальна или очень нежелательна для большинства компаний. Почти всегда первейшей задачей админа является настройка бэкапов и слежение за ними (работоспособность, "учебные" аварии и т.д.), и на бэкап-машине винда уже просто ни к чему.

    В общем, делайте выводы. Мое мнение: если компания не застряла в 90-х, в ней больше 10 сотрудников, и там используется что-то помимо MS Office и виндовых расшаренных папок, то там вполне пригодится unix-админ. Ах да, обязательно выучите парочку скриптовых языков. Например, bash как язык из мира unix, и Python как изначально кроссплатформенный. Когда человек умеет писать скрипты, кончается эникейщик, и начинается системный администратор.
    Ответ написан
    Комментировать
  • Не работает вставляется в вектор?

    Nipheris
    @Nipheris Куратор тега C++
    it < words.end();

    Старайтесь итераторы сравнивать с помощь == и !=. Сравнение на больше/меньше работает не со всеми итераторами, не стоит привыкать к нему.

    *word

    Конструктор копирования корректно определили? Даже если да, зачем такие извращения с созданием объекта сначала на куче, а потом его копирования по значению? не проще ли работать с Word на стеке или наоборот, сохранять в вектор указатель? Вы кстати еще и забываете удалить созданный на куче объект класса Word.
    Ответ написан
  • Что выбрать, единую базу или по базе на каждого пользователя?

    Все зависит от того, что предполагается давать пользователю в управление. Если сервис таков, что юзер никогда-никогда не должен получать доступ к базе, то тогда можно в одном наборе таблиц. Хотя разные БД будут проще в администрировании и на порядок безопаснее (вдруг где-то забудете сделать WHERE по id магазина). Если между магазами не будет общих данных, тогда преимуществ от использования одной базы ИМХО практически нет.
    Ответ написан
    1 комментарий
  • Стиль оформления кода в .NET приложениях. Встречался ли вам ад в коде?

    Nipheris
    @Nipheris Куратор тега C#
    Для меня очевидно, что это писали бывшие разработчики на C/C++. Это древняя нотация, многие называют ее венгерской, только тут какой-то извращенный вариант (надо сказать, что и саму венгерку правильно применяли единицы в свое время, большинство не понимало до конца ее смысла). Сейчас так не пишут и на самих плюсах, для шарпа же это моветон. Выдает нотацию n перед именем индекса (это значит именно "индекс", а не int, правда обычно пишут nUnit или nEmployee, а не nIndex) и C перед именемами классов.
    Если есть нормальная IDE, то венгерская нотация нафиг не нужна, код превращается в рябь из смеси сокращений, которые только раздражают

    Совершенно согласен с вами.

    Не такие уж опытные ребята писали этот код, и они точно не в ладах с оформлением кода в C#. Вероятно, писали давно, когда C# еще появился, и все C++ программеры начинали писать на нем, сохраняя все свои привычки, многие из которых не нужны или даже вредны.
    То, что разные классы по-разному оформлены это не еще не большая беда, далеко не всем проектам удается поддержать одинаковый стиль (хотя оно того стоит конечно).
    Почти все классы в основном проекте лежат, никаких папок и соответствия им нэймспэйсов (за редким исключением).

    Это тоже из плюсов - нормальные люди конечно пользуются неймспейсами, но там они не настолько вездесущи, как в C#, т.к. технология сборки в принципе иная.
    А у вас было подобное? Вы как-то решали эту проблему?

    А это кроме вашей команды во главе с тимлидом и даже с привлечением менеджеров никому не решить. Если вы готовы отрефакторить половину продукта - вперед. Не готовы - лучше не трогайте. Пишите новый код в адекватном стиле. Если бы это был C++, я бы даже вам посоветовал новый код оформлять по правилам проекта, но ЭТИ правила в рамках C# неадекватны совершенно.

    Резюмирую: если нет ресурсов на переработку кода - терпите. Терпение и способность работать с legacy кодом не самого высокого качества - вероятно самая важная черта "программиста в команде". Старый и не самый симпатичный код - это реальность, это так же реально, как и ветхие здания, которые просто так не перестроишь без серьезных вложений.
    Работал в одной организации полтора года, написал сам несколько проектов. код в плане оформления просто чуть ли не идеален. Без всякой чуши типа венгерской нотации и т.д.

    Вам везло в плане качества кода. Теперь не очень повезло. Как сказал AtomKrieg, хорошо что не Кобол (хотя б тогда вам платили еще больше).
    Над методами простые комментарии, а не XML или их вообще нет

    Нормальные XML-комментарии в C# коде это вообще роскошь. Я их вижу только в серьезных библиотеках, а во всяком корпоративном треше так комментятся только самые важные классы в программе (штук 10-15). Радуйтесь, что вообще есть документация. Если есть желание и время - переносите в код, это наверняка будет полезно.
    Ответ написан
    Комментировать
  • ClassName::functionName или objectName.functionName?

    Nipheris
    @Nipheris Куратор тега C++
    Отвечу без догадок.
    > Я понимаю что cout << objectName.functionName означает, что мы выводим возвращаемые данные функции , которая принадлежит объекту класса(оперирует данными объекта).
    Это хорошо соответствует истине, добавить в общем-то нечего.

    > Но вот почему мы иногда использует cout << ClassName::functionName вместо первого варианта я не могу понять...
    "::" это оператор расширения области видимости. В языке C++ различные сущности могут быть объявлены "внутри" других сущностей. Например, функции внутри классов, как в вашем случае - тогда они становятся методами. Классы, функции и переменные могут объявляться внутри namespace-ов. Классы могут объявляться внутри других классов. Классы даже могут объявляться внутри определения функций.
    Во всех этих и других случаях, можно говорить о двух именах сущности - коротком, которое уникально в рамках родительской сущности, и о полном, по которому к сущности можно обратиться из любого места в программе. Например,

    namespace MyLibrary {
        namespace UI {
            class Widget {
             ///
            };
            class Controller {
            private:
                Widget *widget; // Здесь Widget будет видно по короткому имени
            };
        }
    }
    
    namespace App {
      MyLibrary::UI::Widget *w; // А вот здесь уже нужно использовать полное
    }

    Это правило касается всего - и классов, и функций, и переменных. И вот как раз для построения полного имени и нужен оператор "::". Грубо говоря, он "открывает" указанную вами сущность и после него вы можете указать имя вложенной сущности. MyLibrary::UI::Widget - открыли неймспейс MyLibrary, в нем взяли и открыли неймспейс UI, в нем взяли сущность Widget. В нашем случае Widget это класс, поэтому мы можем использовать его в качестве типа, например объявить указатель на его объект. Если бы у нас была переменная mainWidget в том же UI, мы бы могли написать так:
    MyLibrary::UI::mainWidget = new MyLibrary::UI::Widget(); // создали объект виджета в куче и поместили указатель на него в переменную-указатель


    С точкой тут вот в чем дело. По умолчанию функции внутри классов считаются методами ОБЪЕКТА (экземпляра этого класса), и, как вы правильно сказали, оперируют с данными объекта, а значит они НЕ МОГУТ быть вызваны без указания того объекта. Иными словами, они не самостоятельны, для их вызова всегда нужно указывать объект, с которым метод будет работать. Можете представлять себе, что у всех методов экземпляра есть неявный параметр this, который, хоть и не пишется в списке, тем не менее всегда присутствует, и его значение надо задавать. Оператор точка - это и есть способ задать значение "this" - т.е. указать, для какого объекта вызывается метод.

    Совсем другое дело - static-методы. По сути это самостоятельные функции, просто объявлены внутри класса, и имеют доступ к его private-сущностям. Поэтому для их вызова достаточно указать полное имя, используя оператор "::", например Widget::create или MyLibrary::UI:Widget::create, что в принципе одно и то же. Более полная запись нужна, когда вы находитесь в другой области видимости, и просто "не видите" нужный идентификатор. Или же если у вас в текущий области НЕСКОЛЬКО идентификаторов с одинаковым именем (конфликт имен), и компилятору необходимо однозначно понять, о какой сущности вы говорите.

    Касательно случая, который вам непонятен - про использование :: в составном имени метода - тут все просто. Т.к. вы собираетесь не ВЫЗВАТЬ метод, а дать его ОПРЕДЕЛЕНИЕ, вам не нужна точка, т.к. точка это синтаксис вызова метода для конкретного объекта. Вам лишь нужно построить ПОЛНОЕ имя для метода, находящегося внутри класса, чтобы компилятор понял, ЧЕЙ код вы будете писать в фигурных скобках. А полное имя строится с помощью двоеточия, поэтому и получается ClassName::methodName { код метода }. Просто methodName вы написать не можете, т.к. в cpp-файле вы находитесь УЖЕ НЕ ВНУТРИ определения КЛАССА, и компилятор посчитает, что вы объявляете и описываете совсем другую, свободную функцию methodName, совершенно не имеющую отношения к методу methodName в классе ClassName.

    Есть некоторые интересные особенности у "::", например когда слева от него ничего нет. Это значит, что вы обращаетесь к глобальной области видимости. Это позволяет, например, различать глобальную функцию, и функцию с таким же именем, определенную в вашей области видимости. Это можно в приличной книжке все прочесть.

    Если остались вопросы - задавайте. Запомнить проще всего так: точка - это обращение к члену объекта структуры или вызов метода (т.е. слева от точки всегда стоит объект), а "::" - это способ составления ИМЕНИ какого-либо элемента вашей программы - класса, функции, метода, переменной и т.д.
    Ответ написан
    1 комментарий
  • Область применения C, C++, C#?

    Nipheris
    @Nipheris Куратор тега C++
    > Хотел задать вопрос к опытным программистам.

    Ну раз опытным, то думаю разумно поделиться своим опытом. Итак, в чем участвовал за последние 5-6 лет, где были плюсы или шарпы. Три места работы, три команды:
    - десктопная софтинка наподобие 2ГИС - база данных услуг и предприятий с привязкой на карту. C#, карту отрисовывали сами с помощью Direct3D;
    - TCP-сервер GPS-трекеров (такие фиговины, отправляют по GRPS/SMS свои текущие GPS/ГЛОНАСС координаты + всякие плюшки для транспорта - уровень топлива, скорость движения и т.д. - зависит от модели). C++ и обыкновенные сокеты. Сервер небольшой, принимал именно данные от трекеров и писал в базу. Отображалось все на обыкновенном сайте с PHP в бэкенде.
    - веб-сервис, принимающий платежи по WebMoney Merchant и поддерживающий балансы на счетах клиентов. Открывал урл для серверов вебмани, плюс давал простейшие отчеты (проведена транзакция или нет, текущий баланс, транзакции на списание). C# (WCF), данные писались в PostgreSQL.
    - десктопное приложение для проходной - по отпечаткам пальцев входящих/уходящих сотрудников регистрировалось их время пребывания на предприятии. Ну и разумеется - отчеты, агрегации (время отработанное за неделю, опоздания, переработки и т.д.). C# + некоторые части на С++, соединяющие драйвер сканера отпечатков и библиотеку их распознавания по образцам.
    - здоровенное декстопное приложение на C++ + Qt, трейдинговый терминал (более 10к файлов исходников, команда из 30+ человек);
    - довольно объемный ГИС-проект на C#, клиент десктопный (WPF+SharpMap), серверная часть - ASP.NET WebAPI (JSON API).
    - планируется новый ГИС-проект с клиентом уже на C++ и Qt, т.к. существует нереально крутые рендереры на OpenGL от MapBox (тык), а большинству участников текущего проекта плевать - C++ или C#. Qt сейчас развивается очень серьезно, поэтому на сегодняшний день он выровнялся с C#+WPF, а т.к. рендерер на плюсах - то и клиента будем писать на плюсах. На сервере по-прежнему ASP.NET, вероятно новой версии (пока начнем писать, должна успеть выйти в релиз); тех, кто считает, что с ним "сложно в вебе" - аргументы в студию;
    - небольшой сайд-проект - рендер сложного 3D объекта для внедрения в рекламный ролик новой фантастической книги. С++ и OpenGL, написано быстро, дешево и сердито, отрисовано покадрово в PNG-шки, смонтировано в After Effects, все довольны.

    Вывод: поверьте, если инструмент подчиняется вам, то вам открыто много способов решения различных задач. Конечно, для Web-бэкенда C++ будет очень странным выбором, но лично у меня хватает задач и без бесконечных мелких сайтиков.

    Послесловие: безусловно, начинать лучше с того же Паскаля (да, я серьезно, отличный язык для обучения, дисциплинирует, и при этом не скрывает машину от программиста). Но если уж выучите С++, или хотя бы Си, то остальные языки после него будут как игрушки с наворотами. Конечно, для этого вам уже надо знать, что вы хотите стать программистом. Если еще не уверены - лучше попробовать на более простом языке, иначе перегорите не дойдя и до середины.
    Ответ написан
    12 комментариев
  • Как узнать что Task завершил свою работу?

    Nipheris
    @Nipheris Куратор тега C#
    Да, вы поняли правильно. На первый взгляд в коде проблемы нет (если он выполняется из GUI-потока и FromCurrentSynchronizationContext() дает контекст GUI-потока). Что-то не работает?
    Ответ написан
  • Как добавить WS_BORDER чужому окну?

    Nipheris
    @Nipheris Куратор тега C++
    Судя по информации о стилях окна в MSDN, для уже существующего окна этот стиль добавить/удалить невозможно.
    Ответ написан
  • Как сделать изменяемый интерфейс на стороне клиента c# WinForm?

    Nipheris
    @Nipheris Куратор тега C#
    > Подскажите пожалуйста если есть какие мысли по решению данной задачи.
    Есть мысль поставить задачу более конкретно. Понять, что это за "поля", которые можно добавить, к каким сущностям будут привязаны эти поля, какие будут к этим полям запросы, будут ли поля глобальны для всех пользователей, или же они свои у каждого пользователя, и другим не видны.

    > Необходимо что бы администратор программы мог добавить новый label, текстовое поле, изображение, мб даже форму.
    Я не уверен в том, что вы действительно заходите администратору программы давать выполнять такие действия, т.к. он будет понемногу превращаться в программиста. Рано или поздно (а скорее всего рано) клиентам захочется добавлять еще и логику на формы, они попросят для этого язык, и уже целиком превратятся в программистов.

    Я представляю решение вашей задачи как мини-IDE + шелл для работы с базой (непонятно кстати, какой лучше - SQL или, например, документной) в одном флаконе. Такие решения в общем-то существуют и имеют смысл - достаточно вспомнить про 1C с его конфигурациями и средствами разработки, или, например, про Лексему. Однако, я не уверен, что вы хотите и сможете получить подобное решение, раз задаете такой вопрос). Мне все-таки кажется, что ваша проблема более частная, а желание дать возможность администратору клепать формочки - острый недостаток в проработанном техническом задании и/или нежелание вашего клиента платить вам в последствии за развитие и техническую поддержку продукта, которое выливается в попытку переложить рутинные задачи (эти самые "новые поля", "новые формы и лэйблы" и прочие вещи) на дешевые кадры. В общем-то в этом есть смысл, однако чтобы это организовать, нужно довольно много стартовых затрат.
    Ответ написан
    Комментировать
  • Для чего же нужны указатели?

    Nipheris
    @Nipheris Куратор тега C++
    Ну и я тогда тоже попробую.

    Посмотрим на вопрос с другой стороны.
    Переменная - это контейнер для значения. Что нам вообще нужно для работы с переменной? Что нам нужно, чтобы считать/записать значение из/в нее? Нам нужны тип данных и адрес в памяти.
    Тип данных - отдельная история, оставим пока его в стороне. Скажем только, что он определяет допустимые операции со значением и количество памяти, необходимое для хранения значения.
    Поговорим об адресе. В языках, где доступна прямая работа с памятью, любая переменная имеет свой адрес в памяти. Также, в чуть более узком смысле, переменная находится в такой области памяти, в которую разрешена запись. Не имеет особого значения, какой структурой данных управляется эта память - стеком или кучей - важно, чтобы на момент использования эта память была доступна.
    Корректный адрес в памяти - это и уникальный "ключ" переменной, ее отличительная черта. Работая с переменными, программист на низкоуровневом языке неизбежно работает с адресами.
    Другой вопрос - это способ работы с адресом переменной. Когда вы создаете обычную локальную переменную, в работе с ней принимает участие компилятор. Когда вы пишете int a, компилятор (если не вдаваться в детали) размещает у себя в таблице идентификаторов пару: (имя_переменной, адрес_в_памяти). Обычная локальная переменная "а" (еще ее называют "автоматическая переменная") - способ создания переменной средствами компилятора. Компилятор освободит память, занимаемую этой переменной, когда она уйдет из области видимости. Однако, пока вам точно известно, что эта переменная "живет", вы можете совершенно спокойно получить ее адрес с помощью операции & - компилятор отдаст вам его из своей таблицы идентификаторов.

    Но "переменные" в широком смысле можно создавать не только средствами компилятора, но и вручную с помощью malloc (Си) или new (С++). Эти динамические переменные живут столько, сколько вам нужно - вы их создаете, вам их и уничтожать. Об этих переменных компилятор ничего не знает, т.к. вы создаете их динамически во время выполнения программы. Для доступа к этим переменным вам также нужен адрес, но у компилятора его не попросишь: поэтому необходимо самому сохранять те адреса, что вернули вам функция malloc или оператор new. Этот адрес вы можете сохранить в ДРУГОЙ переменной, и такая переменная, хранящая адреса - и есть указатель (кроме того, если указатель не бестиповый (void*) то его тип (float*) еще и подсказывает нам тип переменной, на которую он указывает (float)).

    Очень важно, что в указатель можно сохранить адрес ЛЮБОЙ переменной - как автоматической, которую вам создал компилятор, так и "ручной" - которую создали ВЫ с помощью malloc/new. И передать, например, этот адрес в функцию. Фактически, в языке Си указатели это и есть способ передачи САМОЙ ПЕРЕМЕННОЙ в функцию, а не ее ЗНАЧЕНИЯ на момент вызова. В C++ есть еще ссылки, но это отдельная история (ссылки - это указатель, "обернутый" в обычный идентификатор), по ним задайте отдельный вопрос.

    если можно напрямую данной переменной присвоить новое значение.

    Как раз таки "напрямую" вы не присвоите, т.к. у вас не может быть в одной области видимости ВСЕХ переменных, имеющихся в программе. Хотя бы потому, что у вас могут быть динамические переменные, и единственный способ работы с ними - работать через указатель.

    Если вы никогда не работали с динамической памятью, вы можете спросить, какой смысл в "ручных" переменных, если для хранения их адреса нужна парная переменная-указатель? А вся фишка в том, что адрес динамически созданной переменной также можно хранить в динамически созданном указателе. Тут-то и открывается вся бесконечная свобода построения динамических структур данных. Если вы не слышали про связный список, то самое время почитать хорошую книгу с примерами. В одном ответе этого не расскажешь, это основы программирования.
    Ответ написан
    Комментировать
  • Как правильно регулировать уровень громкости?

    Nipheris
    @Nipheris Куратор тега C#
    Спасибо за суммон.
    В Висте и выше архитектура аудио подсистемы была переработана, поэтому современным API считается WASAPI, а WINMM считается устаревшим.
    Можно разобрать следующий пример: blogs.msdn.com/b/larryosterman/archive/2007/03/06/...

    Необходимые хедеры:
    #include <windows.h>
    #include <mmdeviceapi.h>
    #include <endpointvolume.h>


    Запустим COM:
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    Создадим перечислитель устройств:
    IMMDeviceEnumerator *deviceEnumerator = NULL;
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);


    Вытащим дефолтовый девайс:
    IMMDevice *defaultDevice = NULL;
    hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
    deviceEnumerator->Release();
    deviceEnumerator = NULL;


    Получим интерфейс для работы с громкостью (этот интерфейс полезен именно для работы с master-громкостью устройства):
    IAudioEndpointVolume *endpointVolume = NULL;
    hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
    defaultDevice->Release();
    defaultDevice = NULL;


    Получим предыдущее значение громкости:
    float currentVolume = 0;
    endpointVolume->GetMasterVolumeLevel(&currentVolume);


    Установим новое значение громкости:
    hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL);


    P.S. Не сразу обратил внимание, что у вас C#, постараюсь скорректировать ответ вечером.
    Ответ написан
    2 комментария
  • MVP как правильно вернуть переменную во ViewModel прогрессбара?

    Nipheris
    @Nipheris Куратор тега C#
    Посмотреть бы на код, который регулярно считывает progressVal из модели и пихает в прогресс-бар. Иными словами, SetValProg откуда еще вызывается, кроме как при старте? Лично я пока не вижу никакой проблемы с потоками, про которую говорит tex0, т.к. из другого потока устанавливается только интовое поле у Model.
    Ответ написан
    Комментировать