Несколько вопросов по С/С++

239
15 февраля 2017, 23:09

Несколько вопросов:

1) Первый вопрос в следующем, правильно ли говорить, что подключается библиотека или правильно будет подключается заголовочный файл в языках C\C++? Простой пример:

#include <stdio.h>
int main(void) { ... }
#include <iostream>
int main() { ... }

Я думаю, что при подключении библиотеки при помощи pragma все равно нужно тащить ее заголовочный файл, но это именно заголовочный файл, а не библиотека.

2) Второй вопрос в следующем, при написании кода на С++, стоит ли отказаться от использования макроподстановок в пользу типизированных констант? Например, вместо

#define N 5 

написать

const int N = 5

И откзааться от макросов-функций в пользу inline функций?

3) Третий вопрос, почему некоторые товарищи считают, что в языке СИ нельзя использовать переменные - итераторы непосредственно в заголовке цикла? Возможно, это действительно запрещалось в каком либо старом стандарте, но я с такой проблемой лично не сталкивался.

Answer 1

правильно ли говорить, что подключается библиотека или правильно будет подключается заголовочный файл в языках C\C++?

В классическом случае заголовочный файл и сама библиотека - две отдельные сущности.

  • В классическом случае включение заголовочного файла не является подключением библиотеки. Заголовочный файл - это лишь "анонс" содержимого библиотеки, а не сама библиотека. Сама библиотека подключается отдельно, каким-то платформенно-зависимыми средствами.

    В вашем примере фигурируют заголовочные файлы стандартной библиотеки. Сама стандартная библиотека как правило подключается компилятором автоматически, поэтому у новичков часто возникает иллюзия того, что библиотеки подключаются просто включением заголовочного файла.

  • В связи с популярностью шаблонного программирования в С++ последнее время натуральным образом появились библиотеки, состоящие только из заголовочных файлов (чисто заголовочная библиотека, header-only library). В таком случае включение заголовочного фала фактически и является включением всей библиотеки прямо в ваш код. Больше просто нечего подключать. Это еще одна причина того, почему включение заголовочного фала иногда называют "подключением библиотеки" (в данном случае - справедливо называют).

    Например, та часть стандартной библиотеки С++, которая исторически называется STL, обычно реализуется как чисто заголовочная библиотека.

  • На платформе MSVC существует практика создания заголовочных файлов библиотек, которые внутри себя уже содержат директиву #pragma, которая также обеспечивает и подключение самой библиотеки к проекту. Таким образом, выполняя включение заголовочного файла вы автоматически вызываете и подключение соответствующей библиотеки. В таком случае тоже можно говорить, что включив такой заголовочный файл вы тем самым подключили и саму библиотеку... но все таки стоит понимать суть процесса.

    Возможность подключения библиотек через директиву в исходнике (#pragma) - очень грамотное и полезное свойство MSVC, но оно свойственно только MSVC.

при подключении библиотеки при помощи pragma все равно нужно тащить ее заголовочный файл

Разумеется. Заголовочный файл всегда нужен, независимо от того, надо ли вам что-то подключать при помощи #pragma. Но еще раз: подключение библиотек через #pragma - свойство только MSVC. На других платформах библиотеки подключают не через #pragma, и аналогов такой функциональности пока не видно.

при написании кода на С++, стоит ли отказаться от использования макроподстановок в пользу типизированных констант

Да, за исключением тех ситуаций, когда имеет место смешанный С/С++ проект. В заголовочных файлах, которые потенциально могут включаться и в С код, следует придерживаться #define.

Также, когда речь идет о константах времени компиляции, можно посоветовать использовать constexpr вместо const.

и откзааться от макросов-функций в пользу inline функций?

Там, где это возможно/оправданно - да.

Судя по вашему третьему вопросу (как я его понял), вы пользуетесь более-менее современными компиляторами С, поддерживающим стандарт С99 или выше. Тогда в вашем С уже есть inline-функции и там, где это возможно, стоит использовать именно их даже в С коде.

Однако стоит заметить, что типонезависимые (type-agnostic) макросы в С являются скорее заменителями шаблонных инлайновых функций в С++. Поэтому переход от макросов к обычным inline-функциям не всегда возможен/оправдан.

Третий вопрос, почему некоторые товарищи считают, что в языке СИ нельзя использовать переменные - итераторы непосредственно в заголовке цикла?

Если речь идет об объявлении переменных в заголовке цикла, то это свойство стандарта С99 и старше. В до-С99 языке это не разрешалось.

Answer 2
  1. Библиотека подключается, заголовочный файл включается... :)
  2. Да.
  3. Было нельзя, в современном стандарте - вполне.
  4. Краткость - с.т. :)
Answer 3

Небольшая ремарка по поводу пункта 3, но немножко в другом ракурсе: почему в языке C++ не просто можно, а рекомендуется объявлять переменные непосредственно перед местом их использования. В том числе и в циклах.

Например, потому, что подобная запись:

Foo bar;

в C++ тянет за собой конструктор Foo. А он, в свою очередь, может оказаться не таким уж и лёгким, обладать побочными эффектами, и т.д. Но зачем нам всё это если, например, в ветке кода, по которой может пойти исполнение, эта переменная не будет использоваться вообще?

READ ALSO
Проблема с массивом [требует правки]

Проблема с массивом [требует правки]

почему при выводе информации на консоль получается не то что надо?

266
Ширина выводимого текста WinAPI

Ширина выводимого текста WinAPI

Есть вариант получения ширины текста в логических юнитах через GetTextExtentPoint32, но не смог найти как перевести их в пиксели

344
Проверка является ли строка числом

Проверка является ли строка числом

Есть QString, нужно проверить является ли она числомВ QChar есть метод isNumber(), который это делает, но в QString его нет

462