C++ для начинающих

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: C++ для начинающих

Непрочитанное сообщение Olej » 15 ноя 2015, 20:00

Olej писал(а):А вот числом вариантов как это можно сделать - задача хорошая...
Ещё парочка вариантов может быть так:

Код: Выделить всё

string rep4( const string& base, uint rep ) {
   char buf[ 1000 ];
   strcpy( buf, base.c_str() );
   while( strlen( buf ) < rep )
      memmove( buf + strlen( buf ), buf, strlen( buf ) + 1 ); // удвоить длину
   buf[ rep ] = '\0';
   return string( buf );
}

Код: Выделить всё

string rep5( const string& base, uint rep ) {
   string ret( base );
   while( ret.length() < rep )
      ret += ret; // удвоить длину
   return ret.erase( rep, ret.length() - rep );
}
При очень больших rep такие варианты может быть очень эффективный (или наоборот, предыдущие варианты - не эффективными ;-) ).

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: C++ для начинающих

Непрочитанное сообщение Olej » 16 ноя 2015, 22:45

Olej писал(а):А вот числом вариантов как это можно сделать - задача хорошая...
Я же говорил, что в этом смысле задача благодатная... ;-)
Самый оптимальный из 5-ти предыдущих вариантов - 4-й (как может показаться странным) ... хотя о еальной оптимальности в такой задаче говорить смешно...

Код: Выделить всё

string rep4( const string& base, uint rep ) {
   char buf[ 1000 ];
   strcpy( buf, base.c_str() );
   while( strlen( buf ) < rep )
      memmove( buf + strlen( buf ), buf, strlen( buf ) + 1 ); // удвоить длину
   buf[ rep ] = '\0';
   return string( buf );
}
Например, при base="abc" и rep=30000:
- если 1-й вариант с посимвольным копированием потребует 30000 циклов копирования...
- следующие варианты с циклическим копированием base - 10000 циклов копирования...
- а этот вариант ... сколько? ... 15 ... ( 3 * 2 ^ 15 )

Но здесь сразу бросается в глаза, что это вариант - условный: char buf[ 1000 ] - 1000 здесь взято с потолка и для иллюстрации.
Можно от этого избавится?
Предлагаю:

Вариант 6:

Код: Выделить всё

string rep6( const string& base, uint rep ) {
   char* buf = (char*)alloca( rep * 2 );
   strcpy( buf, base.c_str() );
   while( strlen( buf ) < rep )
      memmove( buf + strlen( buf ), buf, strlen( buf ) + 1 ); // удвоить длину
   buf[ rep ] = '\0';
   return string( buf );
}
Вариант 7:

Код: Выделить всё

string rep7( const string& base, uint rep ) {
   char buf[ rep * 2 ];
   strcpy( buf, base.c_str() );
   while( strlen( buf ) < rep )
      memmove( buf + strlen( buf ), buf, strlen( buf ) + 1 ); // удвоить длину
   buf[ rep ] = '\0';
   return string( buf );
}
Мне тут кой-кто возражал, что char buf[ rep * 2 ] - не будет компилироваться ... но оно не только компилируется, но и работает :lol: :

Код: Выделить всё

olej@nvidia ~/2015_WORK/in.WORK/SchoolCPP/repch $ ./repch
базовая строка?: 123456
длина результата?: 3
123
123
123
123
123
123
123
базовая строка?: 2345
длина результата?: 200
23452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523
23452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523
23452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523
23452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523
23452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523
23452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523
23452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523452345234523
базовая строка?: ^C
Правда, возможность эта - расширение поздних стандартов VLA (VLA — variable-length array, массивы переменной длины) в C появляются в стандарте C99 ... в C++ не знаю с какого стандарта, но в C++11 оно уже работает.
Вложения
repch.cc
(2.2 КБ) 286 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: C++ для начинающих

Непрочитанное сообщение Olej » 30 ноя 2015, 01:48

Совершенно элементарная задача: Как очистить указатель — C++? (даже назвать нормально не умеют! :-( ).
Но она требует понимания.
А поэтому полезна ... для начинающих:
Дан указатель
double **p = 0;
Выполните следующие задания (решения можно оформлять внутри функции main).
Создайте конструкцию, изображенную на рисунке.
Изображение
Выведите число в квадратике на экран. После этого удалите все динамические объекты.
Настолько просто, что я файлы прикреплять не стану:

Код: Выделить всё

#include <iostream>
using namespace std;

int main( void ) {
   double **p = 0; 
   *( *( p = new double* ) = new double ) = 2;
   cout << **p << endl;
   delete *p;
   delete p;
}

Код: Выделить всё

olej@nvidia ~/2015_WORK/in.WORK/SchoolCPP/2ptr $ g++ -Wall  2ptr.cc   -o 2ptr
olej@nvidia ~/2015_WORK/in.WORK/SchoolCPP/2ptr $ ./2ptr
2

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: C++ для начинающих

Непрочитанное сообщение Olej » 27 дек 2015, 10:09

Вот задачка ... точнее простенькое упражнение, ... которое я только-что придумал, и которое показалось мне смешным. ;-)
Оно показывает возможности нетрадиционного использования возможностей языка ... , но требует достаточно хорошего понимания сущности происходящего...

