例如使用printf
代替cout
,scanf
代替cin
,使用#define
宏等等?
我不会说这是坏的,因为这将取决于个人选择。我的策略是,在C++中存在类型安全的替代方案时,请使用它们,因为这将减少代码中的错误。
define
宏被强烈反对,这是有充分理由的。在C++中,您几乎总是可以用更可维护和安全的东西(模板、内联函数等)来替换define
宏的使用。FILE*
及其众多函数。printf
及其格式化字符串的简洁性。printf
,但是你不应该推荐它而忽略其缺点:缺乏类型安全性和很容易搞砸规范和参数之间的匹配。 - Mark Ransommalloc
/free
和 new
/delete
之间。其他情况下,这只是一个风格问题...虽然 C 兼容 C++,但既然 C++ 拥有一切所需而不需要回退,为什么要混合两种语言呢?printf
代替cout
。后者虽然能够实现printf
的大部分或全部格式控制,但是它以一种有状态的方式实现。也就是说,当前的格式模式被存储为(全局)对象的一部分。这意味着糟糕的代码可能会使cout
处于一个状态,导致随后的输出格式错误,除非你每次使用它都重置所有格式设置。它还会对线程使用造成破坏。std::cout
的整个设计是作为一个存储状态的对象。它的主要问题在于缺少复制构造函数;你应该能够轻松地复制、设置状态、执行输出,然后丢弃副本而不影响原始对象。 - MSalters大多数情况下都有更好的解决方案,但并非所有情况。
例如,人们经常使用 memcpy
。我几乎不会这样做(除了在真正的低级代码中)。我总是使用 std::copy
,即使在指针上也是如此。
输入/输出例程也是如此。但确实有时,C风格的 printf
比 cout
(特别是在日志记录中)更容易使用。如果不能使用 Boost.Format,那么当然可以使用 C。
#define
是完全不同的东西。它并不是仅限于 C 的特性,在 C++ 中有许多合法的用途。(但有更多不合法的用途。)
当然,您永远不会使用它来定义常量(这就是 const
的作用),也不会用来声明内联函数(使用 inline
和模板!)。
另一方面,生成调试断言通常很有用,并且通常作为代码生成工具。例如,我正在对类模板进行单元测试,如果没有广泛使用宏,这将是一个真正的痛苦。在这里使用宏并不好,但可以节省成千上万行代码。
对于内存分配,我建议避免使用malloc/free而是坚持使用new/delete。
实际上,printf()
比cout
要快得多,而且C++的iostream库非常庞大。这取决于用户的偏好或程序本身(是否需要等等)。此外,scanf()
已经不适合使用了,我更喜欢使用fgets()
。
printf
通常不比cout
快。甚至可能相反。此外,fgets
和scanf
是完全不同的函数(scanf
提供格式化输入),而fgets
可以被cin
替代。 - Konrad Rudolph能否使用取决于将要使用的编译器。由于您正在使用C ++进行编程,我认为为了最大化兼容性,最好使用C ++提供的内容,而不是C函数,除非您没有其他选择。
从稍微不同的角度来看,我会说在C语言中使用scanf是不好的,更不用说在C++中了。用户输入太过变化无常,无法可靠地通过scanf进行解析。
我本来想在另一个回复下发表评论,但是由于无法... C的printf()比C++的iostream更好,因为它支持国际化。想要翻译一个字符串并将嵌入的数字放在不同的位置?使用ostream无法实现。printf()的格式规范是一个完整的小语言,可以在运行时解释。
void*
参数或返回void*
结果,那么它可能不是类型安全的。带有可变参数列表的函数(如printf
)也通常不是类型安全的。每当你需要使用sizeof
时,该代码很可能就不是类型安全的。 - Kristopher Johnsonprintf
的参数是否为正确类型,但即使编译器确保您不会在这里犯错,也不能传递任何用户定义的类型,因此重载operator<<
并使用cout
是解决需要在 C 中更改语法的问题的解决方案:std::cout << "My object is:" << obj << std::ednl;
相比之下,printf("My object is: "); obj.print(); printf("\n");
。 - David Rodríguez - dribeas