правильное использование оператора предварительного увеличения в сочетании с оператором разыменования указателя - PullRequest
7 голосов
/ 17 декабря 2009

Я только что написал следующую строку кода:

if (++(data_ptr->count) > threshold) { /*...*/ } // example 1

Мое намерение состоит в том, чтобы увеличить переменную count в структуре данных, на которую указывает data_ptr, прежде чем проводить сравнение с threshold, и эта строка кода работает.

Если бы вместо этого я хотел увеличить data_ptr перед сравнением, я написал бы следующее:

if ((++data_ptr)->count > threshold) { /*...*/ } // example 2

Из любопытства я также попробовал эту строку кода:

if (++data_ptr->count > threshold) { /*...*/ } // example 3

И обнаружил, что он ведет себя точно так же, как и первый.

Первый вопрос: Почему в пример № 3 работает так же, как пример № 1? Это вопрос приоритета оператора? Что-то в стандарте? Мне пришлось написать быструю тестовую программу, потому что ответ для меня не был очевиден.

Второй вопрос: Должен ли я написать это if заявление по-другому? Я мог бы сначала выполнить приращение в отдельной строке, а , а затем протестировать условие, чтобы избежать возможной путаницы. Это необходимо, или первые два примера достаточно очевидны сами по себе?

Ответы [ 4 ]

11 голосов
/ 17 декабря 2009

1) Старшинство

2) Предпочтение

5 голосов
/ 17 декабря 2009
  1. Приоритет оператора диктует наблюдаемое вами поведение.
  2. Это не повредит, если вы отделите приращение от сравнения в этом примере, но иногда вы хотите иметь условие с шагом в середине последовательности условий, а затем пытаться отделить приращение от теста может ухудшить читабельность кода, введя вложение, которое в противном случае было бы ненужным.

Например:

if (...1...)
    ...2...
else if (++data_ptr->count > threshold)
    ...3...
else
    ...4...

Versus:

if (...1...)
    ...2...
else
{
    ++data_ptr->count;
    if (data_ptr->count > threshold)
        ...3...
    else
        ...4...
}
5 голосов
/ 17 декабря 2009

Да, это вопрос приоритета оператора. Оператор стрелки имеет более высокий приоритет , чем оператор приращения.

Чтобы ответить на ваш второй вопрос, я обычно разделяю этот тип конструкции на два отдельных утверждения:

++(data_ptr->count);
if(data_ptr->count > threshold) { /*...*/ }

Это подчеркивает происходящее и устраняет возможную путаницу. Однако это, вероятно, вопрос предпочтения.

3 голосов
/ 17 декабря 2009
  1. Оператор -> связывает крепче, чем ++.
  2. Они оба четко определены, и я думаю, что их легко читать. Вещи могут стать хитрыми, если у вас есть дополнительные ссылки на data_ptr в том же выражении.
...