Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


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



Указатели и ссылки

 

Указатели

(http://msdn.microsoft.com/ru-ru/library/89e4h321.aspx)

 

Объявление указателей.

Объявление указателя имеет следующий формат:

 

<Тнп> *<Переменная>;

 

Например, чтобы объявить указатель p Number на тип int, можно использовать оператор:

 

int *pNumber;

или

int * pNumber ;

 

Допускается смешивание объявлений обычных переменных и указателей в одном операторе. Например.

 

int *p N umber , number;

 

Раздельное объявление указателей и переменных выглядят яснее, к тому же позволяет предусмотреть для них индивидуальные комментарии. Например:

 

int number = 33; // Объявление и инициализация переменной типа int

int *p N umber ; // Объявление указателя на переменную типа int

int **ppNumber; // Объявление указателя на указатель

 

Оператор получения адреса (&).

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

 

pNumber = & number ;    // Сохранить адрес переменной number в pNumber

ppNumber = &pNumber;  // Сохранить адрес указателя pNumber в ppNumber

 

Инициализация указателей.

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

 

int number = 33;            // Инициализация целой переменной

int *p N umber = &number;     // Инициализация указателя

int **ppNumber = &pNumber;  // Инициализация указателя на указатель

 

Допускается инициализация указателя значением, эквивалентным нулю. В Visual С++ таким значением является литерал nullptr, который представляет собой указатель, не указывающий ни на что. Например:

 

int *p N umber = nullptr; // Указатель, не указывающий ни на что

 

Поскольку литерал nullptr может быть неявно преобразован в тип bool (логическое значение false), появляется возможность проверить состояние указателя p Number:

 

if (!pNumber) // или if (pNumber == nullptr)

System :: Console :: WriteLine ("p N umber не указывает ни на что.");

 

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

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

 

int number = 33;          // Инициализация целочисленной переменной

int *p N umber = &number;   // Инициализация указателя

System::Console::WriteLine ("pNumber = 0x{0:X}", (int)pNumber);

                     // pNumber = 0x12F0F4

System::Console::WriteLine ("number = {0}", *pNumber); // number=33

*pNumber += 10;

System::Console::WriteLine("number = {0}", *pNumber); // number=43

 

Указатели на тип char.

Например, указатель на тип char обладает интересным свойством – он может быть инициализирован строковым литералом:

 

char *proverb = "Знания в юности – это мудрость в старости.";

 

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

При объявлении массива указателей используется следующий синтаксис:

 

<Тип> *<Название_массива>[<Количество_элементов>];

 

Пример использования массива указателей на целые переменные и вывода их значений:

 

int *р[3]; // Объявление массива указателей из 3-х элементов

int х = 10, у = 20, z = 30; // Объявление целых переменных

р [0] = & x ; //

р [1] = & y ; // Инициализация элементов массива указателей

р[2] = &z; //

for (int i = 0; i < 3; i++)

System::Console::Write("p[{0}]={1} ", i, *р[i]);

                 // Вывод: p [0]=10 p [1]=20 p [2]=30

 

Пример объявления массива строк типа char:

 

const char *str[] = { "String1", "String2", "String3" };

 

 

Выражения с указателями

 

Таблица 8.1. Операторы, используемые с указателями

Оператор Применение
* Оператор косвенного доступа.
–> Доступ к члену структуры через указатель.
[ ] Индексирование указателя.
& Получение адреса переменной.
+ +  и  – – Операторы инкремента и декремента указателей.
+ и – Бинарные арифметические операторы.
==, !=, <, >, <=, >= Сравнение указателей.

 

Ссылки

(http://msdn.microsoft.com/ru-ru/library/dz43scw4.aspx)

 

Объявление ссылки имеет следующим синтаксис:

 

<Тип> &<Название_ссылки> = <Переменная>;

 

После создания ссылки ее название можно использовать в выражениях вместо названия переменной. Например:

 

int x = 10;    // Объявление и инициализация переменной

int &ref = x;  // Объявление ссылки

ref = 20;

System::Console::Write ("x = {0}", x);     // Вывод : x = 20

x = 30;

System::Console::Write ("ref = {0}", ref); // Вывод : ref = 30

 

Пример 8.8. Передача параметров в функцию по ссылке с использованием указателей.

 

#include "stdafx.h"

void func ( int * x ) { * x = * x * 2; } // Определение функции

int main () {

int у = 10;

func (& y );  // Вызов функции с передачей адреса, а не значения

System::Console::WriteLine("y = {0}", y); // Вывод : y = 20

System::Console::ReadLine ();

 return 0;

}

 

Пример 8.9. Передача параметров в функцию с использованием ссылок.

 

#include "stdafx.h"

void func(int &x) { x = x * 2; } // Определение функции

int main() {

int у = 10;

func(y);  // Вызов функции с передачей значения, а не адреса

System::Console::WriteLine("y = {0}", y); // Вывод : y = 20

System::Console::ReadLine ();

 return 0;

}

 

Очевидно, что выражение x = x * 2; выглядит более привлекательно, чем *х = *х * 2; .

 

 

Оператор sizeof

(http://msdn.microsoft.com/ru-ru/library/4s7x1k91.aspx)

 

Формат двух типов оператора sizeof имеет вид:

 

Sizeof (type)

Sizeof expression

 

Пример 8.10. Определение размера данных разного типа в байтах.

 

#include "stdafx.h"

using namespace System;

size_t getPtrSize(char *ptr) { return sizeof(ptr); }

int main() {

char arrchar[] = "Hello, world!"; // Массив символов типа char

Console::WriteLine ("Размер переменной типа char: {0}",

                  sizeof(char));

Console::WriteLine(" Длина строки ' Hello, world! ' в стиле C : {0}",

                  sizeof arrchar);

Console::WriteLine("Количество элементов массива arrchar: {0}",

                  (sizeof arrchar) / (sizeof arrchar[0]));

Console::WriteLine("Размер указателя: {0}",

                  getPtrSize(arrchar));

size_t longSize = sizeof(long); // Размер данных типа long

Console::WriteLine(" Размер переменной типа long: {0}",

                  longSize);

double x = 0, & ref = x ; // Объявление переменной и ссылки на нее

Console::WriteLine("Размер переменной типа double: {0}",

                  Sizeof ref );

Console::ReadLine();

return 0;

}

/* Вывод:

Размер переменной типа char: 1

Длина строки "Hello, world!" в стиле C: 14

Количество элементов массива arrchar: 14

Размер указателя: 4

Размер переменной типа long: 4

Размер переменной типа double: 8

*/

 

 

Указатели и ссылки

 

Указатели

(http://msdn.microsoft.com/ru-ru/library/89e4h321.aspx)

 

Объявление указателей.

Объявление указателя имеет следующий формат:

 

<Тнп> *<Переменная>;

 

Например, чтобы объявить указатель p Number на тип int, можно использовать оператор:

 

int *pNumber;

или

int * pNumber ;

 

Допускается смешивание объявлений обычных переменных и указателей в одном операторе. Например.

 

int *p N umber , number;

 

Раздельное объявление указателей и переменных выглядят яснее, к тому же позволяет предусмотреть для них индивидуальные комментарии. Например:

 

int number = 33; // Объявление и инициализация переменной типа int

int *p N umber ; // Объявление указателя на переменную типа int

int **ppNumber; // Объявление указателя на указатель

 

Оператор получения адреса (&).

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

 

pNumber = & number ;    // Сохранить адрес переменной number в pNumber

ppNumber = &pNumber;  // Сохранить адрес указателя pNumber в ppNumber

 

Инициализация указателей.

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

 

int number = 33;            // Инициализация целой переменной

int *p N umber = &number;     // Инициализация указателя

int **ppNumber = &pNumber;  // Инициализация указателя на указатель

 

Допускается инициализация указателя значением, эквивалентным нулю. В Visual С++ таким значением является литерал nullptr, который представляет собой указатель, не указывающий ни на что. Например:

 

int *p N umber = nullptr; // Указатель, не указывающий ни на что

 

Поскольку литерал nullptr может быть неявно преобразован в тип bool (логическое значение false), появляется возможность проверить состояние указателя p Number:

 

if (!pNumber) // или if (pNumber == nullptr)

System :: Console :: WriteLine ("p N umber не указывает ни на что.");

 

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

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

 

int number = 33;          // Инициализация целочисленной переменной

int *p N umber = &number;   // Инициализация указателя

System::Console::WriteLine ("pNumber = 0x{0:X}", (int)pNumber);

                     // pNumber = 0x12F0F4

System::Console::WriteLine ("number = {0}", *pNumber); // number=33

*pNumber += 10;

System::Console::WriteLine("number = {0}", *pNumber); // number=43

 

Указатели на тип char.

Например, указатель на тип char обладает интересным свойством – он может быть инициализирован строковым литералом:

 

char *proverb = "Знания в юности – это мудрость в старости.";

 

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

При объявлении массива указателей используется следующий синтаксис:

 

<Тип> *<Название_массива>[<Количество_элементов>];

 

Пример использования массива указателей на целые переменные и вывода их значений:

 

int *р[3]; // Объявление массива указателей из 3-х элементов

int х = 10, у = 20, z = 30; // Объявление целых переменных

р [0] = & x ; //

р [1] = & y ; // Инициализация элементов массива указателей

р[2] = &z; //

for (int i = 0; i < 3; i++)

System::Console::Write("p[{0}]={1} ", i, *р[i]);

                 // Вывод: p [0]=10 p [1]=20 p [2]=30

 

Пример объявления массива строк типа char:

 

const char *str[] = { "String1", "String2", "String3" };

 

 

Выражения с указателями

 

Таблица 8.1. Операторы, используемые с указателями

Оператор Применение
* Оператор косвенного доступа.
–> Доступ к члену структуры через указатель.
[ ] Индексирование указателя.
& Получение адреса переменной.
+ +  и  – – Операторы инкремента и декремента указателей.
+ и – Бинарные арифметические операторы.
==, !=, <, >, <=, >= Сравнение указателей.

 

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

Пример 8.1. Объявление и инициализация указателей на целые и символьные переменные, а также получение косвенного доступа к этим переменным через указатели. Использование указателей в выражениях.

 

#include "stdafx.h"

using namespace System;

int main () {

int number 1 = 55, number 2 = 99;  // Объявление и инициализация

                                  // переменных.

int * pNumber = nullptr ;  // Объявление и инициализация указателя.

                        // Указатель не указывает ни на что.

Console::WriteLine ("pNumber = 0x{0:X}", (int)pNumber);

pNumber = & number 1; // Сохранение адреса переменной в указателе .

* pNumber += 11; // Косвенное увеличение переменной number 1

                 // на 11 через указатель. Теперь number1 = 66.

Console::WriteLine("number1 = {0}, pNumber = 0x{1:X}",

                  number1, (int)pNumber);

pNumber = &number2; // Теперь указатель будет указывать

                        // на переменную number 2.

number 1 = * pNumber * 10; // Эквивалентно выражению:

                        // number1 = number2 * 10 = 990.

Console::WriteLine("number1 = {0}, pNumber = 0x{1:X}, " +

        "*pNumber = {2}\n", number1, (int)pNumber, *pNumber);

char theChar = ' Z '; // Объявление и инициализация переменной.

char * pChar = & theChar ; // Объявление и

void * pVoid = pChar ; // инициализация

int * pInt = ( int *) pVoid ; // указателей.

Console :: WriteLine ("Значение theChar = {0}", ( Char ) theChar );

Console :: WriteLine ("Адрес theChar = 0 x {0: X }", ( int ) pChar );

Console :: WriteLine ("Значение * pChar = {0}", ( Char )* pChar );

Console::WriteLine (" Значение *pInt = {0}", *pInt);

Console::ReadLine();

return 0;

}

/* Вывод :

pNumber = 0x0

number1 = 66, pNumber = 0x12F0F4

number1 = 990, pNumber = 0x12F0E0, *pNumber = 99

Значение theChar = Z

Адрес theChar = 0x12F0E4

Значение pChar = Z

Значение * pInt = 90

*/

 

 


Поделиться:



Последнее изменение этой страницы: 2019-04-19; Просмотров: 196; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.084 с.)
Главная | Случайная страница | Обратная связь