![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| sergejzr |
|
|||
![]() Un salsero Профиль Группа: Админ Сообщений: 13285 Регистрация: 10.2.2004 Где: Германия г .Ганновер Репутация: 19 Всего: 360 |
ссылка хорошая, но для новичков ИМХО чуточку слишком много ...
Надо бы на пальцах.. |
|||
|
||||
| ManiaK |
|
|||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
sergej.z Статья уже есть или мне можно приниматься?..
|
|||
|
||||
| sergejzr |
|
|||
![]() Un salsero Профиль Группа: Админ Сообщений: 13285 Регистрация: 10.2.2004 Где: Германия г .Ганновер Репутация: 19 Всего: 360 |
Нет статьи
|
|||
|
||||
| ManiaK |
|
||||||||||||||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Не вопрос!..
Типы данных. Сказанное ниже гарантировано соотносится со спецификациями Си/Си++. Наверняка во многих других языках действуют похожие правила. 1. Простые типы данных. К простым типам относят: одиночные символы, любые числовые переменные и пр.
2. Сложные типы данных. К сложным типам данных относят для Си - структуры, объединения и массивы; для Си++ - тоже + классы. Сложные типы можно также назвать составными, т.к. они в конечном итоге всё равно содержат в себе простые (сложный тип = набор простых). Важно понять, что процессор не умеет работать со сложными типами. Он не может понять, что такое std::string или char[10]. Для него это - набор простых типов. Программист так же никогда не работает со сложными типами напрямую - он работает только с указателями на сложные типы. Что это такое разберём дальше. 3. Указатели. Любой указатель принадлежит простому типу и содержит в себе адрес определённой ячейки памяти. Чаще всего в 32-битных процессорах x86 используют 32-битные же указатели. Проще говоря, в большинстве случаев любой указатель имеет тип unsigned int. Программист работает со сложными объектами только при помощи указателей. Даже когда он видит перед собой объект типом char[10] он должен знать, что это - лишь указатель на область памяти, где находится десять переменных простого типа char. Типы int* и int[] абсолютно идеинтичны - это указатели на массивы памяти. Разница только в одном: один из этих указателей динамический, а другой статический. Что это такое? Проще пояснить примером:
Первый массив называют статическим, второй - динамическим. Соответственно, переменная iArray - статическая, pInt - динамическая. Кстати, если вы напишете вот это:
То вы получите десять переменных-указателей и ни одного массива. Чтобы получать массивы динамическим образом ("на ходу") вам необходимо самостоятельно вызвать оператор new или функцию выделения памяти и после завершения использования - удалить массив вызовом delete или функцией освобождения памяти. Со статическими массивами проще - там компилятор сам решает где взять память и когда её освободить, причём делает и то и другое с необыкновенной быстротой, потому как всё это определяется ещё на моменте компиляции, а не в процессе исполнения. Казалось бы, все преимущества статических переменных на лицо, зачем же использовать динамические? Не торопитесь.
Теперь можно привести примеры с извечной проблемой строк, которая проблемой по сути является только для новичков (камень в огород Си-ненавистников).
Почему первая строка работает, а вторая - сбоит? Всё просто. "STRING" - константный набор данных. Откройте свою программу любым текстовым редактором - вы там без труда найдёте эту строку. В первой строке вышеприведённого кода происходит присвоение указателю char* str адреса константной области данных, содержащей "STRING". При попытке изменить эту область операционная система даёт нам оплеуху и выкидывает программу из списка процессов. Вот этот код работает:
Лучше такой экзотикой не заниматься, а писать сразу в вызов функции strcpy строку "STRING", потому как никто не гарантирует, что где-нибудь в губине кода не произойдёт следующее:
---------- Думаю достаточно понятно объяснил. Если нет - критикуйте, поправлю. Могу продолжить тему и написать что-нибудь вроде "Трюкачи на Си++", но в принципе, говорят, по этому делу есть множество книг Это сообщение отредактировал(а) ManiaK - 31.5.2005, 18:58 |
||||||||||||||
|
|||||||||||||||
| Mayk |
|
||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Несколько ЗУП (замечаний/уточнений/предложений):
1) Про всеми любимый strcat забыл. 2)
Для блеска: лучше что-нибудь типа "по размеру совпадает с unsigned long" - ибо 1) Сработает и для 64 битных компов тоже, и для 16битного доса с оговоркой, что это FAR указатель. 2) Указатели все же имеют тип указателя. 3)
Не правда. pInt - это как раз массив из десяти указателей. Если бы я был новичком, меня бы это могло спутать: как так, [10] есть, а массива нет? Я б вообще мог решить что TYPE* blahblah[] некорректно, и надо юзать только одно - либо TYPE*=new, либо TYPE[]. 4) Опять же, если бы я был новичком в сях, то я считал бы,что первый элемент массива имеет индекс 1, а не 0. То есть я считал бы a[0] бредом(а a[-2] вообще научной фантастикой) А что есть "трюкачи для С++"? Типа a^=b,b^=a,a^=b? Тогда давай! Это сообщение отредактировал(а) Mayk - 31.5.2005, 19:44 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||
|
|||||||
| kometa_triatlon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 384 Регистрация: 7.1.2005 Где: Киев Репутация: 2 Всего: 6 |
ManiaK
Продолжать будешь? Как насчет строк в STL, std::string? Вообще хотелось бы прочитать все возможное о строках. Или хотя бы РАБОТУ со строками, это же лишь введение, показано лишь как правильно объявлять, удалять... -------------------- Всё очень просто: сказки обман, Солнечный остров скрылся в туман, Замков воздушных не носит земля, Кто-то ошибся, ты или я. -------------- Программирование - самое большое удовольствие, которое вы можете получить, будучи одетым. |
|||
|
||||
| kometa_triatlon |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 384 Регистрация: 7.1.2005 Где: Киев Репутация: 2 Всего: 6 |
Несколько важных моментов для новичков и тех, кто переходит с Паскаля:
Добавлено @ 20:14 И еще. Кавычки Ух, сколько дельфистов ломают себе голову, почему не работает
Дело в том, что одинарные кавычки применяются только для символов, для строк - двойные. Это сообщение отредактировал(а) kometa_triatlon - 31.5.2005, 20:08 -------------------- Всё очень просто: сказки обман, Солнечный остров скрылся в туман, Замков воздушных не носит земля, Кто-то ошибся, ты или я. -------------- Программирование - самое большое удовольствие, которое вы можете получить, будучи одетым. |
||||||||
|
|||||||||
| ManiaK |
|
|||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Mayk за пункт 3 и 4 - спасибо! сейчас поправлю статью. Насчёт "трюкачей" - это например:
Вообщем "подводные камни" на тему типов данных и шаблонов. kometa_triatlon Напишем! Можно даже нечто вроде урока "пишем свой класс строк" со всеми подробностями. STL - без вопросов!.. |
|||
|
||||
| Void |
|
||||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Об этом действительно стоит написать не статью, а целую книгу... и не одну... И такие книги есть. И вообще, речь изначально о новичках шла
Вот это, имхо, будет очень хорошое пособие по "классостроению в C++ для начинающих"! Поддерживаю! (к сожалению, только морально, ибо сессия -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
||||
|
|||||
| ManiaK |
|
||||||||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Пишем свой класс строк.
0. Объяснительная. Прежде чем использовать что-то, уже сделанное "дядями", я считаю, лучше понять, как оно работает. Проще всего, по моему мнению, это сделать написав что-нибудь самому. Особенно это хорошо работает в данном случае - мы не операционную систему писать всё-таки собираемся и потому базис можно собрать за относительно небольшой промежуток времени. 1. А что нам, собственно, надо? Для начала определимся, что должен делать наш класс по определению, без чего он вообще жить не может. Для многих начинающих программистов этот вопрос является едва ли не самым сложным. Вот мой список: 1) Класс должен полностью замещать Си-строку. В идеале, везде, где можно воткнуть char* мы должны воткнуть String, но я по ряду причин отказался от данной технологии и остановился на функциях GetCStr. 2) Присвоение. 3) Конкатенация (сложение). 4) Вставку строк/символов в определённое место. 5) Вырезание отдельных символов/строки. 6) Сравнение. 7) Замена. 8) Поиск строк/символов с заданной позиции. 9) Поиск числа вхождений строк/символов. 10) Преобразование строк в численные типы и обратно. Для ускорения написания статьи я буду использовать собственный класс QString. Большинство функций его отлажено и проверенно временем, но некоторые (особенно редко использующиеся) могут содержать некоторые ошибки. Так что, проверяйте, как говорится, "если что - я не виноват":) 3. Пишем объявление класса. Мой метод написания классов: пишу сначала объявление (то, что в *.h находится) не вдаваясь ни в какие подробности реализации и только потом берусь за проработку каждой отдельной функции. Этот метод позволяет на первой стадии не отвлекаться на мелочи и "сверху" взглянуть на проблему, уловить некоторые моменты, про которые можно просто забыть. Так как я использую класс из собственной библиотеки, типы данных у меня объявлены по-своему. Если кому-то не понравится - на то есть операция "Замена" в любом текстовом редакторе. Лично мне кажется, что подобное объявление хоть и приводит к излишей писанине, значительно упрощает чтение программы. Итак, вот список typedef-определений:
Как видите, не трудно "угадать" что под чем скрывается даже при первом прочтении. Только теперь вспомнил: мой класс работает только со строками char*. Но ведь, я думаю, не трудно будет это и самому переделать "по аналогии"?.. Вот декларация базового класса из моей библиотеки: (пара функций и данные будут использоваться в строковом классе, потому привожу здесь. Код копировать не буду - всё элементарно, никаких операций практически не выполняется. Если же будут у кого проблемы - напишу, обращайтесь)
Как видите, всё просто. Аллокатор у меня свой, однако это ни на что не должно влиять. Прошу обратить внимание на все эти "const" разбросаные по всему классу: говоря словами Д. Элджера, подобную технологию надо использовать с полным фанатизмом, либо не использовать вовсе, причём приветствуется первое. Однако это не так просто, особенно когда происходят стыковки со сторонними бибиотеками, где константы не используют - вот тут-то, случается, ночи напролёт боёв с компилятором!.. Теперь декларация класса строки:
У вас в глазах не рябит? Кстати, если вы уже заметили, этот класс совершенно изолирован и может использоваться сам по себе, без подключения даже стандартных string.h или stdlib.h. Разумеется, это только для заголовочного файла - при реализации всё равно придётся на что-то опираться (хотя бы из соображений эфективности). Вопреки опУпсевшемуся уже оператору приведения к char*, я его не включил в список. Хотя бы уже из соображений безопастности (никто не гарантирует мне, что переданный указатель на m_pData будет использоваться только для чтения). Однако вы можете это сделать сами вставив всего одну строчку в декларацию класса:
Разделю-ка я на два поста статейку... Реализация - в следующем. Это сообщение отредактировал(а) ManiaK - 31.5.2005, 22:02 |
||||||||
|
|||||||||
| Void |
|
||||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
В глаза бросилось... И еще - value-типы передавать с модификатором const, имхо, немножко некрасиво... и бессмысленно Это сообщение отредактировал(а) Void - 31.5.2005, 21:17 -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
||||
|
|||||
| ManiaK |
|
||||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Не вижу такого. У меня вот:
Про value-типы скажу ещё. |
||||
|
|||||
| Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
А это поправка -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
| ManiaK |
|
|||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Любопытно:) Я раньше на это внимания не обращал, спасибо!:)
|
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Хмм. А в статье нельзя обойти использование наследования?
Это ведь вроде как для новичков? Если бы я опять был новичком, то слова "allocator, QObject<Char_t>, operator" были бы для меня открытыием. "operator Int_t const ()" я б вообще не понял. Кстати, оно тут вообще надо? Предположим есть функция myConnect(const QString& host, int port), а мы напишем myConnect(123, someHost()). QString host получится из конструктора (кстати, const int в конструкторе - это перебор), someHost() преобразуется в int, а в результате получится совсем не то, что надо. Ну их нафиг эти приведения типов. ИМХО. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |