LINUX.ORG.RU

Интересная книга по C++


0

0

Имеется проблема: при чтении книг по C++ клонит в сон.
Может не те книги читаю? Посоветуйте что-нибудь по-интереснее. Хотелось бы чтобы было поменьше «воды».
С программированием знаком, хотелось бы изучать именно C++, а не основы программирования.

Ответ на: комментарий от www_linux_org_ru

* первая часть решения будет борьба с языком, с большим количеством boilerplate кода (но это если не юзать с++0х)

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от anonymous
template <int k> 
int prenu(int a, int b, int c, int d, int e) { 
  return !(k)*a+!(k-1)*b+!(k-2)*c+!(k-3)*d+!(k-4)*e; 
} 
template<int k>                                              
int maks(int m1, int m2, int a, int b, int c, int d, int e) { 
#define E prenu<k>(a,b,c,d,e) 
  return maks<k+1>(   
        (E > m1) ? E : m1, 
        (E > m1) ? m1 : ((E > m2) ? E : m2) , 
        a, b, c, d, e); 
} 
 
template <> 
int maks<5>(int m1, int m2, int a, int b, int c, int d, int e) { 
  return m1*m1+m2*m2; 
} 
int sum(int a, int b, int c, int d, int e) { 
  return maks<0>(0,0,a,b,c,d,e); 
}

Это форменный пиздец товарищи. У програмистов на с++ это что фишка такая, выкладывать нерабочий код? У одного не компилится. У анонимусов неверный результат выдает. Если уж решили снизойти, то не позорьтесь! Прогоните пару тестиков. Срамота же!

С другой стороны, помню себя в студенчестве — тоже самое, быстрей, быстрей понаписать, жамкнуть F9, а потом разбираться с проблемами в дебагере. Видимо для крестатых это рок такой.

baverman ★★★
()
Ответ на: комментарий от tailgunner

Ты и правда думаешь, что эта простыня легче для понимания

Где я говорил про легкость понимания?

А по-моему, даже этому читателю в вакууме проще будет освоить циклы

Здесь проблема не в отсутствии циклов, а в нехватке такой абстракции, как массив или список.

baverman ★★★
()
Ответ на: комментарий от lester

не лопни, толстячок

Да, забыл что на ЛОРе есть адекватные люди в вашем лице и www_linux_org_ru. Посему фикс:

У програмистов на с++ -> У большинства программистов на с++

Видимо для крестатых -> Видимо, для большинства крестатых.

Как такой вариант?

baverman ★★★
()
Ответ на: комментарий от www_linux_org_ru

Кстати, не знаете, где-то мельком узнал что есть реализация схемы на шаблонах с++. Хотелось бы глянуть. Гугл как-то подозрительно молчит.

baverman ★★★
()
Ответ на: комментарий от anonymous
template <int k> 
int prenu(int a, int b, int c, int d, int e) { 
  return !(k)*a+!(k-1)*b+!(k-2)*c+!(k-3)*d+!(k-4)*e; 
} 
template<int k>                                              
int maks(int m1, int m2, int a, int b, int c, int d, int e) { 
#define E prenu<k>(a,b,c,d,e) 
  return maks<k+1>(   
        (E > m1) ? E : m1, 
        (E > m1) ? m1 : ((E > m2) ? E : m2) , 
        a, b, c, d, e); 
} 
 
template <> 
int maks<5>(int m1, int m2, int a, int b, int c, int d, int e) { 
  return m1*m1+m2*m2; 
} 
int sum(int a, int b, int c, int d, int e) { 
  return maks<0>(0,0,a,b,c,d,e); 
}

Посыпаю голову пеплом. Надо же так пропереться, перепутал нерабочий код с вашим прекрасным и рабочим.

Благодарю за демонстрацию рекурсивных шаблонов и оригинальный способ вычленения n-ого аргумента.

baverman ★★★
()
Ответ на: комментарий от baverman

