Указатели и приведение типов
Так как указатель хранит адрес, можно изменить его до другого типа. Это может понадобиться, например, если требуется взять часть переменной, или если известно, что переменная хранит нужный тип.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <conio.h> #include <stdio.h>
#define SIZE 10
void main() { int A = 10; int *intPtr; char *charPtr;
intPtr = &A; printf("%d\n", *intPtr); printf("--------------------\n"); charPtr = (char*)intPtr; printf("%d ", *charPtr); charPtr++; printf("%d ", *charPtr); charPtr++; printf("%d ", *charPtr); charPtr++; printf("%d ", *charPtr);
getch(); } |
В этом примере используется то, , что размер типа int равен 4 байта, а char - 1 байт. За счёт этого, получив адрес первого байта, можно пройти по остальным байтам числа и вывести их содержимое.
Null pointer - нулевой указатель
Указатель до инициализации хранит мусор, как и любая другая переменная. Но в то же время, этот "мусор" вполне может оказаться валидным адресом. Пусть, к примеру, у нас есть указатель. Каким образом узнать, инициализирован он или нет? В общем случае никак. Для решения этой проблемы был введён макрос NULL библиотеки stdlib. Принято при определении указателя, если он не инициализируется конкретным значением, делать его равным NULL.
?
int *ptr = NULL; |
По стандарту гарантировано, что в этом случае указатель равен NULL, и равен нулю, и может быть использован как булево значение false. Хотя в зависимости от реализации NULL может и не быть равным 0 (в смысле, не равен нулю в побитовом представлении, как например, int илиfloat). Это значит, что в данном случае
?
int *ptr = NULL; if (ptr == 0) { ... } |
вполне корректная операция, а в случае
?
int a = 0; if (a == NULL) { ... } |
поведение не определено. То есть указатель можно сравнивать с нулём, или с NULL, но нельзя NULL сравнивать с переменной целого типа или типа с плавающей точкой.
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <stdlib.h> #include <stdio.h> #include <conio.h>
void main() { int *a = NULL; unsigned length, i;
printf("Enter length of array: "); scanf("%d", &length);
if (length > 0) { //При выделении памяти возвращается указатель. //Если память не была выделена, то возвращается NULL if ((a = (int*) malloc(length * sizeof(int))) != NULL) //a=new int[length * sizeof(int)]; { for (i = 0; i < length; i++) { a[i] = i * i; } } else { printf("Error: can't allocate memory"); } }
//Если переменая была инициализирована, то очищаем её if (a != NULL) { free(a); } getch(); } |
