可以用c而不是c ++做什么?

Alo*_*ave 10 c c++

有什么东西可以在C中完成但在C++中没有,在C++编码时你最想念的是哪些?

我能想到的几件事情:

  1. 我们可以将任何类型的指针分配给void指针,而不是在c中而不是在c ++中.
  2. 声明变量名称是C++中的关键字但不是C;)

编辑:感谢@sbi指出:
1.应该是:我们可以为C中的任何类型的指针分配void指针,但不能在C++中

pae*_*bal 37

注意:我想我会因此而受到抨击,但是,这是C++开发人员的C++问题,所以......

有什么东西可以在C中完成但在C++中没有,在C++编码时你最想念的是哪些?

作为一名C++开发人员,我不会错过C,无论是C99还是其他.

我不是出于好意而写的.对于缺少C/C99功能的C++开发人员来说,这是一个问题,因为他们忽略了C++的基本功能.我相信这个问题及其答案,忽视用C可行或更好的替代品++(不,在"C++向量是讨厌"的评论只是一个虚假的理由).

这就是为什么我会在这里讨论所谓的"缺失特征"......

可变长度数组?

可变长度数组是C99的语言特性.它的主要优点是:

  1. 在堆栈上分配
  2. 创建时可变长度
  3. 无需解除分配

对于最常见的情况,std::vector无论如何都会完成工作并拥有更多功能.例如,除非我错了,可变长度数组具有以下缺点:

  1. 堆栈上的分配意味着您无法从声明它的函数返回VLA
  2. VLA无法调整大小,这意味着如果它太小,那么你就搞砸了
  3. VLA必须在原型范围或块范围内声明.它不能是外部的,也不是静态的.并且您不能将其声明为结构的成员.
  4. 它不能有初始化程序

矢量可以调整大小,并可以返回.使用C++ 0x(和r值引用),您可以使用移动语义返回向量,这意味着不需要无用的临时对象.您可以将它放在struct/class中,它可以是extern或static.您可以使用默认值,数组内容,容器或带有C++ 0x的初始化列表初始化它.

即使在这之后,如果你真的想要的东西,如VLA,在C++中,它是可能的平均C++开发人员编写基于堆栈的载体状容器.并且它不需要完整的语言委员会更新.

只是为了好玩,我碰巧发布了一个简单的C++ VLA类概念验证答案.

C++的向量在大多数情况下是更好的选择,具有更多功能.在极少数情况下,确实需要VLA,其功能可以由用户定义的类模拟.

铸造void *T *

至于将任何内容void *转换为另一个类型指针,这不是C++缺少C的特性:这是弱类型与强类型的选择

并不是说在C++中不可能这样做,因为你可以用演员表来做.这种差异的关键在于降低一种语言中的bug风险,这种语言void *不像另一种语言那样有用:在我目前的C++ 100k行项目中,我没有出现过void *.

指定的初始化器?

构造函数提供了更好的选择.

当然,你没有直接初始化结构中的数据的可能性,但是,数据封装意味着大多数时候,我的对象中的数据是私有的,因此,使用指定初始化器初始化的整个概念他们会很荒谬.

对于类似POD的结构,构造函数很容易编写,并且可以处理指定初始化程序永远不会执行的情况(比如默认情况下初始化具有非零值的成员,甚至调用函数).

由于C++专注于数据封装,因此构造函数提供了指定初始化器的更好替代方案.

编辑2011-11-05:

在重新阅读本节之后,我想澄清一点:指定的初始化程序对于非常有限的情况(即POD)非常有用,这意味着虽然我不会错过它们(如问题中所述),但我不介意拥有它们.

复合文字?

这种语法糖再次假设您既知道结构的确切实现,又拥有对其成员的公共访问权限,这是您通常希望在C++中避免的内容.

如上所述,复合文字不再是功能,方法或构造函数无法处理的东西,具有奖励功能的优点.

声明变量名称是C++中的关键字而不是C?

我知道你的感受:每次我有可能使用interface,final或者synchronized在C++中,我也得到Java颤抖......

:-P

类型通用宏?

C中的问题是你有很多函数,对不同的类型做同样的语义事务,这意味着每个函数必须有不同的名称.例如,根据OpenGroup,存在以下功能:

  • double sin(double x);
  • float sinf(float x);
  • long double sinl(long double x);
  • 等等

资料来源:http://www.opengroup.org/onlinepubs/009695399/functions/sin.html

但他们的名字是一个真正的痛苦要记住,所以有人有一个想法.关于宏的一些内容,它将根据所使用参数的类型使用编译器内置扩展来调用正确的扩展.

这就是C99的神奇之处<tgmath.h>.

这个想法看起来很棒,他们甚至为下一个C标准中的所有功能添加了一个命题来提供这个功能,例如:

#define sin(x) __tgmath(x,,,     \
float, sinf, long double, sinl,  \
/* etc. */                       \
, , sin)(x)
Run Code Online (Sandbox Code Playgroud)

资料来源:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1340.htm

现在,令人震惊的消息:几十年来,这个功能在C++中可用:这称为函数重载.

例如,上面的函数在C++中声明为:

  • double sin (double x );
  • float sin (float x );
  • long double sin (long double x );
  • 等等

因此,"Type-generic宏"是一个被黑客攻击的实现,它致力于(部分地)模拟更通用的C++函数重载.

并猜测:您甚至可以为自己的用户定义类型添加自己的重载.

结论

如上所示,每次我研究C99特征时,结论都是:"嘿,我已经可以用C++做到了!" (通常在句子的某处用"更好"这个词).

说真的,作为一名C++开发人员,我现在想念的是能够在工作中使用C++ 0x.例如,以下C++ 0x功能:

  • auto
  • constexpr
  • 初始化列表
  • r值参考
  • lambda表达式
  • nullptr
  • 等等

整个"C缺少来自C++的特性"是一个被高估的概念,我怀疑,对于C开发人员(和C-with-classes开发人员)而言,它比C++开发人员更有趣.

  • @Jeremy:C++中禁止使用隐式转换来转换__from__`void*`,_ not to_. (2认同)

sch*_*hot 17

您可能会发现ISO C和ISO C++之间的网页不兼容性很有趣.

我大多错过了许多C++中没有的C99功能:

  • 复合文字;
  • 指定的初始化器;
  • 变量参数宏(包含在C++ 0X中).

  • 不要忘记restrict,VLA,类型泛型宏(tgmath.h) (2认同)

Chr*_*fer 15

不是一个主要 C,但可以说一个杀手级功能 C是C89的简单的语法可以很容易地编写一个编译器.好吧,无论如何,与C++编译器相比.

  • 我同意,虽然有趣的是大多数C++笨拙的语法来自于C++旨在向后兼容的事实:-) (10认同)
  • 我认为语言的简单性不仅仅是编译器的编写者. (2认同)