Да, вы можете использовать его в вызовах функций, но учтите, что ваши два примера не эквивалентны. Аргумент pQueue->heap
может оцениваться до или после pQueue->size++
, и вы не можете знать или полагаться на порядок. Рассмотрите этот пример:
int func (void)
{
static int x = 0;
x++;
return x;
}
printf("%d %d", func(), func());
Это напечатает 1 2
или 2 1
, и мы не можем знать, что мы получим. Компилятору не нужно последовательно оценивать параметры функции по всей программе. Поэтому, если мы добавим вторую printf("%d %d", func(), func());
, мы можем получить что-то вроде 1 2 4 3
в качестве вывода.
Здесь важно не писать код, который зависит от порядка вычисления. По той же причине, что и смешивание ++ с другими операциями или побочными эффектами в одном выражении, это плохая практика. В некоторых случаях это может даже привести к неопределенному поведению.
Чтобы ответить на ваши вопросы:
1) Поскольку pQueue-> size находится в вызове функции, я даже не уверенесли это на самом деле pQueue-> size или, вернее, копия целого числа, хранящегося в pQueue-> size. Если бы это была копия, то, очевидно, я бы не добавил 1 к фактическому pQueue-> size, поэтому в этом не было бы смысла.
++ применяется к переменной взвонящий, так что это не проблема. Локальная копия переменной происходит во время вызова функции независимо от ++. Однако результатом операции ++ не является так называемое lvalue (адресуемые данные), поэтому этот код недопустим:
void func (int* a);
...
func(&x++);
++ имеет приоритет и оценивается первым. Результат не является lvalue, и его адрес не может быть получен.
2) Поскольку это вызов функции, он затем перейдет в функцию fix_up и выполнит там весь код. Мне интересно, будет ли это иметь непреднамеренные последствия, может быть, когда он перейдет к fix_up, он будет увеличен на 1, и мой индекс будет на 1 выше, чем я предполагал при выполнении fix_up? Или он будет делать то, что должен делать, и ждать, пока не завершится выполнение fix_up?
Это не проблема, если функция не изменяет исходную переменную с помощью глобального указателя или чего-то подобного. В этом случае у вас будут проблемы. Например,
int* ptr;
void func (int a)
{
*ptr = 1;
}
int x=5;
ptr = &x;
func(x++);
Это очень сомнительный код, и x
будет 1 после строки func(x++);
, а не 6, как можно было ожидать. Это связано с тем, что выражение вызова функции вычисляется и завершается перед вызовом функции.
3) Даже если это нормально, считается ли это хорошей практикой кодирования для C?
В вашем случае все будет хорошо, но это плохая практика. В частности, смешивание операторов ++
или --
вместе с другими операторами в одном и том же выражении является плохой (хотя и распространенной) практикой, поскольку она имеет большой потенциал для ошибок и имеет тенденцию делать код менее читаемым.
Ваш оригинальный код с pQueue->size++;
в отдельной строке превосходит все - придерживайтесь этого. Вопреки распространенному мнению, при написании C вы не получаете бонусных баллов за «большинство операторов на одной линии». Однако вы можете получить ошибки и проблемы с обслуживанием.