Это копия, сохраненная 15 октября 2015 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Я хоронился за Вождем, как мог,
Чтобы от Них мне обрести пощаду.
Мы были там, - мне страшно этих строк, -
Где крестобляди в недрах говнокода
Сквозят глубоко, как в стекле сучок.
Кто - сгинул в функторах, монад не зная брода,
Кто - отстрелил ступню, забыв про lock (),
А кто - решив, что goto даст свободу.
Литература:
Для нюфань:
Три классических учебника для начинающих. Все примерно одинаковой годноты, читать имеет смысл только какой-нибудь один, который больше приглянется.
Герберт Шилдт - C++. Базовый курс (2010) - https://goo.gl/qMLAFl
Роберт Лафоре - Объектно-ориентированное программирование в C++ (2004) - https://goo.gl/QvjR6x
Стивен Прата - Язык программирования C++ (2012) - https://goo.gl/z7kA8u
Для желающих сразу начинать с Откровений Создателя - классика (может показаться суховатым):
Бьерн Страуструп - Программирование. Принципы и практика использования C++ (2009) - https://goo.gl/87qXtW
Учимся не писать говнокод:
Книги про основные подводные камни для тех, кто осилил предыдущий пункт. Следует пролистать все.
Скотт Мейерс - Эффективное использование C++ (2005) - https://goo.gl/wsDXGz
Скотт Мейерс - Наиболее эффективное использование C++ (1996) - https://goo.gl/tHa0tO
Скотт Мейерс - Effective Modern C++ (на ангельском) (2015) - https://goo.gl/uImH0J
Скотт Мейерс - Эффективное использование STL (2002) - https://goo.gl/QtS8Dc
Герб Саттер и Андрей Александреску - Стандарты программирования на языке C++ (2005) - https://goo.gl/Cpk4YR
Наиболее детальные описания языка:
Бьерн Страуструп - Язык программирования C++ (2010) - https://goo.gl/iZBDiV
Стандарт C++14 (на ангельском) - https://github.com/cplusplus/draft/raw/master/papers/n4140.pdf
Последняя на данный момент версия черновика стандарта C++17 (на ангельском) - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4527.pdf
Тонкости языка (для гурманов):
Андрей Александреску - Современное проектирование на C++ (2002) - https://goo.gl/e1V5BC
Герб Саттер - Решение сложных задач на C++ (2002) - https://goo.gl/iWaa6S
Герб Саттер - Новые сложные задачи на C++ (2004) - https://goo.gl/4nn512
Также для легкого чтения подойдет книжка c историей создания C++:
Бьерн Страуструп - Дизайн и эволюция C++ (1994) - https://goo.gl/FqbPwo
Отдельные аспекты:
Читать по необходимости.
Энтони Уильямс - Параллельное программирование на C++ в действии (2012) - https://goo.gl/qJfBkD
Николаи Джоссатис - C++. Стандартная библиотека (2012) - https://goo.gl/PEyiMH
Дэвид Вандевурд, Николаи Джоссатис - Шаблоны C++. Справочник разработчика (2003) - https://goo.gl/0M4NpG
Роберт Седжвик - Фундаментальные алгоритмы на C++ (2001) - https://goo.gl/4jwxSl (части 1-4), https://goo.gl/yDuQgG (часть 5)
Ссылки:
Годный блог, в котором все просто и понятно тян не нужны кококок борщ - http://alenacpp.blogspot.ru/
Краткие описания библиотечных функций и контейнеров - http://ru.cppreference.com/w/
Блог Герба Саттера (на ангельском) - http://herbsutter.com/
Блог Скотта Мейерса (на ангельском) - http://scottmeyers.blogspot.ru/
Куда писать код:
Под шиндошс удобно использовать IDE Microsoft™ Visual Studio®. Базовую версию (2015 Community) можно бесплатно скачать, следуя инструкциям с этой страницы: https://www.visualstudio.com/ru-ru/products/free-developer-offers-vs.aspx. Чтобы начать писать код, нужно запустить Visual Studio, кликнуть "Файл - Создать - Проект - Пустой проект", после создания кликнуть слева правой кнопкой мыши по пункту "Файлы исходного кода", выбрать "Добавить - Создать элемент - Файл C++". Свои хэллоуворлды писать в этот файл, в дальнейшем можно добавить другие файлы и хедеры. Чтобы скомпилировать и запустить проект, нужно нажать "Сборка - Собрать решение", а затем "Отладка - Запуск без отладки".
Под *nix, как правило, уже предустановлен компилятор gcc (если нет, используй sudo aptitude install gcc), так что достаточно сохранить хэллоуворлд, набранный в текстовом редакторе, и выполнить g++ helloworld.cpp и ./a.out. Но удобнее установить какую-нибудь IDE, например, Code::Blocks (sudo aptitude install codeblocks) и работать в ней.
Можно также не устанавливать ничего, а запускать свои хэллоуворлды на http://ideone.com, выбрав в левом нижнем углу язык C++14.
Памятка:
Вопросу по синтаксису идут на хуй.
Лабы идут на хуй.
"Как мне сделать Х на чистых крестах без библиотек" идут на хуй.
Все идут на хуй.
Хейтер сосет члены на пару со своей мамашей.
Тег [code] работает через жабаскрипт-костыль: https://github.com/ololoepepe/MakabaCode
Предыдущий: >>531254 (OP)
https://arhivach.org/thread/94971/
https://arhivach.org/thread/94972/
https://arhivach.org/thread/99414/
https://arhivach.org/thread/100995/
http://arhivach.org/thread/105148/
Обновления шапки:
Добавлена книга Седжвика по алгоритмам.
> на
одна*
И оп пик твой говно. Где связь с С++? Не мог с форчана/редита/другой хуйни спиздить нормальный пик?
Няш, у нас тут своя атмосфера. Ты бы сперва посидел, посмотрел, как тут все заведено, ну серьезно.
Это про heap corruption, видимо. Довольно прикольный эффект, когда изначально смешная картинка для двощеров получает двойное дно, будучи запосщенной в С++-треде. Она это охуенно.
"Оффициальный™" это традиционное для борд написание которое происходит из ошибки опа куклоебских тредов, смекаешь, мой маленький ньюфажный друг? Иди и почитай лурку, или что там у вас сейчас модное про мемесы. Прошлый тред, как и позапрошлый, были с таким же написанием. Стихи в начале шапки потому что это красиво и привлекает внимание. Краткое описание книг там есть, если сделать больше, то шапка раздуется и ее не будут читать. Гораздо проще просто открыть заинтересовавшую книгу и посмотреть, что в ней.
>>537264
Жабаскрипт чтобы было удобно поставить его без перехода в ньюфаг-тред. И еще для долбящихся в глаза.
Ладно. Страдайте тем чем страдаете дальше. Своя атмосфера у них. Может вы ещё все друг друга знаете? Только поясните за длл библиотеки и виртуальные функции. Между ними есть связь? Какая?
Ты можешь импортировать и экспортировать в дллки виртуальные функции так же, как и обычные.
В длл хранится определение функции? Любой? Реквестирую чего нибудь про длл почитать. Можно в длл базовый класс положить и разные программы для разных целей его потом использовать будут? Можно екзшеник и длл на разных языках писать?
Да, определение. Не любой, там есть исключения, но я не распишу тебе за них, потому что сам почти не сталкивался. Почитать вот здесь: http://rsdn.ru/article/baseserv/dlluse.xml Базовый класс положить нельзя, потому что dll предоставляет механизм импорта только функций. Тебе придется все равно явно подключать общий для однотипных дллок хэдер, в котором будет определение класса, но вот потом разные дллки могут по-разному реализовывать его методы. Подводных камней много, поэтому лучше и безопаснее выделить в дллки только глобальные функции. Писать на разных языках можно, можно на одном языке, но компилировать разными компиляторами. Но в обоих этих случаях надо следить, чтобы соглашения о вызовах соответствовали.
Спасибо. Почитаю.
c++ abi нет и не будет
просто если пишешь modern c++ приложение, делаешь его одним екзешником, используя static linking
Годно, но не протухло ли уже? Не обосрусь ли с WDK 10?
https://ideone.com/GZICB0
Запусти оффлайн в режиме отладки и посмотрю, что там происходит, и где вылетает.
Я и на ideone не умею. Пользуюсь кодблоксом и gcc из коробки. Вроде дебагер какой-то установлен. Есть ещё такая менюшка.Что делать чтобы он по шагам нормально разбирал?
Просто жмешь Shift-F7 для шага с заходом в функции, Ctrl-F7 для шага с обходом функций, там же написано. Или ставишь брейкпоинты в нужных местах и жмешь F8, он каждый раз будет останавливаться на ближайшем.
Ага. Ты, блядь, на крестах тоже с орфографическими ошибками пишешь? Тогда понятно, чому твой хэллоуворлд не работает.
Начнём с того, что ты вообще не понимаешь что написал.
1. Алгоритм Евклида - открываешь в википедии и читаешь условия остановки цикла.
2. Нахуй тебе if в коде и переменная c одновременно? Тут либо сверяй в каждой итерации, либо меняй местами в каждой итерации, так чтобы в b всегда хранилось меньшее число.
3. Посмотри на условие в while и посмотри на return, теперь усиленно думай, что тебе вернёт функция. Учитывая, что деление целочисленных на ноль - undefined behaviour, компилятор с включённой оптимизацией может просто нахуй удалить весь цикл и вообще всё тело функции, соптимизировав до return 0; Теперь снова читай первый пункт этого поста.
А теперь об ошибке. На какой-то итерации, у тебя либо a, либо b становится равным нулю, из-за чего на следующей итерации ты делишь на ноль, что скорее всего и становится причиной ошибки.
Какое ядро языка, к херам.
Попробуй отключить стандартные либы и вызови new.
Ни язык, ни компилятор нихера не знают о памяти, сколько её, где она, можно ли брать.
new в любом случае реализован в libstdc++. Да, он может использовать хитрые стратегии выделения памяти, но это нихера не часть компилятора. И нет никакого деления на "оператор new и функцию operator new".
Хочешь поспорить - давай пруфы. Например, для C++11 можешь покурить п. 5.3.4.
Чтобы выводила список всех комментов с возможностю их редактирования, автозамены, удаления и прочего.
Получится ли, или опять new delete вилкой чистить? И если получится, можно код в студию и скриншот, что 2015 студия это может? А то зазря 2013 сносить не хотелось бы.
Пруфы - любой учебник по крестам, в стандарте даже искать лень. Когда ты пишешь где-то в программе new, вызывается встроенный оператор new, который без участия стандартной библиотеки сделает три вещи: осуществит ADL-поиск функции с именем operator new (среди пользовательских, а затем уже, если не нашел, возьмет библиотечную, стандартный алгоритм поиска, короче), ее вызовом получит указатель на неинициализированную область памяти размером с твой объект, вызовет для нее конструктор объекта. Эту последовательность никак нельзя изменить, скажем, нельзя поменять код библиотеки, чтобы по new происходило что-то другое, потому что оператор new встроенный, а не библиотечный.
Соответственно, без проблем можно отключить стандартные либы и вызывать new, если ты даешь свою operator new вместо библиотечной, потому что в этом случае ADL-поиск остановится на твоей функции, и библиотечная не понадобится. Но оператор new останется ровно тем же, встроенным, и последовательность его действий никак не изменится.
Хитрые стратегии и все тому подобное реализуются уже внутри именно функции operator new, а не оператора new, что библиотечные, что пользовательские. Я не утверждал, что вся эта хитрая функциональность является встроенной в компилятор, а поправил твою терминологию тем постом. Оператор new != функция operator new.
Тем своим постом ты сморозил хрень, а не поправил. Можешь теперь даже и не выкручиваться. Учебники идут в жопу - стандарт первичен и смотреть нужно в нём, а в учебнике можно любую хрень написать - истиной она не станет.
Я говорил что единственная "непользовательская" реализация new находится в стандартной библиотеке. Другой нет. И вызывать компилятор будет её. А ты предложил "не путать её с несуществующим встроенным оператором new". Куда, блядь, встроенным?
Тебе написали - не путай оператор new и функцию operator new. Когда компилятор видит оператор new, он по умолчанию вызывает функцию operator new.
Перечитай мой пост еще раз. Ты путаешь операторы и операции, блядь. int * tvoya_mamka = new int (1) - здесь встроенный оператор new сделает жестко зашитую последовательность действий, в.т.ч. вызовет видимую операцию operator new. Так работают все операторы - вызывают соответствующую операцию и, возможно, делают что-то еще.
Хорошо. Усложним вопрос: если мне нужен констэкспр массив, который получается в результате констэкспр функции?
Т.е. например у меня есть констрэкспрмассив из 6 значений 1, 3, 4, 7, 8, 9 например, и из него нужно констрэкспрмассив:
1
1x3
1x3x4
1x3x4x7
1x3x4x7x8
1x3x4x7x8x9
И уже эти значения размеры массивов чар.
Как это сделать? Будет ли работать в 2015 студии?
uint16_t = 1 << 2; //byte order is unknown: 00000000 00000100 or 00000100 00000000
А я хочу в первый байт записать 00000000, а во второй 00000100. С реинтерпрет_кастом как это сделать? Скорость не критична, мне это всего для одного значения сделать надо, сишные библиотеки не нужны.
Не нужен тут каст, union'а достаточно. Вот тебе из интернета:
typedef union { unsigned int value; unsigned char lo, hi; } _intchars;
_intchars data;
unsigned int value;
unsigned char lo, hi;
data.value = value;
lo = data.lo;
hi = data.hi;
Почитал на en.cppreference.com про union, интересно. Но что-то больно часто в тексте статьи undefined behaviour встречается. Да и ради одного значения какую-то сложную структуру городить не хотелось бы. Можно всё-таки через присваивание, например, uint8_t[2] значению uint16_t с помощью reinterpret_cast ?
Зачем тебе реинтерпрет каст? Нужен обычный каст перед сдвигом старшего байта влево.
https://ideone.com/OKZAY7
Если сделать в две строчки (сначала первый байт присвоить data а потом сдвигать уже data) то можно и без явного каста обойтись (будет неявное приведение при присваивании) но смысла нет лишний код писать. Если не использовать reinterpret_cast то порядок битов в числе не важен. Он может быть важен если ты свои байты передаешь через что-то. А если упаковываешь/распаковываешь в пределах одной исстемы то похуй какой он там. И использовать reinterpret_cast, если ты конечно не хочешь отстрелить себе ногу по самое ебало, не нужно. Только в специфических случаях когда без него не обойтись.
Младший байт : num & 255.
Старший байт: (num >> 8) & 255.
И дальше static_cast в однобайтовое, reinterpret не нужен здесь.
На цпп последний раз писал в универе, когда еще никакого c++11 не было даже и помню только базовые вещи, вроде чем указатель от ссылки отличается и что нельзя забывать про очистку памяти. ООП уже по дотнету изучал.
>Тег [code] работает через жабаскрипт-костыль: https://github.com/ololoepepe/MakabaCode
Хм, накатил, а ничего не поменялось, где были теги [CODE][code][/CODE] там и остались.
Страуструпа читай. Либо если знаешь более менее старый C++, почитай Мейерса про C++11, C++14
ну как не нужно
если пишешь либу, но для интерфейсных функций оформляешь доку в doxygen
удобно же - потом эту доку можно в два клика выплевывать хоть в html, размещая на сайте, хоть в pdf
при этом и собственно код, и разясняющая документация к нему будет в одном месте, под одной системой контроля версий
Используюй •, отец.
Массив это не первоклассный объект, поэтому функция не может возвращать его, в.т.ч. и constexpr. Обычно возврат массива эмулируется указателем, но тогда, понятное дело, constexpr вставить не получится, ибо указатели во время компиляции это хуйня какая-то. Для решения твоей задачи легче всего юзать метапрограммирование. Пикрелейтед.
Прочитал 2 учебника страуструпа и половину лафоре, а про constexpr нигде не поминается. Наверняка я много чего ещё не знаю что в новых стандартах ввели. Где почитать?
Прата в оппосте уже с фичами из C++11. И в Скотт Мейерс - Effective Modern C++ про нововведения.
Спасибо огромное, ты единственный, видимо, кто понял, что именно мне нужно — безо всяких union'ов, подключений дополнительных библиотек (например #include <bitset> это вообще конечно из гаубицы по воробьям), а другие >>538848 >>538859 , по ходу, вообще не поняли, что мне нужно. Переписал твой код через reinterpret_cast<uint8_t*>(&a) — чтобы явно обозначить тип приведения в стиле C++
>uint16_t a;
>reinterpret_cast<uint8_t@>(&a)[0] = 0;
>reinterpret_cast<uint8_t@>(&a)[1] = 1U << 2; //00000000 00000100
>std::cout << a << '\n'; //depends on CPU/OS/protocol: with the least first byte a == 1024
Кстати, я правильно понимаю, что reinterpret_cast должен быть "бесплатным", т.е. самым быстрым среди всех возможных кастов?
Спасибо, но оно того не стоит. Но всё равно спасибо, что объяснил, а то бы терзался, считая что это студия мне мешает, а не "не так всё просто".
Она ж 98 года? Мне тут вообще говорят что нынче проще нахуярить винформ на C#, а внутри логику если уж так надо на C++. Неужто все настолько плохо?
Есть 2013 года.
ofs.open(filename, std::ios::binary);
У меня есть цикл записи
for (int i = 0; i < n; ++i) ofs.write(reinterpret_cast<const char*>(some_array), some_array_i_size);
some_array_i_size один и тот же для любого i
А теперь я хочу необычного. Я хочу, чтобы каждый проход цикла файл писал some_array не только подряд, но и отшагивал вперёд на n X some_array_i_size байт, писал туда тоже some_array, и затем отшагивал назад на n X some_array_i_size байт. Т.е. на последнюю итерацию файл "сошьётся" последней итерацией его первой половины с первой итерацией второй половины.
Такое вообще возможно сделать, и если да, то как?
У меня все работает. Надо писать в квадратных скобках code lang="cpp" и /code.
Т.е. можно тупо прыгать вперёд, записывать, прыгать назад и т.д.? Очень хорошо, я не думал, что всё так просто. Очевидно, прыгать назад всегда можно, но вот насчёт вперёд я просто предположить не мог. Тогда предполагаемый костяк решения выглядит как-то так:
http://ideone.com/GbatXp
Онлайн-компиляторы не позволяют писать файлы, сейчас я не дома а работы у меня нет, можешь глянуть, так ли работает? Содержимое файла file.txt должно выглядеть следующим образом:
abcXYZabcXYZABCxyzABCxyz
Если нет, то где я ошибся.
abcabcabcabcABCABCABCABC в файле после выполнения. И еще предупреждения при компиляции, что возможны потери при касте в int в 14 строке, надо size_t юзать.
А нормальные ответы будут ?
Я планирую потратить на изучение языка минимум 2 года усердно, а то и 3 и только потом пробовать идти джуниором. Просто думаю что учить кресты или С#
Ой, ну там остаток от деления i на 2, а не n, ну вы же догадались. Предупреждение херня, какое переполнение для десятка чаров.
>Я планирую потратить на изучение языка минимум 2 года усердно, а то и 3 и только потом пробовать идти джуниором. Просто думаю что учить кресты или С#
А я через 3 месяца пошел на стажировку, потом ещё через 5 месяцев был уже джуном. А через два года - миддлом.
Назревает закономерный вопрос - зачем тебе въебывать 3 года на говно и мочу, если ты можешь быстро выучить основы и пойти работать в компанию, где тебя будут пинать опытные коллеги и делиться мудрыми советами %%соснуть хуйцеов и сделать бочку?
Учить нужно на практике же, а не по примерам из книжек. Если есть идеи для пробных проектов, и можешь себе позволить тратить на них каждый день сравнимое с фуллтайм-работой время, то вперед. Пилишь проекты, учишь на деле язык, IDE, VCS и вот это все. Потом будешь сразу с годным портфолио на гитхабе устраиваться. Если на такое нет времени/сил/желания, то лучше даже не рыпайся. Выучишь через два года самые основы по книжке для ньюфагов и устроишься макакой, будешь работать и учиться в процессе.
Где плюсы сейчас реально нужны кроме геймдева и отсталых контор, платящих копейки?
Интересно, потому что хочу кодить именно на плюсах, с C# и java знаком.
Есть ли спрос на написание многопоточного кода на плюсах(OpenMP, MPI, OpenCL)? Есть шансы на фрилансе чё-нить годного словить по плюсам?
Что там насчёт высокоматематичных отраслей вроде Digital signal processing, Image Processing, High perfomance computing, machine learning - есть спрос и можно ли устроиться туда после самостоятельного освоения мат. части по ним?
Поясните чем С++ касты отличаются от сишного?
Можно написать:
uint16_t a = 0;
(uint8_t)(&a)[1] = 1 << 2;
>Я планирую потратить на изучение языка минимум 2 года усердно
> Цепепе
> учить 2 года
Цепепе это такая параша для управления тем, куда какой байт послать. Она не может быть сложной по определению.
Нихуя не понимаю. Пока что мой английский позволяет мне читать только детские книжки. А гугл переводчик вообще ебанулся.
>например, Int плавать, или указатель к мочеиспусканию
Я учу английский. Обычно могу понять что пишут на SO. Но тут видимо какая то заумная хуета написана, как и на русскоязычных сайтах про эти касты. Объясните как для даунов. В чем преимущество перед сишным кастом?
Прежде всего в том, что можно сделать grep (find in files) и найти все места, где оно используется. Особенно дурно пахнущий reinterpret_cast.
Плюс, ты четко указываешь, что конкретно тебе нужно - просто убрать const у типа, изменить предка на потомка (static_cast - без проверки во время выполнения, dynamic_cast - с проверкой) или же тупо переопределить область памяти.
>Прежде всего в том, что можно сделать grep (find in files) и найти все места, где оно используется.
Комитет по стандартизации C++ именно этим "прежде всего" руководствовался.
По-моему это инициатива лично Страуструпа, которая описана в Дизайне и эволюции.
>>540044
Там же где и 10 лет назад - когда нужна бескомпромиссная производительность. Просто постепенно какие-то задачи (типа текстовых редакторов) уходят из ниши, а другие - приходят.
> Есть шансы на фрилансе чё-нить годного словить по плюсам?
Есть. Смотри в сторону CUDA, OpenCL, OpenCV.
const_cast
reinterpret_cast
static_cast
dynamic_cast
Нет. В рантайме работает только dynamic_cast, он "медленный". Остальные просто отключают разные проверки типов у компилятора.
В основном так но static_cast может добавлять инструкции которые будут выполнятся в рантайме и необходимы для конвертации, например переменную типа int нельзя превратить в double с помощью reinterpret_cast, а с помощью статик каста можно и это будет сделано с помощью дополнительных иструкций. Но в случаях когда reinterpret_cast применим, использование статик каста тоже не добавит инструкций, хотя тут я не уверен конечно.
Ну и как у тебя знаковый тип одной разрядности конвертнётся в знаковый тип другой разрядности в статик касте? С беззнаковыми типами всё просто, дописать или отбросить нужное количество нулевых старших байтов можно ещё на этапе компиляции.
Навскидку: взять адрес this в мембере bar и вычесть из него смещение мембера bar в Foo
Это навскидку. ХЗ, есть ли подводные камни, связанные с POD/не-POD и проч.
> смещение мембера bar в Foo
Но я не могу его достать из самого Bar, только передать из конструктора Foo при создании и хранить внутри инстанса Bar, а этого я бы хотел избежать.
Хочется что-то вроде offsetof(Foo, this) внутри Bar, с шаблонным Bar<Foo>, но оно так не работает, потому что offsetof - это ебаный макрос, туда this не засунешь.
А если есть несколько классов, в которых есть мемберы типа Bar и называются они по-разному?
Нашел вот такую пиздюлинку http://stackoverflow.com/a/709996, если я понял правильно - все оче плохо.
Вот смотри: http://ideone.com/hQtsEN
Что дописать в offset(), чтобы и для bar, и для baz вывелись корректные смещения? То решение соснет, потому что предполагается, что в классе может быть только один Notifier.
А, стоп, тупанул. Вот эта вот хуйня
>Notifier(Owner* owner);
портит всю малину, я именно этого и пытаюсь избежать. Я бы мог просто сделать
Foo(): bar(this, offsetof(Foo, bar)) {...}
и хранить смещение внутри Bar, но их блять охуиллиард и я не хочу тратить место.
Я нихуя не понял, что такое decltype(auto)? Что тут такое auto?
интернет + мозг. Полно FAQов с нубопроектами на любой вкус. Лови пример, на пике - рулетка тем.
когда кастуешь сами типы, а не указатели на них - то да. А то как же ты новый инстанс без копирования создашь? Это как присвоить одному экземпляру другой - вызывается конструктор копирования(если есть). С указателями такой поеботы не надо как правило, но в случае кастов по иерархии наследования и множественном наследовании может понадобиться сдвинуть указатель(как я понимаю).
>>540052 кидал же толковую ссылку http://stackoverflow.com/a/332086 читайте.
Не могу понять, почему std::async не создает новые треды. Правильно ли я понимаю, что с дефолтными флагами он должен обеспечить оптимальное количество тредов?
Или лучше такую задачу решать с пулом тредов?
> std::async
Почитай документацию, там нужно флаг выставлять, он может как создавать новый поток, так и откладывать выполнение пока результат не потребуется (ленивость). Пул тредов тебе мало чем поможет. Оптимальное количество тредов тебе никто не обеспечит, это нужно самому думать. Конкретно в твоем случае на определенном размере списка его лучше отсортировать в одном потоке, а не разбивать на несколько. Твоя реализация будет скорее всего медленнее в любом случае кроме случаев типа сортировки 500 элементов на процессоре с тысячью ядер, из-за того что ты для сортировки двух элементов требуешь два потока. Вообще маленькие списки (3-5 элементов) лучше даже не квиксортом сортировать а пузырком каким-то, или дерево ифов ебнуть. Квиксорт много на рекурсивных вызовах (которые нихуя не бесплатные) производителности теряет. А если ты будешь списки из двух элементов сортировать простым ифом (а не еще одним вызовом квиксорта) - общее количество рекурсивных вызовов сократится вдвое, но алгоритм естественно не такой красивый будет.
>он может как создавать новый поток, так и откладывать выполнение пока результат не потребуется (ленивость)
Вот в том то и дело, что я не понимаю как он рабоает при обоих std::launch::async | std::launch::deferred, но если подать ему только std::launch::async он будет создавать треды безконтрольно. Т.е. в рекурсивной он непригоден, в отличие от cilk_spawn, но cilk я юзать не могу.
Сама сортировка меня не интересует. Я пытался разобраться в поведении std::async, думал оно похоже на cilk_spawn.
Ну и том спасибо.
Так стандартный sort жи небось оптимизирует свои приватные методы с частичными сортировками для малых размеров. Лучше сделать, как Уильямс расписал в книжке. Запросить число ядер во внешнем вызове, разбить коллекцию на столько частей, для каждой сделать async с std::sort, а потом смерджить.
Он тогда сам выбирает, исходя из внутренних соображений. Может, у тебя уже дохуя задач в системе висит, и она считает, что создание новых тредов только уменьшит скорость.
ролл
Можешь поподробнее рассказать что ты уже знал когда устраивался джуном? Я вот совсем скоро лафоре из оп-поста дочитаю и вообще не понимаю когда моих знаний будет достаточно что бы бегать по собеседованиям.
Какой-то неровный список. Строку перевернуть - две строчки, хотя рядом вон например тетрис.
В чем проблема то? Числа слишком большие для примитивных типов? Или стандартный псевдорандом не устраивает?
Огромность массива (если не лезет в память) побеждается подключением STXXL. Огромность чисел - подключением bigint. Генератор в std::generate можно использовать свой. Можешь, заюзав стандартный равномерный генератор интов (он хороший), по схеме Горнера построить число любого размера и пихнуть его в bigint. Такие числа, очевидно, тоже будут равномерно распределены.
Еще байтоебский способ есть. Генерируешь обычным способом uint'ы, но большее количество, чем тебе надо чисел. Например, одно твое большое число можно составить из 20 uint'ов, тогда генеришь их в 20 раза больше. И сразу пишешь в файл в двоичном режиме. Теперь следи за руками. Генерированные числа равномерно распределены, значит их биты тоже (очевидно из формулы для маргинальных распределений), а тогда числа любого размера из этих же битов тоже будут равномерно распределены - биты-то независимы. Поэтому когда ты этот же файл интерпретируешь как последовательно записанные большие числа, сразу получишь нужный массив.
>sudo aptitude
Ну ёбана, не пиши же ты прямо так команды для сосноли. Просто скажи, какой пакет накатить, там дальше сами разберутся в wiki дистра. Пакеты практически везде одинаково называются.
>Code::Blocks
Нахуй. Дропнутое девелом говно. Лучше уж CodeLite. Есть и под шиндовс 32/64. В сочетании с TDN-MinGW работает просто волшебно даже на десятке. Конечно, до VS не дотягивает по свистелкам-перделкам. Но самое нужное, вроде авто-завершения кода и риал-тайм подсветки ошибок, есть. А больше нахуй и не нужно на самом деле.
Алсо проиграл от треда - такой-то референс на нуль, при том что все треды на нулевой нормальные. Карма, хуле.
>dev c++
Да понос это всё, рили.
После VS (а особенно начиная с 2015 Community) любая, любая, блядь, IDE покажется просто куском говна, которая только и умеет пердолиться в консоль и переменные среды. А также выдавать пачку ошибок в которых хуй чё поймёшь (дебилы даже не удосуживаются сохранить инфо об истории вызовов).
мимо-компайлю-дохуя-чего-под-моно
Пожалуй соглашусь, хотя мне еще невероятно CodeLite доставляет в контексте си и плюсовой разработки. Нетбинсы и экслипсы по сравнению с ним то еще тормозное говно, причем с самыми неожиданными багами.
Я сам на крестах в основном на CodeLite пишу (тащемта выше его и советовал). За clang code completion я их готов просто на руках носить. Эклипс вообще говно. Да пошли они нахуй JRE ставить ради редактора кода.
Попизди мне тут. Поломались треды, которые во время котосибирского шатания были на нулевой.
Так раздел про куда кодить для совсем ньюфагов. Если ты можешь в менеджмент пакетов, то с хэллоуворлдом разберешься наверняка. Тем более, что под никсы много IDE и все говно, так что я указал самую известную и переносимую, которая, к тому же, есть в большинстве дистрибутивов, даже самых дремучих.
[]-версия new схороняет размеры всего выделенного у себя.
Оно хорошо и удобно, когда ты пишешь что-то уровня laba5.cpp. Тогда да, все просто и понятно, разбираться не нужно. Когда у тебя тысяча строк кода средней сложности, работа без удобств начинает напрягать, и ты уже готов изучить "эти финтифлюшечки". Когда у тебя больше 10к строк, да с многопоточностью, ты взвоешь после первой попытки дебаггинга без них.
Я просто к тому, что добавить новинки которых мало с описанием нового стандарта это милое дело, а старой литературы по крестам просто дохуя, даже если считать только хорошую, и если добавить в шапку ее всю, то это ничего не даст, кроме того, что ньюфаги с большей вероятностью получат устаревшие знания.
Как изучишь синтаксис. На собеседованиях узнаешь, чего ты не знаешь. Тем более у многих кд для собеседований кандидата 2-3 месяца
http://stackoverflow.com/questions/7519039/real-time-keyboard-input-to-console-in-windows
Начиная со второго ответа читай.
Вот пример ошибки:
>Unhandled exception at 0x0F4635BA (msvcp120d.dll) in TESt.exe: 0xC0000005: Access violation writing location 0xCCCCCCD0.
где-то наебался твой Лафоре, залез за границы разметки памяти, а студия молодец, фигня твой dev C++
походу это я даун, переписал с нуля оба кода в студию и все работает. А как я мог залезть за границы разметки памяти? Я вообще не понимаю почему сейчас все работает, а тогда не работало ведь вроде тоже самое написал.
Блядь, ну сравни их через diff посимвольно, хуле ты?
Код показывай
Если копипастнул с пдфки, то (МОЖЕТ БЫТЬ?) цифры могли копипастнутся как чары. Ровно вчера поздно вечером на эти грабли наступил и сильно охуел, это как вообще возможно. MS Visual Studio 2013 Express, перепечатал ручками, заработало.
Т.е. не Лафоре наебался (как я говорил прежде), а лучше ручками перепечатывать. Вот Страуструп для ньюфагов на своём сайте весь код из книги даёт на скачивание + решения наиболее сложных упражнений.
там цифр вообще не было. И я от руки печатал, я ж говорю - это я где-то наебался но не понял где. Сонный был немного.
Допустим, есть код:
#define A 5
#define B A3
Все вхождения B будут заменены на A3
Вопрос: есть ли возможность, чтобы вхождения B заменялись сразу на 15?
Блять, там где A3 имелось ввиду AЗВЕЗДОЧКА3
компайлер сначала заменит твой A на 5 и B на 53, насчет того, что он заменит 53 на 15 я не уверен.
>есть ли возможность, чтобы вхождения B заменялись сразу на 15?
#define B 15
Возьми другой препроцессор, типа https://www.slac.stanford.edu/comp/unix/gnu-info/m4_11.html
Не могу сделать задание
\t>Предположим, что в функции main() определены три локальных массива одинакового размера и типа(скажем, float).Первые два уже инициализи - рованы значениями.Напишите функцию addarrays(), которая принимает в качестве аргументов адреса грех массивов, складывает соответствующие элементы двух массивов и помещает результат в третий массив.Четвертым аргументом этой функции может быть размерность массивов.На всем протяжении программы используйте указатели.
код:
[code lang="cpp"]
#include<iostream>
using namespace std;
const int n = 5;
int main(){
\tvoid sum(int, int,int, const int );
\tint ar1[n] = { 0, 1, 1, 1, 1 };
\tint ar2[n] = { 1, 1, 1, 1, 1 };
\tint ar3[n];
\tsum(ar1, ar2, ar3, n);
\tfor (int k = 0; k < n; k++){
\t\tcout << (ar3 + k);
\t}
\tchar ak;
\tcin >> ak;
\treturn 0;
}
void sum(int s1, int s2, int* dest,const int n){
\tfor (int j = 0; j < n; j++){
\t\tdest[j] = s1[j] + s2[j];
\t}
}
[/code]
\tРезультат работы программы такой : 23456
Не могу сделать задание
\t>Предположим, что в функции main() определены три локальных массива одинакового размера и типа(скажем, float).Первые два уже инициализи - рованы значениями.Напишите функцию addarrays(), которая принимает в качестве аргументов адреса грех массивов, складывает соответствующие элементы двух массивов и помещает результат в третий массив.Четвертым аргументом этой функции может быть размерность массивов.На всем протяжении программы используйте указатели.
код:
[code lang="cpp"]
#include<iostream>
using namespace std;
const int n = 5;
int main(){
\tvoid sum(int, int,int, const int );
\tint ar1[n] = { 0, 1, 1, 1, 1 };
\tint ar2[n] = { 1, 1, 1, 1, 1 };
\tint ar3[n];
\tsum(ar1, ar2, ar3, n);
\tfor (int k = 0; k < n; k++){
\t\tcout << (ar3 + k);
\t}
\tchar ak;
\tcin >> ak;
\treturn 0;
}
void sum(int s1, int s2, int* dest,const int n){
\tfor (int j = 0; j < n; j++){
\t\tdest[j] = s1[j] + s2[j];
\t}
}
[/code]
\tРезультат работы программы такой : 23456
а, и результат не 23456, а 12345
Лет в 14 писал игру и в ней все объекты хранились в массивах. Типа players, items и т. п. В итоге обращение к пятому item'у в инветаре выглядело как items[players[current_player].inventory[5]], где invetory[5] - индекс этого массива. В итоге при использовании таких индексов появлялись трех-четырех вложенные записи, и я подумал, что так быть не должно. В итоге понял, что указатели (которые представляют всю память как один большой массив) мне помогут.
"Указатели, без сомнения, - один из самых важных и сложных аспектов C++" (c) Шилдт.
А ты, кусок мудака, даже скопипастить код в ideone или pastebin, а потом скопипастить ссылку на своё дерьмо не можешь. Так что вали с крестов, ибо чем нас меньше, тем больше нам платят.
А совсем все расставила по местам книга assembler для windows 2000 что ли, в которой были объяснены защищенный режим, плоская модель памяти, MMU и прочие штуки.
Да я-то могу, но чет думал этот [соде] поможет, а сейчас не дома, так что вечерком скину код.не ругайся
Спасибо большое, решил проблему.
Есть тут кто-нибудь, кто пишет в виме - его я хоть чуть-чуть знаю? Как отлаживать код? Хочу как в криэйторе по коду бегать с f5, тут у меня нихуя настроить не получилось. youcompleteme не работает, я хз.
Я пишу в emacs, однако отладку делаю в qtcreator. Никогда с сегфолтами не имел проблем. Попробуй обновиться.
Круто, а это решение, сейчас попробовал на тестовом примере. Только не знаешь, можно ли указать несколько working directory? а то у меня их несколько.
working directory - это то, что меняет команда cd. Она вроде бы у процесса может быть только одна. Если тебе нужно их несколько, то тебе нужно прописать остальные в PATH?
А это не то, где должен находиться сам бинарник? У меня исходники лежат в разных каталогах, часть из них в каталоге build, который out-of-source. Или это совсем не то и уже все есть в отладочных символах? Я хочу навигацию по коду во время отладки.
Нашел http://tuhdo.github.io/c-ide.html - на первый взгляд вроде годно, что скажешь?
Она наследуется между процессами. Если ты запускаешь отладку из IDE, то будет не путь к бинарнику, а путь к проекту там.
Нет, это то, откуда твой бинарник будет думать, что он запущен. Т.е. если ты наберешь fopen("bla.txt") то это на самом деле будет fopen("/...working_directory/bla.txt").
>Нашел http://tuhdo.github.io/c-ide.html - на первый взгляд вроде годно, что скажешь?
Я пользуюсь редактором как редактором. Терпеть не могу все эти тормозящие фишки (когда появится многопоточность у elisp может и будет терпимо, а ща - нет).
Когда я отлаживал опенсорсный компилятор, а там много рекурсивных функций многократно вызывающих сами себя, и сложно ставить брейкпоинты, а также сложные структуры данных, которые трудно понять без pretty print, я полюбил отладочную печать и с тех пор особо часто отладчиком не пользуюсь.
Есть набор макросов типа #define L cout << __LINE <<, которые быстро пишутся после ; и так же быстро стираются через поиск с заменой. Для сложных проектов обязательно есть prettyprint.cpp, хотя сейчас у меня в основном библиотеки, которые это уже умеют. Забыл уже, зачем нужен отладчик. Зачем он нужен?
Какой пиздец. Ты ведь понимаешь, что ты будешь за это гореть в аду? В 2015 году, когда отладчик умеет выполнять скрипты, когда в нем видны стеки всех потоков и визуализируется состояние памяти, ты как ебаный неандерталец хуяришь отладочные печати, да еще и на макросах вместо виртуальных методов сериализации объектов.
Даже я в свои 15 имею некоторое представление о том, как делать не надо.
Ок. Программа падает в каком-то месте. Отладчик показывает, где. Ты понимаешь, что в этом месте все ок, просто когда-то что-то где-то повредило память. Твои действия?
>и так же быстро стираются через поиск с заменой
[code lang="cpp"]
class Lass
{
public:
\tstatic void getOut ()
\t{
\t\twalkInPark ();
\t\teatInCafe ();
\t\ttakeHerHome ();
\t\tstayTheNight ();
\t}
};
//...
struct ass
{
\tstatic void getOut ()
\t{
\t\toutput << makeShit ();
\t}
};
//...
//Делаем поиск с заменой " L" на " "
//Легким движением руки...
Lass::getOut ();
//превращается в...
ass::getOut ();
//Вы восхитительны, сегодня вместо секса с тян вы хорошенько просретесь
[/code]
>и так же быстро стираются через поиск с заменой
[code lang="cpp"]
class Lass
{
public:
\tstatic void getOut ()
\t{
\t\twalkInPark ();
\t\teatInCafe ();
\t\ttakeHerHome ();
\t\tstayTheNight ();
\t}
};
//...
struct ass
{
\tstatic void getOut ()
\t{
\t\toutput << makeShit ();
\t}
};
//...
//Делаем поиск с заменой " L" на " "
//Легким движением руки...
Lass::getOut ();
//превращается в...
ass::getOut ();
//Вы восхитительны, сегодня вместо секса с тян вы хорошенько просретесь
[/code]
В 14-19 обычно примерно так и рассуждают. Потому что мозгов мало, а гормонов много.
Разница заключается в том, что принты дают тебе избранную информацию, разворачивающуюся во времени (я могу хоть backtrace каждую итерацию печатать, нашел чем выпендриваться), а отладчик - много информации о состоянии в конкретный момент времени. Первое полезнее намного чаще. И чем сложнее твой код, тем более бесполезен отладчик, потому что ставить условные брейкпоинты в коде, обрабатывающем деревья - это то еще дерьмо.
"да еще и на макросах вместо виртуальных методов сериализации объектов." - ты идиот? prettyprint.cpp мной упомянутое это что по-твоему? Макросы нужны, чтобы быстро печать набивать и так же быстро стирать перед коммитом. Потому что это отладка, а не печать логов.
Дядя не в курсе про регэкспы в своем редакторе. А еще дядя пользуется табами для индентации.
Про IntelliTrace не слыхал?
Дядя в курсе про регэкспы. Еще дядя в курсе, что любые текстовые замены без учета контекста опасны, и используют их обычно до первой многочасовой ебли с кодом из-за неправильно замененного символа по дефектному регэкспу где-то в глубинах кода. Что я слышу? Ах да, ты же всегда пишешь регэкспы без ошибок, мой маленький друг! Тогда смею заметить, что тебе не нужны отладочные печати и отладчик, можно сразу хуярить совершенный код и в продакшон.
>2015
>брейкпоинты
Мань, твои знания об отладчиках явно ограничиваются каким-нибудь махровым встроенным в C++ Builder. Сейчас в них просто нет смысла. Если упало, ты просто двумя кликами отматываешь состояние программы назад до ближайшей точки, в которой изменялись проблемные данные. Еще одним кликом запускаешь скрипт, который выведет нужные данные в удобочитаемом виде. Заметь, нужные данные, а не стотысячмильенов экземпляров того же класса, для которых тоже выполнится отладочная печать. При этом ты не срешь в репозиторий отладочным кодом, не тратишь время на чтение ненужной информации, не ебешься с поиском по тексту. Серьезно, тебе определенно стоит попробовать современные отладчики, а то ты говоришь как человек из 80-х.
>многочасовой ебли с кодом из-за неправильно замененного символа
Дядя не в курсе о git diff.
>Ах да, ты же всегда пишешь регэкспы без ошибок, мой маленький друг!
Дядя не в курсе о скриптах в его редакторе.
У тебя заменилось 1000 вхождений макроса L и одно вхождение Lass. Ты запускаешь diff, он показывает 1001 расхождение. Твои действия?
Двачую. А когда понадобится изменить визуальную ширину отступа, не придется копаться в настройках отображения табов целых десять секунд! Мы можем воспользоваться уже проверенным с отладочными печатями методом - заменить восемь пробелов на четыре по регэкспу.
Бля, чувак, я не хочу кликать и ХОДИТЬ ПО КОДУ. Мне проще кинуть взгляд на текст и увидеть, в каком месте данные начали расходиться с тем, что я ожидал увидеть. Причем я могу сделать это в коде, который редактируется через sshfs и запускается там же, через ssh, а сам при этом сидеть под пальмой с ноутом и дряннейшим gprs, попивая смузи. Ща ты мне будешь парить про УДАЛЕННУЮ ОТЛАДКУ и прочие охуенные радости IDE-бляди, ведь, йоба, 2015 год, в сперме столько веселых кнопочек напридумали.
>>542768
В репозитории отладочная печать вообще отсутствует (иначе это логгирование, которое делается по другим правилам). Поэтому diff мне даст только новый код. При удалении отладочной печати все будет видно. Это, в общем-то, универсальное правило - проверять каждую добавленную строчку перед коммитом.
Что касается поиска/замены, я тоже проверяю каждую строчку через y/n. Не беда вообще.
>в каком месте
У тебя есть 50 потоков, в каждом потоке обрабатывается кусок коллекции из миллиона объектов, для каждого объекта выводится отладочная печать. Ты видишь, что проблемные данные изменялись несколько раз, разными потоками, непонятно в каком порядке. Что дальше?
Алсо, удаленная отладка не оче удобна, но точно лучше, чем ЭТО.
Ну окей, и что ты будешь делать с отладчиком в коде с такой волшебной архитектурой?
>я тоже проверяю каждую строчку через y/n
Это охуенно на самом деле. Если у тебя почасовая оплата. Сидишь, попиваешь кофий, проверяешь тысячи однообразных строк. Сбиваешься ближе к концу. Откатываешься и начинаешь заново. О, а вот и рабочий день кончился.
Отладчик для каждого потока независимо и для всех вместе позволяет мотать состояние вперед и назад. По сути, отладка ничем не будет отличаться от однопоточной, потому что ты действительно рулишь самим состоянием, а не его маняпроекцией на текущий поток и текущие данные.
Ты бредишь. Строк вида "L <<" не может быть тысячи. Если их тысячи, значит я за этот день добавил тысячу мест, печатающую информацию, что есть тоже бред.
>писать меньше тысячи строк в день
>с учетом однообразных копипастов
Ох лол, ну ты продуктивный вообще.
Не, на самом деле не спорю, что так делать вполне реально. Но зачем есть капусту, когда есть картошка? Зачем накладывать ограничения на собственную производительность ритуалами копипаста и поиска с проверкой?
Ты что с отладочными печатями делаешь? Посмотрел, нашел логическую ошибку, поправил в коде. Тут то же самое, только без копипаста, проблем с потоками и многократных перезапусков.
Я смотрю ПРОЦЕСС не полагаясь на собственную кратковременную память или что бы то ни было еще. Мне машина печатает фильтрованное состояние в нужных мне местах.
Далее - зависит от, например, в проблемном месте ставится нужный там assert.
А ты смотришь ТОЧКУ и дрючишься с ней, ходя туда-сюда (STEP OVER STEP INTO STEP INTO STEP OUT), найдя, наконец, где ты забыл написать -1. Вот и разница. Причем ничего действительно сложного (типа компилятора) ты никогда не отлаживал, просто пишешь кривые мутабельные многопоточные программы.
И не прикидывайся, блин, "писать меньше тысячи строк в день" - если у тебя коммиты по тысяче строк, ты уже скорее всего делаешь что-то не так. Типичный багфикс обычно занимает пару строк, ты не в курсе об этом? Вместо реального программирования какие-то фантазии выдаешь.
Какие к чёртовой матери тысяча строк в день? Я пишу несколько строчек в день, а иногда я пишу отрицательное количество строчек в день, это по моим субъективным критериям показатель качества. Вот так вот сократишь дублирующийся код, или перепишешь кусок кода более кратко, и моча по штанине потекла.
мимо диванный погромист
Ну, ну, попизди мне тут. Компиляторы я у него не писал, лол свой говноязык не считается кококкокок. Вообще, хуле я тут тебя пытаюсь заставить в good practices? Не хочешь познать удобный инструмент и упростить/ускорить разработку при необходимости возвращаясь к отладочным печатям, которые никуда не денутся - и не надо, ешь говно дальше пожалуйста. За державу обидно только.
Алсо, тысяча строк это вполне такой средний десятичасовой рабочий день из 15-20 коммитов.
Так тикеты с багами без добавления функциональности разгребать обычно джунам поручают и всякому скаму.
Ты читать не умеешь. Важно не что ты писал, а что ты отлаживал. Отладчики очень плохо дружат с обработчиками разных деревьев, включая компиляторы и интерпретаторы. Настоящие компиляторы, а не твой курсач. А хорошо они дружат с линейной тривиальщиной. Которая и без них элементарно отлаживается бгг. Или AI к примеру. Без графика во времени отлаживать нечего.
Твои good practices для меня давно пройденный этап. Поэтому я и спрашивал сколько тебе лет. Это у тебя начало бомбить, мне-то похуй, хоть дрочи у баллмера во время отладки.
То есть или ты сеньер и никогда не отлаживаешь свой код, или мешаешь коммиты с отладкой и фичами. Если второе, открой для себя rebase и squash в нем, если первое - слезь с дивана.
>плохо дружат
Если тебе не сложно, приведи конкретный пример, когда отладка AST отладчиком чем-то отличается от общего случая. Только, пожалуйста, без отсылок к говну мамонта, а для современного отладчика.
>бомбить
Да б-же упаси. Я хочу разобраться, потому что ты прячешься за туманными фразами.
Кагбэ это стандартная организация рабочего процесса по крайней мере, везде, где я видел. Есть трекер задач, по тикетам из него коммитят только добавление функциональности и срочные критичные баги. По умолчанию подразумевается, что все идущее в коммит уже проходит тесты. Если ты написал функциональность, а потом оказывается, что таки проебался - ты разруливаешь это в своей ветке, других не ебет вообще, сеньор ты или говна кусок - без разницы. Обычно коммитов с собственными багфиксами небольшое число по сравнению с коммитами по существу, если только ты не совсем криворукое хуйло, или тесты ленишься писать. Для некритичных багов, которые нашли тестировщики, существует отдельный трекер, на который сажают джунов и провинившихся.
При обходе дерева портятся данные и где-то в другом месте программа (тест) вылетает. причем пусть это не куча портится, а что-то менее тривиальное. В линейном коде ты можешь поставить бряк повыше и посмотреть там данные. Уже это гемор, но хуй с ним. Но при обработке дерева у тебя нет "повыше". Одна и та же функция может вызываться много раз. Придется ебаться с условными брейкпоинтами, ставить их на адреса и т. д. Вот прикинь баг у тебя в функции на 30 уровне вложенности причем там 5 функций и все друг друга вызывают, и проявляется он только так.
С печатью ты просто печатаешь в консоль то, за чем ты следишь, и стектрейс. Далее бинарным поиском глазами по портянке находишь лажу. Теперь в принципе можно поставить условный бряк и посмотреть внимательнее. Но зачастую проще уточнить печатаемое. Так или иначе, локализуешь баг.
Пишешь фичу. Написал - коммит. Запустил тесты. Пофиксил. Коммит. Еще раз запустил. Пофиксил. Коммит. Далее в конце дня клонируешь ветку, делаешь squash всех коммитов в один и push, чтобы коллеги не наблюдали твои мучения.
Ты предлагаешь так: написал фичу. Прогнал тесты. Половина проходит. Дописал патчи (без коммита). Еще половина проходит, зато первая половина отвалилась. Тут бы хорошо сделать diff но откатиться ты можешь только к состоянию без фичи... Привет, начинаешь вспоминать, а что ты вообще делал. Ты ж не джун, лол.
Поэтому я могу засрать отладочной печатью хоть все исходники и, найдя проблему, сделать stash. Ведь чистый код зафиксирован. А ты, ты не джун, кек.
Так не, ты опять мыслишь категориями брейкпоинтов, с которыми идет работа только с кодом без учета состояния. Я тебе уже десять сообщений подряд талдычу, что это прошлый век, и сейчас отладчики могут работать по данным, с учетом состояния. В твоем случае отладка выглядит тривиально:
1. Падение. Отображается нераскрученный стек.
2. Ты смотришь его вершину и видишь конкретный объект, в котором порченные данные. Надо узнать, кто это сделал.
3. Ты выбираешь этот объект и "отматываешь время" назад до момента, когда он в последний раз кем-то менялся.
4. Если изменение было легальное, отматываешь еще.
5. Находишь нелегальное изменение, причем у тебя есть не только проекция состояния в этот момент на отладочные печати, но и полное состояние программы. Как будто данные испортились вот прямо только что, а до падения еще далеко. Это позволяет делать интересные вещи, например, поправить данные не полностью, или как минимум исправить их на корректные вручную, чтобы без ебли с кодом быстро проверить, действительно ли баг только в этом месте.
Для аналогичного с отладочными печатями тебе придется, во-первых, отлаживать многократными запусками, потому что в пределах одного запуска ты ничего не можешь поменять, а только читать вывод. Это неудобно, когда у тебя специфические или долго генерируемые входные данные, если еще и баг плавающий, то вообще пиздец. Во-вторых, когда тебе кажется, что ты нашел баг, у тебя нет быстрого способа проверить, только ли в этом куске кода дело. Нужно править код, перекомпилировать а это иногда довольно долго, потом может оказаться, что рядом был еще один баг, ну ты понел. В третьих, отладочные печати по количеству ложных срабатываний примерно как брейкпоинты. Либо они печатают каждый раз при передаче управления и точно так же как брейкпоинты не зависят от состояния, либо тебе придется добавлять условия на рантайм в них, и ты уйдешь от лаконичных макросов из одной строчки.
Так то локальные коммиты, там можно содомию устраивать, понятное дело. Проблема в том, что если делать push вечером, то придется больше мерджить, поэтому приходится соблюдать баланс.
У тебя гемор лежит между п. 4 и 5. Потому что нелетальное изменение может быть и за 1000 таких итераций. И ты рассматриваешь простую ситуацию, при которой объект тебе известен (и это не object.vector[5].maly_yoba.x). Но в таком случае и отладочная печать тривиальна. Ты просто печатаешь многокилобайтный лог, дальше - бинарный поиск глазами.
Самое больше преимущество тут в том, что глаза видят больше, чем помещается в кратковременную память. Можно хоть мегабайты просматривать в поисках аномалий. И ты при этом расслаблен, потому что память свободна. Ты думаешь в рамках процесса, а не точки на нем.
>Для аналогичного с отладочными печатями тебе придется, во-первых, отлаживать многократными запусками, потому что в пределах одного запуска ты ничего не можешь поменять, а только читать вывод.
Это удобно, потому что тебе не нужно помнить о том, что ты делал, что менял, что смотрел (такс, тут ошибка, делаем 5 ходов сюда, 5 ходов сюда, меняем 1 на 2 - пофиксили).
>Это неудобно, когда у тебя специфические или долго генерируемые входные данные, если еще и баг плавающий, то вообще пиздец.
А это второй момент. Отладчик развращает и заставляет писать хуево поддерживаемый код. В том плане, что в твоем коде должны быть отделены "долго генерируемые входные данные", например, они должны уметь дампиться и читаться из дампа. С отладчиком ты можешь на это долгое время плевать, пока это кровь из носа не понадобится, а без отладчика ты будешь заранее думать, как добиться такой модульности. Почему в никсовом мире так любят писать скриптовые обертки вообще ко всему? А вот поэтому. Нахуя мне отладчик, если у меня есть питоний repl, а крестовые функции довольно изолированы среди питоньего клея? Еще момент в том, что отвязываешься от IDE и начинаешь проще относиться к смеси языков, кодогенерации и прочему.
В любом случае это холивар. Я допускаю, что человеку, отлаживающему гуй, например, отладчик удобнее. Но какого хуя меня муками ада пугать? Я пуганый, у меня были моменты, когда заказчику нужен был MSVS и я сидел в винде в этой IDE. Но удовольствия от клац-клац никакого нету.
>>542874
На ВМК были нужны математики с диофантовыми уравнениями, умеющие списывать сочинения, или олимпиадники. Тупой я для ВМК, сдал только физику на Ломоносове, нарисовав принцип Гюйгенса, а к летним экзаменам меня от тамошних абитуриентов с нулевым знанием программирования, "шуриков" и прочего говна меня уже тошнило.
У тебя гемор лежит между п. 4 и 5. Потому что нелетальное изменение может быть и за 1000 таких итераций. И ты рассматриваешь простую ситуацию, при которой объект тебе известен (и это не object.vector[5].maly_yoba.x). Но в таком случае и отладочная печать тривиальна. Ты просто печатаешь многокилобайтный лог, дальше - бинарный поиск глазами.
Самое больше преимущество тут в том, что глаза видят больше, чем помещается в кратковременную память. Можно хоть мегабайты просматривать в поисках аномалий. И ты при этом расслаблен, потому что память свободна. Ты думаешь в рамках процесса, а не точки на нем.
>Для аналогичного с отладочными печатями тебе придется, во-первых, отлаживать многократными запусками, потому что в пределах одного запуска ты ничего не можешь поменять, а только читать вывод.
Это удобно, потому что тебе не нужно помнить о том, что ты делал, что менял, что смотрел (такс, тут ошибка, делаем 5 ходов сюда, 5 ходов сюда, меняем 1 на 2 - пофиксили).
>Это неудобно, когда у тебя специфические или долго генерируемые входные данные, если еще и баг плавающий, то вообще пиздец.
А это второй момент. Отладчик развращает и заставляет писать хуево поддерживаемый код. В том плане, что в твоем коде должны быть отделены "долго генерируемые входные данные", например, они должны уметь дампиться и читаться из дампа. С отладчиком ты можешь на это долгое время плевать, пока это кровь из носа не понадобится, а без отладчика ты будешь заранее думать, как добиться такой модульности. Почему в никсовом мире так любят писать скриптовые обертки вообще ко всему? А вот поэтому. Нахуя мне отладчик, если у меня есть питоний repl, а крестовые функции довольно изолированы среди питоньего клея? Еще момент в том, что отвязываешься от IDE и начинаешь проще относиться к смеси языков, кодогенерации и прочему.
В любом случае это холивар. Я допускаю, что человеку, отлаживающему гуй, например, отладчик удобнее. Но какого хуя меня муками ада пугать? Я пуганый, у меня были моменты, когда заказчику нужен был MSVS и я сидел в винде в этой IDE. Но удовольствия от клац-клац никакого нету.
>>542874
На ВМК были нужны математики с диофантовыми уравнениями, умеющие списывать сочинения, или олимпиадники. Тупой я для ВМК, сдал только физику на Ломоносове, нарисовав принцип Гюйгенса, а к летним экзаменам меня от тамошних абитуриентов с нулевым знанием программирования, "шуриков" и прочего говна меня уже тошнило.
Думаю, нет. Либо не понимаю, что это значит, и в каком случае это может быть использовано.
Мне нужен небольшой класс, который используется только в данной функции.
Уточни что ты имеешь ввиду под "определить шаблонный класс".
#include <sstream>
int main()
{
double d;
std::string s("0.735");
std::istringstream is(s);
std::cout << d << '\n' << is.str() << '\n' << is.str().empty() << '\n' << is.eof() << '\n';
is >> d;
return 0;
}
Почему is.str().empty() == false когда мы считали (i)stringstream в double? При этом ведь is.eof() == true
P.S. Быстро скомпилировать можно здесь:
http://www.tutorialspoint.com/compile_cpp11_online.php
Oops, накололся. Держите исправленную версию:
https://ideone.com/guzhGP
А вопрос всё тот же. Почему is.str().empty() == false после считывания (i)stringstream в double? При этом ведь is.eof() == true
Преврати функцию в struct с перегруженным operator() и вкладывай что хочешь.
И хотелось бы услышать ваше мнение об этой библиотеке или стандарте, я в душе не ебу что это
уроки чего? берешь документацию и ебашишь что просят
https://ideone.com/guzhGP
std::stringstream в своём конструкторе имеет копию строки, именно копию аргумента, а не указатель на нулевой элемент аргумента. Стало быть, раз уж мы успешно опустошаем строковый поток, надо бы и его строку подопрокинуть? Из каких соображений этого не происходит?
1) недостаток дизайна языка (не продумали, забыли, забили);
2) в целях скорости (вручную сотрёшь, если надо);
3) чтобы можно как-то повторно использовать .str() (ЗАЧЕМ???)
В чем вопрос? Что значить подопрокинуть строку?
>гемор лежит
Ну вообще, это вопрос удобства, конечно. Если тебе настолько удобнее парсить глазами вывод консольки, то почему бы и нет? Правда мне кажется, что нелюбовь к отладчикам у тебя таки от неосиляторства, у меня у самого так было, лол.
>x развращает
Это можно высечь в граните и поставить под любой мало мальски удобной фичей.
>отделены "долго генерируемые входные данные"
Разумеется. Но вот бывают ситуации, когда это проблематично. Например, юнит-тесты проходят, а при обращении к реальной БД падает один раз из тысячи. Если у тебя там не исключение бросается, а access violation, например кококок делай проверки скорость не важна, то ты заебешься прикручивать обработчик, который будет делать дамп. А когда прикрутишь, это не будет "хорошо поддерживаемым кодом". А будет платформозависимым говном.
Потому что итерация по один раз загруженной в поток строке дешевле, чем pop_back. Логика здесь как и везде в крестах простая - тебе предоставлен наиболее общий случай из наиболее быстрых. Вдруг ты захочешь сделать сброс и вернуться в начало строки? А может, захочешь ее таки стереть? При такой реализации и то и другое делается быстро, а в твоем варианте за тебя решают, что строка больше не нужна.
>копию
Неправда. Там два перегруженных конструктора - с const & и с && и еще дефолтный. Так что на основе временного объекта оно будет конструироваться почти бесплатно.
>Логика здесь как и везде в крестах простая - тебе предоставлен наиболее общий случай из наиболее быстрых.
Да, логично. Просто для ньюфага было неочевидно, спасибо.
>>543316
>Там два перегруженных конструктора - с const & и с && и еще дефолтный.
Возможно, я не правильно понял тебя, но как тогда менять буфер, чтобы переиспользовать объект stringstream?
http://stackoverflow.com/questions/9507008/passing-by-reference-to-a-constructor
>However don't forget that once a reference has been assigned it can not be changed so if assignment requires a change to str then it will have to be a pointer instead.
>Так что на основе временного объекта оно будет конструироваться почти бесплатно.
И что ты подразумеваешь под временным объектом? Можно пример.
http://ideone.com/89Jim9
Что я хочу сделать? Я хочу создать const std::vector<unsigned int>& -- т.е. при помощи функции создать объект по ссылке, БЕЗ КОПИРОВАНИЯ. Казалось бы UB, но чукча умный, чукча объявил переменную статиком и сопроводил это комментом о состоянии своего психического здоровья.
Я всё правильно сделал или нет? Я знаю, есть способ через void и второй аргумент зафигачить, но это неспортивно. Мне интересно, происходит ли в main() копирование или нет:
std::vector<unsigned int> classification{ string_classification(line) };
Нет. C++11 издание книжки Страуструпа для ньюфагов, 11 глава.
5. Write a program that reads strings and for each string outputs the character classification of each character, as defined by the character classification functions presented in §11.6. Note that a character can have several classifications (e.g., x is both a letter and an alphanumeric).
Не происходит. Ты посути глобльную переменную используешь. Твоя функция будет возвращать всегда один и тотже объект. И если ты его изменишь в одном месте, все остальные тоже изменятся. Если хочешь делать эффективно читай про мув семантику, std::move и т.п. Но если ты новичек пока лучше туда не лезть, и вообще по возможности ссылки не использовать. Ну а потом наоборот, не пердолится с указателями, лол. Ссылки достаточно сложная концепция (в том виде в котором она в плюсах) еще и в других языках вроде аналога нет, знать и использовать нужно обязательно, но новичку лучше немного в языке освоится в общем, а потом уже погружаться.
>как тогда менять
Через метод str ().
>что ты подразумеваешь под временным объектом
rvalue-объект, для которого вызовется конструктор с rvalue-параметром. Например, basic_istringstream { string {"Tvoya mamka"} };
Здесь сконструированный на основе "Tvoya mamka" безымянный string будет rvalue-объектом. Конструктор знает, что его можно испортить, и поэтому сделает поверхностное копирование вместо глубокого. Перенесет указатель на данные в свою строку и все. Выполняется гораздо быстрее.
А я ко всем, кто его юзал обращусь. Как в сравнении со студией вообще? Правда, что тормозное говно без задач? Стоит ставить и пробовать?
Эээм. Так символы все равно копируются же при вызове самой верхней функции. Что ты хочешь сделать вообще, я не понял? Как ссылка на вектор вместо вектора тебе поможет не копировать что-либо, если в main ты все равно новый вектор создаешь, а для аргументов функций и конструкторов тоже, да выполняется std::decay, после которого ссылка трактуется как сам объект? Ты там совсем пизданулся штоле, лол?
[code]int a = new int, b = new int;
delete a, b;[/code]
Сработает ли delete для b? Нигде не нашёл такой инфы. Просто в коде много массивов и все они удаляются в конце, поэтому получается несколько строк с этим delete. Хотелось бы сократить.
>Так символы все равно копируются же при вызове самой верхней функции.
Одним байтом я готов пожертвовать на копирование, но объекты больше четырёх байт пускай по ссылочке отрабатывают.
Ну ты же сам прекрасно понимаешь, что работать со стандартными типами быстрее с копированием.
>Как ссылка на вектор вместо вектора тебе поможет не копировать что-либо, если в main ты все равно новый вектор создаешь
И он будет один, а не два (я это и уточнял).
>>543491
Спасибо. А вообще то, что я сделал, это как, общепринятый паттерн для тяжёлых объектов -- создать конст референс функцию, внутри которой возвращается статическая переменная, или нет?
Просто нигде не встречал такого.
Да, там опечатка и должны быть звёздочки.
Немного поиграл с массивами и обнаружил, что массив b не удалится.
[code]int a = new int[Size], b = new int[Size];
delete[] a, b;[/code]
В данном случае массив b останется висеть в памяти.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/3d6fa578-6008-474e-9f3d-369a33d5d995/c-delete-operator-with-multiple-arrays?forum=vclanguage
Здесь пишут, что в стандарте delete принимает только один параметр. Получается, когда компилятор видит конструкцию типа: delete[] a, b; — он воспринимает это как два выражения, разделённые запятой, поэтому он сначала выполняет delete для a, а потом просто b.
[code]delete[] a, b;
//эквивалентно
delete[] a;
b;[/code]
Можно даже сделать, чтобы удалялся именно b, если написать так:
[code]delete (a, b);[/code]
Я всё правильно понимаю?
А, да, показалось, что там [], а не (). Понял.
//эквивалентно
delete[] a;
b;[/code]
Здесь удаляется массив a.
[code]delete[] (a, b);[/code]
Здесь удаляется массив b.
[code]delete[] a, delete[] b;[/code]
Здесь удаляется всё.
[code]delete[] a;
delete[] b;[/code]
Здесь тоже.
В принципе, я разобрался.
SFML.
Стандартизация уменьшает необходимость boost с каждым годом. Потерпи немного.
Кинули на пару месяцев на легаси проект, сразу вопрос:
http://ideone.com/I2NQpL
Почему хуйня на 20 и 21 строчках даёт одинаковый результат? Имя функции, если та передаётся аргументом, эквивалентно её адресу?
Имя функции и указатель на функцию всегда взаимозаменяемы. Можно использовать имя, когда требуется указатель, можно не дереференсить указатель на функцию для её вызова. Алсо, почему ты решил, что Си тред мертв?
http://ideone.com/0iMfwL
Ты тело лямбы забыл, должно быть что-то типа
std::function<void (std::vector<T>&, std::vector<T>&, bool)> merging = [&](std::vector<T> &lfirst, std::vector<T> &lsecond, bool lascending_order) {return;};
Спасибо
При вызове функции для аргументов вызвается std::decay. Он, в том числе, навешивает указатели на массивы и функции.
>Если тебе настолько удобнее парсить глазами вывод консольки, то почему бы и нет? Правда мне кажется, что нелюбовь к отладчикам у тебя таки от неосиляторства, у меня у самого так было, лол.
У меня нет нелюбви к отладчикам, это мне написали про "будешь гореть в аду". Мне отладчик просто нужен редко до статистической погрешности.
Парсить глазами - у меня есть вся гамма утилит для работы с текстом, от грепа до gnuplot.
>Это можно высечь в граните и поставить под любой мало мальски удобной фичей.
Ну да, динамической типизацией, например. Или wysiwyg html-редакторами.
Иногда за удобство требуется платить в будущем. И наоборот. Вот tex, например, для мелких документов неудобен, однако удобен для крупных. Отладчики - они как ворд. Те, кто отладчики не любят, они стремятся к модульной архитектуре, биндигам к скриптовым языкам, дампам состояния и т. п. Хорошей архитектуре отладчик нужен только в реально экстренных ситуациях.
>Если у тебя там не исключение бросается, а access violation, например кококок делай проверки скорость не важна, то ты заебешься прикручивать обработчик, который будет делать дамп.
Ты о #ifdef DEBUG не в курсе что ли? Тестовые сборки должны быть с проверками, и скорость не важна. И ты еще говоришь о неосиляторстве, почему я должен говорить о таких простых вещах сеньору-помидору?
Для access violation скорее нужен valgrind чем отладчик, кстати, и выцеплять их нужно до того, как все упало.
Э нет, ты еще про assert вспомни. Как только ты добавляешь логику выбора между debug и release, потенциально в них начинают происходить разные вещи. Потом получается код, который работает в debug версии, а в release не работает, или наоборот. Вот буквально джве недели назад в очередной раз столкнулся. Один мудила прикрутил к тестовой сборке старую версию vld, которая не только ловила утечки, но еще местами прощала ошибку я так и не догнал до конца, что там было, но вроде что-то в духе delete вместо delete [], которая в релизной версии вызывала крах. Все, пиздарики, при переходе на релизную версию все крашится. Искали это говно почти неделю, связать крах с прикрученным в самом начале vld очень сложно. И да, без отладчика вообще бы хуй нашли, потому что в библиотеки ты отладочные печати не повставляешь.
И это если забыть про то, что код, в котором на каждом шагу #ifdef, просто неприятно читать.
>Э нет, ты еще про assert вспомни
Я про assert и говорю. Ты написал "кококок делай проверки скорость не важна", спизданул хуйню какую-то. Assert'ы иногда можно выпилить из release, да и то не часто.
>старую версию vld, которая не только ловила утечки, но еще местами прощала ошибку
Вот уж спермопроблема-то. Вместо внешней утилиты valgrind какая-то хуита, которая прощает ошибки.
>я так и не догнал до конца, что там было, но вроде что-то в духе delete вместо delete []
Ручной delete я несколько лет не писал. delete[] - никогда в жизни. Ну, плюс-минус. Голые указатели в 2015? Говноконтора какая-то.
>иногда можно выпилить из release
Так assert автоматически проверяет DEBUG и ничего не делает в релизной, хуле его выпиливать-то? И в любом случае не решается проблема же.
>какая-то хуита, которая прощает ошибки
Так про то и речь же. В идеальном мире ты все пишешь сам с нуля или используешь железобетонно проверенные библиотеки, в которых нет ошибок. А в реальности часто то, что ты подсунешь, например, вместо стандартных new и delete, писал либо ты сам, либо другой хуй из твоей же конторы, либо Вася с гитхаба, и поэтому у тебя получается, что не идеально проверенный код отличается в тестовой и релизной сборках, а вполне обыкновенный. И цена ошибки тут гораздо выше, потому что обнаружится это в последний момент.
>Голые указатели в 2015
ВНЕЗАПНО под капотом у smart pointers голые указатели. Говорю же, это самописные аллокаторы были тому що нужна была нестандартная стратегия выделения памяти из соображений байтоебства. Прямые запросы, кэширование, все дела.
>Так assert автоматически проверяет DEBUG и ничего не делает в релизной, хуле его выпиливать-то? И в любом случае не решается проблема же.
Проблема решается в том, что ты пытаешься повторить баг в дебажной версии и у тебя вместо сегфолта вылезает ассерт. Или же ты видишь в каком месте сегфолт и видишь парой строчек выше ассерт, и уже знаешь, куда копать. Ситуация - типичная. Ситуаций, когда баг проявляется только в релизе, в разы меньше. При этом даже если ты отдаешь заказчику релизную версию без ассертов ради 5% прироста производительности, тестерам-то почему не дать релиз, но с ассертами?
В общем, не писать проверки "из соображений производительности" - это бред. Их нужно писать всегда, а потом с профайлером в руках поотключать те, которые жрут больше 5% производительности. То есть - никакие не отключать бгг.
>А в реальности
А в реальности ты знаешь о неидеальности твоих средств и тебе в голову не придет реализовывать leak detector через include <йоба-хеадер перекрывающий стандартные аллокаторы>. И ты мне еще что-то говоришь про 2015 год.
Этим должна заниматься виртуальная машина, так же, как и профилировкой. Она вполне может заменить вызовы libc на что-то еще. И у тебя и твоего Васи в таком случае будут просто разные версии valgrind, у тебя будет ругаться, у него нет, ну бывает.
И даже если от этого никуда не деться, как можно это запихнуть чисто в DEBUG сборку? А я знаю как - мышкой крайне неудобно настраивать сборку под все случае жизни, поэтому у вас только DEBUG (со всем говном - ассертами, без оптимизации и т. п.) и RELEASE (без всего). Т.е. вещей типа O0+ASSERTS+PROFILE или O2+ASSERTS у вас нету, потому что cmake вы пользоваться не умеете и написать cmake .. -DMY_YOBA_ASSERTS не можете, это же в консоль пердолиться. А неосилятор при этом - я.
>ВНЕЗАПНО под капотом у smart pointers голые указатели.
Зачем тебе лезть под капот? Ты придумал ПАТЧ? Синдром NIH как есть. На современных крестах можно написать десятки тысяч строк без new и delete. И особенно - без new[], для которого есть vector.
А так я, кажется, понял, в чем секрет такой производительности. Писать по 1000 строчек в день велосипедов - очередной аллокатор, очередной умный указатель, очередной хэш-мап, и называть это разработкой на С++.
>Так assert автоматически проверяет DEBUG и ничего не делает в релизной, хуле его выпиливать-то? И в любом случае не решается проблема же.
Проблема решается в том, что ты пытаешься повторить баг в дебажной версии и у тебя вместо сегфолта вылезает ассерт. Или же ты видишь в каком месте сегфолт и видишь парой строчек выше ассерт, и уже знаешь, куда копать. Ситуация - типичная. Ситуаций, когда баг проявляется только в релизе, в разы меньше. При этом даже если ты отдаешь заказчику релизную версию без ассертов ради 5% прироста производительности, тестерам-то почему не дать релиз, но с ассертами?
В общем, не писать проверки "из соображений производительности" - это бред. Их нужно писать всегда, а потом с профайлером в руках поотключать те, которые жрут больше 5% производительности. То есть - никакие не отключать бгг.
>А в реальности
А в реальности ты знаешь о неидеальности твоих средств и тебе в голову не придет реализовывать leak detector через include <йоба-хеадер перекрывающий стандартные аллокаторы>. И ты мне еще что-то говоришь про 2015 год.
Этим должна заниматься виртуальная машина, так же, как и профилировкой. Она вполне может заменить вызовы libc на что-то еще. И у тебя и твоего Васи в таком случае будут просто разные версии valgrind, у тебя будет ругаться, у него нет, ну бывает.
И даже если от этого никуда не деться, как можно это запихнуть чисто в DEBUG сборку? А я знаю как - мышкой крайне неудобно настраивать сборку под все случае жизни, поэтому у вас только DEBUG (со всем говном - ассертами, без оптимизации и т. п.) и RELEASE (без всего). Т.е. вещей типа O0+ASSERTS+PROFILE или O2+ASSERTS у вас нету, потому что cmake вы пользоваться не умеете и написать cmake .. -DMY_YOBA_ASSERTS не можете, это же в консоль пердолиться. А неосилятор при этом - я.
>ВНЕЗАПНО под капотом у smart pointers голые указатели.
Зачем тебе лезть под капот? Ты придумал ПАТЧ? Синдром NIH как есть. На современных крестах можно написать десятки тысяч строк без new и delete. И особенно - без new[], для которого есть vector.
А так я, кажется, понял, в чем секрет такой производительности. Писать по 1000 строчек в день велосипедов - очередной аллокатор, очередной умный указатель, очередной хэш-мап, и называть это разработкой на С++.
>Зачем тебе лезть под капот?
Потому что я могу. Потому что стандартные версии рассчитаны на стандартное применение. В конкретном случае было всего три или четыре сценария выделения памяти, но нестандартных, использование самописных аллокаторов ускорило работу в полтора раза. Собственно, они и писались после того, когда выяснилось, что со стандартными медленно пашет.
Хороший погромист отличается умением думать. Умение думать включает в себя не только отказ от велосипедов там, где они не нужны, но и отказ от стандартных средств, когда их недостаточно. Такие дела.
>в разы меньше
Редко, да метко.
>поотключать
В самом начале проверки есть везде, причем сделанные не через ассерты, а удобно, с исключениями. Потом оказывается, что, допустим, есть 10% кода, в котором производительность критична. Оттуда убираются исключения и вставляются ассерты. С этим проблем нет. Проблема есть, когда ты вместо ассерта пишешь #ifdef и хуяришь нетривиальный код, различный в разных версиях. Мы же с тобой говорили об обработчике-создателе дампа. Ну вот, ты пишешь что-то подобное, а потом оказывается, что в одной версии оказался корректный код, а в другой некорректный, и начинается ебля.
>в голову не придет реализовывать leak detector через include
Этот leak detector есть надстройка над вендовым API для контроля аллокаций. Уж извини, под каждой системой свои методы решения задач, valgrind'а не завезли.
Про аллокаторы было с утечками вообще никак не связано, это чисто вопрос быстродействия.
>у вас нету
Есть, отчего же? Не из лесу же, под cmake все и делается. Сборок пять или шесть всего. Про неудобность настройки не понял тебя, настроить можно что угодно, но в итоге-то нужно протестировать единственную релизную версию, с оптимизациями и без говна. Если ты делаешь #ifdef'ы, то придется их убирать хотя бы из этой единственной тру релизной версии, и тогда все, что ты ИНТЕЛЛЕКТУАЛЬНО ТЕСТИРОВАЛ будет уже не совсем тем кодом, который идет в продакшен. В продакшене появляются баги, которых нет ни в одной из других сборок, в тестовой, "совсем тестовой", "полурелизной", "почти релизной", ну ты понел. А в релизной версии нет инструментов для ловли бага, потому что говно удалили, а отладочная информация не включается. Ты отдаешь релиз тестерам, они говорят "вот тут примерно хуйня какая-то". И приходится ебаться вслепую, потому что кое-что наставил блядских compile-time условий.
>Зачем тебе лезть под капот?
Потому что я могу. Потому что стандартные версии рассчитаны на стандартное применение. В конкретном случае было всего три или четыре сценария выделения памяти, но нестандартных, использование самописных аллокаторов ускорило работу в полтора раза. Собственно, они и писались после того, когда выяснилось, что со стандартными медленно пашет.
Хороший погромист отличается умением думать. Умение думать включает в себя не только отказ от велосипедов там, где они не нужны, но и отказ от стандартных средств, когда их недостаточно. Такие дела.
>в разы меньше
Редко, да метко.
>поотключать
В самом начале проверки есть везде, причем сделанные не через ассерты, а удобно, с исключениями. Потом оказывается, что, допустим, есть 10% кода, в котором производительность критична. Оттуда убираются исключения и вставляются ассерты. С этим проблем нет. Проблема есть, когда ты вместо ассерта пишешь #ifdef и хуяришь нетривиальный код, различный в разных версиях. Мы же с тобой говорили об обработчике-создателе дампа. Ну вот, ты пишешь что-то подобное, а потом оказывается, что в одной версии оказался корректный код, а в другой некорректный, и начинается ебля.
>в голову не придет реализовывать leak detector через include
Этот leak detector есть надстройка над вендовым API для контроля аллокаций. Уж извини, под каждой системой свои методы решения задач, valgrind'а не завезли.
Про аллокаторы было с утечками вообще никак не связано, это чисто вопрос быстродействия.
>у вас нету
Есть, отчего же? Не из лесу же, под cmake все и делается. Сборок пять или шесть всего. Про неудобность настройки не понял тебя, настроить можно что угодно, но в итоге-то нужно протестировать единственную релизную версию, с оптимизациями и без говна. Если ты делаешь #ifdef'ы, то придется их убирать хотя бы из этой единственной тру релизной версии, и тогда все, что ты ИНТЕЛЛЕКТУАЛЬНО ТЕСТИРОВАЛ будет уже не совсем тем кодом, который идет в продакшен. В продакшене появляются баги, которых нет ни в одной из других сборок, в тестовой, "совсем тестовой", "полурелизной", "почти релизной", ну ты понел. А в релизной версии нет инструментов для ловли бага, потому что говно удалили, а отладочная информация не включается. Ты отдаешь релиз тестерам, они говорят "вот тут примерно хуйня какая-то". И приходится ебаться вслепую, потому что кое-что наставил блядских compile-time условий.
Ориджинал. Когда доходит до 400 постов, я начинаю беспокоиться, потом тяну до последнего, и уже перед самым бамплимитом собираю яйца в кулак, и, проклиная все на свете, выдавливаю из себя очередную порцию стихов. Да, я знаю, что я хуевый поэт, и вообще это калька с Данте.
Как мне считать текст из файла в массив символов char для последующих операций с ним?
Или, может быть, есть какие-нибудь еще варианты считывания текста и оперирования с ним?
//Сколько символов в файле
std::size_t mamka_size = 0FFFFFFh;
std::ifstream tvoya_mamka {"mamka.txt"};
std::istream_iterator it {tvoya_mamka};
//Размер массива не меньше размера файла
std::array <char, max_size> arr;
std::copy_n (it, mamka_size, std::begin (arr));
istream_iterator <char>, конечно же.
Не работает, браток.
Какие библиотеки нужны?
Подключены
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
#include <iterator>
Спасибо, няша!
Я подумал, что C, потому что массив символов char.
http://en.cppreference.com/w/cpp/io/basic_ifstream
Функцию сравнения нужно вынести в класс-компаратор, который будет шаблонным параметром.
Была if (yoba < yoba[i+1]) станет if(compare(yoba, yoba[i+1])), то есть сравнение ты выносишь в отдельную функцию. Точнее не функцию, а класс с перегруженным operator():
template<class T>struct Less { bool operator(T l, T r){return l < r; };
template<class T>struct Greater { bool operator(T l, T r){return l > r; };
И далее было void yoba_sort(массив), стало template<class Comparator = Less> void yoba_sort(массив) { Comparator comparator; ... }
Латиница ничего не меняет.
Здесь тоже нет реакции на Run.
А у тебя компилятор там есть? А ты точно компилишь c++, а не фортраном каким-нибудь? А ты конфиги не менял?
char *name = "слово";
Подскажите пожалуйста, где я могу об этом почитать. Ну или объясните в кратце об этом. До этого я думал, что звездочка юзается либо как знак умножение, либо как указатель. Я только начал учиться и знаю обо всем этом крайне мало
Это не разыменование, это объявление переменной name с типом "указатель на char".
Достаточно коротко, что бы я ничего не понял. А где почитать об этом - не в курсе?
Массив - непрерывный кусок памяти плюс константный указатель на начало массива.
const char name == char name[];
Когда ты пишешь char name = "abc", в память непрерывно записывается "abc", то есть три char значения. Дальше работаешь с этим всем как с массивом или с указателем (name == *(name + i)). Иди почитай про указатели ещё раз.
А-а-а, опять забыл, что звёздочки съедаются.
"Массив - непрерывный кусок памяти плюс константный указатель на начало массива.
const char 1name == char name[];
Когда ты пишешь char 1name = "abc", в память непрерывно записывается "abc", то есть три char значения. Дальше работаешь с этим всем как с массивом или с указателем (name[k] == *(name + k)). Иди почитай про указатели ещё раз.
Если файл нужно считать ПОЛНОСТЬЮ, то C++11 средствами ПРОТОТИПЫ решения будут среди следующих вариантов:
http://insanecoding.blogspot.ru/2011/11/how-to-read-in-file-in-c.html
Если ты совсем новичок, то самый понятный из всех приемлемых по скорости способов вот:
http://ideone.com/wJBJbt
не обращай внимания, что не компилируется, откуда ему файл data.txt найти-то
std::string govno{ "mocha" };
&govno[0] это то же самое, что и govno.data() ?
По ходу, нет: data() даёт копию данных, если я правильно понял, из-за дописывания '\0' к массиву чаров...
http://programmers.stackexchange.com/questions/218879/what-is-the-difference-between-string-c-str-and-string0
Не совсем так.
>>544759
По стандарту последовательное размещение в памяти гарантируется только для vector. Теоретически string может быть, например, оберткой над list, и каждый его символ физически не соседствует с предыдущим и следующим. Метод data () гарантирует, что вернет const char *, но просто ли берется указатель на первый символ, или все строится при вызове прямо на месте, не уточняется. Ирл бывают реализации строк, основанные на подсчете ссылок, это полезно, когда у тебя одна и та же подстрока встречается много раз. В этом случае строка реализуется как дерево указателей на подстроки, а при вызове data () который в этом случае весьма дорогой все они копируются в временный буфер, ан который и возвращается указатель. Поэтому для &govno[0] никаких гарантий дать нельзя, кроме того, что там будет первый символ строки. Использовать это как адрес всей строки некорректно.
Хотя нет, вот тут таки все поменялось с новым стандартом. До C++11 было так, как я сказал, а теперь добавили требование на непрерывное хранение. Кроме того, data () и c_str () обе возвращают строку с нулем на конце а раньше это требовалось только для c_str (). Таким образом, ноль в любом случае хранится после строки, и разницы с &govno[0] нет, за исключением одного. Когда строка пустая, &govno[0] вызовет access violation, а data () и c_str () вернут nullptr. Лучше использовать методы, в общем.
Лол, покурил стандарт, все еще веселее. Для всех трех data (), c_str () и &govno[0] поведение одинаково, даже для пустых строк они вернут указатель на строку из единственного нуля. Так что теперь можно использовать любой из способов, разницы никакой нет.
http://ideone.com/RXyHUL
Не менял. Что нужно менять и докачивать? А то еще несколько суток буду с попыткой начать, тщетно пытаться.
>Лол, покурил стандарт
Давай прямую выдержку в студию.
>Для всех трех data (), c_str () и &govno[0]
Для первых двух точно да. Но они же работают через копирование, дописывая '\0' в конце так?
Кроме того, &govno[0] дописывает или не дописывает '\0' в конце?
21.4.1/4 гарантирует, что все символы в [0, size ()), т.е. не считая терминального нуля, хранятся последовательно.
21.4.5/2 гарантирует, что govno[govno.size()] вернет указатель на какой-то \0, который не обязан находиться сразу после строки в памяти.
Но.
21.4.7/1 гарантирует, что data () и c_str () вернут p = &govno[0], но одновременно и гарантирует, что p + govno.size () == &govno[govno.size()], который указывает на \0, согласно 21.4.5/2.
Таким образом, единственная возможная реализация таки ставит \0 сразу после строки в памяти. Алсо, никакое копирование было бы невозможно и без этого пункта, потому что сложность всех этих методов гарантируется константная, а копирование требует линейной.
Короче, я правильно понял, что
govno.data() == govno.c_str() == &govno[0]
вообще всегда и во всём, включая govno.length() == 0 ?
Вообще не понимаю, как люди учили язык до C++11. Это же не язык был, а что-то ужасное.
Ты еще не видел того, что было до стандартизации. RTTI десять лет вводили по различным компиляторам.
Так, чувак. Если у тебя норм интернет, сходи и скачай Visual Studio Community 2015. Если у тебя говно инет, то я видел у тебя ещё и Code::Blocks. В этом случае ты идёшь вот сюда http://www.mingw.org/
Или сразу вот сюда http://sourceforge.net/projects/mingw-w64/
Качаешь оттуда вирусняк, распаковываешь, запускаешь. После того, как ты запустишь установщик, он предложит тебе выбрал файлы для скачивания. Качаешь файлы для C++ (не помню, что именно, сам справишься).
ВАЖНО! Либо скачивай сразу в папку, где у тебя лежит Code::Blocks, либо потом перемести скачанную папку MinGW в папку Code::Blocks.
Потом запускаешь (или перезапускаешь Code::Blocks), он должен выдать сообщение о том, что найден новый компилятор. Идёшь в настройки, ищешь строку вроде "Выбрать компилятор", выбираешь найденный и пробуешь опять...
В этот момент я пошёл и загуглил ебаное "eclipse c++", нашёл вот это. http://habrahabr.ru/post/241133/
Если эта статья тебе не поможет, допишу конец моего поста. И почему мне кажется, что нихуя мне не придётся дописывать?
>Потому что стандартные версии рассчитаны на стандартное применение.
У стандартных умных указателей аллокатор - один из шаблонных параметров. Я так и не понял, зачем лезть внутрь.
Изначальный вопрос был не в этом, а в том, зачем делать new[], тягающий malloc, там, где vector работает.
>Умение думать включает в себя не только отказ от велосипедов там, где они не нужны, но и отказ от стандартных средств, когда их недостаточно.
Помимо стандартных средств и велосипедов есть еще и сторонние средства типа boost::pool.
>Мы же с тобой говорили об обработчике-создателе дампа. Ну вот, ты пишешь что-то подобное, а потом оказывается, что в одной версии оказался корректный код, а в другой некорректный, и начинается ебля.
Это ты сам себе выдумал. Ты говорил о том, что "данные долго готовятся перед багом", на что я сказал, что в том месте, где они готовятся, нужно добавить save_data();exit();, запустить программу, далее и вместо долгого получения данных сделать load_data();. После отладки этот код стирается.
>Этот leak detector есть надстройка над вендовым API для контроля аллокаций. Уж извини, под каждой системой свои методы решения задач, valgrind'а не завезли.
Так это под твоей системой принято на каждый чих дебаггер вызывать и дрючиться.
>В продакшене появляются баги, которых нет ни в одной из других сборок, в тестовой, "совсем тестовой", "полурелизной", "почти релизной", ну ты понел.
В продакшене появляется баг, в дебажной не повторяется. Тогда ты смотришь полурелизную - нет бага, почти релизную - есть. Ага, смотришь, чем они отличаются и видишь vld
>Проблема есть, когда ты вместо ассерта пишешь #ifdef и хуяришь нетривиальный код, различный в разных версиях.
Бля. Вы все ещё спорите об отладке и дебагах? Позовёте когда закончите.
>Проблема есть, когда ты вместо ассерта пишешь #ifdef и хуяришь нетривиальный код, различный в разных версиях.
Это - моветон. Ты просто делаешь 2 уровня ассертов
#ifdef ASSERT_LEVEL == 0
#define assert1 пусто
#define assert2 пусто
#elseif ASSERT_LEVEL == 1
#define assert1 код ассерта
#define assert2 пусто
#else
#define assert1 код
#define assert2 код
#endif
И далее везде расставляешь стандартные assert'ы и там, где тебе надо, даешь им уровень.
>но в итоге-то нужно протестировать единственную релизную версию
Это называется "скупой платит дважды". Тестеру нужно дать все версии и пусть тестирует дольше, но локализует версию, в которой появляется баг.
У Алены недавно аватарка сменилась, что-то совсем постарела и погрустнела. Так что не рекомендую Америку, жизнь там тяжелая у крестоблядей.
Во-во-во, этому чаю за счёт комитета стандартизации. Нашли что обсудить. Скорость постинга околонулевая, не считая них, по ходу все в школу пошли в сентябре.
>один из шаблонных параметров
Во-первых, у умных указателей стандартных в шаблонных параметрах нет никакого аллокатора, только deleter. И нужен он обычно вообще не для управления памятью, а для освобождения ресурсов, которые нельзя просто взять и удалить. Во-вторых, аллокатор в любом случае должен уметь выдавать raw-pointer на свежевыделенную память, этого требует интерфейс. Память эту он берет у системы опять же при помощи raw-pointers, и хранит у себя дополнительный пул. Тебе придется пачкаться как минимум в двух точках - при получении памяти и при отдаче ее по требованию.
>делать new[], тягающий malloc, там, где vector работает
Это все инкапсулировано в аллокаторах, которые прикручены для нестандартной стратегии выделения памяти, в месте, где это критично по скорости. Я это уже говорил, по-моему.
>типа boost::pool
boost помогает, конечно же. Но в библиотеках тоже есть не все, и чем специфичнее задача, тем меньше шансов, что ты найдешь готовое решение, которое не придется допиливать. К тому же, boost весьма прожорлив, это ограничивает его применимость.
>данные долго готовятся перед багом
У нас же не 70-е с пакетной обработкой данных. Данные забираются маленькими порциями, изредко какая-то порция вызывает крах.
>на каждый чих дебаггер вызывать и дрючиться
Утечки дебаггером даже у нас не ловят. Это извращение какое-то было бы.
>Ага, смотришь, чем они отличаются и видишь vld
...vld и еще несколько прикрученных утилит. Не забывай, если для каждой комбинации утилит делать отдельную сборку, то получится k! сборок, и ты заебешься даже просто ждать, пока они скомпилируются и прогонятся, не говоря об отладке.
>>545170
Хоть горшком назови, только в печь не ставь.
>Это называется "скупой платит дважды". Тестеру нужно дать все версии и пусть тестирует дольше
Нет, ты не понял меня. Я не говорю, что тестировать нужно только ее. Имелось в виду, что конечная цель - работоспособная релизная версия, и если пляски с тестированием кучеи промежуточных сборок не решают проблему из-за различия в параметрах с релизной, то приходится делать как-то иначе.
Значицца так. Мне скучно, поэтому я роллирую, и если не выпадет что-то чересчур сложное реализую через шаблоны, на метауровне.
http://pastebin.com/zGqpsbXv
Просто рероллить в тематике это очень весело!
ах да не обращайте внимание на смесь английского и транслита, для себя писал. И r,p,s - это размещение, перестановка и сочетание соответственно. Еще я не уверен что оно будет нормально работать с факториалами больше 13.
>Во-первых, у умных указателей стандартных в шаблонных параметрах нет никакого аллокатора, только deleter.
Это параметр в allocate_shared, не суть вообще. Главное, о чем я говорил, что под капот им лезть не нужно, чтобы написать кастомный аллокатор.
>Во-вторых, аллокатор в любом случае должен уметь выдавать raw-pointer на свежевыделенную память, этого требует интерфейс.
Изначальный вопрос был о том, откуда взялся delete[], почему вместо него не было vector<yoba, my_yoba_allocator>. Ты написал,
>Но в библиотеках тоже есть не все, и чем специфичнее задача, тем меньше шансов, что ты найдешь готовое решение, которое не придется допиливать.
Хуй знает.
>Не забывай, если для каждой комбинации утилит делать отдельную сборку, то получится k! сборок, и ты заебешься даже просто ждать, пока они скомпилируются и прогонятся, не говоря об отладке.
Да у тебя же КОМБИНАТОРНЫЙ ВЗРЫВ. Для локализации бага достаточно log2(k) сборок, но проще сделать k сборок - т.е. постепенно прикручивать фичи. Когда тестер дает баг, программист пытается найти его в релизе, а далее постепенно откатывается к дебагу, потом (если баг еще в наличии) - по коммитам до последней работающей версии.
http://pastebin.com/pMhNDp30
>>545233
что не так с ним?
Если есть какие-то альтернативы взять у пользователя данные и что бы он не нажимал энтер, то я о них не знаю, я ток Лафоре 10 глав прочитал.Да и функция из conio.h используется только одна - _getch(); когда программа просит пользователя нажать любую кнопку что бы выйти.
Опять интерфейс макабы рулит.
>Во-вторых, аллокатор в любом случае должен уметь выдавать raw-pointer на свежевыделенную память, этого требует интерфейс.
Изначальный вопрос был о том, откуда взялся delete[], почему вместо него не было vector<yoba, my_yoba_allocator>. Ты написал "Говорю же, это самописные аллокаторы", но я так и не нашел, где это было написано до моего вопроса, слово "аллокатор" первый раз встречается в том посте.
А так в целом могу сказать, что нежелание пользоваться дебаггером приучает к системному подходу. Ты спокойно локализуешь баг вплоть до сборки и коммита, а дальше смотришь, а что, собственно, поменялось. Потом смотришь дампы того, что поменялось и, возможно, запускаешь дебаггер. А дебаггером - хуяк-хуяк, есть RELEASE есть DEBUG, две недели ебемся с vld.
Ну значит я хотел про это написать постом раньше, но забыл. Не серчай.
К главе "Виртуальные функции" я только сейчас перехожу, а про указатели на функции Лафоре в главе "указатели" ничего не говорил. Вот пройду виртуальные функции - модернезирую свою ПРОГРАММУ.
P.s. капча: Выберите все изображения, где есть указатели.
Я дочитал до функции факториала, в которой ты факториал вычисляешь с помощью int b; Ты знаешь, что int значение это крайне мало для такого огромного говна, как факториал, и твоя функция для 13! уже выдаст ошибку? Ситуацию можно улучшить с помощью использования unsigned вместе с long long, но это тоже мало. Короче, чувак, твоё говно - полное говно и дальше факториала я не читал.
и что мне делать с факториалом что бы было достаточно для 20 хотя бы? Я же просто не знаю еще.
>Choose s povtorami or not 1/2
>Type m and n cherez probel:
this is voshititelno
А разгадка одна - следует использовать свой класс, в котором число не ограничивается по размеру например, deque из битовых полей, а умножение перегружено Карацубой.
Ок, попозже займусь этим. А сейчас мне пора ехать. Спасибо за критику и советы, Аноны.
Нет! Писать самому.
Почему опять что-то не так? На Code::Blocks запускается Hello World, набираю свою программу, и запускается окно хеллоу ворлд, а потом и вообще нихрена. Блжат что за ебля с этими компиляторами, я не пойму.
Тебе дали ссылку на настройку eclips'a, а ты пошёл делать по недописанному мини-гайду по настройке Code::Blocks? Возьми сажи, братишка. Лично для тебя принёс.
GetPrivateProfileString я так понимаю для опущенцев, libconfig/libconfuse для пидоров, Program_options из состава boost только ради них ставить не стоит, а QSettings если уже сразу на QT пишешь ?
Про g_key_file из состава glib для поехавших гномоблядков даже не вспоминаю.
И где же здесь мое окно dos? И выводит не то что нужно а опять этот ссаный хеллоуворд.
(извиняюсь за дубляж)
Такая ситуация :
26 лет.
Программач - это моё профильное образование, но опыта работы в нём нет. Да , чисто мой косяк, хотя есть оправдание - в моём регионе реально негде работать по профилю. И поэтому года три работал и занимался совершенно другой хренью. Сейчас надоело. Вкатываюсь.
Решил потратить пару месяцев, чтобы подтянуться до среднего\базогового уровня (освежить память , знания и т.д) чтобы переехать куда-нибудь (например СПб : большой город, но не такой дорогой как МСК) и ходить на собеседования .
И я даже определился с языком - C++.
Но я сейчас дальше носа собственного не вижу.
Советоваться в плане направления движения не с кем, коннекта никакого нет.
На форумах удобно спрашивать, по конкретным вопросам, а не по абстрактным.
Самому себе задания придумывать не могу, по той же причине - просто сомневаюсь в актуальности (пока в планах добить Липпмана, потом СТЛ и что-нить по алгоритмам и оптимизации кода), но что делать дальше - не знаю.
Поэтому ищу ментора. Нянька не нужна - просто человек, который подскажет куда смотреть,
на что обращать внимание, что поделать, чтобы докатиться до уровня собеседований
..или как то так
(или может нужны дополнительные руки, благо времени свободного в избытке)
Допустим предварительно стоит Linux на виртуалке. Но там же делается это через некий vim, и как загрузить туда эти библиотеки или что это. Чеееерртт мне учить кресты нужно а я ебусь с этими программами вместо этого.
vim не обязательно. Хоть в блокноте код пиши. потом компилятор из консольки запускаешь.
Это глупость какая-то. Если ты вызываешь невиртуальный метод объекта tvoya_mamka, то ты уже знаешь его тип и размер, и можешь просто писать sizeof (tvoya_mamka). Если у тебя есть только указатель на базовый класс, то делаешь виртуальный метод из одной строчки, который возвращает этот sizeof. Но в любом случае sizeof вычисляются на этапе компиляции, поэтому код сгенерируется с жестко зашитым числом-размером, как будто ты написал return 4, например.
Читать книжки из шапки про "учимся не писать говнокод".
Научиться в git, какую-нибудь систему сборки, фреймвор для тестирования gtest.
Познать STL.
Познать boost.
Реализовывать простые идеи выше была картинка-рулетка, результаты выкладывать на гитхаб.
Только не в крестах. Это не пистон тебе, лол.
спасибо за ответ , бро.
скопирую твое сообщение в ориентиры
просто когда не с кем посоветоваться пыл пропадает и рабочий настрой. это как по глухому лесу идти : идёшь идёшь , а куда придёшь и придёешь ли вообще - хрен пойми.
Потому что этот string содержит внутри себя указатель на char* и больше ничего. Ты можешь поменять размер блока данных по этому указателю, но сам класс должен иметь один и тот же размер (сумма размеров его полей).
http://soliduscode.blogspot.ru/2012/04/creating-local-variables-in-assembly.html
http://wiki.osdev.org/Stack
Поэтому размеры классов известны на этапе компиляции - это позволяет создавать высокоэффективный код, при котором память на стеке выделяется простым вычитанием, а обращение к полям класса - прибавлением постоянного смещения поля к указателю на начало класса.
Размер выделенной памяти (capacity) + реальное число элеменов (size)
У вектора есть две величины, size и capacity. Size - это размер блока данных, capacity - сколько фактически памяти выделено. Vector просит у системы памяти больше, чем нужно, чтобы эффективно работал push_back. Поэтому 12 - это указатель на начало данных, размер фактических данных, максимальный размер до перевыделения памяти.
>Когда ты пишешь. string s; внутри функции
а если в глобальном пространстве имён или с модификатором static, то он где и какого размера выделяется?
В статически распределяемой памяти, которая выделяется во время запуска. Размер будет тот же. Со static ты фактически получаешь глобальную переменную, которую видно только из одной функции. Как в фортране. Основной минус в том, что рекурсия в таком случае невозможна, все "экземпляры" функции используют одну и ту же памяти, для рекурсии нужен стек.
Была вижуал студия, пытался фортран прикрутить, и безрезультатно. Ладно, пойду освобождать место и выкачивать заново студию.
понял и с вектором тоже вроде понял. всем спасибо
Нет, string хранит указатель на область памяти с символами, которая меняет свой размер.
string - массив char значений, заканчивающийся нулевым '\0' знаком, по которому и определяется размер строки. Поэтому на самом деле string занимает char* + char места, но через sizeof выдаёт только размер указателя.
>больше ничего.
А как же size и capacity? + строки до 16-ти символов хранят текстовые данные прямо в себе.
Ну если sizeof(string)==4, как иначе может быть? Size и capacity видимо вычисляются динамически проходом до \0. Может, конечно, там pimpl, но как-то странно это.
Это не pimpl же. Методы находятся в самом basic_string, а указатель смотрит на POD, в котором size, capacity, копия начала строки и еще один указатель на данные.
Какую книжечку на русском почитать чтобы понять твой вопрос? В лафоре такого нет.
То есть, ты не знаешь, возможно ли добиться того, что я хочу?
Странные у тебя представления об эстетике.
1) удалить последние n элементов вектора наиболее эффективно (pop_back() в цикле на n итераций не канает, давайте что-нибудь поумнее);
2) задачка со звёздочкой: удалить первые n элементов вектора
http://stackoverflow.com/questions/7351899/remove-first-n-elements-from-a-stdvector
std::vector<myvector::value_type>(myvector.begin()+N, myvector.end()).swap(myvector);
как это будет для данной задачи вообще -- так, что ли?
std::vector<v::std::string>(v.begin() + N, v.end()).swap(v);
1. v.resize(v.size() - n);
2. по твоей ссылке есть ответы тащемта, самый тривиальный - vector::erase
>наиболее эффективно
define "эффективно"
Можешь завести указатели на начало и конец вектора и работать относительно них. При удалении фактически ничего не удалять, а сдвигать указатели. Как припрет - чистить память.
Исследования показали, что строки слишком часто передаются по значению. Поэтому от старого подхода, когда все они лежат в самом объекте и получается 32 байта, отказались почти все производители стандартной библиотеки.
Конечно нет. У нее область видимости будет не неймспейс, а тело функции. Точно так же, как у обычных локальных переменных, к которым извне нет доступа. Неймспейс вообще никакой роли здесь не играет.
>define "эффективно"
Самый быстрый способ сдвинуть 0 элемент вектора на N-ный в том же самом объекте (ничего новое не создаётся, даже временное). При этом erase это самый медленный способ, очевидно.
А ещё я хотел спросить, правильно ли я понял синтаксис решения по ссылке:
std::vector<v::std::string>(v.begin() + n, v.end()).swap(v);
erase таки будет самым быстрым способом. В современных реализациях STL он проверяет тип элементов вектора на TriviallyCopyable. Если да, то он вызовет memmove, быстрее которого энивей ничего нет для любых данных. Если нет, он будет вызывать move-конструкторы и замедлится, но это и правильно, потому что объекты с нетривиальными конструкторами перемещения не должны перемещаться незаметно для себя, вдруг они свой адрес хранят или еще чего.
Приведенное решение как раз таки медленнее всех прочих, потому что в нем: Вызовется конструктор вектора, аллокатор для памяти на n элементов, конструкторы копирования n элементов, метод swap, деструкторы всех элементов старого вектора, деструктор самого старого вектора и деаллокатор всей его памяти. Хуйню написал, короче.
Да. Это задачки из книжечки.
помогите, не работает программа, подскажите как исправить чтобы заработала пожалуйста
http://pastebin.com/imCCkvc7
Не был у вас пару тысяч лет. Хотел бы добавить пару IDE.
Clion, хоть пока и сыровата, особенно со сложными шаблонами. А ещё и жрёт дохуя, но очень неплох для кроссплатформы, благодаря интегрированному cmake. И сама иде абсолютно одинаковая на 3х платформах, под ко-е я крестоблядствую. Mac, Linux, Win.
Второе, что хотел бы добавить QTCreator. Вполне неплохая ИДЕ и жрёт мало. Можно юзать тоже на 3х платформах. Хотя есть свои проблемы с шаблонами.
Третье. Пока самый лучший компиль для кроссплатформы на винде - MinGW w64. http://sourceforge.net/projects/mingw-w64/ . Как показывает практика, то код после него шикарно компилируются под линем обычным gcc Удивительно, да?. И с нек-ми проблемами под OS X Yosemite. Особенно это касается фитч 11 стандарта.
Но если целевая платформа винда, то студия вне конкуренции, благодаря куче тулз и хорошему дебаггеру. А ещё нормально юзать глубокое winapi нормально получится только со студии.
Если мак, то крайне не советую юзать XCode. Местами у него пиздящий дебаггер.
И четвёртое. Хотел бы добавить пару книг.
Ни для кого не секрет, что бустовые потоки почти полностью спизжены в стандарт.
Возможно пропихнут asio. Ну и кучу других фишек в последующих стандартах.
И в большинстве компаний знание буста немаловажное требование.
Так что вот - http://rghost.ru/8gdkXVy8l . Увы, но не помню откуда спиздил её.
Немного проектирования и архитектуры. На примерах, к-е вполне могут встретиться.
http://rghost.ru/6CPFv7GFg . Тоже не помню, прощу прощения.
И хотел ещё норм книгу по проектированию дать. Но чот проебал её. Позже найду, надеюсь.
Помимо встроенных.
valgrind, callgrind - под линь и мак. Позволят отследить как утечки, так и найти "бутылочное горлышко" в вашей программе, к-е замедляет её работу.
http://valgrind.org/
Под винду пробовал только Dr. Memory, если не ошибаюсь, что у него нет коллстака всего кода, но отлично подходит для нахождения потенциальных утечек памяти.
http://www.drmemory.org/
Бесплатный статический анализатор кода - cppcheck.
Не самая лучшая штука, но тем не менее ошибки уровня
void f(cons std::string str){}
Сообщит. Особенно актуально, когда это ваш тип данных. Копирования которого весьма накладное.
Ну и дополнительно - кодить с -pedantic под gcc. Для студии выставляйте /W3.
Тоже позволит писать хороший код.
Поясните мне за классы и объекты. Пожалуйста.
Вот создаю я класс ЧЕЛОВЕК и в нем же (функцию или процедуру?) при обращении к которой, можно будет получить всю информацию про какого то человека:
class chelovek {
public:
string name;
string last_name;
int age;
void showinfo(){
cout<<name;
cout<<last_name;
cout<<age;
}
};
Класс готов, теперь я могу в программе создать объекты этого класса. Создам двух человеков:
chelovek one
one.name="vasya";
one.last_name="pupkin";
one.age=25
chelovek two
two.name="petya";
two.last_name="huev";
two.age=40
Ну и решил я значит вывести инфу про Васю:
chelovek.?vasya.show_info(0);
Вопросы:
Как создать объект класса "программно", не зная их общего количества?
Например, "группа студентов" - я хочу добавлять их по очереди из уже работающей программы, как это сделать?
Всякие попытки дать уникальное имя классу не работают, типа: "chelovek-n+1"
Задача которую я хочу решить звучит примерно так: при помощи классов создать программу, в которую можно вписывать неопределнное количество людей. У каждого человека должны быть описаны Имя фамилия возраст etc. Программа должна иметь меню управления, из которого имеется возможность проверить все методы класса, такие как "сортировка по имени, фамилию, возрасту", "показать всех людей (перечислить)", "удалить человека", "добавить человека"
Анонимус, отзовись! Я не прошу написать за меня программу. Может быть я неправильно понимаю, что такое классы? Перечитал дохуя инфы, дошел уже до ютубов.
Но всё равно остается непонятным - как управлять объектами класса? То же перечисление всех людей из списка - как вот это вот всё.
Спасибо.
Поясните мне за классы и объекты. Пожалуйста.
Вот создаю я класс ЧЕЛОВЕК и в нем же (функцию или процедуру?) при обращении к которой, можно будет получить всю информацию про какого то человека:
class chelovek {
public:
string name;
string last_name;
int age;
void showinfo(){
cout<<name;
cout<<last_name;
cout<<age;
}
};
Класс готов, теперь я могу в программе создать объекты этого класса. Создам двух человеков:
chelovek one
one.name="vasya";
one.last_name="pupkin";
one.age=25
chelovek two
two.name="petya";
two.last_name="huev";
two.age=40
Ну и решил я значит вывести инфу про Васю:
chelovek.?vasya.show_info(0);
Вопросы:
Как создать объект класса "программно", не зная их общего количества?
Например, "группа студентов" - я хочу добавлять их по очереди из уже работающей программы, как это сделать?
Всякие попытки дать уникальное имя классу не работают, типа: "chelovek-n+1"
Задача которую я хочу решить звучит примерно так: при помощи классов создать программу, в которую можно вписывать неопределнное количество людей. У каждого человека должны быть описаны Имя фамилия возраст etc. Программа должна иметь меню управления, из которого имеется возможность проверить все методы класса, такие как "сортировка по имени, фамилию, возрасту", "показать всех людей (перечислить)", "удалить человека", "добавить человека"
Анонимус, отзовись! Я не прошу написать за меня программу. Может быть я неправильно понимаю, что такое классы? Перечитал дохуя инфы, дошел уже до ютубов.
Но всё равно остается непонятным - как управлять объектами класса? То же перечисление всех людей из списка - как вот это вот всё.
Спасибо.
Почитал тут шапку, и кажется я иду нахуй. Что хотя бы гуглить то по моему вопросу.
Возьми учебник попроще, скажем, Java in a Nutshell, где разобрана 8-я жабба, потом вернись к плюсам.
>не зная их общего количества
Коллекции в JiaN разобраны оч. подробно.
Думаю, мне этот способ не подходит.
Почему никак не гуглится "создать объект класса c++" или "перечислить объекты класса" ?
Может я в корне неправильно мыслю?
Объекты создаешь с помощью new. Хранишь их в std::vector (читай документацию). Можно сделать отдельный класс для хранения человеков (внутри него будет вектор) в котором будут все необходимые операции над человеками, но возможно, для тебя такое еще рано.
Код на https://ideone.com/.
Второе, судя по твоим словам, то ты хуёво понимаешь что пишешь. Поэтому читай литературу, будь добр.
Касаемо твоего вопроса. Объекты класса ничем не отличаются от того же std::string. Поэтому ты точно так же можешь объединять их в массив http://www.cplusplus.com/doc/tutorial/dynamic/ , юзать для хранения std::vector http://en.cppreference.com/w/cpp/container/vector , std::list http://en.cppreference.com/w/cpp/container/list и так далее.
То что ты хочешь будет выглядеть примерно так:
int main()
{
std::vector<chelovek> people_list;
while(condition)
{
chelovek human;
/ Тут твоя реализация общения с пользователем.
Уровня создать человека? Д/Н.
Введите имя и прочее.
...
/
people_list.push_back(human);
}
return 0;
}
Теперь все созданные люди у тебя хранятся в std::list.
Чтобы найти какого-то конкретного по имени тебе нужно перебрать всех людей в листе.
chelovek find_human(const std::vector<chelovek> &people, const std::string &name)
{
for (int i = 0; i!=people.size(); ++i)
if (people.name == name) return people;
return chelovek(); //возвращаем пустой объект
}
Простой вариант. Но учти, что в стандартной либе уже есть std::find http://www.cplusplus.com/reference/algorithm/find/ и подобные им. Второе есть std::map и подобные, где поиск идёт по ключу.
В третьих для перебора элементов лучше всего использовать итераторы. std::vector<T, Alloc>::begin(), std::vector<T, Alloc>::end() и так далее. Более подробно описано в референсах.
В четвёртых, если юзать 11 стандарт, то можно перебрать всё таким образом:
for (const auto &human: people){ ... }
http://en.cppreference.com/w/cpp/language/range-for
Вот как-то так. И повторю, что читай больше литературы.
Код на https://ideone.com/.
Второе, судя по твоим словам, то ты хуёво понимаешь что пишешь. Поэтому читай литературу, будь добр.
Касаемо твоего вопроса. Объекты класса ничем не отличаются от того же std::string. Поэтому ты точно так же можешь объединять их в массив http://www.cplusplus.com/doc/tutorial/dynamic/ , юзать для хранения std::vector http://en.cppreference.com/w/cpp/container/vector , std::list http://en.cppreference.com/w/cpp/container/list и так далее.
То что ты хочешь будет выглядеть примерно так:
int main()
{
std::vector<chelovek> people_list;
while(condition)
{
chelovek human;
/ Тут твоя реализация общения с пользователем.
Уровня создать человека? Д/Н.
Введите имя и прочее.
...
/
people_list.push_back(human);
}
return 0;
}
Теперь все созданные люди у тебя хранятся в std::list.
Чтобы найти какого-то конкретного по имени тебе нужно перебрать всех людей в листе.
chelovek find_human(const std::vector<chelovek> &people, const std::string &name)
{
for (int i = 0; i!=people.size(); ++i)
if (people.name == name) return people;
return chelovek(); //возвращаем пустой объект
}
Простой вариант. Но учти, что в стандартной либе уже есть std::find http://www.cplusplus.com/reference/algorithm/find/ и подобные им. Второе есть std::map и подобные, где поиск идёт по ключу.
В третьих для перебора элементов лучше всего использовать итераторы. std::vector<T, Alloc>::begin(), std::vector<T, Alloc>::end() и так далее. Более подробно описано в референсах.
В четвёртых, если юзать 11 стандарт, то можно перебрать всё таким образом:
for (const auto &human: people){ ... }
http://en.cppreference.com/w/cpp/language/range-for
Вот как-то так. И повторю, что читай больше литературы.
Бля. Обосрался. В std::vector хранится инфа. А не в листе.
Хотел пример с листом сделать, но вектор ближе всего к обычному массиву. И имеет random access.
Так что там везде про std::vector
Откуда 4? Capacity может быть больше чем size. Проходом по строке его не вычислишь.
Объект класса в первый элемент вектора, например. Доставьте эту "строчку" кода, пожалуйста.
Видимo в 14-том стандарте string содержит указатель на старый string. Все равно же нужно хранить capacity.
http://ideone.com/uHYFbQ
http://en.cppreference.com/w/cpp/container/vector/data
Return value
Pointer to the underlying element storage.
Получай underlying storage и пиши в него что хочешь.
Как записать в массив объект класса состоящий из 3х разных свойств.
https://ideone.com/eRnzhR
У тебя массив char а ты суешь туда людей. Создай вектор vector<chelovek> massiv; А лучше удали всю ту хуйню что ты написал и читай книги из шапки. Не понимаешь нихуя.
>>546407
От души, братишка, спасибо. Про IDE я сделаю, наверное, отдельный раздел, который вынесу из шапки во второй пост, чтобы не захламлять ее. В шапке будут инструкции для быстрой сборки хэллоуворлдов, а во втором посте уже обзорная инфа про IDE.
Про буст вот жалко, что на русском ничего толком нет. Я добавлю, но у меня есть подозрение, что анон неохотно читает на ангельском.
Про проектирование, наверное, стоит добавить Гамму, и этим ограничиться, потому что большинство книжек отвязаны от крестов и рассчитаны уже на серьезную разработку, а у нас тут вроде как языкотред, и основных паттернов, по идее, будет достаточно. Хотя, это только мое мнение, я сделаю, как анон решит, разумеется.
Про утилиты тоже черкну во втором посте.
Еще я собираюсь изменить структуру шапки, чтобы отделить C++11 ньюфажные книжки от старых. А то все выбирают Лафоре, который как раз таки 2004 года, лол.
Не обязательно использовать push_back. Если он точно знает что ему нужно именно 10 элементов можно и так.
Я не увидел, что он создал вектор определенного размера.
Вот это сейчас вообще пушка была.
Зачем нужен кетчуп, когда есть майонез?
Библиотеки вообще отличаются более чем полностью.
Доставьте, пожалуйста, простейший пример
ввода-вывода-хранения объекта класса с несколькими своствами. Без массивов. Хранение не постоянное, а в рамках работы программы.
Хули тебе здесь надо?
Ты памятку прочитал?
Кинь свой телеграм, я тебе все объясню
Второй вопрос про начало, а не про конец. С концом всё понятно, ресайз.
http://habrahabr.ru/post/244963/
Господи, какой же понос, что за хуйню я читаю? Что это блядь такое вообще? Я не очень в крестах, извините.
>при помощи классов создать программу, в которую можно вписывать неопределнное количество людей. У каждого человека должны быть описаны Имя фамилия возраст etc. Программа должна иметь меню управления, из которого имеется возможность проверить все методы класса, такие как "сортировка по имени, фамилию, возрасту", "показать всех людей (перечислить)", "удалить человека", "добавить человека"
Подайте хотя бы исходник не такой же но аналогичной программы.
Это и есть круд?
О чем они были?
Внезапно осознал, что некуда девать свой творческий потенциал, потому что все что приходит на ум - давно уже сделано в стократном количестве.
потому что там хуйня для любителей с++11
сериализация - неотемлимая часть любого развитого фреймворка общего назначения любого языка
ну а то, что ты, блядь, вообще не знаешь что это такое и при этом кодишь что-то - твои проблемы
Возьмите меня на работу.
Почитал отдельно про сериалиазцию. Понял, сохранял структуры, было дело.
Но там правда крестопонос во всей красе. Хотя с новым стандартом знаком.
Если мне не принципиально какой тип, лишь бы N байт минимум обеспечил, я беру по табличке
char - 1
short - 2
int - 2
long - 4
long long - 8
Если мне дохуя принципиально (читать файлы, пакеты из сети), то я должен сначала скорректировать byteorder, затем взять int8_t, int16_t, int32_t, int64_t.
Итак, вопросы:
- чем правильнее всего корректировать byteorder?
- как быть если машина не поддерживает например 16 битные числа и тип int16_t недоступен?
- как работают типы (и присутствуют ли вообще) long long/int64_t на 32-битной машине? Реализует ли кокомпилятор эмуляцию автоматически?
- как быть 100% уверенным что структура/массив не имеют алигнов с пустыми байтами? Для чтения файла например.
1. Хуй знает, я, если честно, не сталкивался с ручным обеспечением этого. Понятно, что для малых объемов вообще несущественно, как это делать, а для больших я бы, например, прочитал в сыром порядке, а потом векторными операциями прогнал, чтобы перевернуть каждый блок. Платформозависимость во все поля, ага.
2. http://en.cppreference.com/w/cpp/types/integer вот тут видно, что некоторые из них опциональны, и поддерживаться не обязаны. Для остальных поддержка требуется стандартом 18.4.1, так что они энивей есть, хотя могут быть медленными из-за эмуляции. Не используй опциональные типы, либо будь готов ставить самостоятельно using с редиректом на int_fast16_t или типа того, если на очередной платформе соснешь.
3. int64_t и uint64_t опциональные, long long жестко требуется, начиная с 11 стандарта. Так что любой компилятор, соответствующий 11 стандарту обязан эмулировать как минимум long long и все неопциональные fixed-width типы но отдельно для них, разумеется, никто ничего не делает, все объявляют синонимами int/long long, поэтому на практике опциональные просто тоже делаются их синонимами. Как эмулируется long long - дело байтоебское, все это на асме написано, конечно же.
4. В 11 стандарте ввели alignof () в дополнение к sizeof ().
Не. Про то что они опциональные я в курсе. Я о том как читать/писать байтовый поток содержащий такие типы если они недоступны? Ебаться с логикой и сдвигами? Ладно, пусть так, но какой IFDEF использовать? Или может готовое что есть?
Так вышло, что я поддерживаю одновременно проекты на 8, 16 и 32 битных контроллерах. Уже забыл, когда объявлял переменные без явного указания длины)
Многобайтные расширения поддерживает любой нормальный компилятор, проблема одна - замедление исполнения, причем существенное. Например, интегрирование результатов 12-битного АЦП через прерывания на 8081 контроллере занимало у меня чуть ли не за сотню тактов.
Самая жопа это выравнивание, конечно. Даже если у тебя нет структур, а ты хочешь превратить четыре байта во флоат. При работе с STM под IAR постоянно приходится помнить про прагму data_alignment, например.
Со струтурами же, чтобы не было пропусков, просто смотришь внимательно, чтобы чары шли по два или четыре, добиваешь их явно пустыми байтами и т.п.
Но потом впендюриваешь еще один в середину, и все ломается. Поэтому я в принципе перестал делать явное преобразование массива в структуру, а все поля перегоняю ручками.
Гарантий тебе никто не даст. Рано или поздно ты обязательно выстрелишь себе в ногу.
(быстроапдейт)
Просветление меня настигло, когда оказалось, что с точки зрения IAR в инте под msp430 два байта, а под STM - четыре. Тут-то я и сел переписывать все свое библиотечное барахло, да.
Я вот стараюсь смотреть не на стандарт, а на возможности конкретного компилятора, прагмы, вот это все.
Прошу пояснить теоретическую "структуру" и работу программы. Что считывать и что куда записывать. В двух словах.
Максимально упрощенно, без усложнений.
Сроки горят, читаьт кникни не успеваю, буду делать свой говногод на ходу. Преподу на код похуй. Лищь бы работало.
Мои рассуждения: создаем класс для типичной записи (запись, автор, дата (только число)).
Делаем функцию, которая будет создавать объект (самое непонятное).
Записываем объект в одномерный и единственный массив (с большой размерностью, 100 например) - нереально наверное без ваших векторов и прочего говна.
И делаем функцию вывода записанных объектов этого класса.
Я верно мыслю или нет?
Бля, чувак, я не знаю, как объяснить. В общем так: если ты понимаешь, как работает класс, то делаешь приватные "переменные/массивы/ещё какая-нибудь хуйня", в чём будешь хранить данные и потом в паблике пилишь функции записи и вывода и с классом работаешь. Если ты не понимаешь, как работают классы, то делаешь так: создаёшь класс "xyeclass", пишешь в классе "public:" и под пабликом пишешь все свои переменные или какая там хуйня, вроде int date; потом создаёшь объект типа "xyeclass", к примеру так - xyeclass var; теперь пишешь var.date = 100500; таким образом записываешь все переменные. Учти, что если у тебя что-то вроде xyeclass *ptr = &var; то вместо ptr.date = 100500; тебе надо писать ptr->date = 100500. Через точку записываешь и считываешь данные из класса. Ну и да, если совсем не ебаться с хранением объектов, то пишешь xyeclass var[100500]; потом var[0].date = 100500; var[1].date = 1488; и так далее. Таким же образом и выводишь: std::cout<<var[0].date<<var[0].xyu;
Дальше объяснять лень, надеюсь тебе препод даст пизды за то, что в футбол хуями играешь, а не дело делаешь.
Таки всё так, как я думал, но как мне реализовать "новую запись"? Записей много и я не знаю их названия, но допустим хочу создать объекты класса с названиями zapis1, zapis2и тд. Как это сделать? В названии объекта игнорируются переменные и я не могу двинуться дальше.
Ты что, гумунитурий? Я же тебе показал, тупица:" xyeclass var[100500]; var[0].date = 100500; var[1].date = 1488; либо запили функцию со статическим счётчиком записей, и передавай ей указатель на объект, либо запили цикл, который сперва проверяет, чего хочет пользователь - получить в жопу свои данные, или наоборот, посрать данными. Потом цикл либо выводит данные, либо опять же по статической переменной счётчика делает новую запись в var[счётчик].date. И я в прошлом своём посте написал, как выдавливать данные из указателя на объект, поэтому съеби нахуй, пожалуйста.
CREATE TABLE notes (
id serial PRIMARY KEY,
content text NOT NULL
);
INSERT INTO notes (content) VALUES ('я ебал коня');
SELECT * FROM notes;
Блять, ты не понимаешь, нахуй.
class govnokniga;
public:
char text;
char autor;
int etc-govno;
Я могу прямо в коде создать ебучую запись, но не могу сделать этого из уже работающей программы.
govnokniga zapis1.
Я не могу вместо zapis1 написать переменную, например. В твоем примере все пишется в массив?
Что мешает вместо govnoknoga zapis1; написать govnokniga zapis[100500]; и потом использовать этот массив, забив хуй на память? Есть способы динамического выделения памяти, но там надо уметь работать с указателями, векторами и тому подобным говном. Я тебе дал самый простой способ, который может сделать даже первоклассник. Потом прочитаешь литературу и будешь пилить нормальные программы; в моём примере тебе нахуй не нужно ебаться с новой инфой.
То есть я как и прежде объявляю класс (я правильно его показал же?), а потом тупо создаю объекты этого класса с присваиванием им индекса массива? Я не догоняю просто, как массив связан с классом. Запись будет иметь тип date? Я смогу записать в массив этоттипа разве?
ВОт строка
govnokniga zapis[100500]
что обозначает? Мы создаем объект класса типа массив? или что тут происзодит.
Да, я просто торопился и опустил это.
Имя класса - такая же хуйня, как и всякие int, char, float, и используется точно так же. Но к переменным и функциям класса доступ происходит не напрямую, как в int, char, float, а через оператор "точка". Поэтому govnokniga zapis[100500] - просто создание массива типа govnokniga(как int) по имени zapis из 100500 объектов.
И ещё, про оператор точка и данные класса. Смотри, вот у тебя есть
class xyeclass{
pubic:
int date;
string str;
};
теперь ты создаёшь объект:
xyeclass var, another_var;
var.date = 100500;
another_var.date = 1488;
var.str = "эта строка";
another_var.str = "и другая строка";
теперь, если написать
cout<<var.date<<endl<<var.str<<endl;
cout<<another_var.date<<endl<<another_var.str<<endl;
тебе выдаст такое:
100500
эта строка
1488
и другая строка
И ещё, про оператор точка и данные класса. Смотри, вот у тебя есть
class xyeclass{
pubic:
int date;
string str;
};
теперь ты создаёшь объект:
xyeclass var, another_var;
var.date = 100500;
another_var.date = 1488;
var.str = "эта строка";
another_var.str = "и другая строка";
теперь, если написать
cout<<var.date<<endl<<var.str<<endl;
cout<<another_var.date<<endl<<another_var.str<<endl;
тебе выдаст такое:
100500
эта строка
1488
и другая строка
Это старая шутка, или сам придумал?
Есть вкудахт/телеграм у тебя? Я могу тебе помочь и разжевать все что тебе нужно, у меня как раз время свободное есть, болею.
Разобрался без вас, ребята.
Я не использую интернет в телефоне.
if (mark.sim == 'r' && map.background[mark.coord_y][mark.coord_x + 1] != '#') {
\t\t\tmark.coord_x++;
\t\t\tcontinue;
\t\t}
\t\telse if (mark.sim == 'r') {
\t\t\tmark.sim = 'b';
\t\t}
\t\tif (mark.sim == 'b' && map.background[mark.coord_y + 1][mark.coord_x] != '#') {
\t\t\tmark.coord_y++;
\t\t\tcontinue;
\t\t}
\t\telse if (mark.sim = 'b') {
\t\t\tmark.sim = 'l';
\t\t}
\t\tif (mark.sim == 'l' && map.background[mark.coord_y][mark.coord_x - 1] != '#')
\t\t{
\t\t\tmark.coord_x--;
\t\t\tcontinue;
\t\t}
\t\telse if (mark.sim = 'l') {
\t\t\tmark.sim = 'f';
\t\t}
\t\tif (mark.sim == 'f' && map.background[mark.coord_y - 1][mark.coord_x] != '#')
\t\t{
\t\t\tmark.coord_y--;
\t\t\tcontinue;
\t\t}
\t\telse if (mark.sim == 'f')
\t\t{
\t\t\tmark.sim = 'r';
\t\t}
эт все цикл типа. суть в том, что этот пидараст не может в "определится" - он при возможном выборе всегда сделает шаг назад, вместо того что бы пиздовать вперед.
ЧЯДНТ
единственную человеческую блок-схему что я нашел кидаю сюды
http://myrobot.ru/articles/logo_mazesolving.php
if (mark.sim == 'r' && map.background[mark.coord_y][mark.coord_x + 1] != '#') {
\t\t\tmark.coord_x++;
\t\t\tcontinue;
\t\t}
\t\telse if (mark.sim == 'r') {
\t\t\tmark.sim = 'b';
\t\t}
\t\tif (mark.sim == 'b' && map.background[mark.coord_y + 1][mark.coord_x] != '#') {
\t\t\tmark.coord_y++;
\t\t\tcontinue;
\t\t}
\t\telse if (mark.sim = 'b') {
\t\t\tmark.sim = 'l';
\t\t}
\t\tif (mark.sim == 'l' && map.background[mark.coord_y][mark.coord_x - 1] != '#')
\t\t{
\t\t\tmark.coord_x--;
\t\t\tcontinue;
\t\t}
\t\telse if (mark.sim = 'l') {
\t\t\tmark.sim = 'f';
\t\t}
\t\tif (mark.sim == 'f' && map.background[mark.coord_y - 1][mark.coord_x] != '#')
\t\t{
\t\t\tmark.coord_y--;
\t\t\tcontinue;
\t\t}
\t\telse if (mark.sim == 'f')
\t\t{
\t\t\tmark.sim = 'r';
\t\t}
эт все цикл типа. суть в том, что этот пидараст не может в "определится" - он при возможном выборе всегда сделает шаг назад, вместо того что бы пиздовать вперед.
ЧЯДНТ
единственную человеческую блок-схему что я нашел кидаю сюды
http://myrobot.ru/articles/logo_mazesolving.php
сукбля пацаны простите за табы((((((((((((
По наставлению универа начал в борланде кодить. Он хорош или стоит всё же на вижуал переходить?
Господа, катиться мимо вас толстая веб-пхп-макака, это я.
В веб пошёл от нужды быстро работу найти, но подобное программирование никогда не привлекало, сейчас хочу уйти от туда.
Думаю либо про андроид с жабой, либо про кресты.
За спиной паскаль, руби, два курса вуза, Кормен и т.п., и чувство что это моё.
Но вот в чем вопрос, чем сейчас занимаются программисты на C/C++ ? Меня интересуют конкретные задачи.
И какой уровень нужен для поиска работы?
Что в портфолио положить?
Вот с вебом всё ясно, с мобильными тоже.
А вот чем вы на работе заняты я не очень понимаю.
Помогите разобраться.
При создании проекта появляется такая вот ошибка
if (X > 0 && Maze[Y][X - 1] == Free && Solve(X - 1, Y))
{
return true;
}
вот как выглядит эта параша, функция булевая.
Выполни операцию недопустимую для отрицательных чисел и обработай исключение.
По идее попытка взять корень от <0 вызовет исключение, а вообще ищи функцию C++ которая 100% скинет
Я так понял, что лучшим вариантом будет вижуал студиа для экзешников, а вот с g++ что - то не могу разобраться. Какой формат файла я получаю на выходе? Что за a.out?
[code]auto in = fstream("input.txt");[/code]
Возникает вопрос, будет ли вызван copy constructor, или move?
Тебе в незасаганный тред.
Это копия, сохраненная 15 октября 2015 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.