C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Сложение строк / C++ для начинающих / C++

Сложение строк

Не вопрос!..

Типы данных.

Сказанное ниже гарантировано соотносится со спецификациями Си/Си++. Наверняка во многих других языках действуют похожие правила.

1. Простые типы данных.

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

Код

char ch;// один 8-битный символ (в разных компиляторах может быть unsigned или signed)
unsigned char uch;// гарантированно беззнаковая 8-битная переменная; байт проще говоря
signed char sch;// гарантировано знаковая 8-битная переменная; минус один бит на знак
int i;// целочисленная переменная со знаком
unsigned int ui;// целочисленная переменная без знака
float fl;// число с плавающей точкой


2. Сложные типы данных.

К сложным типам данных относят для Си - структуры, объединения и массивы; для Си++ - тоже + классы. Сложные типы можно также назвать составными, т.к. они в конечном итоге всё равно содержат в себе простые (сложный тип = набор простых). Важно понять, что процессор не умеет работать со сложными типами. Он не может понять, что такое std::string или char[10]. Для него это - набор простых типов. Программист так же никогда не работает со сложными типами напрямую - он работает только с указателями на сложные типы. Что это такое разберём дальше.

3. Указатели.

Любой указатель принадлежит простому типу и содержит в себе адрес определённой ячейки памяти. Чаще всего в 32-битных процессорах x86 используют 32-битные же указатели. Проще говоря, в большинстве случаев любой указатель имеет тип unsigned int. Программист работает со сложными объектами только при помощи указателей. Даже когда он видит перед собой объект типом char[10] он должен знать, что это - лишь указатель на область памяти, где находится десять переменных простого типа char. Типы int* и int[] абсолютно идеинтичны - это указатели на массивы памяти. Разница только в одном: один из этих указателей динамический, а другой статический. Что это такое? Проще пояснить примером:
Код

int iArray[10];// Создаётся десять переменных типом int следующих в памяти друг за другом и тут же -
// создаётся константа(!) типом int* - указатель; причём переменной "указатель" тут же автоматически
// присваивается значение адреса десяти int-овых переменных - всё в одной строчке!

int* pInt;// Создаётся только(!) переменная типом int*; никакого массива мы ещё не получили!
pInt = new int[10];// Вот теперь всё в порядке; функция(в Си - оператор) new создаёт десять
// переменных типом int и возвращает адрес на первую из этих переменных, который
// присваивается переменной-указателю pInt

Первый массив называют статическим, второй - динамическим. Соответственно, переменная iArray - статическая, pInt - динамическая. Кстати, если вы напишете вот это:
Код

int* pInt[10];

То вы получите десять переменных-указателей и ни одного массива. Чтобы получать массивы динамическим образом ("на ходу") вам необходимо самостоятельно вызвать оператор new или функцию выделения памяти и после завершения использования - удалить массив вызовом delete или функцией освобождения памяти. Со статическими массивами проще - там компилятор сам решает где взять память и когда её освободить, причём делает и то и другое с необыкновенной быстротой, потому как всё это определяется ещё на моменте компиляции, а не в процессе исполнения. Казалось бы, все преимущества статических переменных на лицо, зачем же использовать динамические? Не торопитесь.
Код

int* i = new int;// Тоже массив, кстати. Правда содержит всего один элемент...
// какие-то операции с i
delete i;// Освобождаем старый массив (указатель никуда не девается!)
i = new int [10];// Создаём новый, значительно больше прежнего

int iA[10];
delete iA;// Ошибка!
iA = new int[12];// Тоже самое...

int nElements = 0;
// Вычисление значения nElements
int iArray[nElements];// Ошибка! Рамер должен быть константным!
int pArray = new int[nElements];// Никаких проблем, всё работает...

Теперь можно привести примеры с извечной проблемой строк, которая проблемой по сути является только для новичков (камень в огород Си-ненавистников).
Код

char* str = "STRING";// Глупо выглядит, но эта строчка - работает!
strcpy(str, "А вот эта - нет");

Почему первая строка работает, а вторая - сбоит? Всё просто. "STRING" - константный набор данных. Откройте свою программу любым текстовым редактором - вы там без труда найдёте эту строку. В первой строке вышеприведённого кода происходит присвоение указателю char* str адреса константной области данных, содержащей "STRING". При попытке изменить эту область операционная система даёт нам оплеуху и выкидывает программу из списка процессов. Вот этот код работает:
Код

char* str = "STRING";// Тишина... и мёртвы с косами ходят...
char* s = new char[7];
strcpy(s, str);// Ей богу, на воровство похоже!

Лучше такой экзотикой не заниматься, а писать сразу в вызов функции strcpy строку "STRING", потому как никто не гарантирует, что где-нибудь в губине кода не произойдёт следующее:
Код

str[3] = 'O';// Забыли мы где находимся :-)


----------

Думаю достаточно понятно объяснил. Если нет - критикуйте, поправлю. Могу продолжить тему и написать что-нибудь вроде "Трюкачи на Си++", но в принципе, говорят, по этому делу есть множество книг:)
Автор: ManiaK