Яка з цих відповідей щодо функцій є неправильною?


17

Тому, хоча я робив кілька тривалих компіляцій, я вирішив пройти загальний тест на C ++ на ODesk і натрапив на це питання.

Це питання

Якщо я не помиляюся, враховуючи формулювання (або його відсутність), все це може бути правдою.

а.

int Foo() { }
int Foo(int bar) { }

б. Ну, return void;було б неправильно семантично, але функції, очевидно, можуть мати voidтипи повернення.

void Foo() { }

c. Це визначення вбудованих функцій, так.

г. Не вдаючись до деталей щодо розміщення наступних елементів,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Далі ви завжди могли це зробити, використовуючи лямбда і функтори .

е.

void Foo(int& bar)
{
    ++bar;
}

int foobar = 5;
Foo(foobar);

f.

int bar = 5;

int& GetBar()
{
    return bar;
}

GetBar() = 6;

г.

int bar = 5;

int* GetBar()
{
    return &bar;
}

(*GetBar()) = 5;

Я не бачу, де на це питання є справді помилкові відповіді. Я щось пропускаю?

Потрібно сказати, що у мене закінчився час і провалилася вся справа. Я думаю, я поганий програміст на C ++. :(


18
Приїхав сюди, щоб кричати на якусь дитину, що робила домашнє завдання, був приємно здивований.
SomeKittens

Насправді, не всі мови вимагають розширення функцій вбудованого режиму. "inline" - це натяк компілятора, а не команда в Delphi, і C, C ++ мають винятки . Тож "с" може бути і помилковим. Можливо, буде цікавіше написати відповідь, в якій буде показано, як кожне твердження може бути неправильним.
Móż

1
@ Ӎσᶎ Якби там було текстове поле. Я хочу повернутися назад і натиснути "Повідомити про це за допомогою цього питання".
Qix

5
Це не масив функцій. Це масив функціональних покажчиків.
користувач253751

@immibis Щоправда, але питання насправді не з'ясовується (принаймні, мені це не було).
Qix

Відповіді:


21

Все це питання хитромудрий. Постановка запитання передбачає можливість декількох варіантів вибору, тоді як радіо кнопки вказують на один вибір.

Крім того, b є досить підозрілим, оскільки порожнечі функції нічого не повертають.

D також сумнівний, наскільки я знаю, ви не можете мати масив функцій. Звичайно, ви можете мати масив функціональних покажчиків, але це не зовсім те саме.


Правильно; D - це як запитати, чи можна зателефонувати int. Звичайно, якщо ви кинете його на вказівник і цей вказівник посилається на функцію ...
Qix

1
Я готовий зробити ставку на D - це відповідь, на яку вони йдуть, але так, питання погано.
Гурт Робота

Хоча voidфункції не повертають жодного значення , вони все одно повертають тип void . Тому я кажу, що B - це правда.
Томас Едінг

@ThomasEding Це все ще дуже погані формулювання з їх боку. Ви цього не робите return void;, а натомість return;.
Qix

10

Відповідь в) також, мабуть, помилкова.

"Вбудовані функції розширюються під час компіляції, щоб уникнути накладних викликів."

По-перше, компілятору C ++ дозволено ігнорувати inlineпідказку, зовсім не розширюючи функції.

По-друге, заявлена ​​"причина" для розширення - це надмірне спрощення. Насправді справжня причина здійснення розширення (чи ні) цілком у руках письменника-компілятора.


Ви маєте рацію, але я думав про це в сенсі «добре, компілятор визначив , що робить хоче вбудовувати функцію» , а не inlineнатяк.
Qix

Ну, компілятор не може повністю ігнорувати натяк. Принаймні, це мандатний ефект, що робить виняток з ODR.
Дедуплікатор

@Deduplicator - Так, це може. "Незалежно від того, як ви позначаєте функцію вбудованою, компілятор може ігнорувати запит: компілятор може вбудовувати-розширювати деякі, всі, або жодне з місць, де ви викликаєте функцію, позначену як вбудовану." - джерело isocpp.org/wiki/faq/Inline-Functions
Стівен C

@StephenC: Прохання про розширення його в inline можна ігнорувати, так. Я лише сказав, що явний виняток з ODR не може.
Дедуплікатор

Я бачу. Я оновив формулювання своєї відповіді
Stephen C

7

c. Це визначення вбудованих функцій, так.

Це не зовсім правильно.
Незважаючи на свою назву, ключове слово inlineне гарантує, що функція буде окреслена. Єдине, в чому ви можете бути впевнені, це те, що компілятор не буде скаржитися, якщо він побачить визначення функції вбудованої системи кілька разів.

Отже, строго кажучи, варіант С невірний, але я не думаю, що це відповідь, яку очікують автори вікторини, оскільки є відповідь, яка є ще більш помилковою.

г. Не вдаючись до деталей щодо розміщення наступних елементів,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Далі ви завжди могли це зробити, використовуючи лямбда і функтори.

У вашому прикладі functions- це масив покажчиків на функції, а не масив самих функцій. Так само і лямбди і функтори насправді теж не функціонують. Це класи, які відповідають оператору виклику функцій, але це не робить їх функціями в очах визначення мови C ++.

Функції в C ++ трохи схожі на громадян другого класу. Ви можете їх визначити та зателефонувати, але як тільки ви спробуєте зробити щось інше з типом функції (наприклад, створити їх масив), ви або отримаєте помилку, або вони мовчки перетворять себе в покажчик.


Я погоджуюся з бітом D, але я читав cяк функції, які вже були позитивно позначені для вбудовування, порівняно з самим inlineключовим словом. Я розумію inline, це підказка.
Qix

4

Якщо що-небудь, це повинно було бути b . Ви не returnможете void, але ви можете повернути null. Недійсна в оголошенні функції повинна бути там, щоб сповістити компілятора про відсутність повернутого значення.

Тип порожнечі

В С і С ++

Функція з типом недійсного результату закінчується або досягненням кінця функції, або виконанням оператора повернення без поверненого значення. Тип пустоти також може з'являтися як єдиний аргумент прототипу функції, який вказує на те, що функція не приймає аргументів. Зауважте, що незважаючи на ім'я, у всіх цих ситуаціях тип пустоти виступає як тип одиниці, а не як нульовий або нижній тип, навіть незважаючи на те, що на відміну від реального типу одиниці, який є одинаковим, тип пустоти містить порожній набір значень, і мова не дає жодного способу оголосити об'єкт або представити значення з типом void.


2
-1: Хоча voidфункції не повертають жодного значення , вони все одно повертають тип void . Тому я кажу, що B - це правда.
Томас Едінг

Повернення недійсності дозволено за деяких обставин. Дивіться тут .
Джош Келлі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.