Указатели в языке си: Указатель в языке Си : обозначение и использование

2.8. Понятие указателя в Си

Указаетль — это переменная, которая содержит адрес некоторого объекта в памяти компьютера. Понятно, что адрес — целое число. Понимание и правильное использование указателей очень важно для создания хороших программ.

    Многие конструкции языка Си требуют применения указателей. Например, указатели необходимы для успешного использования функций и динамического распределения памяти. С указателями следует обращаться очень осторожно. Так использование в программе неинициализированного указателя может приветси к «зависанию» компьютера. При неправильном, неаккуратном использовании указателей в программе могут возникнуть ошибки, которые очень трудно бывает обнаружить. Обойтись же без указателей в программах на язке Си нельзя.

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

    Указатель объявляется следующим образом.
1.    Вначале указывается тип указателя. Это некоторый тип языка Си. В данном случае он определяет тип объекта, на который указывает указатель.
2.    Вслед за этим через пробел ставится звездочка — *. Она обозначает, что следующая за ней переменная является указателем.
Получается довольно простая формула:

тип *<простая переменная>

Например:

char *ch;
int *temp, i, *j, *k;
float *pt, fon;

    Здесь указателями являются: ch, temp, j, k pt.

Операции над указателями в Си.

    Простейшая операция над указателями — это операция &, что означает «взять адрес». Существует еще одна операция над указателями. Она обозначается символом звездочка *. Смысл этой операции таков: «значение, расположенное по указанному адресу».

    Хотя знак звездочка * соответствует обычной операции умножения, но никак нельзя перепутать эти две операции. Ведь арифметическая операция умножения имеет два операнда. Иначе говоря, при умножении должны быть указаны, как данные, два числа, участвующие в умножении. Поэтому и говорят, что умножение — это бинарная операция. Операция * над указателями, в отличие от арифметического умножения, — это унарная операция. То есть, другими словами, она использует всего один операнд (одно данное).

    Рассмотрим простейшие программки, поясняющие использование указателей в языке Си.

    Ниже на рисунке показана первая программа.

 
    Поясним использование команд с указателями.
1.    Команда pf=&x означает «взять адрес числа, находящегося в x и записать его в pf.
2.    Следующая команда y=*pf позволяет записать значение, расположенное по указанному в pf адресу, в y. Поэтому в первой строке на рисунке ниже Вы видите распечатку результатов решения указанной программы: x=10.100000 y=10.100000.
3.    Далее в команде *pf++ происходит изменение адреса. Выполняется команда ++ увеличение на 1 (increment).
4.    Следующая команда y=*pf позволяет записать значение, расположенное по адресу, указанному в pf. Этот адрес только что был увеличен на 1 в предыдущей команде. Поэтому во второй строке распечатки решения программы Вы видите, что в y находится уже другое число, а именно ноль.
5.    Следующая команда y=1+*pf*y прибавляет к 1 произведение адреса из pf на содержимое y. Как показано в предыдущем пояснении, к этому времени в y находится число ноль. Поэтому в третей строке распечатки решения Вы видите результат работы программы для последненго случая, поясняющего использование указателей в программе на языке Си.
6.    Как видно из данной программы, к указателям можно применять операцию присваивания или использовать указатели в арифметических действиях.
Например, y=*pf или y=1+*pf*y.
 

Спецификация %p функции printf() в Си.

    Спецификация %p функции printf() в Си позволяет напечатать адрес памяти в шестнадцаеричной форме. Рассмотрим еще одну программку. В ней покажем новую возможность использования оператора присваивания при работе с указателями.

 

    Поясним использование команд с указателями во второй программе.
1.    Команда p=&x позволяет взять адрес числа x и записать его в p.
2.    Команда g=p позволяет присвоить указателю g адрес из p.
3.    Далее в первой и второй строках распечатываются в шестнадцатеричной системе адрес из p и адрес из g.
4.    В третей строке распечатки Вы видите число из x и указатель из g в десятичной системе счисления.
 

