Как легко отличить использование * в качестве указателя * в качестве оператора разыменования * в качестве оператора умножения в C? - PullRequest
1 голос
/ 07 марта 2020

Использование * очень запутанно, особенно для нас, новичков, C. Я имею в виду, как легко отличить использование * в качестве указателя, * в качестве оператора разыменования, * в качестве оператора умножения? Я вижу много разного использования * в сети, и это довольно запутанно, особенно в отношении различных позиций *, например, как в примере кода ниже. Какие позиции * правильно и целесообразно использовать, чтобы избежать путаницы с указателями, разыменовкой и умножением? Код является просто примером и может ... Infact не скомпилируется.

int main(void){
  int *size, length, width;
  *size1= malloc(sizeof(int) * length);
  *size2= (int *) malloc(width * sizeof(int) * width);
  *size3= malloc(sizeof(int) *length);
  printf("%d\n%d\n%d\n", size1,size2,size3);
  return (0);
}

Примечание: я новичок в C, и, пожалуйста, не отсылайте меня к бесполезным ссылкам и ("предположительно") дубликатам. это не отвечает точно на тот же вопрос, что и этот ... пожалуйста, позволяйте другим высказать свое мнение, чтобы мы получили максимальные ответы, никто не знает всего этого, вы будете удивлены, что может появиться что-то новое, даже для так называемого C старожилы.

1 Ответ

1 голос
/ 08 марта 2020

Когда вы читаете код C, вы должны уметь различать guish определений и выражений. Определение начинается с типа, которому может предшествовать класс хранения, такой как extern, static, typedef ... и / или квалификаторы типа, такие как const и, volatile. Звезда перед определяемым идентификатором указывает на то, что эта переменная является указателем, а несколько звездочек указывают на несколько уровней косвенности.

В выражении звезда может встречаться как бинарный оператор, между операндами или как унарный оператор, перед своим операндом. Бинарный оператор * является оператором умножения, тогда как унарный * является оператором разыменования.

Как правило, *, следующий за идентификатором или постфиксным оператором, является оператором умножения. , Операторами Postfix являются ++, --, индексация с помощью [] и вызов функции с необязательными аргументами внутри ().

Путаница возникает из-за краткости языка C, который позволяет Программист, чтобы объединить эти различные варианты использования по желанию:

 int x=0,*p=&x,n=*p**p;

Эта уродливая строка действительно запутывает. Давайте сначала вставим значимые пробелы для улучшения читабельности:

 int x = 0, *p = &x, n = *p * *p;

Интервалы в большинстве случаев не нужны для компилятора C, но следование простым правилам повышает удобочитаемость для людей:

  • добавляет пробел с обеих сторон бинарных операторов
  • добавьте пробел после , и ;, за исключением конца строки
  • не вставляйте пробел между унарными операторами и их операндом, за исключением sizeof.
  • последовательный отступ кода, обычно 4 пробела на уровень

В приведенной выше строке кода определены 3 переменные x, p и n , * p - указатель на int, тогда как x и n являются int переменными. * x инициализируется до 0 * p инициализируется по адресу x. * инициализатор для n является результатом умножения значения, на которое указывает p, на самого себя.

Определение нескольких переменных с разными уровнями косвенности в одном и том же определении неодобрительно, потому что это сбивает с толку и подвержен ошибкам Рекомендуется переписать приведенное выше определение в 3 строки:

 int x = 0;
 int *p = &x;
 int n = *p * *p;
...