C ++

Как использовать указатели C ++

Как использовать указатели C ++
Память компьютера - это длинный ряд ячеек. Размер каждой ячейки называется байтом. Байт - это пространство, занятое английским символом алфавита. Объект в обычном понимании - это последовательный набор байтов в памяти. Каждая ячейка имеет адрес, который представляет собой целое число, обычно записанное в шестнадцатеричной форме. Есть три способа доступа к объекту в памяти. Доступ к объекту можно получить с помощью так называемого указателя. Доступ к нему можно получить, используя так называемую ссылку. К нему по-прежнему можно получить доступ с помощью идентификатора. В этой статье основное внимание уделяется использованию указателей и ссылок. В C ++ есть заостренный объект и объект-указатель. У остроконечного предмета есть интересующий предмет. Объект-указатель имеет адрес указанного объекта.

Вам необходимо иметь базовые знания C ++, включая его идентификаторы, функции и массивы; чтобы понять эту статью.

У объекта-указателя и объекта-указателя есть свой идентификатор.

Оператор Address-Of, &

Это унарный оператор. Если за ним следует идентификатор, он возвращает адрес объекта идентификатора. Рассмотрим следующее объявление:

int ptdInt;

Ниже приведен код, следующее выражение, вернет адрес, идентифицированный ptdInt:

& ptdInt

Вам не нужно знать точный адрес (номер) при кодировании.

Оператор косвенного обращения, *

Это унарный оператор в контексте указателей. Обычно он печатается перед идентификатором. Если используется в объявлении идентификатора, то идентификатор является объектом-указателем, который содержит только адрес указанного объекта. Если используется перед идентификатором объекта-указателя, чтобы что-то вернуть, то возвращаемое значение является значением указанного объекта.

Создание указателя

Взгляните на следующий фрагмент кода:

float ptdFloat;
float * ptrFloat;
ptrFoat = &ptdFloat;

Сегмент начинается с объявления заостренного объекта ptdFloat. ptdFloat - это идентификатор, который просто идентифицирует объект с плавающей запятой. Ему мог быть присвоен реальный объект (значение), но в этом случае ему ничего не было присвоено. Далее в сегменте идет объявление объекта-указателя. Оператор косвенного обращения перед этим идентификатором означает, что он должен содержать адрес указанного объекта. Тип объекта, плавающий в начале оператора, означает, что заостренный объект является плавающим. Объект-указатель всегда имеет тот же тип, что и заостренный объект. ptrFoat - это идентификатор, который просто идентифицирует объект-указатель.

В последнем операторе кода адрес указанного объекта присваивается объекту-указателю. Обратите внимание на использование оператора адреса &.

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

Объект-указатель может быть объявлен и инициализирован указанным объектом в одной инструкции, как показано ниже:

float ptdFloat;
поплавок * ptrFoat = &ptdFloat;

Первая строка предыдущего сегмента кода и эта одинаковы. Вторая и третья строки предыдущего сегмента кода были объединены здесь в один оператор.

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

В следующем сегменте кода оператор косвенного обращения используется для возврата содержимого указанного объекта.

int ptdInt = 5;
int * ptrInt = &ptdInt;
cout << *ptrInt << '\n';

Выход 5.

В последнем операторе здесь оператор косвенного обращения использовался для возврата значения, на которое указывает идентификатор указателя. Таким образом, при использовании в объявлении идентификатор для оператора косвенного обращения будет содержать адрес указанного объекта. При использовании в возвращаемом выражении в сочетании с идентификатором указателя оператор косвенного обращения возвращает значение указанного объекта.

Присвоение нуля указателю

Объект-указатель всегда должен иметь тип указанного объекта. При объявлении объекта-указателя необходимо использовать тип данных указанного объекта. Однако значение десятичного нуля может быть присвоено указателю, как в следующем сегменте кода:

int ptdInt = 5;
int * ptrInt;
ptrInt = 0;
или в сегменте,
int ptdInt = 5;
int * ptrInt = 0;