Операции над указателями в Си.

    Прежде всего вспомним базовые типы данных в Си. В Си определены 5 типов данных, которые можно назвать базовыми.

 Char — символьные,
 Int — целые,
 Float — с плавающей точкой,
 Double, — с плавающей точкой двойеной длины,
 Void — пустой, не имеющий значения.

    Ключевое слово Void отсутствовало в языке Си стандарта Керниган&Ритчи и было привнесено в стандарт ANSI из языка C++. Введение этого типа оказалось весьма удачным. Вообще нельзя создать переменную типа пустой или не имеющий значения. Но можно создать указатель на тип void. Указателю на тип void можно присвоить указатель любого другого типа. Однако, при обратном присваивании необходимо использовать явное преобразование указателя на void.

   void *pv;
   float f, *pf;
   pf=&f;
   pv=pf;
   pf=(float*)pv;

    В языке Си допустимо присвоить указателю любой адрес памяти. Однако, если объявлен указатель на целое int *pi;, а по адресу, который присвоен данному указателю, находится переменная другого типа, например, типа float, то при компиляции программы будет выдано сообщение об ошибке в строке p=&x;

    Эту ошибку можно исправить, преобразовав указатель на int к типу float явным преобразованием типа:

p=(int*)&x;

    При этом потеряется информация о том, какой тип указывал исходный указатель. Пример программы смотрите ниже:

 

    Поясним работу программы:
1). Команда float x=10. 1, y, z; помещает число 10.1 в переменную x.
2). Команда p=&x позволяет взять адрес числа x, то есть получить указатель числа x.
      Обратите внимание на то, что имеется несовпадение типов указателя p и числа x: величина p имеет тип int, хотя величина x имеет тип float.
      Это источник будущей ошибки. В этом Вы сможете убедиться по ходу урока в дальнейшем.
3). Команда y=*p помешает в y значение, расположенное по указанному адресу, то есть это число y=1092721024.000000.
      Вы видите, что несовпадение типа указателя привело к ошибке, так как на самом деле в x находится число 10.1
4). Команды g=&x; и z=*g; позволяют получить правильный указатель числа x и правильное значение числа x в z.

 

    Сделаем необходимые выводы. Типы указателей для числа x, как легко понять, не совпадают. Поэтому результаты выполнения команд z=*g и y=*p тоже не совпали. Использование указателей разных типов привело к ошибке. Было отброшено предупреждение о том, что указатель и исходное число должны быть одного типа. В данном случае число имеет тип float x=10.1, поэтому тип указателя должен быть float *g. Таким образом, правильный результат получится только в том случае, когда тип указателя float *g совпадает с типом исходного числа float x=10.1.

    При программировании нужно строго следить за тем, чтобы тип указателя и тип исходного числа совпадали!

Использованы материалы http://my-pc.jino.ru/lessons/ci/les00.html

Указатели в языке Си

Указатель — это переменная, содержащая адрес другой переменной.

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

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

имя_типа — любой из типов данных С. Он определяет тип переменной, на которую указывает указатель.

Звездочка (*) — это знак операции ссылки по указателю, и в данном случае он означает, что имя_указ является указателем на переменную типа имя_типа.

Указатели можно объявлять вместе с обычными переменными.

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

Инициализируется указатель оператором присваивания:

указатель=&переменная,

& — операция взятия адреса.

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

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

Потенциальные опасности

Указатели могут нести потенциальные опасности. Это связано с использованием неинициализированного указателя в левой части оператора присваивания.

Например, в этом операторе объявляется указатель на значение типа int

int *ptr;

Этот указатель еще не инициализирован, поэтому ни на что не указывает. Точнее он не указывает ни на что известное. У неинициализированного указателя есть какое-то значение, просто мы его не знаем. Во многих случаях это 0. Допустим, этот неинициализированный указатель используется в операторе присваивания: *ptr = 12;

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

Поэтому необходимо корректно инициализировать указатели перед тем, как их использовать. Это необходимо делать самостоятельно, ни в коем случае не полагаться на компилятор.

Если переменная многобайтная, то адрес переменной фактически представляет собой адрес первого (младшего) байта из занимаемых ею.

Хотя указатели могут быть полезны и при работе с простыми переменными, наиболее удобны они в работе с массивами.

В языке С указатели и массивы тесно связаны.

Имя массива без квадратных скобок является указателем на первый элемент массива. Например, если объявлен массив data[], то data — это адрес первого элемента данного массива. Получить адрес первого элемента массива можно и таким способом: &data[0];

В языке С справедливо соотношение (data == &data[0]).

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

Пример.

short arr1[6], *p_arr1;

float arr2[3], *p_arr2;

p_arr1= arr1; p_arr2= arr2;

