Автор Тема: Програмирование на C++  (Прочитано 76696 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #60 : 08 Февраль 2011, 22:05:49 »
Ещё один вопрос связанный по с++, но не с самим языком а с компиляцией: в учебнике много примеров даются с разделением интерфейса от реализации, те есть 1 файл main.cpp один abc.h с прототипами класса и один с классом abc.cpp. Так вот мой компилятор при попытке компилировать main (в main упоминается что нужно подключить "abc.h") не подхватывает abc.cpp, хотя как я понимаю должен бы как-то. Учитывая что vs2010 у меня это тоже не сделала предпологаю что нужно что-то дописывать ещё при подключении, но что и где?
На данный момент я просто код main переношу из main.cpp в abc.cpp и компилирую abc.cpp. Надеюсь я понятно выразился? Если вы меня не поняли то в прикреплённом файле один из примеров с такой вот разделённой реализацией.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #61 : 08 Февраль 2011, 23:31:53 »
abc.cpp должен присутствовать в проекте, компилятор сам о его существовании не узнает. Если он есть в проекте, то IDE сообщает о нём компилятору и тот его подхватывает, т.е. одного его существования недостаточно. Ты добавлял его непосредственно в проект?

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #62 : 08 Февраль 2011, 23:35:07 »
Цитата: HoRRoR
Ты добавлял его непосредственно в проект?
А если я не создаю новый проект, а просто открываю те cpp файлы в примере то как дать знать компилятору о существовании abc.cpp ?

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #63 : 08 Февраль 2011, 23:48:05 »
В какой IDE ты это делаешь? Тут либо создавать проект, либо вручную скармливать всё компилятору через командную строку...

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #64 : 08 Февраль 2011, 23:51:39 »
HoRRoR,minigw. Я думал что раз уж мы назвали файл таким же именем как и .h файл то он должен бы автоматом подхватываться и это только мой компилятор баловался  :)

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #65 : 08 Февраль 2011, 23:57:03 »
MinGW - это компилятор, а я про среду разработки спрашивал. Предполагаю, что это Dev-C++ (потому как там можно открывать одиночные файлы без создания проектов). Я угадал?
Цитата
Я думал что раз уж мы назвали файл таким же именем как и .h файл то он должен бы автоматом подхватываться и это только мой компилятор баловался
Нет, тут другая политика. Как раз .h файлы и вовсе необязательно указывать компилятору - они подхватываются из объявлений в .cpp. Те, в свою очередь, независимо друг от друга компилируются в объектные файлы - а .h своего рода связующее звено, которое говорит, что такие-то переменные/функции/данные имеются в других файлах, т.е. в объектных файлах остаются ссылки на эти объявленные переменные/функции/данные. Потом объектные файлы загружаются и линкуются, в них ищется информация, объявленная в заголовочных файлах.
« Последнее редактирование: 09 Февраль 2011, 00:03:08 от HoRRoR »

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #66 : 09 Февраль 2011, 23:15:30 »
HoRRoR,codeblocks в связке с minigw у меня. Ну да можешь не отвечать по этому поводу, спасибо за объяснение почему же стандартно cpp файл тот не подключается, через командную строку каждый раз всё равно неудобно будет открывать все нужные файлы.

Добавлено позже:
И ещё вопрос: как получить текущее время в том виде чтобы его можно было потом использовать (например чтобы это была строка с разделителем, которую можно было бы разбить на лексемы и использовать нужные данные или что подобное), ну хотя бы в виде часы:минуты:секунды, ну или как-то так. Функция time() из ctime возвращает количество секунд прошедшего с 1972 года вроде, но как это использовать в своих целях я не придумал  :) Может есть ещё какие хитрости?

Добавлено позже:
P.S Дейтел под девятую главу жжёт блин, сложные упражнения даёт. Некоторые вообще жуткие по типу "создайте 3д поле 4x4x4 для игры в крестики-нолики с пк".

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #67 : 09 Февраль 2011, 23:17:23 »
Ну, либо использовать больше возможностей этих функций, либо же использовать WinApi. Хотя, существование первого варианта делает второй не совсем целесообразным.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #68 : 11 Февраль 2011, 23:30:02 »
Нашёл ещё вот такой вот метод вывода русского текста (пока наилучший):
// установить вручную шрифт Lucida Console в свойствах окна консоли
// и запомнить это для всех окон с этим именем
// записать в начале программы строку
 #include <windows.h>
