Что такое указатель в C?
Указатель на С, представляет собой переменную , которая хранит адрес другой переменной. Указатель также может использоваться для ссылки на другую функцию указателя. Указатель можно увеличивать / уменьшать, т. Е. Указывать на следующую / предыдущую ячейку памяти. Назначение указателя - сэкономить место в памяти и сократить время выполнения.
Как использовать указатели в C
Если мы объявим переменную v типа int, v фактически сохранит значение.
v теперь равно нулю.
Однако каждая переменная, кроме значения, также имеет свой адрес (или, проще говоря, место, где она находится в памяти). Адрес можно получить, поставив перед именем переменной амперсанд (&).
Если вы напечатаете адрес переменной на экране, он будет выглядеть как совершенно случайное число (более того, оно может отличаться от запуска к запуску).
Давайте попробуем это на практике с указателем в примере C
Результатом этой программы будет -480613588.
Итак, что такое указатель? Вместо того, чтобы хранить значение, указатель y будет хранить адрес переменной.
Переменная указателя
Int * y = & v;
ПЕРЕМЕННАЯ |
УКАЗАТЕЛЬ |
Значение сохраняется в имени хранение / адрес памяти |
Переменная , что указывает на адрес хранения / памяти другой переменной |
Объявление указателя
Как и переменные, указатели в программировании на C должны быть объявлены до того, как их можно будет использовать в вашей программе. Указателям можно давать любые имена, если они подчиняются правилам именования C. Объявление указателя имеет следующий вид.
data_type * pointer_variable_name;
Здесь,
- data_type - это базовый тип указателя для типов переменных языка C и указывает тип переменной, на которую указывает указатель.
- Звездочка (*: та же звездочка, что используется для умножения), которая является оператором косвенного обращения, объявляет указатель.
Давайте посмотрим на некоторые допустимые объявления указателей в этом руководстве по указателям C:
int *ptr_thing; /* pointer to an integer */int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */double *ptr2; /* pointer to a double */float *ptr3; /* pointer to a float */char *ch1 ; /* pointer to a character */float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */
Инициализировать указатель
После объявления указателя мы инициализируем его, как стандартные переменные, адресом переменной. Если указатели в программировании на C не инициализируются и используются в программе, результаты непредсказуемы и потенциально катастрофичны.
Чтобы получить адрес переменной, мы используем оператор амперсанда (&), помещенный перед именем переменной, адрес которой нам нужен. Инициализация указателя выполняется с использованием следующего синтаксиса.
Синтаксис указателя
pointer = &variable;
Ниже представлена простая программа для иллюстрации указателя:
#includeint main(){int a=10; //variable declarationint *p; //pointer variable declarationp=&a; //store address of variable a in pointer pprintf("Address stored in a variable p is:%x\n",p); //accessing the addressprintf("Value stored in a variable p is:%d\n",*p); //accessing the valuereturn 0;}
Выход:
Address stored in a variable p is:60ff08Value stored in a variable p is:10
Оператор | Смысл |
* | Обслуживает 2 цели
|
& | Служит только одной цели
|
Типы указателей в C
Ниже приведены различные типы указателей в C :
Нулевой указатель
Мы можем создать нулевой указатель, присвоив нулевое значение во время объявления указателя. Этот метод полезен, когда у вас нет адреса, назначенного указателю. Нулевой указатель всегда содержит значение 0.
Следующая программа иллюстрирует использование нулевого указателя:
#includeint main(){int *p = NULL; //null pointerprintf(“The value inside variable p is:\n%x”,p);return 0;}
Выход:
The value inside variable p is:0
Указатель пустоты
В программировании на языке C указатель void также называется универсальным указателем. У него нет стандартного типа данных. Указатель void создается с помощью ключевого слова void. Его можно использовать для хранения адреса любой переменной.
Следующая программа иллюстрирует использование указателя void:
#includeint main(){void *p = NULL; //void pointerprintf("The size of pointer is:%d\n",sizeof(p));return 0;}
Выход:
The size of pointer is:4
Дикий указатель
Указатель называется «диким» указателем, если он ничем не инициализируется. Эти типы указателей C неэффективны, потому что они могут указывать на какое-то неизвестное место в памяти, что может вызвать проблемы в нашей программе и может привести к сбою программы. Всегда нужно быть осторожным при работе с дикими указателями.
Следующая программа иллюстрирует использование дикого указателя:
#includeint main(){int *p; //wild pointerprintf("\n%d",*p);return 0;}
Выход
timeout: the monitored command dumped coresh: line 1: 95298 Segmentation fault timeout 10s main
Другие типы указателей в 'c' следующие:
- Висячий указатель
- Сложный указатель
- Рядом указатель
- Дальний указатель
- Огромный указатель
Указатели прямого и косвенного доступа
В C есть два эквивалентных способа доступа к переменному содержимому и управления им.
- Прямой доступ: мы используем напрямую имя переменной
- Косвенный доступ: используем указатель на переменную
Давайте разберемся с этим с помощью программы ниже
#include/* Declare and initialize an int variable */int var = 1;/* Declare a pointer to int */int *ptr;int main( void ){/* Initialize ptr to point to var */ptr = &var;/* Access var directly and indirectly */printf("\nDirect access, var = %d", var);printf("\nIndirect access, var = %d", *ptr);/* Display the address of var two ways */printf("\n\nThe address of var = %d", &var);printf("\nThe address of var = %d\n", ptr);/*change the content of var through the pointer*/*ptr=48;printf("\nIndirect access, var = %d", *ptr);return 0;}
После компиляции программы без ошибок результат:
Direct access, var = 1Indirect access, var = 1The address of var = 4202496The address of var = 4202496Indirect access, var = 48
Указатель арифметики в C
Операции с указателем кратко описаны на следующем рисунке.
Приоритетная операция (приоритет)
При работе с указателями C мы должны соблюдать следующие правила приоритета:
- Операторы * и & имеют тот же приоритет, что и унарные операторы (отрицание !, приращение ++, декремент--).
- В том же выражении унарные операторы *, &,!, ++, - оцениваются справа налево.
Если указатель P указывает на переменную X, то * P можно использовать везде, где можно записать X.
Следующие выражения эквивалентны:
int X = 10 int * P = & Y; Для приведенного выше кода верны выражения ниже. | |
Выражение | Эквивалентное выражение |
Y = * P + 1 * P = * P + 10 * P + = 2 ++ * P (* P) ++ | Y = X + 1 X = X + 10 X + = 2 ++ X X ++ |
В последнем случае необходимы круглые скобки: поскольку унарные операторы * и ++ оцениваются справа налево, без скобок увеличивался бы указатель P, а не объект, на который указывает P.
В таблице ниже показаны арифметические и базовые операции, которые можно использовать при работе с указателями C.
Операция | Объяснение |
Назначение | int * P1, * P2 P1 = P2; P1 и P2 указывают на одну и ту же целочисленную переменную |
Увеличение и уменьшение | Int * P1; P1 ++; P1--; |
Добавление смещения (постоянное) | Это позволяет указателю перемещать N элементов в таблице. Указатель будет увеличиваться или уменьшаться в N раз на количество байтов типа переменной. P1 + 5; |
Указатели и массивы C с примерами
Традиционно мы обращаемся к элементам массива по его индексу, но от этого метода можно отказаться, используя указатели. Указатели упрощают доступ к каждому элементу массива.
#includeint main(){int a[5]={1,2,3,4,5}; //array initializationint *p; //pointer declaration/*the ptr points to the first element of the array*/p=a; /*We can also type simply ptr==&a[0] */printf("Printing the array elements using pointer\n");for(int i=0;i<5;i++) //loop for traversing array elements{printf("\n%x",*p); //printing array elementsp++; //incrementing to the next element, you can also write p=p+1}return 0;}
Выход
12345
Добавление определенного числа к указателю переместит положение указателя к значению, полученному в результате операции сложения. Предположим, p является указателем, который в настоящее время указывает на ячейку памяти 0, если мы выполним следующую операцию сложения, p + 1, тогда она будет выполняться следующим образом:
Поскольку p в настоящее время указывает на ячейку 0 после добавления 1, значение станет 1, и, следовательно, указатель будет указывать на ячейку памяти 1.
Указатели и строки C с примерами
Строка - это массив объектов типа char, заканчивающийся нулевым символом '\ 0'. Мы можем управлять строками с помощью указателей. Этот указатель в примере C объясняет этот раздел
#include#include int main(){char str[]="Hello Guru99!";char *p;p=str;printf("First character is:%c\n",*p);p =p+1;printf("Next character is:%c\n",*p);printf("Printing all the characters in a string\n");p=str; //reset the pointerfor(int i=0;i Выход
First character is:HNext character is:ePrinting all the characters in a stringHelloGuru99!Другой способ работать со строками - использовать массив указателей, как в следующей программе:
#includeint main(){char *materials[ ] = { "iron", "copper", "gold"};printf("Please remember these materials :\n");int i ;for (i = 0; i < 3; i++) {printf("%s\n", materials[ i ]);}return 0;} Выход:
Please remember these materials:ironcoppergoldПреимущества указателей в C
- Указатели полезны для доступа к ячейкам памяти.
- Указатели обеспечивают эффективный способ доступа к элементам структуры массива.
- Указатели используются для динамического выделения и освобождения памяти.
- Указатели используются для формирования сложных структур данных, таких как связанный список, граф, дерево и т. Д.
Недостатки указателей в C
- Указатели немного сложны для понимания.
- Указатели могут приводить к различным ошибкам, таким как сбои сегментации, или могут обращаться к области памяти, которая вообще не требуется.
- Если указателю указано неверное значение, это может привести к повреждению памяти.
- Указатели также несут ответственность за утечку памяти.
- Указатели сравнительно медленнее, чем у переменных.
- Программистам очень сложно работать с указателями; поэтому программист обязан осторожно манипулировать указателем.
Резюме
- Указатель - это не что иное, как область памяти, в которой хранятся данные.
- Указатель используется для доступа к ячейке памяти.
- Существуют различные типы указателей, такие как нулевой указатель, дикий указатель, пустой указатель и другие типы указателей.
- Указатели можно использовать с массивами и строками для более эффективного доступа к элементам.
- Мы можем создавать указатели на функции для динамического вызова функции.
- Арифметические операции могут выполняться с указателем, что называется арифметикой указателя.
- Указатели также могут указывать на функцию, что упрощает вызов различных функций в случае определения массива указателей.
- Если вы хотите иметь дело с разными типами данных переменных, вы можете использовать указатель типа void с приведением типов.