Учитывая две функции:
int foo(int, int);
а также
int bar(int*);
(Предполагая, что bar передается в массиве размера n, где n = количество параметров foo, соответствующие значения эквивалентны, а функции функционально одинаковы)
Разве когда-нибудь «лучше» использовать первый подход над вторым?
Один недостаток, который я могу придумать int bar(int*)
в том, что это может сделать перегрузку более сложной. Например.:
int areaOfRectangle(int width, int height);
int areaOfRectangle(int x1, int y1, int x2, int y2);
хорошо, но как вы собираетесь делать это с массивами?
int areaOfRectangle(int* widthHeight);
int areaOfRectangle(int* coordinates); // error
Выше не будет компилироваться, потому что int areaOfRectangle(int*)
не может быть объявлен / определен дважды.
Кроме того, если вы просто используете массив как способ произвольной группировки параметров, вы затрудняете чтение и использование своего кода. Для сравнения:
int calculateIncome(int normalHours,
int overtimeHours,
int normalRate
int overtimeRate); // Self documenting
int calculateIncome(int* parameters); // How do I use this function?
int calculateMean(int* numbers); // Parameters are logically grouped,
// so array makes sense
Третий вопрос (который Санчо описывает в своем ответе) заключается в том, что int bar(int*)
опасный. Что происходит, когда пользователь называет вашу функцию меньшим массивом, чем тот, который вы ожидали? Вызов int Foo(int, int)
с другой стороны, при неправильном количестве параметров компиляция не производится.
Это зависит от того, что вы подразумеваете под «лучше»: если передача нескольких параметров лучше согласуется с логической структурой вашей программы, то для удобочитаемости гораздо лучше передать несколько параметров. Хорошим тестом того, может ли это быть так, является вопрос о том, выиграют ли отдельные элементы массива от именования по отдельности. Если ответ «да», то отдельные параметры лучше. Сохранение нескольких байтов здесь и там при передаче параметров не компенсирует даже небольшую потерю читаемости.
Да, прежний подход int foo(int, int);
можете проверить параметры во время компиляции. int bar(int*)
необходимо сделать предположения о переданном массиве.
Это зависит от того, что «лучше»:
Для лучшей производительности:
1 Если массив имеет только несколько элементов (скажем, менее 6 параметров, зависит от целевого ЦП и доступные регистры могут использоваться для передачи параметров), метод foo () лучше, так как все переменные могут передаваться по регистру; и foo может напрямую получить значение из регистра. Для бара требуется разыменование указателя.
2 ЕСЛИ в массиве более 10 элементов. Лучше пройти с использованием указателей, так как здесь меньше операций со стеком, чтобы поместить параметр на вершину стека.
Для меньшего количества ошибок:
метод foo () лучше, так как для метода bar () элементы могут быть изменены с помощью операторов в bar, которые могут быть видны после возврата из bar (), и это может привести к ошибке, если вы не поддерживаете операции элементов в баре () осторожно.