В массиве short – arr1 следующий элемент массива находится на два байта дальше в памяти, чем предыдущий и адрес следующего элемента соответственно на 2 больше, чем адрес предыдущего. В массиве float – arr2 адрес каждого следующего элемента на 4 больше, чем предыдущего.

Как же обращаться к последовательным элементам массива с помощью указателя? Из приведенных примеров видно, что указатель нужно увеличивать на 2 для перебора элементов типа short, и на 4 — в массиве типа float. Обобщая, можно сказать, что указатель увеличивается на sizeof(тип_данных) для обращения к следующему элементу.

Pointers In C: Учебное пособие по C на хинди #26

Зачем изучать язык программирования C? : Учебное пособие по C на хинди #1

Что такое кодирование и язык программирования C? : Учебное пособие по C на хинди #2

Установка и настройка кода VS с помощью компилятора C: Учебное пособие по C на хинди #3

Базовая структура программы на языке C на хинди: Учебное пособие по C на хинди #4

Основной синтаксис программы на языке C: C Учебник на хинди #5

Переменные и типы данных в C: Учебник на хинди #6

Операторы в C: Учебное пособие по C на хинди #7

Упражнение по программированию на C 1. Таблицы умножения: Учебное пособие по C на хинди #8

Спецификаторы формата C и управляющие последовательности с примерами: Учебное пособие по C на хинди #9

Операторы управления If Else In C: Учебное пособие по C на хинди #10

Switch Операторы управления регистром In C: Учебное пособие по C на хинди #11

Циклы In C: Учебное пособие по C на хинди #12

Do While Loop In C: Учебное пособие по C на хинди #13

Цикл в то время как в C: Учебное пособие по C на хинди # 14

Цикл For In C: Учебник C на хинди #15

Операторы Break and Continue на C: Учебник C на хинди #16

Оператор Goto на C: Учебник C на хинди #17

Приведение типов на C: Учебник C In Hindi #18

Функции на C: Учебник по C на хинди #19

C Упражнение 1: Решение таблицы умножения + Shoutouts: Учебник по C на хинди #20

Рекурсивные функции: Рекурсия на C: Учебник по C на хинди #21

C Упражнение 2: Единицы и преобразования: Учебное пособие по C на хинди #22

Массивы в C: Учебник по C на хинди #23

Упражнение 2: Решение + Shoutouts: Учебник по C на хинди #24

Упражнение 3 Рекурсии: Учебник по C на хинди #25

Указатели на C: Учебник по C на хинди #26

Массивы и арифметика указателей в C: Учебное пособие по C на хинди #27

Упражнение 3 О рекурсиях: решение + выкрики: Учебное пособие по C на хинди #28

Всегда ли рекурсия хороша? : Учебное пособие по C на хинди #29

Упражнение 4. Печать узоров звезд на языке C: Учебное пособие по C на хинди #30

Вызов по значению и вызов по ссылке на языке C: Учебное пособие по C на хинди #31

Передача массивов в качестве аргументов функции: Учебное пособие по C на хинди #32

Образец звезды на языке C. Упражнение 4 Решение: Учебное пособие по C на хинди #33

Строки в C: Учебное пособие по C на хинди #34

Строковые функции на C и библиотека string.h: Учебное пособие по C на хинди #35

Обращение массива на C. Упражнение 5: Учебное пособие по C на хинди #36

Структуры на C : Учебное пособие по C на хинди #37

Typedef на языке C: Учебное пособие по C на хинди #38

Unions In C: Учебное пособие по C на хинди #39

Обращение массива в языке C Упражнение 5: Решение: Учебное пособие по C на хинди #40

Язык C HTML Parser Упражнение 6: Учебное пособие по C на хинди #41

Статические переменные в C : Учебное пособие по C на хинди #42

Учебное пособие по C. Упражнение 6: Решения и ответы: Учебное пособие по C на хинди #43

Менеджер туристического агентства C Language. Упражнение 7: Учебное пособие по C на хинди #44

Структура памяти программ на языке C — динамическая Распределение памяти: Учебное пособие по C на хинди #45

C Language Менеджер туристического агентства Упражнение 7 Решение: Учебное пособие по C на хинди #46

Динамическое выделение памяти Malloc Calloc Realloc & Free(): Учебное пособие по C на хинди #47

C Language Менеджер сотрудников Упражнение 8: Учебное пособие по C на хинди # 48

Классы хранения на языке C Auto, Extern Static и Register Storage Classes: Учебное пособие по C на хинди #49