В любом случае указатель (идентификатор) называется нулевым указателем; это означает, что это указывает в никуда. То есть у него нет адреса какого-либо указанного объекта. Здесь 0 - это десятичный ноль, а не шестнадцатеричный ноль. Шестнадцатеричный ноль будет указывать на первый адрес памяти компьютера.

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

Имя массива как постоянный указатель

Рассмотрим следующий массив:

int arr [] = 000, 100, 200, 300, 400;

Имя массива, arr - это фактически идентификатор, который имеет адрес первого элемента массива. Следующее выражение возвращает первое значение в массиве:

* обр

В случае с массивом оператор приращения ++ ведет себя иначе. Вместо добавления 1 он заменяет адрес указателя на адрес следующего элемента в массиве. Однако имя массива - это постоянный указатель; это означает, что его содержимое (адрес) не может быть изменено или увеличено. Итак, для увеличения начальный адрес массива должен быть назначен непостоянному указателю следующим образом:

int * ptr = arr;

Теперь ptr можно увеличивать, чтобы указывать на следующий элемент массива. ptr был объявлен здесь как объект-указатель. Без * здесь не было бы указателя; это был бы идентификатор для хранения объекта int, а не для хранения адреса памяти.

Следующий сегмент кода, наконец, указывает на четвертый элемент:

++ptr;
++ptr;
++ptr;

Следующий код выводит четвертое значение массива:

int arr [] = 000, 100, 200, 300, 400;
int * ptr = arr;
++ptr;
++ptr;
++ptr;
cout << *ptr << '\n';

Выход 300.

Имя функции как идентификатор

Имя функции - это идентификатор функции. Рассмотрим следующее определение функции:

int fn ()

cout << "seen" << '\n';
возврат 4;

fn - идентификатор функции. Выражение,

& fn

возвращает адрес функции в памяти. fn похож на заостренный объект. Следующее объявление объявляет указатель на функцию:

int (* функция) ();

Идентификатор указанного объекта и идентификатор объекта-указателя различаются. func - указатель на функцию. fn - идентификатор функции. Итак, func может указывать на fn следующим образом:

func = &fn;

Значение (содержание) func - это адрес fn. Два идентификатора могли быть связаны с помощью оператора инициализации следующим образом:

int (* функция) () = &fn;

Обратите внимание на различия и сходства в обработке указателей функций и скалярных указателей. func - указатель на функцию; это заостренный объект; он объявлен иначе, чем скалярный указатель.

Функцию можно вызвать с помощью,

fn ()
или же
func ()

Его нельзя вызвать с помощью * func ().

Когда функция имеет параметры, вторые круглые скобки содержат типы параметров и не обязательно должны содержать идентификаторы для параметров. Следующая программа иллюстрирует это:

#включать
используя пространство имен std;
float fn (float fl, int in)

возврат эт;

int main ()

поплавок (* функция) (число с плавающей запятой, целое число) = &fn;
float val = func (2.5, 6);
cout << val << '\n';
возврат 0;

Выход 2.5.

Справочник по C ++

Ссылка в C ++ - это просто способ создать синоним (другое имя) для идентификатора. Он использует оператор &, но не так, как & используется для указателей. Рассмотрим следующий фрагмент кода:

int myInt = 8;
int & yourInt = myInt;
cout << myInt << '\n';
cout << yourInt << '\n';

Результат:

8
8

Первый оператор инициализирует идентификатор myInt; я.е. myInt объявлен и содержит значение 8. Второй оператор создает новый идентификатор, yourInt синоним myInt. Для этого в объявлении между типом данных и новым идентификатором помещается оператор &. Операторы cout показывают, что два идентификатора являются синонимами. Чтобы вернуть значение в этом случае, вам не нужно ставить перед ним * . Просто используйте идентификатор.

myInt и yourInt здесь не два разных объекта. Это два разных идентификатора, которые ссылаются (идентифицируют) одно и то же место в памяти, имеющее значение 8. Если значение myInt изменится, значение yourInt также изменится автоматически. Если значение yourInt изменено, значение myInt также изменится автоматически.

