Указатели


Указатели также являются переменными и играют очень важную роль в языке программирования C. Они используются по нескольким причинам, например:

  • Струны
  • Распределение динамической памяти
  • Отправка аргументов функции по ссылке
  • Построение сложных структур данных
  • Указание на функции
  • Создание специальных структур данных (например, дерева, попыток и т. Д.)

И многое другое.

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

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

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

Строки как указатели

Мы уже обсуждали строки, но теперь мы можем погрузиться немного глубже и понять, что такое строки в C на самом деле (которые называются C-строками, чтобы отличать их от других строк при смешивании с C ++)

Следующая строка:

char * name = "John";

делает три вещи:

  1. Он выделяет вызываемую локальную (стековую) переменную name, которая является указателем на один символ.
  2. Это заставляет строку «John» появляться где-то в памяти программы (конечно, после того, как она скомпилирована и выполнена).
  3. Он инициализирует nameаргумент, чтобы указать, где находится Jсимвол (за которым следует остальная часть строки в памяти).

Если мы попытаемся получить доступ к nameпеременной как к массиву, она сработает и вернет порядковое значение символа J, поскольку nameпеременная фактически указывает точно на начало строки.

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

Разыменование

Разыменование - это обращение к месту, куда указывает указатель, а не к адресу памяти. Мы уже используем разыменование в массивах - но мы этого еще не знали. Оператор скобок - например, обращается к первому элементу массива. А поскольку массивы на самом деле являются указателями, доступ к первому элементу массива аналогичен разыменованию указателя. Разыменование указателя выполняется с помощью оператора звездочки .[0]*

Если мы хотим создать массив, который будет указывать на другую переменную в нашем стеке, мы можем написать следующий код:

/* define a local variable a */
int a = 1;

/* define a pointer variable, and point it to a using the & operator */
int * pointer_to_a = &a;

printf("The value a is %d\n", a);
printf("The value of a is also %d\n", *pointer_to_a);

Обратите внимание, что мы использовали &оператор, чтобы указать на aтолько что созданную переменную .

Затем мы обратились к нему с помощью оператора разыменования. Мы также можем изменить содержимое разыменованной переменной:

int a = 1;
int * pointer_to_a = &a;

/* let's change the variable a */
a += 1;

/* we just changed the variable again! */
*pointer_to_a += 1;

/* will print out 3 */
printf("The value of a is now %d\n", a);

Упражнение

Создайте указатель на nвызываемую локальную переменную pointer_to_nи используйте его для увеличения значения nна единицу.