Менеджер сотрудников на языке C — Упражнение 8 Решение: Учебное пособие по C на языке хинди #50

Камень, бумага, ножницы для кодирования Упражнение на языке C 9: Учебное пособие по C на хинди #51

Пустой указатель на языке C: Учебное пособие по C на хинди #52

NULL Указатель на языке C: Учебное пособие по C на хинди #53

Висячий указатель на языке C: Учебное пособие по C на хинди #54

Дикий указатель на языке C: Учебное пособие по C на хинди #55

Камень, бумага и ножницы на языке C — Упражнение 9 Решение: Учебное пособие по C на хинди №56

Умножение матриц на языке C — Упражнение 10: Учебное пособие по C на хинди # 57

Введение и работа с препроцессором C: Учебное пособие по C на хинди #58

#define и #include Директивы препроцессора: Учебное пособие по C на хинди #59

Предопределенные макросы и другие директивы препроцессора: Учебное пособие по C на хинди #60

Умножение матриц в C — упражнение 10 Решение: Учебное пособие по C на хинди #61

Файловый ввод-вывод на C: Учебное пособие по C на хинди #62

Проверка палиндрома на языке C — Упражнение 11: Учебное пособие по C на хинди #63

Функции для файлового ввода-вывода на языке C: Учебное пособие по C на хинди #64

Числовой палиндром Программа на языке C: Упражнение 11 Решение: Учебное пособие по C на хинди #65

Автоматический генератор квитанций на языке C. Упражнение 12. Учебное пособие по языку C на хинди #66

Режимы файлов, fgets, fputs, fgetc, fputc и многое другое по работе с файлами C: Учебное пособие по языку C на хинди #67

Аргументы командной строки на языке C: Учебное пособие по C на хинди #68

Автоматический генератор счетов на C (решение) — Упражнение 12: Учебное пособие по C на хинди #69

Калькулятор командной строки на C — Упражнение 13: Учебное пособие по C на хинди #70

[Решено] Командная строка Калькулятор на C Упр.13 : Учебник по C на хинди #71

Указатели функций в C: Учебное пособие по C на хинди #72

Функции обратного вызова с использованием указателей на функции в C: Учебное пособие по C на хинди #73

Упражнение 13 Область круга с использованием указателей на функции: Учебное пособие по C на хинди #74

Память Утечка в C: Учебное пособие по C на хинди #75

Площадь круга на C Упражнение 14 Решение: Учебное пособие по C на хинди #76

Master C Language Points Online Class

  1. Все темы
  2. Технология
  3. Разработка программного обеспечения
  4. Языки программирования
Предварительный просмотр

С Дэном Гукиным Нравится 641 пользователям

Продолжительность: 1ч 33м Уровень мастерства: Продвинутый Дата выпуска: 21. 04.2020

Начать бесплатную пробную версию на 1 месяц

Детали курса

Борьба с концепцией указателей в программировании на C? Ты не один. Хотя указатели могут быть определены просто как переменные, содержащие ячейку памяти, даже опытные программисты часто пугаются этой мощной части языка Си. В этом продвинутом курсе инструктор Дэн Гукин уделяет особое внимание указателям, начиная с основ, а затем опираясь на них. Дэн рассказывает об основах получения, хранения и использования адресов; выделение памяти и буферы; и связанные списки. Затем он углубляется в некоторые более продвинутые концепции, в том числе о том, как отправить указатель на функцию, сортировать указатели и использовать указатели для управления памятью.

Навыки, которые вы приобретете

  • С (язык программирования)

Познакомьтесь с инструктором

  • Дэн Гукин

    Безумный гений

Отзывы учащихся

230 оценок

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

  • 5 звезд Текущее значение: 179 77%
  • 4 звезды Текущее значение: 38 16%
  • 3 звезды Текущее значение: 10 4%
  • 2 звезды Текущее значение: 1 <1%
  • 1 звезда Текущее значение: 2 <1%
Мартин Кустер

Мартин Кустер

Разработчик программного обеспечения с опытом работы в аэрокосмической отрасли, телефонии, компьютерных операционных системах, HA/DR и приложениях.

3/5 11 декабря 2022 г.

Контент не для опытных разработчиков ПО. Материал, касающийся связанных списков, не похож ни на один материал, который я изучил в курсе Data Structures CS.

Полезный · Отчет

Таха Эд-Дафили

Таха Эд-Дафили

ученик

5/5 26 октября 2022 г.

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

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *