你已经了解C ++时学习C语言?

时间:2009-12-16 16:25:30

标签: c++ c

我认为我对C ++有深入的了解,而且我想学习C语言。

有很多资源可以帮助人们从C到C ++,但我没有找到任何有用的东西来做相反的事情。

具体做法是:

  1. 每个C程序员都应该知道广泛使用的通用库(比如boost for C ++)吗?
  2. 最重要的C语言(如C ++的RAII)是什么?
  3. 我应该学习C99并使用它,还是坚持使用C89?
  4. C ++开发人员的任何陷阱/陷阱?
  5. 还有什么有用的知识吗?

10 个答案:

答案 0 :(得分:26)

这里已经有了很多,所以也许这只是一个小小的补充,但我发现这是最大的差异。

库:

  • 我把它放在第一位,因为在我看来这是实践中最大的不同。 C标准库非常(!)稀疏。它提供最低限度的服务。对于其他一切你必须自己动手或找到一个可以使用的库(很多人都可以)。你有文件I / O和一些非常基本的字符串函数和数学。对于其他一切,您必须自己动手或找到要使用的库。我发现从C ++迁移到C时我会错过扩展容器(特别是地图),但还有很多其他容器。

成语:

  • 这两种语言都有手动内存(资源)管理,但C ++为您提供了一些隐藏需求的工具。在C中你会发现自己更频繁地手工跟踪资源,你必须习惯这一点。特别的例子是数组和字符串(C ++ vectorstring为你节省很多工作),智能指针(你不能在C中真正做“智能指针”。你可以做引用计数,但你必须自己上下调整引用计数,这非常容易出错 - 智能指针首先被添加到C ++中的原因),以及缺少RAII一般你会如果您习惯于现代风格的C ++编程,请注意到处处。
    • 你必须明确建筑和破坏。你可以争论这个缺陷的优点,但结果会有更多的显式代码。
  • 错误处理。 C ++异常可能很难实现,所以不是每个人都使用它们,但如果你使用它们,你会发现你必须非常注意你如何进行错误通知。需要检查所有重要调用的返回值(有些人会认为所有调用)需要很多纪律,而且很多C代码都没有这样做。
  • 字符串(和一般的数组)不会随身携带。你必须在C中传递很多额外的参数才能解决这个问题。
  • 如果没有名称空间,您必须仔细管理全局名称空间。
    • 没有明确将函数绑定到类型,就像在C ++中使用class一样。您必须维护一个约定,以便为与类型关联的所有内容添加前缀。
  • 你会看到更多的宏。宏在C中用于C ++具有相同语言特性的许多地方,特别是符号常量(C有enum但很多旧代码使用#define代替),而且用于泛型(C ++使用)模板)。

建议:

  • 考虑寻找一般用途的扩展库。请查看GLibAPR
    • 即使您不想要一个完整的库,也要考虑查找一般用途的地图/字典/哈希表。还要考虑捆绑包含大小的裸骨“字符串”类型。
  • 习惯于在所有公共名称上添加模块或“类”前缀。这有点乏味,但它会为你节省很多麻烦。
  • 大量使用前向声明来使类型不透明。在C ++中,您可能在标头中包含私有数据并依赖private阻止访问,在C中您希望尽可能将实现细节推送到源文件中。 (在我看来,你实际上也希望用C ++做这件事,但是C让它变得更容易,所以更多的人会这样做。)

    C ++揭示了标题中的实现,即使它在技术上隐藏了它在类外的访问。

    // C.hh
    class C
    {
        public:
           void   method1();
           int    method2();
    
       private:
           int    value1;
           char * value2;
    };
    

    C将“类”定义推送到源文件中。标题是所有前向声明。

    // C.h
    typedef struct C C;           // forward declaration
    
    void c_method1(C *);
    int  c_method2(C *);
    
    // C.c
    struct C
    {
        int    value1;
        char * value2;
    };   
    

答案 1 :(得分:12)

Glib是现代C的一个很好的起点,让你习惯于不透明类型和半对象定位等概念,这些概念在现代C中很常见。另一方面,标准POSIX API是有点“经典”C。

从C ++到C的最大差距不是语法,它是成语,就像C ++一样,有不同的编程学派。如果您使用设备驱动程序而不是XML解析器,那么您将编写完全不同的C.

答案 2 :(得分:6)

Q5。还有什么有用的知识吗?

购买K& R2的副本并阅读。在每页成本的基础上,它可能是您用自己的钱购买的最昂贵的计算书,但它会让您对C及其中的思维过程深表感谢。做练习也会磨练你的技能,让你习惯语言中的可用语言而不是C ++。

答案 3 :(得分:4)

按顺序提出问题:

  1. 不幸的是,没有像Boost for C那样的东西。
  2. 这也不是RAII的顺序。
  3. 尝试实现C99的唯一编译器是Comeau。
  4. 很多人到处都是,我很害怕。
  5. 相当多。 C与C有着截然不同的心态。
  6. 其中一些看似相当简洁,但这就是生活。 C有一些很好的库,但没有像Boost这样的地方可以将它们收集起来,或者像Boost那样为C ++提供相对统一的界面。

    有许多习语,但其中很多都是你编辑代码的方式,例如通过快速连续编写fopen()和匹配fclose()来模仿RAII,之后才会在其间编写代码来处理数据。

    每个角落等待的陷阱/陷阱主要源于缺少像字符串和向量这样的动态数据结构,因此您经常需要自己编写这些内容。没有运算符重载,构造函数等,使它们真正成为通用目标要困难得多。很多图书馆都有它们,但你最终还是自己动手了,因为:

    1. 图书馆做得不怎么样,或者
    2. 使用图书馆更多工作比它值得。

    心态的差异几乎肯定是最重要的,至少对我而言。当我编写C ++时,我几乎把所有努力集中在设计最干净的接口上,而且我倾向于将接口的实现视为几乎一次性代码。在大多数情况下,我不打算对代码的那一部分进行微调 - 只要界面很好,替换整个实现通常很容易,我不用担心它。

    在C中,似乎(至少对我而言)将界面与实现分开几乎彻底或干净得多。因此,我倾向于花费更多的时间来尽可能干净地实现代码的每个部分,因为后来的更改往往更加困难并且丢弃并且更换不太好的部分实际上不太可能工作非常好。

    编辑(因为人们已经提出了关于C99支持的问题):虽然我关于缺乏C99支持的陈述可能看起来很苛刻,但事实是这是真的。

    MS VC ++:支持C95,并且有几个C99功能(例如C ++风格的评论分隔符),主要是因为C99标准化了他们以前作为扩展的内容。

    Gnu:根据C99 Features Status页面,gcc(4.4)的最新迭代具有一些C99特征,但是一些(包括VLA)被描述为“破碎”,而其他特征为“缺失”。一些缺失的“功能”实际上是整个区域,而不是单个功能。

    PCC:PCC site声称C99符合性仅是未来的目标,而不是现实。

    Embarcadero Technologies(nee Borland)似乎根本没有说明与C99的一致性 - 从外观来看,他们最后一次使用C编译器可能是在C99甚至发布之前。 / p>

    微软openly states他们目前没有支持C99的计划,他们甚至不会在VS 2010发布之前考虑它。虽然我找不到任何关于它的公开声明,但Embarcadero看起来大致相同:没有暗示当前的计划,甚至他们也不会考虑很快就会对它进行研究。

    虽然gcc和pcc似乎都有计划,但他们目前只是这样:计划。他们都公开承认,目前他们并不是非常接近符合C99。

答案 4 :(得分:2)

以下是您想要了解的一些主要内容的 quick reference

答案 5 :(得分:2)

这是你没有要求的建议:我认为大多数潜在的雇主认为如果你是C ++你知道C.学习C的细节,而一个有趣的学术练习,IMO会不会让你获得很多资格点。

如果你最终处于需要做C的位置,你会很快就能发现差异。

但不要听我说。学习C ++我太懒了,太傻了。)

答案 6 :(得分:2)

  

还有什么有用的知识吗?

C99不是c ++任何修订的子集,而是单独的语言。

答案 7 :(得分:1)

当我回到C时,我所遇到的最大冲击是变量是在函数级别定义的 - 即你不能将变量作用于块(if语句或for循环中)在函数内部。

答案 8 :(得分:1)

除极少数情况外,任何C代码都是有效的C ++,因此实际上并没有新的东西需要学习。
这更像是一种忘却的问题 不使用new,不使用类,在代码块的开头定义变量等。
从严格意义上说,C ++不是面向对象的,但它仍然是程序性的,支持类。也就是说,你实际上已经在C ++中使用过程式编程,最令人震惊的变化就是没有类,继承,多态等等。

答案 9 :(得分:0)

由于C ++几乎是C89的超集,你应该已经了解了所有C89。您可能希望专注于C89和C99之间的差异。