// записать в начале функции main ( после строки с символом [B]{[/B] )
// две следующих строки
 SetConsoleCP(1251);
 SetConsoleOutputCP(1251);

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #69 : 13 Февраль 2011, 16:53:38 »
Вопрос номер n+1: А как-то можно ограничить ввод? Только не по количеству символов, а чтобы когда я ожидаю что будет введено число то символы не вводились и наоборот? В многих приложениях я встречал что когда пытаешься ввести в поле для цифр символы то ввод не происходит, правда эти приложения не являлись консольными так что не знаю можно ли сделать что-то подобное здесь.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #70 : 13 Февраль 2011, 17:14:46 »
Кури Win Api или ищи какие-нибудь унифицированные мультиплатформенные библиотеки.
Как вариант - перехватывать нажатия клавиш, а консолью управлять самостоятельно (т.е. создать альтернативу стандартному вводу) - это будет простейшим решением, наверное. Почитай про создание простейших графических приложений на Win Api - принцип тот же, только с консолью.
Главное - не принимай виндовые примочки за что-то единственное. Знай, что это лишь частный случай реализации Api. Абстрагирование - наше всё.

Добавлено позже:
Вообще я палку перегнул немного. В данном случае - достаточно будет просто перехватывать нажатия клавиш и фильтровать их.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #71 : 13 Февраль 2011, 23:44:24 »
Цитата: HoRRoR
Вообще я палку перегнул немного. В данном случае - достаточно будет просто перехватывать нажатия клавиш и фильтровать их.
Ну я вот тоже об этом думал, только не знаю как реализовать чтобы повсюду работало и надеялся что какая-то из стандартных библиотек это умеет и она доведена до ума  :)

Добавлено позже:
А как у c++ обстоят дела с прерываниями? У меня тут по OS лабораторная где нужно их реализовать, примеры даны на паскале и asm'е, а можно ли реализовать это же на c++ ? У меня всё равно не даны указания на каком языке писать программу с их использованием. Среди примеров есть например обработка прерываний клавиатуры за каскадной схемой (подменяет стандартный обработчик прерываний так что при отпускании клавиши на клавиатуре звучит сигнал). Это же самое но на с++ реально ли реализовать вообще? Я так понимаю раз с++ унаследовал всё от с, который был придуман в бородатые времена и который слегка смахивает на asm то и возможность обработки прерываний должна бы быть, мои рассуждения правильные?

Добавлено позже:
Задание скорее всего у меня будет такое: сделать обработчик прерываний таймера, который после установки каждые 10 секунд подаёт звуковой сигнал и вызывает моргание светодиодов на клаве (наверное имеются в виду индикаторы капса, намлока и scroll лока) на 1 секунду. Парадокс конечно в том что на клаве у пк где мы сдаём лабы нет светоидов.
Реально это будет сделать на с++? Или проще на асме?

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #72 : 14 Февраль 2011, 01:03:37 »
C++ не смахивает на asm по определению. Но возможностей его хватит на что угодно. Тем более, если учесть, что паскаль менее гибок в этом плане.
Лучше делал бы на асме - обычно суть этих лаб - показать, как всё работает на самом низком уровне. C++ уже будет некой оболочкой, но на нём должно быть проще.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #73 : 14 Февраль 2011, 11:50:46 »
Цитата: HoRRoR
Лучше делал бы на асме - обычно суть этих лаб - показать, как всё работает на самом низком уровне. C++ уже будет некой оболочкой, но на нём должно быть проще.
Понятно, ну я сегодня ещё у преподши уточню можно ли его на с++ делать, а потом буду решать уже. Может она хочет видеть работу только на asm и проблема выбора отпадёт сама собой :)

