Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Освоение указателей в C: практическое руководство от экспертов

Освоение указателей в C

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

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


Адреса памяти в C

Если у вас есть переменная var, выражение &var возвращает адрес, где хранится var.

Манипуляции с адресами часто встречаются, например, в scanf():

scanf("%d", &var);

Это сохраняет ввод пользователя непосредственно в ячейку памяти переменной var. Короткая демонстрация:

#include <stdio.h>
int main() {
    int var = 5;
    printf("var: %d\n", var);
    printf("address of var: %p", &var);
    return 0;
}

Вывод

var: 5
address of var: 0x7fffc1a2b1c8

Примечание: Адрес будет отличаться при каждом запуске и на каждой системе.


Что такое указатель?

Указатель — это переменная, которая хранит адрес памяти, а не обычное значение. Храня адреса, указатели обеспечивают косвенный доступ к данным, позволяя управлять динамической памятью, создавать эффективные структуры данных и осуществлять низкоуровневый системный контроль.

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

Типичный синтаксис объявления:

int *p;

Также встречаются вариации:

int *p1; int *p2;

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

int *p1, p2; /* p1 — указатель, p2 — int */

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

Пример:

int *pc, c;
c = 5;
pc = &c;

Здесь c получает значение 5, а pc сохраняет адрес c.


Разыменование указателей

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

int *pc, c;
c = 5;
pc = &c;
printf("%d", *pc); /* Выводит 5 */

Помните: pc — это указатель; *pc извлекает значение, на которое он указывает. Попытка присвоить адрес *pc (например, *pc = &c;) недопустима.

Оператор * называется оператором разыменования.


Изменение значений через указатели

Вы можете изменить базовые данные через их указатель:

int *pc, c;
c = 5;
pc = &c;
*pc = 1; /* c становится 1 */
printf("%d", c); /* Выводит 1 */

Несколько переменных могут использовать один и тот же указатель после переназначения:

int *pc, c, d;
c = 5;
d = -15;
pc = &c;
printf("%d", *pc); /* 5 */
pc = &d;
printf("%d", *pc); /* -15 */

Практический пример

Запустите эту полную программу, чтобы наблюдать, как значения указателей остаются постоянными, а данные, на которые они ссылаются, могут меняться:

#include <stdio.h>
int main() {
    int *pc, c;
    c = 22;
    printf("Address of c: %p\n", &c);
    printf("Value of c: %d\n\n", c);
    pc = &c;
    printf("Address of pointer pc: %p\n", pc);
    printf("Content of pointer pc: %d\n\n", *pc);
    c = 11;
    printf("Address of pointer pc: %p\n", pc);
    printf("Content of pointer pc: %d\n\n", *pc);
    *pc = 2;
    printf("Address of c: %p\n", &c);
    printf("Value of c: %d\n\n", c);
    return 0;
}

Вывод

Address of c: 0x7fffc1a2b1c8
Value of c: 22
Address of pointer pc: 0x7fffc1a2b1c8
Content of pointer pc: 22
Address of pointer pc: 0x7fffc1a2b1c8
Content of pointer pc: 11
Address of c: 0x7fffc1a2b1c8
Value of c: 2

Пояснение

  1. int *pc, c; — объявляет указатель pc и int c.
  2. c = 22; — сохраняет 22 в памяти c.
  3. pc = &c; — указывает pc на c.
  4. c = 11; — обновляет значение через прямой доступ.
  5. *pc = 2; — меняет значение через указатель.

Распространенные ошибки с указателями

Типичные ошибки включают путаницу между указателями и значениями:

int c, *pc;
// Неверно — присваивание значения указателю
pc = c; // Ошибка
// Неверно — попытка присвоить адрес разыменованному указателю
*pc = &c; // Ошибка
// Верно — присваивание адреса указателю
pc = &c; // OK
// Верно — присваивание значения по адресу, на который указывает указатель
*pc = c; // OK

Для новичков синтаксис int *p = &c; может быть запутан. Он эквивалентен:

int *p;
p = &c;

Запись int* p = &c; уменьшает неопределенность.


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

Язык C

  1. C# Hello World — создание вашего первого C# приложения
  2. Понимание ключевых слов и идентификаторов C#: правила, списки и лучшие практики
  3. Мастерство C# переменных и примитивных типов данных: полное руководство
  4. Операторы C# — исчерпывающее руководство по операторам в C#
  5. Освоение побитовых и сдвиговых операторов в C#: полное руководство
  6. Основы ввода-вывода в C#: Console.WriteLine, ReadLine и форматирование
  7. Выражения, операторы и блоки в C#: подробное руководство с примерами
  8. Освоение комментариев в C#: виды, лучшие практики и XML-документация
  9. Освоение указателей в C: практическое руководство от экспертов
  10. Понимание взаимосвязи между массивами и указателями в C