> а в чем различие на практике?
Различие принципиальное. У тебя есть переменная scratch. Ее значение - это какие-то байты по адресу определенному. Когда ты к ней обращаешься
char scratch = getColor( 0 );
компиллер генерирует такой код, например:
push 0
call getColor // вызов getColor
mov byte ptr [0x00401020], eax // положить результат в байт по адресу, тут ее адрес 00401020
А предположим она у тебя char *scratch.
Тогда она в 32-битной системе (проца) будет 4-байтным значением (DWORD, ULONG и тп), в ней будет хранится АДРЕС чего-то. Т.е. в принципе по*** пишешь ты char *scratch, void *scrach или int *scratch. Если указываешь звездочку - это значит там будет указатель 4-байтный. А тип - это значит на какой тип данных указывает переменная. Это надо чтоб компиллер тебе говорил об ошибках возможных. Впринципе можно взять указатель и рассматривать данные по нему как данные другого типа. Пример
void *ptr = (void*)0x00401020; // указатель на 0x00401020
((mystruct*)ptr)->field1 = 0; // рассматриваем как указатель на структуру mystruct
//или:
*((int*)ptr) = 0; // рассматриваем *ptr (данные по адресу ptr) как int и кладем туда int
тогда сначала берется значение по адресу какому-то (значение переменной), там лежит опять адрес, и значение по этому адресу уже будет *ptr.
Если тебе, скажем, надо дать возможность ф-ии модифицировать переменную переданую (а не только передать ее значение) - можно передать указатель на нее. По этому адресу будет значение и ф-ия туда сможет записать свою ***ню.
Или, скажем, у тебя какая-то структуру большая в памяти должна динамически выделяться, тогда делаем mystruct *s = (mystruct*)malloc( sizeof( mystruct ) );
и у тебя в s указатель на место в памяти где отделено sizeof( mystruct ) байт под структуру. s->field1 - поле структуры. а если s хранит структуру а не указатель то s.field1.
Такие мелочи приводят к ошибкам в больших проектах, читайте книги.
лол NiOx вроде умный чел а написал ***ню) нахер определять указатели ? че за правило неписаное такое?
нихера не надо определять если явно не нужно.