Добавлено позже:
Цитата: HoRRoR
C++ не смахивает на asm по определению.
Это я о обычном с так отозвался. С++ конечно не похож.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #74 : 14 Февраль 2011, 17:03:09 »
Это я о обычном с так отозвался. С++ конечно не похож.
В смысле об обычном? Язык высокого уровня и ассемблер - принципиально разные вещи.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #75 : 14 Февраль 2011, 19:21:41 »
Цитата: HoRRoR
В смысле об обычном? Язык высокого уровня и ассемблер - принципиально разные вещи.
Я о обычном си, с его всеми функциями похожими на асм.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #76 : 14 Февраль 2011, 20:17:48 »
Я о обычном си, с его всеми функциями похожими на асм.
Чем же? Меня немного шокируют твои заявления.
Да и чем функции C принципиально отличаются от функций C++? Мне было бы интересно знать.
Значимых различий между этими языками не так уж много, скорей лишь разница в количестве возможностей. Грубо говоря, C++ - это дополненный до ООП и слегка модифицированный C.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #77 : 14 Февраль 2011, 22:07:35 »
HoRRoR, да хотя бы принт с его тараканами :)

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #78 : 14 Февраль 2011, 22:10:52 »
Ничего не понял из твоих слов. Объясни подробно что ты имеешь ввиду.

Оффлайн Mr2

  • Пользователь
  • Сообщений: 1594
  • Пол: Мужской
  • Free roaming sorcerer
    • Facebook
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #79 : 14 Февраль 2011, 22:11:39 »
HoRRoR, да хотя бы принт с его тараканами :)
Да. После << я в него(print) даже вникать не стал. :)

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #80 : 15 Февраль 2011, 01:22:23 »
О боже мой, вот вы о чём. Ну это бред, извините, сравнивать вывод в поток и функцию. Почитайте про перегрузку операторов, прежде чем считать использование оператора за функцию. Конечно, можно заставить оператор вызывать функцию, но это уже другой вопрос.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #81 : 15 Февраль 2011, 19:58:38 »
HoRRoR,ты меня изначально не понял по этому поводу, тут схожесть как в том случае когда друг увидев мой телефон сказал "у меня такой же, только серый и раскладушка"  :) Я не о том что си это низкоуровневый язык вроде asm'а или что они реализованы похоже как ты наверное подумал изначально.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #82 : 15 Февраль 2011, 22:59:12 »
Ты можешь нормальным языком изложить свои мысли? Так, чтобы я однозначно тебя понял?
Ты сравниваешь принципиально разные вещи, вот я и хочу узнать, что же ты в них общего нашёл.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #83 : 15 Февраль 2011, 23:16:01 »
HoRRoR,наличие указателей всюду где только можно и вообще непривычная (для меня) конструкция многих функций. Примеры:
scanf ("%d%f",&x,&y)
printf("%s", message)

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #84 : 15 Февраль 2011, 23:45:25 »
Где связь вышесказанного с:
1. Схожестью функций си и функций ассемблера?
2. Различием между функциями си и функциями си плюс плюс?
Для меня это сейчас как вырванная из контекста фраза.
А указатели только там, где они нужны. Тебе надо вникнуть в принципы работы, чтобы понять, что это такое и зачем они нужны.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #85 : 16 Февраль 2011, 00:18:54 »
HoRRoR,я уже тебе написал что схожесть минимальная и она остаётся схожестью и это лично мне оно похоже. Я отлично понимаю что есть разница между asm кодом вида mov es, ax и кодом на си.
Цитата: HoRRoR
2. Различием между функциями си и функциями си плюс плюс?
Нулевое если учитывать что можно использовать всё что осталось от си. И большое если использовать тот же самый вывод в поток вместо print, ловить ввод через опять же таки поток, а не через get. функции.
Цитата: HoRRoR
Тебе надо вникнуть в принципы работы, чтобы понять, что это такое и зачем они нужны.
Я вник до уровня что они нужны для удобства и экономии памяти.
А вообще пустой диалог получается, я так понимаю ты изучил си и знаешь его хорошо и поэтому для тебя он удобен, мне же он не привычен и сравним с asm'ом, который опять же мне не удобен (оба одинаково неудобны и поэтому для меня явл. взаимозаменяемыми понятиями) , а тебе тоже хорошо знаком. Вот потому то тебе и сложно меня понять. Надеюсь хоть в этот раз я более-менее понятно выразился, предлагаю дальше уже не докапываться где же схожесть си и asm'а так как они могут быть похожи лишь внешне и лишь тем кто с ними мало знаком вроде меня  :)

Добавлено позже:
Кстати нашёл удобную кнопочку в Code::Blocks в одной из менюшек для добавления файлов в текущий проект (даже если проекта по сути то и нет), делается всё в 2 клика после того как открыт любой cpp файл, в том числе и любой файл от примера Дейтела.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #86 : 16 Февраль 2011, 02:52:39 »
Ладно, закроем эту тему, пока мой мозг не вытек в образовавшиеся трещины.

