Написание программ с использованием указателей

Страницы работы

5 страниц (Word-файл)

Содержание работы

7.160101.3381.02.06

Зм.

Аркуш

№ Докум

Підпис

Дата

Написание программ с использованием указателей

Літ

Лист

Листів

Студент

у

1

НУК  ІАЕ

Викладач

Попов

Лабораторная работа №6

Тема: Написание программ с использованием указателей

Цель: Изучить понятие указателей, научиться применять указатели на практике

Теоретические сведения

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

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

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

тип_указателя * имя_указателя;

Здесь тип_указателя означает базовый тип указателя. Им может быть любой тип.

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

Операторы для работы с указателями

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

m = &count;

записывает в указатель m адрес переменной count. Этот адрес относится к ячейке памяти, которую занимает  переменная count. Адрес и значение переменной никак

 

7.160101.3381.02.06

Лист

 

2

 

Зм.

Лист

№ док

Подпись

Дата

 

не связаны друг с другом. Оператор & означает «адрес». Следовательно, предыду-щий оператор присваивания можно прочитать так: «присвоить указателю m адрес переменной count».

Приоритет операторов & и * выше, чем приоритет всех арифметических операторов, за исключением унарного минуса.

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

Присваивание указателей

Указатель можно присваивать другому указателю. Например.

#include <stdio.h>

int main (void)

{

  int x;

  int *p1, *p2;

  p1 = &x;

  p2 = p1;

  printf (“ %p”, p2); // выводит адрес переменной x

  return 0;

}

Адресная арифметика

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

p1++;

переменная  p1 будет не 2001, а 2002, поскольку при увеличении указателя p1 на единицу он ссылается на следующее целое число. Это же относится и к оператору декрементации.

Правила адресной арифметики:

При увеличении указатель ссылается на ячейку, в которой хранится следующий

 

7.160101.3381.02.06

Лист

 

3

 

Зм.

Лист

№ док

Подпись

Дата

 

элемент базового типа. При уменьшении он ссылается на предыдущий элемент. Для указателей на символы сохраняются правила «обычной» арифметики, поскольку размер символов равен 1 байт. Все остальные указатели увеличиваются или уменьшаются на длину соответствующих переменных, на которые они ссылаются. Это гарантирует, что указатели всегда будут ссылаться на элемент базового типа.

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

p1 = p1 + 12;

смещает указатель p1 на 12-й элемент базового типа, расположенный после текущего адреса.

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

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

Указатели можно сравнивать между собой. Например, следующий оператор, в котором сравниваются указатели p и q, является совершенно правильным.

If (p<q) printf (“указатель p содержит меньший адрес,

                       чем указатель q\n”);

Как правило, указатели сравниваются между собой, когда они ссылаются на один и тот же объект, например массив.

7.160101.3381.02.06

Лист

4

Зм.

Лист

№ док

Подпись

Дата

Пример

В приведенной ниже программе числа, введенные с клавиатуры, заталкиваются в стек. Если пользователь ввел число 0, значение выталкивается из стека. Программы прекратит свою работу, когда пользователь введет число –1.

#include <stdio.h>

#include <stdlib.h>

#define SIZE 50

void push (int i);

int pop (void);

int main (void)

{

  int value;

  tos = stack; //Указатель tos ссылается на вершину стека

  p1 = stack;

  do {

    printf (“введите число: “);

    scanf (“%d”, &value);

    if (value!=0) push (value);

    else printf (“Число на вершине стека равно %d\n”, pop());

  } while (value!=-1);

  return 0;

}

void push (int i)

{

  p1++;

  if (p1==(tos+SIZE)) {

    printf (“стек переполнен. \n”);

    exit (1);

  }

  *p1 = i;

}

int pop (void)

{

  if (p1==tos) {

    printf (“стек исчерпан. \n”);

    exit (1);

  }

  p1--;

  return *(p1+1);

}

7.160101.3381.02.06

Лист

5

Зм.

Лист

№ док

Подпись

Дата

Похожие материалы

Информация о работе