Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Указатели в C.docx
Скачиваний:
4
Добавлен:
08.08.2019
Размер:
34.26 Кб
Скачать

Void main()

{

int number;

int *pNumber = number;

delete pNumber;// ошибка - память для *pNumber не была выделена при помощи new.

}

Общие вопросы и ЧаВо

Вопрос: Почему я получаю ошибки "symbol undefined" при использовании new и delete?

Ответ: вероятнее всего, это происходит потому, что ваш исходный код интерпретируется компилятором как написанный на языке C. Операторы new и delete являются новыми возможностями языка C++. Ситуацию обычно можно исправить, указав для исходных файлов расширение *.cpp вместо *.c

Вопрос: в чем разница между new и malloc?

Ответ: Оператор new существует только в языке C++ и является стандартным (за исключением особых функций в Windows) способом выделения памяти. Вы не должны использовать malloc в C++, разве что в случае крайней необходимости. Поскольку malloc не был разработан для объектно-ориентированных возможностей языка C++, его использование для выделения памяти для классов приведет к тому что конструктор класса вызван не будет, как пример того какие проблемы могут возникнуть. В результате проблем возникших при использовании malloc и free, а также, потому что они устарели для любого использования (в языке C++) в этой статье они не обсуждаются детально. Я не одобряю использование этих функций, где бы то ни было.

Вопрос: можно ли использовать free и delete вместе?

Ответ: Вы должны освобождать память тем же механизмом, которым вы её выделяли. Например, используйте free только в случае если память выделялась функцией malloc, delete используется только если память выделялась при помощи new, и так далее.

Ссылки

Ссылки определенно находятся вне темы этой статьи. Но поскольку меня очень часто спрашивали о ссылках люди, которые читали эту статью, я опишу их кратко. Ссылки очень схожи с указателями и в большинстве случаем они могут быть использованы как альтернатива указателям. Как вы помните я уже писал что амперсанд (&) читается при объявлении как "адрес переменной ...". В случае присутствия амперсанда в объявлении в том виде, который показан ниже - его следует читать как "ссылка на переменную ...".

int& Number = myOtherNumber;

Number = 25;

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

int* pNumber = &myOtherNumber;

*pNumber = 25;

Другое отличие между указателями и ссылками это то, что вы не можете "сбросить" ссылку. Это означает что нельзя изменять значение адреса ссылки после того как она была инициализирована. Например, код ниже выведет "20":

int myFirstNumber = 25;

int mySecondNumber = 20;

int &myReference = myFirstNumber;

myReference = mySecondNumber;

printf("%d", myFristNumber);

При использовании в классе, значение ссылки должно быть установлено в конструкторе следующим образом:

CMyClass::CMyClass(int &variable) : m_MyReferenceInCMyClass(variable)

{

// код конструктора

}

Заключение

Тему указателей сложно освоить с первого раза, так что стоит просмотреть всё заново. Большинство людей не понимает всё с первого прочтения. Вот основные моменты снова:

Указатели это переменные, которые указывают на область памяти. Вы объявляете указатель добавляя звездочку (*) перед именем переменной (int * number).

Вы можете получить адрес переменной, добавив амперсанд (&) перед её именем, например pNumber = &my_number.

Звездочка при объявлении переменной (например, int * number), читается как "адрес памяти который указывается переменной ...".

Амперсанд при объявлении переменной (например, int &number), читается как "адрес переменной ..."

Вы можете выделять память, используя оператор new.

Указатели ДОЛЖНЫ быть того же типа что и переменные на которые вы хотите чтобы они указывали. Например, int *number не будет указывать на MyClass.

Вы можете передавать указатели в функции.

Вы должны удалит память, которая была выделена при помощи оператора delete.

Вы можете получить указатель на массив, который уже существует следующим образом: &array[0];.

Вы должны удалить массив память, для которого была динамически выделена следующим образом: delete[], а не просто delete.

Это не абсолютно полное руководство по работе с указателями. Есть еще много вещей, которые я мог бы раскрыть более детально, таких как указатели на указатели, и тем, которых я не коснулся вообще, например, функциональных указателей, которые слишком сложны для этой статьи. Так же есть вещи, которые используются слишком редко, чтобы сбивать начинающих с толку обилием деталей.

Вот и все! Попробуйте запустить код представленный в этой статье и придумать ещё какие-нибудь свои вариации и примеры.

-------------------------------------------------------------------------------

http://translated.by/you/a-beginner-s-guide-to-pointers/into-ru/trans/

© Andrew Peace

Original (English): A Beginner's Guide to Pointers (http://www.codeproject.com/KB/cpp/pointers.aspx)

Translation: © Mr.ElectroNick, Someone.else, Grigoriy, m0nhawk, Dmitry-Leushin, ventalf, voxpuibr, Axx, dShadow.

License: The Code Project Open License (CPOL)

translated.by crowd