stdio.h
или же cstdio
? и почему? Рассмотрим следующие программы:
#include<stdio.h>
int main()
{
printf("Hello World");
return 0;
}
#include<cstdio>
int main()
{
printf("Hello World");
return 0;
}
Оба работают как положено. Так какое использование является более подходящим?
Ответ: Ни! Удивлены? Читать дальше.
Стандартная библиотека C ++ предоставляет все стандартные заголовки C для совместимости, в то время как C ++ как язык также предоставляет все эквивалентные заголовки. Как соглашение,
cxxxxx
,Стандарт C ++ упоминает это под Приложение D (нормативное) Особенности совместимости:
§ 2 упоминает важный отличительный момент. Это правило, примененное к приведенным выше примерам, означает:
Давайте применим это правило к нашим образцам кодов и измерим все за и против:
Образец 1:
Это приводит все символы из stdio.h в глобальное пространство имен. Преимущество состоит в том, что вы можете использовать символы без какой-либо квалификации, поскольку они импортируются в глобальное пространство имен. Недостатком является то, что вы в конечном итоге загрязняете глобальное пространство имен многими именами символов, которые вы, вероятно, никогда не будете использовать. Это может привести к конфликту имен символов. В C ++ всегда рассматривайте глобальное пространство имен как минное поле и по возможности избегайте его.
Образец 2:
Это очень плохая практика, потому что нет гарантии, что реализация поместит символы в глобальное пространство имен, стандарт просто не требует этого. Мы просто полагаемся на поведение одной конкретной реализации компилятора. Мы не можем и не должны предполагать, что все компиляторы будут делать это. Строго говоря, программа не одобрена стандартом, и это использование не переносимо во всех реализациях.
Правильное использование заключается в использовании cstdio
и полностью квалифицировать имена символов или привести их в область видимости using
декларации. Это гарантирует, что все символы, которые мы используем, присутствуют в std
пространство имен, и мы не загрязняем глобальное пространство имен. Пример правильного использования:
#include<cstdio>
using std::printf;
int main()
{
printf("Hello World");
return 0;
}
Обратите внимание, что директива using namespace std;
, особенно в шапке, не очень хороший вариант и вы всегда должны использовать using
деклараций.
Обратите внимание, что мы считаем stdio.h
против cstdio
здесь только пример использования, на практике это относится к все самый cxxxx
а также xxxx.h
заголовки, кроме нескольких как <math.h>
а также <cmath>
.
Поскольку этот пост немного устарел, я хотел бы поделиться следующим:
Using X.h // Compatible with C language standard
---------------
#include <X.h>
int main() {
// Invoke X's corresponding function
return 0;
}
Using X // Not compatible with C language standard
--------------
#include <X>
int main() {
// Invoke X's corresponding function
return 0;
}
С.5.1 (раздел из документа C ++ 17)
Модификации заголовков [diff.mods.to.headers]
Для совместимости со стандартной библиотекой C стандартная библиотека C ++ предоставляет заголовки C, перечисленные в D.5, но их использование
устарел в C ++.Для заголовков C нет заголовков C ++
<stdatomic.h>
,<stdnoreturn.h>
, а также<threads.h>
и сами заголовки C
часть С ++.Заголовки C ++
<ccomplex>
(D.4.1) и<ctgmath>
(D.4.4), а также их соответствующие заголовки C<complex.h>
а также<tgmath.h>
, не делайте
содержат любой контент из стандартной библиотеки C и вместо
просто включите другие заголовки из стандартной библиотеки C ++.
Д.5
Заголовки стандартной библиотеки C [depr.c.headers]
1. Для совместимости со стандартной библиотекой C стандартная библиотека C ++ предоставляет заголовки C, показанные в таблице 141.
И то и другое C ++ 11 а также C ++ 17 Стандартные технические документы утверждают использование <X.h>
остается для совместимости со стандартом C, хотя их использование рассматривается как осуждается.
Они рассматривают «Undeprecating» использование заголовков библиотеки C в C ++ 20. <X.h>
выделены зеленым цветом. C ++ 11 и C ++ 17 устарели, на данный момент, заявлено как «слабая рекомендация» и «твик» для сохраненияЗаголовки стандартной библиотеки C (c.headers)«отображается ниже:
«Базовые заголовки библиотеки C являются важной функцией совместимости, и в ближайшее время никуда не денутся». (от Обзорный документ C ++ 20)
Стандарт D.5 C
заголовки библиотеки [depr.c.headers]Слабая рекомендация: В дополнение к вышесказанному, также удалите
соответствующие заголовки C из стандарта C ++, так как у нас нет
соответствующий<stdatomic.h>
,<stdnoreturn.h>
, или же<threads.h>
Заголовки.
Как и выше, но со следующими настройками:
20.5.5.2.1 Заголовки стандартной библиотеки C [c.headers]Для совместимости со стандартной библиотекой C, стандартом C ++
библиотека предоставляет заголовки C, показанные в таблице 141. Таблица 141 — C
заголовки
<assert.h> <inttypes.h> <signal.h> <stdio.h> <wchar.h>
<complex.h> <iso646.h> <stdalign.h> <stdlib.h> <wctype.h>
<ctype.h> <limits.h> <stdarg.h> <string.h>
<errno.h> <locale.h> <stdbool.h> <tgmath.h>
<fenv.h> <math.h> <stddef.h> <time.h>
<float.h> <setjmp.h> <stdint.h> <uchar.h>
Заголовок
<complex.h>
ведет себя так, как будто он просто включает в себя заголовок<complex>
,
Заголовок<tgmath.h>
ведет себя так, как будто он просто включает в себя заголовки<complex>
а также<cmath>
,
Бьярне Страуструп рекомендует максимизация взаимодействия между
Языки Си и Си ++, от снижение несовместимости столько, сколько
возможный. Другие утверждают иначе, поскольку это усложняет вещи.
Ну, это похоже <X.h>
не куда угодно. В конечном счете, вы можете использовать оба. Лично я бы решил, какой из них я буду использовать, чтобы ваш код обратная совместимость с кодом C или нет.