Ссылки однотипные.

Ссылка на функцию

Так же, как у вас может быть ссылка на скаляр, вы также можете иметь ссылку на функцию. Однако кодирование ссылки на функцию отличается от кодирования ссылки на скаляр. Следующая программа иллюстрирует это:

#включать
используя пространство имен std;
float fn (float fl, int in)

возврат эт;

int main ()

float (& func) (float, число) = fn;
float val = func (2.5, 6);
cout << val << '\n';
возврат 0;

Выход 2.5.

Обратите внимание на первый оператор в основной функции, который делает func синонимом fn. Оба ссылаются на одну и ту же функцию. Обратите внимание на одноразовое использование и положение &. Итак, & является здесь ссылочным оператором, а не оператором адреса. Чтобы вызвать функцию, просто используйте любое имя.

Идентификатор ссылки - это не то же самое, что идентификатор указателя.

Функция, возвращающая указатель

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

#включать
используя пространство имен std;
float * fn (float fl, int in)

поплавок * fll = &fl;
return fll;

int main ()

float * val = fn (2.5, 6);
cout << *val << '\n';
возврат 0;

Выход 2.5

Первый оператор в функции, fn (), нужен только для создания объекта-указателя. Обратите внимание на одноразовое использование и положение * в сигнатуре функции. Также обратите внимание, как указатель (адрес) был получен в функции main () другим объектом-указателем.

Функция, возвращающая ссылку

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

#включать
используя пространство имен std;
float & fn (float fl, int in)

float & frr = fl;
return frr;

int main ()

float & val = fn (2.5, 6);
cout << val << '\n';
возврат 0;

Выход 2.5.

Первый оператор в функции, fn (), нужен только для создания ссылки. Обратите внимание на одноразовое использование и положение & в сигнатуре функции. Также обратите внимание, как ссылка была получена в функции main () по другой ссылке.

Передача указателя на функцию

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

#включать
используя пространство имен std;
float fn (float * fl, int in)

return * fl;

int main ()

поплавок v = 2.5;
float val = fn (& v, 6);
cout << val << '\n';
возврат 0;

Выход 2.5

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

поплавок * fl = & v;

И fl, и & v указывают на один и тот же заостренный объект, содержащий 2.5. * fl в операторе возврата не является декларацией; это означает, что значение заостренного объекта, на которое указывает объект-указатель.

Передача ссылки на функцию

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

#включать
используя пространство имен std;
float fn (float & fl, int in)

возврат эт;

int main ()

поплавок v = 2.5;
float val = fn (v, 6);
cout << val << '\n';
возврат 0;

Выход 2.5

Обратите внимание на использование и положение & для параметра float в сигнатуре функции. Как только начинается вычисление функции fn (), делается следующий оператор:

поплавок & fl = v;

Передача массива функции

Следующая программа показывает, как передать массив функции:

#включать
используя пространство имен std;
int fn (int массив [])

вернуть массив [2];

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (обр);
cout << val << '\n';
возврат 0;

Выход 200.

В этой программе передается массив. Обратите внимание, что параметр сигнатуры функции имеет объявление пустого массива. Аргументом в вызове функции является только имя созданного массива.

Может ли функция C ++ вернуть массив?

Функция в C ++ может возвращать значение массива, но не может возвращать массив. Компиляция следующей программы приводит к сообщению об ошибке:

#включать
используя пространство имен std;
int fn (int массив [])

вернуть массив;

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (обр);
возврат 0;

Указатель указателя

Указатель может указывать на другой указатель. То есть объект-указатель может иметь адрес другого объекта-указателя. Они по-прежнему должны быть одного типа. Следующий фрагмент кода иллюстрирует это:

int ptdInt = 5;
int * ptrInt = &ptdInt;
int ** ptrptrInt = &ptrInt;
cout << **ptrptrInt << '\n';

Выход 5.

В объявлении указателя на указатель используется двойной *. Чтобы вернуть значение последнего заостренного объекта, по-прежнему используется двойной *.

