Всем привет. Указатели люди воспринимают по-разному и многие их, мягко говоря, не очень любят. Ну, если они выглядят так:
float(*(*mymegapointer)(double(*)(int)))(int)
То оно и понятно. Но с указателями также можно делать разные прикольные вещи, о некоторых из которых я расскажу.
Начало массива
Имя массива — это указатель на его первый элемент. То есть, если функция f() принимает в качестве аргумента массив, то она принимает на самом деле указатель на его 1-ый элемент. Таким образом, можно схитрить относительно начала массива:
char a[6] = "hello";
puts(a + 1);
Этот фрагмент программы выведет на экран «ello», то есть, выведет слово со второго символа. Так можно выводить на экран строку с n-ого символа вот так:
puts(str + (n - 1));
Конечно, это не единственное применение этой «хитрости», но идею, я надеюсь, вы поняли.
Шифрование текста
Пусть у нас int занимает 4 байта, а char — 1 байт. Тогда в переменной типа int может поместиться строка из 4-х символов. После этого нам остаётся эту строку прочитать как int — и всё! Строка из 4-х символов зашифрована. То есть, длинную строку можно разбить на кусочки, зашифровать каждый из них и получить набор на первый взгляд ничего не значащих чисел.
#include <stdio.h>
int main(int argc, char* argv[]) {
int i;
char* str = (char*)&i;
scanf("%s", str);
printf("%in", i);
scanf("%i", &i);
printf("%sn", str);
return 0;
}
Эта программка просит пользователя ввести строку (не более 4-х символов длиной) и выводит на экран число. Потом просит ввести число и выводит по нему строку. Шифрование можно усовершенствовать, к примеру, умножая или деля полученные числа на 2, 3 и т.д. Ну, это уже на ваше усмотрение.
Доступ к защищённым полям класса
На что указывает указатель на объект класса? Логично, на объект. Объект — это выделенная память, в которой располагаются поля класса одно за другим. Указатель на объект на самом деле указывает на первое поле в классе. И неважно, public оно или private. Так что можно просто привести указатель на объект к типу этого самого поля и разыменовать его. А чтобы получить доступ к следующему полю класса, нужно прибавить к указателю на первое поле единичку.
Код:
#include <iostream>
class test {
public:
test();
void showvali();
void showvalf();
private:
int vali_;
float valf_;
};
test::test() {
vali_ = 0;
valf_ = 0.0;
}
void test::showvali() {
std::cout << vali_ << "n";
}
void test::showvalf() {
std::cout << valf_ << "n";
}
int main(int argc, char* argv[]) {
test* t = new test;
int* vali = (int*)t;
float* valf = (float*)(vali + 1);
*vali = 5;
*valf = 10.84353;
t->showvali();
t->showvalf();
delete t;
return 0;
}
Вот, пара приколов, которые можно делать с указателями. Они, конечно, не единственные, но хотя бы несколько. Всем пока!
Автор: username666