Присваивание посредством указателя



Лекция7- программирование -«Указатели»

СОДЕРЖАНИЕ

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

Операторы указателей. 2

Базовый тип и приведение типа в указателях. 3

Присваивание посредством указателя. 4

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

Арифметика указателей. 5

Сравнение указателей. 5

Указатели и массивы.. 5

Индексация указателя. 5

Строковые константы.. 6

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

Соглашение о нулевом указателе. 6

Указатель на указатель. 7

Вопросы для самоконтроля. 7

 


Указатели

Указатель – это объект, содержащий адрес памяти, используемый для того, чтобы получить доступ к значению другого объекта, которым может быть переменная или массив. Так, если х содержит адрес у, тогда говорят, что х «указывает» на у.

Указатели являются одним из наиболее мощных средств С++. Они же оказываются и самыми трудными в освоении. Будучи вероятным источником всяческих неприятностей, указатели тем не менее играют ключевую роль в программировании на С++. Именно посредством указателей С++ поддерживает такие средства, как связанные списки и динамическое выделение памяти. Указатели позволяют функциям изменять содержимое своих аргументов.

В последующих обсуждениях возникнет необходимость в ссылках на размеры некоторых базовых типов данных С++. Для определённости мы будем вести рассуждения применительно к типичной 32-разрядной среде, где символы имеют длину 1 байт, целые (int) – четыре байта, переменные с плавающей точкой (float) – тоже четыре байта, а переменные (double) - восемь байтов.

Переменные-указатели объявляются особым образом. Общая форма объявления переменной-указателя такова:

тип *имя переменной;

Здесь:

 тип - задаёт базовый тип указателя, который определяет, на данные какого типа будет указывать этот указатель;

имя переменной – имя переменной указателя.

Так, чтобы объявить ip, как указатель на int, необходимо написать:            int *ip;

Указатель на данные типа float выглядит следующим образом:                float *fl;

Итак, в предложениях объявления указание перед именем переменной знака звёздочки (*) делает эту переменную указателем.

Операторы указателей.

Для использования с указателями предусмотрены два специальных оператора: * и &. Оператор & является унарным (требует только одного операнда); он возвращает адрес памяти, в которой расположен его операнд. Например, предложение

prt = &total;                   //помещает в prt адрес памяти, где находится переменная total.

Второй оператор, *, в некотором роде обратный по отношению к &. Этот унарный оператор возвращает значение переменной, расположенной по адресу, который указан в качестве операнда этого оператора. Таким образом, предложение:

val = *prt;                         // поместит значение переменной total в val.

Приведённая ниже программа выполняет последовательность описанных операций.


 

Задание 7-1

// 7_1 UKAZ.cpp: главный файл проекта.

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

       #include "stdafx.h"

       #include <iostream>

       using namespace std;

int main()

{

       setlocale (LC_ALL,"Russian");

       int total;

       int *prt;

       int val;

       total = 3200;

       prt = &total;           // получение адреса total

       val = *prt;             // получение значения по этому адресу

     

       cout << "total равно: " << val << "\n";

       cin.get();

}

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

Базовый тип и приведение типа в указателях

При использовании указателей важно следить за тем, чтобы переменные-указатели всегда указывали на переменные правильных типов. Если, например, объявлен указатель на тип int , то компилятор предполагает, что любой объект, на который указывает этот указатель, является целочисленной переменной. Если в действительности это переменная другого типа, то наверняка верного ответа вы не получите. Например, приведённый ниже фрагмент неверен:

int *p;

double f;

//….

p = &f;                //ошибка

Фактически компилятор в этой точке сообщит об ошибке и программа далее компилироваться не будет.

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

int *p;

double f;

//….

p = (int *)&f;                  //теперь формально правильно

Однако приведение типа в операциях присваивания указателей различающихся типов обычно к добру не приводит, что иллюстрирует следующая программа

 

Задание 7-2

// Задание 7_2.cpp: определяет точку входа для консольного приложения.

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

// Приведение типов в указателях приводит к неверному

// результату

#include "stdafx.h"

#include <iostream>

using namespace std;

int main()

{

       setlocale(LC_ALL, "Russian");

       double x, y;

       int *p;

       x = 123.23;

       p = (int *)&x; // использование приведения типа

       y = *p;      // это присваивание не приведёт к желаемому результату

 

       cout << "y равно: " << y << "\n";

 

return 0;

}

Реальный вывод этой программы: 1.37439е+009, а вовсе не 123.23.

Присваивание посредством указателя

Можно использовать указатель с левой стороны предложения присваивания, чтобы присвоить значение ячейке памяти, на которую указывает указатель. Приняв, что р является указателем на int, следующее предложение присвоит значение 101 ячейке памяти, на которую указывает р.

*р = 101;

Для того, чтобы увеличить значение по адресу, можно использовать предложение:

(*р)++;

В приведённой ниже программе демонстрируется присваивание значения посредством указателя.

Задание 7-3

// Задание 7_3.cpp: определяет точку входа для консольного приложения.

// Присвоение значений с помощью указателей

#include "stdafx.h"

#include <iostream>

using namespace std;

int main()

{

       setlocale(LC_ALL, "Russian");

       int *p, num;

       p = &num;               // р - хранит адрес num

       *p = 100;               // num - присваивается 100

       cout << num << " ";

       (*p)++;                 // значение num увеличивается на 1

       cout << num << " ";

       (*p)--;                 // значение num уменьшается на 1

       cout << num << " \n";

return 0;

}

Вывод программы: 100 101 100

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

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

Арифметика указателей

С указателями можно использовать 4-е арифметических оператора: ++, --, + и -.

Чтобы разобраться, как работает арифметика указателей, предположим, что:

р1 – указатель на переменные целого типа с текущим значением 2000 (т.е. р1 содержит адрес 2000). Программа работает в 32- разрядной среде, тогда после выполнения предложений содержимое р1 меняется следующим образом:

р1++;                                 // р1 станет 2004 (а не 2001)

р1--;                                   // р1 станет 1996 (а не 1999)

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

Для указателей на символы инкремент и декремент действуют на указатель по правилам «обычной» арифметики, потому что символы имеют размер один байт. Однако указатель на любой другой тип данного будет увеличиваться или уменьшаться на длину своего базового типа. Так предложение:

р1 = р1 + 9;                    // р1 будет указывать на девятый элемент базового типа за тем, на который
 он указывает в настоящий момент

Итак, допустимыми арифметическими операциями для указателей являются:

Æ сложение и вычитание указателя и целого числа;

Æ вычитание одного указателя из другого.

Никакие другие арифметические операции над указателями недопустимы.


Дата добавления: 2019-07-15; просмотров: 173; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!