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

Не будь таким, как я.

Студентам-программистам сегодня нелегко понять указатели. Мы не тратим столько времени на понимание того, как работает память. И по этой причине я написал подробное руководство, которое мне хотелось бы иметь, когда я изучал указатели.

Не будем терять время и приступим!

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

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

// general variables
int num;
char letter;
// pointer variables
int* numPtr;
char* letterPtr;

Люди часто путают объявление указателя с оператором разыменования (*), который будет рассмотрен позже.

Как использовать указатели в качестве переменных?

Чтобы использовать указатель в качестве переменной, вы можете присвоить ему адрес другой переменной, если он соответствует правильному типу данных. int* должен хранить только адрес переменной int. Давайте посмотрим на пример.

// declarations
int num;
int* ptr;
// assignments
num = 10;
ptr = #

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

Распространенная ошибка №1
Присвоение указателю неадресного значения

int num = 10;
int* ptr;
ptr = 10;  // 10 is not an address of a variable
ptr = num; // num's value is 10, same issue as above

Это очень частая ошибка новичков. Указатели не могут хранить int отдельно. Указатель может хранить только адрес.

Распространенная ошибка №2
Назначение адреса другому типу данных

char ch = 'a';
int* temp;
int* ptr;
ptr = &ch;  // ptr cannot take address of char, only address of int
ptr = &temp; // ptr cannot take address of int*, only address of int

Первое должно иметь смысл. Наш указатель может принимать только адреса целых чисел, поэтому адрес символа не должен работать. Однако со вторым примером немного сложнее. Переменная temp - это тип данных int*, который является указателем. Наша переменная ptr ожидала адрес целого числа, а не адрес указателя.

Указатели хранят адрес типа данных слева от самой правой звездочки. Это непросто, но позвольте мне привести несколько примеров.

  • int* хранит адреса int
  • float* хранит адреса float
  • char** хранит адреса char*
  • double***** хранит адреса double****

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

Дополнительные указатели для указателей

За исключением некоторых странностей, указатели ведут себя так же, как переменные. Потому что на самом деле они всего лишь переменная. Вам может быть интересно, какой смысл изучать указатели? До сих пор мы знали, как получать и сохранять адреса в указатели. Но указатели допускают одну дополнительную операцию, которая позволяет нам получать доступ к памяти по адресу. Мы называем это оператором разыменования (*). Я расскажу об этом в следующей статье, а пока я просто хотел рассмотреть несколько других синтаксических различий для указателей.

  1. Значение 0 по умолчанию для указателей - nullptr для C ++ и NULL для C
  2. Указатели одного типа могут использовать друг друга как значения.
  3. Сложение и вычитание целых значений являются допустимыми операциями + -
  4. Умножение, деление и взятие по модулю недопустимые операции * / %
  5. Вы не можете жестко закодировать адреса с числами

Вот и все! До этого момента вы узнали, как указатели работают как переменные. Указатели используются почти так же, как целые числа, числа с плавающей запятой и символы. В следующей статье я начну знакомство с оператором разыменования (*) и другими вариантами использования указателей.