> Здесь проблема не в отсутствии циклов, а в нехватке такой абстракции, как массив или список.

Такая абстракция остуствует где? В глове сферического читателя SICP?

tailgunner ★★★★★
()
Ответ на: комментарий от metar
int& max(int& a, int& b) { 
    return (a < b)? b : a; 
} 
 
void swap(int& a, int& b)   { 
    a ^= b; 
    b ^= a; 
    a ^= b; 
} 
 
int fun(int a, int b, int c, int d, int e, int f, int g, 
        int h, int i, int j)  { 
    swap(a,  
        max(a,  
        max(b,  
        max(c,  
        max(d,  
        max(e,  
        max(f,  
        max(g,  
        max(h,  
        max(i, j) ))))))))  
    ); 
    swap(b,  
        max(b,  
        max(c,  
        max(d,  
        max(e,  
        max(f,  
        max(g,  
        max(h,  
        max(i, j) ))))))) 
    ); 
    return a*a + b*b; 
}

Вот этот код точно не рабочий. Простите, что сразу не проверил.

Итого мы имеем четыре попытки: одна не собирается, две работают неверно и одна прекрасна и работает.

Скажите спасибо анонимусу, который не пожалел своего времени и отстоял вашу честь.

baverman ★★★
()
Ответ на: комментарий от baverman

> Здесь проблема не в отсутствии циклов, а в нехватке такой абстракции, как массив или список.
Имхо, если в голове читателя при программировании на Си отсутствует понимание таких вещей, как цикл, массив и указатель, то он ССЗБ. Всем остальным лучше ими пользоваться.
Ваше задание можно выполнять с мыслью «интересно, как оно будет?», но судить по нему массу сишников, которым неинтересно, - излишне.

metar ★★★
()
Ответ на: комментарий от tailgunner

Такая абстракция остуствует где? В глове сферического читателя SICP?

К той странице списки еще не давались.

Интересно, вас то что задело? Условия вроде все оговорил, там «представим себе», «воображение».

baverman ★★★
()
Ответ на: комментарий от metar

при программировании на Си

А вы не думали над программированием как наукой, отвлеченной от конкретного языка? Например лямбда исчисление?

Неужели вам столько лет что разминка мозга приносит страдания?

baverman ★★★
()
Ответ на: комментарий от baverman

> Интересно, вас то что задело?

?

Условия вроде все оговорил

Да код в результате настолько уродливый, что вызывает недоумение.

tailgunner ★★★★★
()
Ответ на: комментарий от baverman

Вот этот код точно не рабочий. Простите, что сразу не проверил.

Пардон, вредная привычка, все время забываю, что swap c xor'ами портит данные при одинаковых аргументах.)))

void swap(int& a, int& b)   {  
    static int x;
    x = a;
    a = b;
    b = x;
}

metar ★★★
()
Ответ на: комментарий от metar

Спасибо, что уделили внимание. Теперь у нас есть две неплохие реализации.

Теперь честно, неужели это задача была настолько простой до не интересности большинству сишников/цппшников? Ладно с товарищами, пишущими на Си, они ребята серьезные, глупостями не занимается. Но с++? Молодые энергичные парни, жизнь бьет ключом? Любопытство?

Вместо этого угрюмость, — «зачем мне это — у меня есть STL». Семь бед один ответ. Не понимаю.

baverman ★★★
()
Ответ на: комментарий от tailgunner

Да код в результате настолько уродливый, что вызывает недоумение.

Что поделать. Переменных много. Какая реализация понравилась больше?

Моя просто может быть записана практически на любом языке один-в-один.

baverman ★★★
()
Ответ на: комментарий от baverman

Да, забыл что на ЛОРе есть адекватные люди в вашем лице и www_linux_org_ru

дважды горжусь: не вошёл в список адекватных :)

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

:) Я имел в виду людей много пишущих на c++.

Я что-то пропустил? Если так, то у вас высшее звание: «Мистер Адекватность».

baverman ★★★
()
Ответ на: комментарий от baverman

