C Указатель

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

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

Пожалуйста, посмотрите на следующий пример, который выведет адрес определённой переменной:

Пример

#include <stdio.h> int main () { int var_example = 10; int *p; // Определите переменную-указатель p = &var_example; printf("Адрес переменной var_example: %p\n", p); return 0; }

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

var_example 变量的地址: 0x7ffeeaae08d8

На приведённом выше примере мы поняли, что такое адрес памяти и как получить к нему доступ. Теперь давайте посмотрим, что такое указатель.

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

Указатель — это адрес памяти, а переменная-указатель — это переменная, используемая для хранения адресов памяти. Как и другие переменные или константы, перед использованием указателя для хранения адреса другой переменной его необходимо объявить. Общая форма объявления переменной-указателя:

type *var_name;

Здесьtype— это базовый тип указателя, который должен быть допустимым типом данных C,var_name— это имя переменной-указателя. Звёздочка, используемая для объявления указателя,*такая же, как звёздочка, используемая в умножении. Однако в этом операторе звёздочка используется, чтобы указать, что переменная является указателем. Ниже приведены допустимые объявления указателей:

int *ip; /*Указатель на целое число*/ double *dp; /*Указатель на double*/ float *fp; /*Указатель на float*/ char *ch; /*Указатель на символ*/

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

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

Как использовать указатели?

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

Пример

#include <stdio.h> int main () { int var = 20; /*Объявление фактической переменной*/ int *ip; /*Объявление переменной-указателя*/ ip = &var; /*Сохранить адрес var в переменной-указателе*/ printf("Адрес переменной var: %p\n", &var ); /*Адрес, сохранённый в переменной-указателе*/ printf("Адрес, сохранённый в переменной ip: %p\n", ip ); /*Доступ к значению с помощью указателя*/ printf("Значение переменной *ip: %d\n", *ip ); return 0; }

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

var 变量的地址: 0x7ffeeef168d8
ip 变量存储的地址: 0x7ffeeef168d8
*ip 变量的值: 20

NULL-указатели в C

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

NULL-указатель — это константа со значением ноль, определённая в стандартной библиотеке. Рассмотрим следующую программу:

Пример

#include <stdio.h> int main () { int *ptr = NULL; printf("Адрес ptr — %p\n", ptr ); return 0; }

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

ptr 的地址是 0x0

В большинстве операционных систем программам не разрешён доступ к памяти по адресу 0, поскольку эта память зарезервирована операционной системой. Однако адрес памяти 0 имеет особое значение: он указывает, что указатель не указывает на доступное место в памяти. Но по соглашению, если указатель содержит нулевое значение (ноль), считается, что он ни на что не указывает.

Чтобы проверить нулевой указатель, можно использовать оператор if, как показано ниже:

if(ptr) /*Если p не NULL, то выполнить*/ if(!ptr) /*Если p равен NULL, то выполнить*/

Подробное объяснение указателей в C

В C существует много концепций, связанных с указателями. Все эти концепции просты, но все они важны. Ниже перечислены некоторые важные концепции, связанные с указателями, которые программисты на C должны чётко понимать:

КонцепцииОписание
Арифметика указателейНад указателями можно выполнять четыре арифметические операции: ++, --, +, -
Массив указателейМожно определить массив, используемый для хранения указателей.
Указатель на указательC допускает указатели на указатели.
Передача указателей в функцииПередача параметров по ссылке или адресу позволяет изменять переданные параметры в вызываемой функции.
Возврат указателя из функцийC позволяет функциям возвращать указатели на локальные переменные, статические переменные и динамически выделенную память.
Другие расширения