функция — массив передачи параметров C ++ против отдельных элементов

Учитывая две функции:

int foo(int, int);

а также

int bar(int*);

(Предполагая, что bar передается в массиве размера n, где n = количество параметров foo, соответствующие значения эквивалентны, а функции функционально одинаковы)

Разве когда-нибудь «лучше» использовать первый подход над вторым?

2

Решение

Один недостаток, который я могу придумать 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) с другой стороны, при неправильном количестве параметров компиляция не производится.

1

Другие решения

Это зависит от того, что вы подразумеваете под «лучше»: если передача нескольких параметров лучше согласуется с логической структурой вашей программы, то для удобочитаемости гораздо лучше передать несколько параметров. Хорошим тестом того, может ли это быть так, является вопрос о том, выиграют ли отдельные элементы массива от именования по отдельности. Если ответ «да», то отдельные параметры лучше. Сохранение нескольких байтов здесь и там при передаче параметров не компенсирует даже небольшую потерю читаемости.

3

Да, прежний подход int foo(int, int); можете проверить параметры во время компиляции. int bar(int*) необходимо сделать предположения о переданном массиве.

2

Это зависит от того, что «лучше»:

  1. Для лучшей производительности:

    1 Если массив имеет только несколько элементов (скажем, менее 6 параметров, зависит от целевого ЦП и доступные регистры могут использоваться для передачи параметров), метод foo () лучше, так как все переменные могут передаваться по регистру; и foo может напрямую получить значение из регистра. Для бара требуется разыменование указателя.

    2 ЕСЛИ в массиве более 10 элементов. Лучше пройти с использованием указателей, так как здесь меньше операций со стеком, чтобы поместить параметр на вершину стека.

  2. Для меньшего количества ошибок:
    метод foo () лучше, так как для метода bar () элементы могут быть изменены с помощью операторов в bar, которые могут быть видны после возврата из bar (), и это может привести к ошибке, если вы не поддерживаете операции элементов в баре () осторожно.

0
По вопросам рекламы [email protected]