Задача:
Класс string C++ является всего лишь контейнером, в который помещаются символы char. В том числе, в него могут быть помещены и терминальные символы '\0', являющиеся в традиционном символьном массиве (char[ ]) C/C++ признаком конца строки, и недопустимые, вообще то говоря, в качестве значения символов. Основываясь не этом, в переменную типа string может быть помещена последовательность терминированных C-строк, что превращает эту переменную в массив переменного размера, содержащий C-строки.
Основываясь на этом нештатном качестве, «запакуйте» в переменную типа string все строки окружения программы (environment). Продемонстрируйте возможность передачи этой строки по цепочке вызовов функций и возможность извлечения из неё любой переменной окружения (скажем PATH).

И решение:

Код: Выделить всё

#include <iostream>
#include <cstring>
using namespace std;

void get_path( string & e ) {
   const char *p = e.c_str(), *find = "PATH=";
   while( *p != 0 ) {
      if( 0 == strncmp( p, find, strlen( find ) ) ) break;
      p += strlen( p ) + 1;
   }
   cout << p << endl;
}

int main( int argc, char **argv, const char *envp[] ) {
   string env;
   int i = 0;
   do {
      if( envp[ i ] != NULL ) env += envp[ i ];
      env.push_back( '\0' );
   }
   while( envp[ i++ ] != NULL );
   get_path( env );
}
Выполняем:

Код: Выделить всё

olej@nvidia ~/2015_WORK/own.BOOK/+Reshebnik/C++/codes/string/arstr $ ./arstr 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/olej/Chromium/depot_tools:/home/olej/Chromium/depot_tools

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: C++ для начинающих

Непрочитанное сообщение Olej » 24 дек 2016, 14:54

Используйте Онлайн компиляторы для компиляции и отладки примеров C++ кода: это гораздо быстрее и удобнее!

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: C++ для начинающих

Непрочитанное сообщение Olej » 27 июн 2017, 16:34

Вот учебный курс (это от Yandex подарок ;-) ), который может быть очень неплох, но только для 1-го знакомства, для начинающих (уровня СШ или 1-й курс, ознакомление): Введение в программирование (C++)
(потому что ознакомление и изучение - это не одно и то же).

Там же из отзывов можно прочитать:
Евгений Александрович Тюрин
15 июня 2017 г.
1 - значит первый! По сути курс для школьников и не олимпиадный (хотя есть задачки на подумать). После этого курса станет ясно, что программистом вы не стали и еще далеко, потому что пошли не в ту сторону. Однако здесь полно задачек, чтоб попрактиковаться. Сам по себе курс скучноват, т.к. "++" добавили только для понта (увы). Это процедурный С, а из полюсов берется пара объектов и пара стандартных шаблона. Вас не научат правильной работе с указателями, поэтому для С тоже маловато. Конечно мы не увидим здесь еще курсов от яндикса по программированию. Для тех, кто дочитал мой отзыв, порекомендую курсы по алгоритмам (методы и структуры данных). Не смотрите в сторону курсов mail.ru, т.к. там всего один курс по делу (многопоточное программирование). Я поставил одну звезду, потому что оценка за курс завышена, а его материал уступает другим курсам по с/с++. Однако этот курс лучший в своем сегменте (средняя школа).
И это так и есть ... и я с этим соглашусь - что это "курс лучший в своем сегменте" ;-)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: C++ для начинающих

Непрочитанное сообщение Olej » 28 янв 2018, 21:30

Вот есть такая новая книжка:
Изображение
Программирование на C++ в примерах и задачах
Год издания: 2017
Автор: Васильев А.Н.
Издательство: "Э"
ISBN: 978-5-699-87445-3
Язык: Русский
Эту книгу (хоть и новая) можете свободно скачать здесь:
Формат: DjVu
Качество: Отсканированные страницы
Количество страниц: 369
Насколько она хороша? Я (пока?) не знаю ... но там в качестве задач-упражнений приводятся довольно много математических методов .... типа решения дифференциальных уравнений - возможно это кому-то понадобится.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: C++ для начинающих

Непрочитанное сообщение Olej » 28 янв 2018, 21:52

Olej писал(а):но там в качестве задач-упражнений приводятся довольно много математических методов .... типа решения дифференциальных уравнений - возможно это кому-то понадобится.
Оно и понятно:
Автор книги - Васильев Алексей Николаевич, доктор физико-математических наук, профессор кафедры теоретической физики физического факультета Киевского национального университета имени Тараса Шевченко.
(это стр.9 из книги)

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 14 гостей