C и по наследству C ++ забиты операторами и по своей сути зависят от контекста. Вам придется к этому привыкнуть:
Если *
появляется перед именем переменной, которая объявляется (или определяется), это модификатор типа и делает эту переменную указателем.
Если это унарный префиксный оператор для переменной, которая является частью выражения, это разыменование (или что бы там ни было).
Если это бинарный инфиксный оператор для двух переменных, которые являются частью выражения, это умножение (или что бы там ни было).
(Из этого вы можете видеть, что *
в вашем unsigned char * pixel
не является унарным префиксом разыменования, а является модификатором типа .)
Обратите внимание, что &
очень похоже на *
, только его смысл отличается: он делает переменную ссылкой , является оператором адресации или двоичное И.
Вы можете отличить оператор разыменования от оператора умножения по тому факту, что обычно оператор умножения не имеет имени типа слева.
Одна из рекомендаций при написании собственного кода - "прижать" к себе * при использовании в качестве указателя / deref:
unsigned char *pixels = ...
if (*pixels == ...)
и ставить * при использовании в качестве умножения:
int y = x * 7;
Есть и другие подсказки, которые вы можете использовать ( например, тот факт, что указатель deref является унарным оператором, а множественный - двоичным оператором).
Вы написали о разыменовании в C . Можете ли вы определить результат, просто взглянув на него? ==>
int v[] = {5,6}, w[] = {7,8};
int m[][2] = { {1,2}, {3,4} };
int result = * v * * * m * * w;
С уважением
rbo
Ответ: практика. Каждый новый язык программирования в какой-то степени будет выглядеть забавно, один смешнее, чем другой. Научитесь им пользоваться, и это станет естественным.
Важно отметить, что C по сравнению с другими языками заключается в том, что, когда несколько объявлений объединяются в одном операторе, звездочка применяется к отдельным элементам, а не ко всему набору в целом. Например:
int* foo,bar;
создает указатель на int с именем foo и int с именем bar. Я всегда привязываю звездочку к переменной и избегаю смешивания указателей и не указателей в одном операторе, таким образом:
int *foo; int *ptr1,*ptr2,*ptr3; int bar,boz,baz;
Также важно отметить, что квалификаторы класса хранения, такие как 'const' и 'volatile', не всегда могут связываться как один ожидал бы. Заявление
volatile int *foo;не означает, что «foo» является изменчивым, а скорее, что то, на что указывает «foo», является изменчивым. Если сам foo является «изменчивым», нужно написать «int * volatile foo;»
Точно так же англоговорящие люди понимают, что одно и то же слово может иметь разные значения в зависимости от контекста. Как только вы немного погрузитесь в контекст, обычно становится очевидно, что делает оператор.