Массив указателей

Следующая программа показывает, как кодировать массив указателей:

#включать
используя пространство имен std;
int main ()

int num0 = 000, num1 = 100, num2 = 200, num3 = 300, num4 = 400;
int * no0 = & num0, * no1 = & num1, * no2 = & num2, * no3 = & num3, * no4 =&num4;
int * arr [] = no0, no1, no2, no3, no4;
cout << *arr[4] << '\n';
возврат 0;

Результат:

400

Обратите внимание на использование и положение * в объявлении массива. Обратите внимание на использование * при возврате значения в массиве. С указателями указателей задействованы два *. В случае массива указателей один * уже позаботился, потому что идентификатор массива является указателем.

Массив строк переменной длины

Строковый литерал - это константа, возвращающая указатель. Массив строк переменной длины - это массив указателей. Каждое значение в массиве - указатель. Указатели - это адреса к ячейкам памяти, они имеют одинаковый размер. Строки разной длины находятся в другом месте памяти, а не в массиве. Следующая программа иллюстрирует использование:

#включать
используя пространство имен std;
int main ()

const char * arr [] = "женщина", "мальчик", "девочка", "взрослый";
cout << arr[2] << '\n';
возврат 0;

На выходе получается «девушка».

Объявление массива начинается с зарезервированного слова «const» для константы; за которым следует «char» для символа, затем звездочка *, чтобы указать, что каждый элемент является указателем. Чтобы вернуть строку из массива, * не используется из-за неявного характера указателя каждой строки. Если используется *, то будет возвращен первый элемент строки.

Указатель на функцию, возвращающую указатель

Следующая программа показывает, как кодируется указатель на функцию, возвращающую указатель:

#включать
используя пространство имен std;
int * fn ()

int num = 4;
int * inter = #
возвращение интер;

int main ()

int * (* функция) () = &fn;
int val = * func ();
cout << val << '\n';
возврат 0;

Выход 4.

Объявление указателя на функцию, возвращающую указатель, аналогично объявлению указателя на обычную функцию, но перед ним стоит звездочка. Первый оператор в функции main () иллюстрирует это. Чтобы вызвать функцию с помощью указателя, поставьте перед ней *.

Заключение

Чтобы создать указатель на скаляр, сделайте что-нибудь вроде,

поплавок заостренный;
поплавок * указатель = &pointed;

* имеет два значения: в объявлении указывает указатель; чтобы что-то вернуть, это для значения заостренного объекта.

Имя массива - это постоянный указатель на первый элемент массива.

Чтобы создать указатель на функцию, вы можете сделать,

int (* функция) () = &fn;

где fn () - функция, определенная в другом месте, а func - указатель.

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

Чтобы создать ссылку на функцию, вы можете сделать,

поплавок (& refFunc) (число с плавающей запятой, число) = fn;

где fn () - функция, определенная в другом месте, а refFunc - ссылка.

Когда функция возвращает указатель, возвращаемое значение должно быть получено указателем. Когда функция возвращает ссылку, возвращаемое значение должно быть получено по ссылке.

При передаче указателя на функцию параметр - это объявление, а аргумент - это адрес указанного объекта. При передаче ссылки на функцию параметр - это объявление, а аргумент - это ссылка.

При передаче массива функции параметр - это объявление, а аргумент - это имя массива без []. Функция C ++ не возвращает массив.

Для указателя на указатель требуется два * вместо одного, где это необходимо.

Chrys

OpenTTD против Simutrans
Создание собственного транспортного симулятора может быть увлекательным, расслабляющим и чрезвычайно увлекательным занятием. Вот почему вам нужно попр...
Учебник OpenTTD
OpenTTD - одна из самых популярных бизнес-симуляторов. В этой игре вам нужно создать замечательный транспортный бизнес. Тем не менее, вы начнете в нач...
SuperTuxKart для Linux
SuperTuxKart - отличная игра, созданная для того, чтобы бесплатно познакомить вас с Mario Kart в вашей системе Linux. Играть в нее довольно сложно и в...