|
Программирование >> Перегруженные имена функций и идентификаторы
Мой компилятор выдает сообщение о неверной повторной декларации, хотя я только раз определил функцию и только раз вызвал Подразумевается, что функции, вызываемые без декларации в области видимости (или до такой декларации), возвращают значение типа int. Это приведет к противоречию, если впоследствии функция декларирована иначе. Если функция возвращает нецелое значение, она должна быть объявлена до того как будет вызвана. Как наилучшим образом декларировать и определить глобальные переменные? Прежде всего заметим, что хотя может быть много деклараций (и во многих файлах) одной глобальной (строго говоря внешней ) переменной, (или функции), должно быть всего одно определение. (Определение - это такая декларация, при которой действительно выделяется память для переменной, и присваивается, если нужно, начальное значение). Лучше всего поместить определение в какой-то главный (для программы или ее части). c файл, с внешней декларацией в головном файле .h, который при необходимости подключается с помощью #include. Файл, в котором находится определение переменной, также должен включать головной файл с внешней декларацией, чтобы компилятор мог проверить соответствие декларации и определения. Это правило обеспечивает высокую мобильность программ и находится в согласии с требованиями стандарта ANSI C. Заметьте, что многие компиляторы и компоновщики в системе UNIX используют общую модель , которая разрешает многократные определения без инициализации. Некоторые весьма странные компиляторы могут требовать явной инициализации, чтобы отличить определение от внешней декларации. С помощью препроцессорного трюка можно устроить так, что декларация будет сделана лишь однажды, в головном файле, и она c помощью #define превратится в определение точно при одном включении головного файла. Что означает ключевое слово extern при декларации функции? Слово extern при декларации функции может быть использовано из соображений хорошего стиля для указания на то, что определение функции, возможно, находится в другом файле. Формально между: extern int f(); int f(); нет никакой разницы. Я, наконец, понял, как объявлять указатели на функции, но как их инициализировать? Используйте нечто такое: extern int func(); int (*fp)() = func; Когда имя функции появляется в выражении, но функция не вызывается (то есть, за именем функции не следует ( ), оно сворачивается , как и в случае массивов, в указатель (т.е. неявным образом записанный адрес). Явное объявление функции обтчно необходимо, так как неявного объявления внешней функции в данном случае не происходит (опять-таки из-за того, что за именем функции не следует ( ). Я видел, что функции вызываются с помощью указателей и просто как функции. В чем дело? По первоначальному замыслу создателя Си указатель на функцию должен был превратиться в настоящую функцию с помощью оператора * и дополнительной пары круглых скобок для правильной интерпретации. int r, func(), (*fp)() = func; r = (*fp)(); На это можно возразить, что функции всегда вызываются с помощью указателей, но что настоящие функции неявно превращаются в указатели (в выражениях, как это происходит при инициализациях) и это не приводит к каким-то проблемам. Этот довод, широко распространенный компилятором pcc и принятый стандартом ANSI, означает, что выражение: r = fp(); работает одинаково правильно, независимо от того, что такое fp - функция или указатель на нее. (Имя всегда используется однозначно; просто невозможно сделать что-то другое с указателем на функцию, за которым следует список аргументов, кроме как вызвать функцию.) Явное задание * безопасно и все еще разрешено (и рекомендуется, если важна совместимость со старыми компиляторами). Где может пригодиться ключевое слово auto? Нигде, оно вышло из употребления. Что плохого в таких строках: char c; while((c = getchar())!= EOF)... Во-первых, переменная, которой присваивается возвращенное getchar значение, должна иметь тип int. getchar и может вернуть все возможные значения для символов, в том числе EOF. Если значение, возвращенное getchar присваивается переменной типа char, возможно либо обычную литеру принять за EOF, либо EOF исказится (особенно если использовать тип unsigned char) так, что распознать его будет невозможно. Как напечатать символ % в строке формата printf? Я попробовал \%, но из этого ничего не вышло Просто удвойте знак процента %%. Почему не работает scanf( %d ,i)? Для функции scanf необходимы адреса переменных, по которым будут записаны данные, нужно написать scanf( %d , Почему не работает double d; scanf( %f , &d); scanf использует спецификацию формата %lf для значений типа double и %f для значений типа float. (Обратите внимание на несходство с printf, где в соответствии с правилом расширения типов аргументов спецификация %f используется как для float, так и для double).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |