указатель - переменная, хранящая адрес ячейки памяти - адрес в памяти по которой лежит переменная зачем нужны указатели? указатели это способ сделать так, чтобы функции имели возможность влиять на переменные, которые вне этих функций существуют оператор унарный амперсанд (&) по переменной возвращает адрес этой ячейки в памяти по типу T возвращает T* оператор унарная звездочка возвращает то, что лежит по переменной по типу T* возвращает тип T
разница в int* и double* проявляется при прибавлении к ним целых чисел (меняется шаг перемещения по памяти) инты лежат по адресам, кратным 4, все даблы по кратным 8
//array to pointer convertion (только для сишных массивов)
int a[5];
*a = 1;
a[2] = 2[a] (a[2] == *(a+2) == *(2+a))при передаче в функцию массив превращается в указатель если массив используется как rvalue, то он превращается в указатель на первый элемент
что можно делать с указателями:
- разыменовывать
- прибавлять целые числа
- инкрементировать, декрементировать
- присваивать новые значения
- вычитать указатели, которые указывают на одно и то же
- сравнивать указатели одного типа
void* - указатель на неизвестный тип, может указывать на любую переменную, кроме тех, которые были объявлены с CV все указатели на любой тип неявно могут приводится к void*:
int n = 3;
int* p = &n;
void* vp = p;нельзя инкрементировать, разыменовывать
не существует указателей на ссылки и указателей на битовые поля
nullptr - константа, обозначающая ноль типа nullptr_t, prvalue NULL - задефайненый ноль до C++11 с C++11 задефайненый nullptr
можно сишным приведением перевести целочисленное число в указатель (переведется в шестнадцатеричную систему)
прикол сумма не используя + через битоёбство:
int Add (int x, int y) {
char* p = reinterpret_cast<char*>(x);
char* t = reinterpret_cast<char*>(&p[y]); // &(*(p+y))
int* v = reinterpret_cast<int*>(&t);
return *v;
}void (*pf)(int); — pointer to function void (*a[10])(int); — array of pointers to functions
smart ptr - указатель, который сам чистить память под собой, когда его уничтожают. нельзя копировать, присваивать
delete(nullptr) - ничего не делает
если выйти указателем за границу массива, потом вернуться обратно в массив и разыменовать его - всё равно UB