Цитата
Я вник до уровня что они нужны для удобства и экономии памяти.
Ну, иногда. Но дело, в принципе, в другом - без них многие вещи реализовать не представляется возможным и это, можно сказать, часть архитектуры программно-аппаратных решений, даже в каком-то смысле элемент её фундамента. Поработай с памятью напрямую, с объектами классов через указатели на них, с массивами побольше поработай, с динамическими в т.ч. Ещё бы в ассемблер повникать не помешало - когда увидишь, как это работает, то и суть поймёшь.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #87 : 16 Февраль 2011, 16:24:53 »
Цитата: HoRRoR
Ещё бы в ассемблер повникать не помешало - когда увидишь, как это работает, то и суть поймёшь.
Ну они указывают на участок памяти, если присвоить им адрес переменной то будут указывать на ту же память где храниться переменная, так?
Цитата: HoRRoR
с объектами классов через указатели на них
Ну я пробовал возвращать значения в виде указателя на элемент класса, но преимуществ не заметил да и Дейтел написал что это опасно и что это плохой стиль так как пользователь может подсунуть потом что угодно и программа из-за этого будет некорректно работать  :)

Кстати: а может ли функция возвращать сразу несколько значений? Мне с самого начала было интересно.

И ещё я тут Дейтела пример рассматриваю и вот у него некоторые строчки без комментов, прокомментируйте пожалуйста (это конструктор если что):
Employee::Employee( const char * const first, const char * const last,  //W
   const Date &dateOfBirth, const Date &dateOfHire )                    //T
   : birthDate( dateOfBirth ),                                          //F
     hireDate( dateOfHire )                                             //?
Конкретно интересует первая строчка, это 2 константных указателя на константные данные, wright? Ну а 3я и 4я как я понимаю это инициализация уже переменных класса.
« Последнее редактирование: 16 Февраль 2011, 16:35:44 от gepar »

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #88 : 16 Февраль 2011, 18:58:12 »
Цитата
Ну они указывают на участок памяти, если присвоить им адрес переменной то будут указывать на ту же память где храниться переменная, так?
Всё верно, но мне кажется, что ты всё же не совсем понимаешь их предназначение.

Цитата
Ну я пробовал возвращать значения в виде указателя на элемент класса, но преимуществ не заметил да и Дейтел написал что это опасно и что это плохой стиль так как пользователь может подсунуть потом что угодно и программа из-за этого будет некорректно работать
Глупости какие-то Дейтел говорит. В кривых руках всё опасно.
Как ещё организовывать передачу объектов класса, как не через указатели? Вариант, конечно, через ссылки, но это не всегда удобно. Создавать копии или временные экземпляры в большинстве случаев не имеет смысла.

Цитата
Кстати: а может ли функция возвращать сразу несколько значений? Мне с самого начала было интересно.
Да, но через return только одно. Ты можешь передавать значения по указателям или ссылкам.
void foo_ref(int &a1, int &a2)
{
  a1 = 1;
  a2 = 2;
}

// Более опасно, желательно проверять на NULL:
void foo_ptr(int *a1, int *a2)
{
  *a1 = 1;
  *a2 = 2;
}

Цитата
Конкретно интересует первая строчка, это 2 константных указателя на константные данные, wright? Ну а 3я и 4я как я понимаю это инициализация уже переменных класса.
Всё верно.
Employee::Employee(
  const char * const first, // Константный указатель на константный char (ни указатель, ни данные по нему менять нельзя)
const char * const last,  // Константный указатель на константный char
   const Date &dateOfBirth, const Date &dateOfHire )                    // Константные ссылки на переменные типа Date
   : birthDate( dateOfBirth ),                                          // birthDate = dateOfBirth
     hireDate( dateOfHire )                                             // hireDate = dateOfHire