> Здесь проблема не в отсутствии циклов, а в нехватке такой абстракции, как массив или список

массив в Си это абстракция?

блин смешно ж чесслово, может предложить Вам такую же задачу решить в функциональных языках, но без возможности создавать функции? :)

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

qnikst ★★★★★
()
Ответ на: комментарий от Bwglb3

А почему ты переделал условие задачи? Функция должна принимать 3 аргумента, а не 10.

Потому что развернуть цикл для трех переменных не составляет труда, и как выразился анонимус, такую задачу решают даже школьники.

baverman ★★★
()
Ответ на: комментарий от qnikst

массив в Си это абстракция

И что же такое массив в Си?

заглянуть в учебники по императивным языкам

Схема императивный язык. Правда SICP не совсем учебник по схеме.

то ты заметишь, что там циклы будут (да и массивы тоже) будут до определения функций

main?

baverman ★★★
()
Ответ на: комментарий от baverman

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

Bwglb3
()
Ответ на: комментарий от Bwglb3

А решать задачу для большего числа аргументов с теми же ограничениями - дебилизм.

Пожалуй верно. Таким радостным, как я вчера, может быть только блаженный.

baverman ★★★
()
Ответ на: комментарий от baverman

> Посыпаю голову пеплом. Надо же так пропереться, перепутал

правда, «проперело» тебя

Cargo
()
Ответ на: комментарий от qnikst

То есть, по-вашему, массив в Си — это «охренеть абстракция».

Товарищ, пожалуйста, сосредоточтесь. Я понимаю зуд в жопе страшная штука, но попробуйте говорить членораздельно.

паскалебасики спасают от этого :)

Да, поэтому они предпочтительнее для обучения чем C.

baverman ★★★
()
Ответ на: комментарий от baverman

> То есть, по-вашему, массив в Си — это «охренеть абстракция». да..

по моему в языках, в терминах которых переменная это именованный адрес памяти с информацией о типе. И в которых массив это указатель на 1ый элемент массива. Говорить о массиве как о чем-то сложном не разумно. Выражения вида A[b] не более, чем синтаксический сахар (как модно сейчас писать).

Да, поэтому они предпочтительнее для обучения чем C.

может быть, басики для этого и делались.

qnikst ★★★★★
()

Это даже не смешно как-то. Что мешает почитать о синтаксисе языка? Тем более на лиспе это вообще в 3 строчки задача.

