Подтвердить что ты не робот

Поддерживает ли C перегрузку?

Я просто хочу знать, поддерживает ли C над загрузкой? Поскольку мы используем системные функции, такие как printf с разными аргументами. Помогите мне

4b9b3361

Ответ 1

Нет, C не поддерживает какую-либо перегрузку (если вы не считаете, что встроенные операторы уже перегружены, чтобы быть формой перегрузки).

printf работает с использованием функции varargs. Вы делаете вызов, который выглядит так, как будто он может быть перегружен:

printf("%d", 12); // int overload?
printf("%s", "hi"); // char* overload?

На самом деле это не так. Существует только одна функция printf, но компилятор использует специальное вызов для вызова, где любые аргументы, которые вы предоставляете, помещаются последовательно в стек [*]. printf (или vprintf) проверяет строку формата и использует это, чтобы выяснить, как читать эти аргументы. Вот почему printf не является безопасным для типов:

char *format = "%d";
printf(format, "hi"); // undefined behaviour, no diagnostic required.

[*] стандарт фактически не говорит, что они переданы в стек, или вообще упоминают стек, но это естественная реализация.

Ответ 2

C не поддерживает перегрузку. (Очевидно, что даже если бы это было так, они не использовали бы это для printf: вам понадобится printf для любой возможной комбинации типов!)

printf использует varargs.

Ответ 3

Нет, C не поддерживает перегрузку, но поддерживает Функции Variadic. printf является примером функций Variadic.

Ответ 4

Все зависит от того, как вы определяете "поддержку".

Очевидно, язык C предоставляет перегруженные операторы на основном языке, поскольку большинство операторов в C имеют перегруженные функциональные возможности: вы можете использовать двоичный + с int, long и с типами указателей.

В то же время C не позволяет создавать собственные перегруженные функции, а стандартная библиотека C также должна использовать разные функции, которые будут использоваться с разными типами (например, abs, fabs, labs и т.д.).

Другими словами, C имеет некоторую степень перегрузки жестко закодированных на основной язык, но ни стандартная библиотека, ни пользователи не могут выполнять собственную перегрузку.

Ответ 5

Нет, C не поддерживает перегрузку. Если вы хотите реализовать перегрузку, похожую на С++, вам придется вручную управлять именами функций, используя какое-то согласованное соглашение. Например:

int myModule_myFunction_add();
int myModule_myFunction_add_int(int);
int myModule_myFunction_add_char_int(char, int);
int myModule_myFunction_add_pMyStruct_int(MyStruct*, int);

Ответ 6

Не напрямую, и это не так, как работает printf, но можно создать эквивалент перегруженных функций с использованием макросов, если типы имеют разные размеры. Таким образом можно реализовать типичные математические функции в tgmath.h стандарта C99.

Ответ 7

В стандарте C для перегрузки оператора нет положения; предложения по его добавлению были отклонены на том основании, что многие системы сборки не имеют возможности для размещения нескольких функций с тем же именем. Хотя С++ может обойти это, например, имея

void foo(int);
int foo(char*);
long foo(char *, char **);

скомпилировать функции, названные такими же, как v__foo_i, i__foo_pc и l__foo_pc_ppc [компиляторы используют разные соглашения об именах, хотя стандарт С++ запрещает использование внутренних двойных подчеркиваний в идентификаторах, чтобы позволить компиляторам давать имена вещей, как указано выше, без конфликтов ]. Авторы стандарта C не хотели, чтобы какие-либо компиляторы изменяли соглашения об именах, чтобы разрешить перегрузку, поэтому они не предусматривают его.

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

void foo_zz1(int);
int foo_zz2(char*);
long foo_zz3(char *, char **);
inline void foo(int x) { foo_zz1(x); }
inline int foo(char* st) { foo_zz2(st); }
long foo(char *p1, char **p2) { foo_zz3(p1,p2); }

Я помню, как смотрел встроенный компилятор для гибрида между C и С++, который поддерживал вышеупомянутое как нестандартное расширение, но я не уверен в деталях. В любом случае, даже если некоторые компиляторы C поддерживают перегрузку функций, которые не имеют внешней привязки, она не поддерживается C14, и я не знаю (к сожалению) о любых активных усилиях по добавлению такой функции в будущие стандарты C.

Тем не менее, GCC может быть создан с использованием макросов для поддержки формы перегрузки, которая не поддерживается непосредственно на языках с перегрузкой оператора. GCC включает в себя внутреннее значение, которое будет определять, может ли выражение быть оценено как константа времени компиляции. Используя это внутреннее, можно написать макрос, который может оценивать выражение различными способами (в том числе вызывающими функциями) в зависимости от аргумента. Это может быть полезно в некоторых случаях, когда формула будет оцениваться как константа времени компиляции, если задана аргумент константы времени компиляции, но приведёт к ужасному беспорядку, если будет задан переменный аргумент. В качестве простого примера предположим, что вы хотите битово-обратное 32-битное значение. Если значение постоянное, это можно сделать с помощью:

#define nyb_swap(x) \
  ((((x) & 1)<<3) | (((x) & 2)<<1) | (((x) & 4)>>1) | ((((x) & 8)>>3) )
#define byte_swap(x) \
  ( (nyb_swap(x)<<4) | nyb_swap((x) >> 4) )
#define word_swap(x) \
  ( (byte_swap(x)<<24) | (byte_swap((x) >> 8)<<16) | \
    (byte_swap((x) >> 16)<<8) | (byte_swap((x) >> 24)) )

И выражение типа uint32_t x=word_swap(0x12345678); просто загрузило бы x с помощью 0x87654321. С другой стороны, если значение не является константой, результат будет ужасным: выражение типа uint32_t y=word_swap(x); может генерировать множество десятков инструкций; вызов функции с частично развернутым контуром будет почти таким же быстрым, но гораздо более компактным. С другой стороны, использование цикла предотвратило бы, чтобы результат считался константой времени компиляции.

Используя GCC, можно определить макрос, который либо будет использовать макрос константы, заданный константой, либо вызвать функцию при задании переменной:

#define wswap(x) \
  (__builtin_constant_p((x)) ? word_swap((x)) : word_swap_func((x))

Этот подход не может делать все, что может сделать перегрузка на основе типов, но он может сделать много перегрузок, не может.

Ответ 8

C Не поддерживает перегрузку. Но мы можем реализовать эту функциональность, программируя нашу собственную библиотеку, которая, в свою очередь, может обеспечить поддержку перегрузки.

Ответ 9

Нет c не поддерживает перегрузку функции. Но вы можете заставить его скомпилировать/работать, если вы используете g++ (компилятор С++).