Ссылка - это что-то вроде второго имени для существующей переменной. По сути это как бы автоматический указатель, который нельзя менять - он всегда указывает на переменную, для которой был создан и автоматически разадресовывается. Т.е. работать с ней можно как с переменной, на которую она указывает. Иногда имеет смысл передавать переменные через ссылки (например, когда указатели не совсем удобны) - тогда не создаются копии переменных. Ну, или когда необходимо менять переменную внутри вызываемой функции.
« Последнее редактирование: 16 Февраль 2011, 19:02:58 от HoRRoR »

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #89 : 17 Февраль 2011, 19:33:43 »
HoRRoR, ага, с const понял, спасибо.
Нуждаюсь в хорошей статье по динамическим структурам (Дейтел писал только об обычных, а мне нужно сделать лабораторную по динамическим) может у кого завалялась ссылка, только на англ. не подойдёт информация. У меня ещё по ним пример есть в лабе, но он мне как-то не особо понятен.
#include <iostream.h>
struct Node{
int d; //информационное поле
Node *next; //указатель на следующий
Node *prev; //указатель на предыдущий
};
/*описание прототипов функций */
Node * first(int d); //инициализация списка (создание первого эл-та)
void add(Node **tail, int d); //добавление в конец
Node * find(Node * const head, int i); //поиск по ключу элемента
bool remove(Node **head, Node **tail, int key); //удаление
Node * insert(Node * const head, Node **tail, int key, int d); //вставка элемента в список
//----
int main()
{
// Формирование первого элемента списка
Node *head = first(l);
// устанавливаем указатель на конец на первый элемент списка
Node *tail = head;
// Добавление в конец списка четырех элементов 2, 3, 4, и 5:
for (int i = 2; i<6; i++) add(&tail, i);
// Вставка элемента 200 после элемента 2:
insert(head, &tail, 2, 200);
// Удаление элемента 5:
if(!remove (&head, &tail, 5)) cout << "не найден";
// вывод списка на экран
Node *pv = head;
while (pv){
cout << pv->d << ' ';
pv = pv->next;
}
return 0;
}
//описание функций
// Формирование первого элемента (инициализация списка)
Node * first(int d)
{
Node *pv = new Node; //выделение памяти под первый элемент
pv->d = d; //заполнение информационной части
pv->next = 0; //формирование указателя на следующий (на конец)
pv->prev = 0; //формирование указателя на предыдущий (на конец)
return pv; //возврат указателя на голову (первый элемент)
}
// Добавление в конец списка
void add(Node **tail, int d)
{
Node *pv = new Node; //выделение памяти под создаваемый элемент
pv->d = d; //заполнение инф. поля
pv->next = 0; //формирование указателя на следующий (конец)
pv->prev = *tail; //формирование указателя на предыдущий
(*tail)->next = pv;
//изменение указателя на следующий предыдущего элемента
*tail = pv; //изменение указателя на хвост
}
// Поиск элемента по ключу
Node * find(Node * const head, int d)
{
Node *pv = head; //берем первый элемент списка
while (pv) //просматриваем список до конца
{
if(pv->d == d)break;
//если нашли элемент с соответствующим ключом, выходим из цикла
pv = pv->next; //переходим к следующему элементу
}
return pv; //возвращаем указатель на найденный элемент, //если искомый элемент не найден – возвращаемое значение pv=0
}
// Удаление элемента
bool remove(Node **head, Node **tail, int key)
{
if(Node *pkey = find(*head, key)){ // 1
if (pkey == *head){ // 2
*head = (*head)->next;
(*head)->prev =0;}
else
if (pkey == *tail){ // 3
*tail = (*tail)->prev;
(*tail)->next = 0;}
else{ // 4
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;}
6
delete pkey;
return true; // 5
}
return false; // 6
}
// Вставка элемента после заданного
Node * insert(Node * const head, Node **tail, int key, int d)
{
if(Node *pkey = find(head, key)) //если заданный элемент найден
{
Node *pv = new Node; //выделяем память под новый элемент
pv->d = d; //заполняем инф. поле
// 1 - устанавливаем связь нового узла с последующим:
pv->next = pkey->next;
// 2 - устанавливаем связь нового узла с предыдущим:
pv->prev = pkey;
// 3 - устанавливаем связь предыдущего узла с новым:
pkey->next = pv;
// 4 - устанавливаем связь последующего узла
//(не последнего !) с новым:
if( pkey != *tail) (pv->next)->prev = pv;
//иначе обновление указателя на конец списка,
//так как узел вставляется в конец:
else *tail = pv;
return pv; //возвращаем указатель на вновь созданный элемент
}
return 0;
}

Например мне непонятно что такое void add(Node **tail, int d); и прочие строки где есть по две звёздочки, что это? Не указатель на указатель на элемент же  :)