(defun f(&rest args) 
  (apply #'(lambda(x y)(+ (* x x) (* y y))) 
         (subseq (sort args #'>) 0 2))) 

someone
()
Ответ на: комментарий от qnikst

по моему в языках, в терминах которых переменная это именованный адрес памяти с информацией о типе. И в которых массив это указатель на 1ый элемент массива.

Говорить о массиве как о чем-то сложном не разумно.

сложном

Вы только что дали неимоверно насыщенное определение, привлекая такую абстракцию как «указатель». Минимум два академических часа, а то и три. В группе для одаренных детей.

Массив в терминах Cи, пожалуй, самый сложный массив на свете.

baverman ★★★
()
Ответ на: комментарий от someone

Это даже не смешно как-то

Из лиспа у нас есть только defun, if/cond, +, -, *, /. И лучше бы тебе продемонстрировать решение побыстрее, чтобы лисперам не было за тебя стыдно.

baverman ★★★
()
Ответ на: комментарий от someone

Что мешает почитать о синтаксисе языка?

Синтаксис уже освоен. Об S-expressions говорили.

baverman ★★★
()
Ответ на: комментарий от baverman

Тебе уже написали - ты занимаешься ерундой. Задача для трех аргументов решается несколькими вложенными if-ами. Для большего числа аргументов есть массивы и циклы.

Bwglb3
()
Ответ на: комментарий от baverman

> Вы только что дали неимоверно насыщенное определение, привлекая такую абстракцию как «указатель». Минимум два академических часа, а то и три. В группе для одаренных детей.

давай поспорим, что если ты нарисуешь кучу квадратиков на доске и скажешь, что это память, потом, покажешь как там хранятся значения. То объяснить всем, что же такое массив.

Массив в терминах Cи, пожалуй, самый сложный массив на свете.

http://www.haskell.org/tutorial/arrays.html

зато этот массив самый близкий к реальному представлению =)

qnikst ★★★★★
()
Ответ на: комментарий от baverman

>чтобы лисперам не было за тебя стыдно. Я переживу. Если побыстрее в плане скорости, то тут нечего парится. 10 или 30 разница небольшая. Тем не менее если надо решение скорее - смотри onlisp там сортировка на макрах. Тупо макроэкспандишь и постишь. Искать - лень.

someone
()
Ответ на: комментарий от baverman

кстати таких «абстраций» как массив, список, for, указатель, передача параметров по ссылке у нас нет, но есть template, подсчитаешь сколько академических часов нужно, чтобы это рассказать? =)

qnikst ★★★★★
()

В конце концов можно и вот так на c++:

#include <iostream>

using namespace std;

typedef int T;

T max(T a, T b, T c)
{
    T x;
    x = a > b ? a : b;
    x = x > c ? x : c;
    return x;
}
 
T mid(T a, T b, T c)
{
    T l = a > b ? a : b;
    T s = a > b ? b : a;
    return c > l ? l : 
           c < s ? s : c;;
}

T task(T t0, T t1, T t2, T t3, T t4, T t5, T t6, T t7, T t8, T t9)
{
    T a = max(t0, t1, t2);
    T b = mid(t0, t1, t2);
    a = max(a, b, t3);
    b = mid(a, b, t3);
    a = max(a, b, t4);
    b = mid(a, b, t4);
    a = max(a, b, t5);
    b = mid(a, b, t5);
    a = max(a, b, t6);
    b = mid(a, b, t6);
    a = max(a, b, t7);
    b = mid(a, b, t7);
    a = max(a, b, t8);
    b = mid(a, b, t8);
    a = max(a, b, t9);
    b = mid(a, b, t9);
    return a*a + b*b;
}

int main()
{
    cout << task(0, 1, 9, 3, 4, 5, 6, 8, 7, 2) << endl;
    return 0;
}
kamre ★★★
()
Ответ на: комментарий от kamre

Вроде все условия соблюдены.

Хотя, конечно, можно было в условии сразу написать что все данные должны быть immutable. Тогда такое решение не подходит.

kamre ★★★
()
Ответ на: комментарий от kamre

Тогда вот так:

#include <iostream>

using namespace std;

typedef int T;

T max(T a, T b, T c)
{
    T x;
    x = a > b ? a : b;
    x = x > c ? x : c;
    return x;
}
 
T mid(T a, T b, T c)
{
    T l = a > b ? a : b;
    T s = a > b ? b : a;
    return c > l ? l : 
           c < s ? s : c;
}

T recurse(int depth, T a, T b, T t0, T t1, T t2, T t3, T t4, T t5, T t6)
{
    return depth == 0 ? a*a + b*b :
        recurse(depth - 1, max(a, b, t0), mid(a, b, t0), t1, t2, t3, t4, t5, t6, 0);
}

T task(T t0, T t1, T t2, T t3, T t4, T t5, T t6, T t7, T t8, T t9)
{
    return recurse(7, max(t0, t1, t2), mid(t0, t1, t2), t3, t4, t5, t6, t7, t8, t9);
}

int main()
{
    cout << task(0, 1, 9, 3, 4, 5, 6, 8, 7, 2) << endl;
    return 0;
}
kamre ★★★
()
Ответ на: комментарий от baverman

> Да, забыл что на ЛОРе есть адекватные люди в вашем лице и www_linux_org_ru

программисты обычно прагматики, если не объяснишь, откуда берутся странные ограничения — тебя не поймут

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от baverman

Молодой человек, все же вместо книжек по C++, стоит почитать SICP, и будете гладким и шелковистым Арамисом.

гы-гы-гы

те, кто пишут шаблоны на с++, давно знают, как решать подобные этой задачи — т.к. в шаблонах нет ничего, кроме рекурсии и сопоставления с образцом (что почти то же, что оператор ?:)

тем не менее, задача хорошая, так как показывает, где с с++ приходится бороться

вот решение задачи «вычислить то, что ты просил, но во время компиляции»:

#include <iostream>

template<int* array> struct Util { };

/// борьба с языком будет заключаться в повторении этих define-ов для разного количества аргументов
#define DEFINE_ARRAY(el_type, name, v1, v2, v3, v4, v5) el_type name[] = { (v1), (v2), (v3), (v4), (v5) }; template<> struct Util<name> { typedef Cons<v1, Cons<v2, Cons<v3, Cons<v4, Cons<v5, Nil > > > > > expression; };

/// а вот и решение задачи
template<int value, class T> struct Cons
{
    static const int max = value > T::max ? value : T::max;
    static const int max2 = value > T::max ? T::max : value > T::max2 ? value : T::max2;
    static const int solution = max*max + max2*max2;
};
struct Nil
{
    static const int max = 0;
    static const int max2 = 0;
    static const int solution = 0;
};

/// тестируем
DEFINE_ARRAY(int, a, 7, 4, 1, 5, 0);
const int result = Util<a>::expression::solution;
int prove[result]; /// это доказывает, что результат получен во время компиляции

int main()
{
    std::cout << result;
    return 0;
}
www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

тут на самом деле предполагается, что числа не только целые, но и неотрицательные, и везде по-хорошему надо еще расставить unsigned

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от baverman

Вот ещё вариант. Быдлокод, но при таких ограничениях сойдёт:

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

Там опечатка в предпоследнем if'е, может, она ввела вас в заблуждение.

$ cat test.cpp
#include <iostream>

int f(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) {
 if (a1 > a0) return f(a1, a0, a2, a3, a4, a5, a6, a7, a8, a9);
 if (a2 > a1) return f(a0, a2, a1, a3, a4, a5, a6, a7, a8, a9);
 if (a3 > a2) return f(a0, a1, a3, a2, a4, a5, a6, a7, a8, a9);
 if (a4 > a3) return f(a0, a1, a2, a4, a3, a5, a6, a7, a8, a9);
 if (a5 > a4) return f(a0, a1, a2, a3, a5, a4, a6, a7, a8, a9);
 if (a6 > a5) return f(a0, a1, a2, a3, a4, a6, a5, a7, a8, a9);
 if (a7 > a6) return f(a0, a1, a2, a3, a4, a5, a7, a6, a8, a9);
 if (a8 > a7) return f(a0, a1, a2, a3, a4, a5, a6, a8, a7, a9);
 if (a9 > a8) return f(a0, a1, a2, a3, a4, a5, a6, a7, a9, a8);

 return a0*a0 + a1*a1;
};

int main() {
 int a[10];
 for (int i = 0; i < 10; ++i)
  std::cin >> a[i];
 std::cout << f(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]) << '\n';
 return 0;
};
$ g++ test.cpp
$ cat test
2
8
1
5
2
2
6
5
3
9
$ ./a.out < test
145
$ echo $((8*8+9*9))
145
anonymous
()
Ответ на: комментарий от www_linux_org_ru

вот решение задачи «вычислить то, что ты просил, но во время компиляции»:

Прелесть же. Пожалуй, теперь и я так смогу. Спасибо за отличный пример.

baverman ★★★
()
Ответ на: комментарий от kamre

Хотя, конечно, можно было в условии сразу написать что все данные должны быть immutable.

Тогда вот так:

Еще одно решение. Браво. Забавная рекурсия, вариант того, что хотел сделать qnikst, но не смог.

baverman ★★★
()

Просто праздник бега в мешках %)

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.