代码之家  ›  专栏  ›  技术社区  ›  Ande Turner

C:好习惯Re:向C++过渡

  •  19
  • Ande Turner  · 技术社区  · 16 年前

    我在大学刚开始学习C,现在已经有两个月了,明年我们将继续学习C++。

    是否有任何习惯我应该进入我的C编程,这将有助于过渡到C++的未来,或者是最好的思考它们完全分开?

    当你学习C然后C++时,你用C的方式做了什么改变?

    13 回复  |  直到 16 年前
        1
  •  26
  •   paercebal    16 年前

    已经有很多好的答案了。我的将更加“以心态为导向”。

    数据与行动!

    • 在C语言中,所有的操作都是“将此效果应用于此数据”。
    • 在C++中,这更像是“数据应该表现”。

    而“数据应该表现出来”可以在C语言中完成(并且完成了!)在C++中,实现这一点所需的一切都是可以访问的:封装、构造函数、重载重写、模板等。

    我发现这个“数据应该表现”的想法是一个非常好的指导原则,当编码在C++中。

    C++语法糖不是可选的

    你会发现很多C++特性可以在C中完成,有些人用它来作为不学习它们的借口。这种心态很危险 把C++看作一种新语言,而不是一种扩展 “在一些帖子中看到)。

    避免C++写C++的一个副作用是,当C++开发者应该理解C++代码时,他/她不应该理解你的小的个人框架,只模仿C++的糖。事实上,他/她不会对你的框架感兴趣。说实话,他/她只会对你感到同情/轻蔑,因为你浪费了宝贵的时间来制作它。最终,他/她会恨你,如果他/她必须使用你的框架而不是C++糖。

    像“我可以用C方式来做”这样的指导原则只会让你错失良机。如果你已经有了这种以C为中心的思维模式,最好不要开始学习C++。

    你选择的语言从来都不是最好的。你应该成为最好的。如果你写C++代码,那就用C++的方式写。

    C兼容C++代码是语义错误

    用typedefing结构使其可由C编译器编译是一个坏笑话。使用指针而不是引用是你未来自我的一记耳光。这个 extern "C" 只会使代码变弱,而不是变强。并使用 void * 通用性只会增加C++程序员的数量,他们会乐意以惊人的方式把你的头移走。

    除非你真的 真的? 不得不。

    对于一个永远不会使用的特性,您只需要用一种费时的编码风格来衡量自己。

    编译器是强大的朋友/敌人

    低级别工作对一些开发人员有奇怪的影响。他们非常相信自己对编译代码的控制。将此控制权委托给更高级别的构造对他们来说是困难的。

    一个很好的例子就是放弃构造函数/析构函数模式,因为” 有时候,构造器花费了太多时间…最好按我的方式去做… “。

    C++编译器能够很好地优化显然未优化的代码。事实上,编译器生成的代码可能与您认为生成的代码大不相同。

    不要试图比编译器更好/更聪明,因为:

    1. 您可能已经输了,因为即使是旧的编译器通常也会产生比您今天所梦想的更好的代码。
    2. 即使你今天打赢了,明天也会自动变成失败,因为编译器将来会越来越好,所以你今天的“优化代码”将成为未来几年的程序瓶颈和重构主题(不要为你提到可耻的记忆)。

    所以,相信你的编译器。

    不要对代码的生成进行微观管理。做你自己的工作,让编译器自己做。

    注意,这一点不应用于证明生成缓慢/低效代码的合理性。如果过早的优化是万恶之源,那么您仍然必须使用您的语言知识和编译器来生成良好和高效的代码(请参见下一点)。

    了解每个C++构造的优点/滞留/成本

    例如,事实上,虚方法向函数调用中添加了一个间接方向,这意味着某些人的性能将显著降低。事实是,性能问题通常出现在其他地方。

    无知不是借口。

    了解为每个C++构造生成的代码(即内联、引用、构造函数、析构函数、异常、函数重载、函数重写、模板、虚拟函数等)。知道什么会被优化,什么不会。

    这样,不仅你不会为你不需要的东西付费(这是C++的指导原则),而且你也会从零花钱,但带给你很多东西中获益。

    要谦虚

    有些人在C++中做的研究,在他们出生的那天比我们大多数人都要好。即使我们忽视了 Stroustrup ,名称如下 Meyers , Abrahams , Alexandrescu , Sutter 等等。经常出现在新想法旁边。尽管(或由于)它的外星观,STL是革命性的图书馆。像图书馆一样 Boost 尽管与一些完整的框架(如Java或.NET API)相比,它的“小尺寸”是一个巨大的存储库,提供了优秀的代码供您学习。

    只是因为你发现了一些新的特征“奇怪”或“外星人”,不要低估它。试着理解它可能会给你带来另一个工具,并且会增加你对语言的掌握,并且会让你的大脑工作,这在开发人员的工作中是件好事。

    我认识的大多数人都失败了他们的“转换为C++”只是假设这个或这个功能是无用的,因为他们不费力去理解它。

    RAII !!!!!

    如果你不知道它是什么,就去学习它。

    没有RAII,您的C++代码只是被窃听的代码,避免编译错误。

    RAII是C++最重要的概念之一。

    其他一切都是相关的。

        2
  •  19
  •   Stack Overflow is garbage    16 年前

    最好的建议可能是把它们当作完全独立的语言来对待。是的,大多数C代码可以由C++编译器编译,但通常不是一个好方法。

    C是一种非常低级的黑客语言。你看到的就是你得到的。它有指针和结构,所以使用指针和结构。它的类型安全性非常低,因此您尽可能忽略类型安全性。

    另一方面,C++允许大量的抽象。您通常希望使用迭代器,而不是指针,迭代器在概念上表现为指针,但不是(或可能不是)。

    您可以使用模板来保持类型安全性,并且仍然可以重用相同的单个函数定义,而不是丢弃类型信息(例如让函数接受void*,这样它们就可以处理任何指针类型)。

    而且,我们还为您提供了一个优秀的标准库,使您能够用简单的预定义构建块来表示复杂的算法。

    C++是一种多范式语言。这里的一些回答已经说过C++是面向对象的,它是部分真实的。它确实支持面向对象的代码,是的,但这不是C++的。 .

    C++ 支持通用编程,这通常优于OOP。它对函数编程也有一些有限的支持。当然,它还支持C风格的过程性编程。C++中的诀窍是理解所有这些,所以你知道什么时候使用。这就是C++的力量,在所有这些范式之间转换和混合的能力。把C++称为OOP语言的人和那些称之为改进C的人一样,忽略了这一点,它允许你用这些样式中的任何一种编写代码,但这两种方法都不值得。C是一种更好的C类语言,有很多更好的OOP语言。如果你想坚持一个单一的范例,那就用一种专门为此设计的语言。

        3
  •  10
  •   DevSolar    16 年前

    有趣的是,这里有多少人声称C和C++是“完全不同的”,以及“C++是面向对象的,C不是”…

    第一步:C++最初被设计成一个 延伸 C语言。实际上,C++标准文档 符合C标准。事实上,C++中的许多事情与C语言不同,但声称这两个完全分离是有点远的。好的C代码可以用C++编译器编译,而对于一些微不足道的问题,C和C++的解决方案可以看得一模一样。

    第二,不要让自己被愚弄相信C++是“面向对象语言”。C++是一种语言 支架 对象方向,正确。但它也支持通用编程和过程编程。只集中在C++的OOP方面消耗了它的大部分能量。

    至于习惯…不要太依附于C样式的字符串( char * )和数组( int foo[] )。这两种方法在C++中很少使用,因为有更强大(更方便)的替代品。 string vector .

    密切关注指针和动态内存分配。虽然优秀的C++代码很少,但必须注意它们是如何工作的。这样做的同时,你也会意识到 为什么? 好的C++代码封装它们,或者用引用替换它们,因此它们在生产质量代码中不多见。

    在设计C代码时,从 struct 保存相关数据(例如地址字段),然后构造处理该类型结构的函数( address_read( struct address_t * ) ,请 address_write( struct address_t * ) , address_modify_name( struct address_t *, char * ) 等等)。添加 main() 最后按适当顺序调用这些函数的函数。数据是程序的重要部分,而不是功能。这将使C++(和面向对象)的步骤更容易。

    还有很多,但我不想在一个这样的帖子里回答所有的问题。-)

        4
  •  7
  •   Ash    16 年前

    如果你能抓住它,我建议你看 The C++ Programming Language 由C++的创建者Bjarne Stroustrup。

    特别是“读者笔记”和“C++教程”将让你更好地理解C++与C在哪里和如何不同,并集中精力进行进一步的学习。当然,整本书在用C++工作时很有用。

    有趣的是,在第一章中,比亚恩说

    “在关于是否 在C++之前需要学习C,我是 坚信最好走 直接到C++。

    当然他会,不是吗,但是如果你接受他的推理,你最好尽快跳进C++。

        5
  •  6
  •   pmg    16 年前

    把语言分开。

    C和C++可以是相似的,但它们是不同的语言,对于相似的构造有不同的规则。如果你能把两者分开,那就更好了。

    当切换到C++时,准备好去学习(学习一种不同的、不兼容的方法):

    1. 预处理器 在C++中,你不应该像C.那样使用预处理器。
    2. :c没有
    3. 指针 C++可以被编码以更安全地处理它们。
        6
  •  4
  •   Aakash Goel    16 年前

    你转移到C++意味着你觉得你需要类,或者更好的库。 这就是我的感受。我还学习了C++的更好的特性,用我的C背景。 现在,我主要研究向量(除了类和模板)。

    我觉得语言太相似了

    把它们完全分开想。

        7
  •  4
  •   erik    16 年前

    我的猜测是,C++你将学习可能不会过于面向对象,至少它不是在我的大学反正。我们运行C++程序本质上是C程序。

    一定要了解如何实现类,以及指针的基本知识。

    您的文件I/O处理也将不同……而不是fstream在实现iostream函数的语法上读取。

    在简单的C++程序中浏览Web教程。 CodeProject 总是一个好资源。

        8
  •  4
  •   Liran Orevi    16 年前

    C++程序是完全不同的。你最好把时间花在学习C++上,而不是致力于改进C++的C元素。

    例如,即使是简单的“hello world”程序,也有很大的不同:

    丙:

    #include <stdio.h>
    int main(void)
    {
      printf("Hello, world!\n");
      return 0;
    }
    

    C++:

    #include <iostream>
    int main()
    {
       std::cout << "Hello, world!\n";
    }
    

    (示例来自 here )

    因为“printf”是一个函数,而“cout”不是一个函数,而是一个ostream类的实例。

    进一步阅读: iostream .

        9
  •  3
  •   Pierre    16 年前

    尽可能使用结构和函数指针来模拟类和抽象方法的方法。

    例如,如果您想定义一辆车,以及从使用C的车辆派生的一辆车,您将编写(对不起,我不会检查代码-):

    struct Vehicle
      {
      void (*checkFuel)(Vehicle*);
      void (*start)(Vehicle*);
      void (*move)(Vehicle*);
      void (*stop)(Vehicle*);
      }
    
    void start1(Vehicle* v)
      {
      v->checkFuel(v);
      printf("START!");
      }
    
    void start2(Vehicle* v)
      {
      v->checkFuel(v);
      printf("VROOOOMM!");
      }
    
    
    struct Car
      {
      Vehicule base;
      int (*klaxon)(Car*);
      }
    
    Vehicule* newVehicule()
     {
     Vehicule* v=(Vehicule*)malloc(sizeof(Vehicule));
     v->start= start1;
     v->move=
     (...)
     return v;
     }
    
    
    Car* newCar()
     {
     Car* c=(Car*)malloc(sizeof(Car));
     Vehicule* v=(Vehicule*)c;
     v->start= start2;
     v->move=
     (...)
     c->kaxon=(...)
     return c;
     }
    
        10
  •  2
  •   Duleb    16 年前

    以下是一些要点:

    1)确保你精通指针。关注数组和指针是如何工作的,它们之间的相似性和区别是什么。

    2)完善C的最好方法是编写程序。尽可能多地写。对于初学者,您可以为一些库函数编写自定义函数。您可以尝试使用 strcpy、strcmp、strncpy、memcpy、memmove。

    3)学习如何调试。(gdb真的很酷)。

    4)开始遵循特定的编码风格,并尝试坚持下去。

    5)始终为代码提供有意义的注释。

        11
  •  0
  •   ewanm89    16 年前

    C++是面向对象的,C不是。所以常见的事情,比如保持指针代码的整洁和对函数/方法的注释,以及理解如何不使用ifdefs获得无限的预处理器循环。

    然而,面向对象的方法通常更适合于实际编写关于对象的代码。所以您需要考虑新特性的区别。

        12
  •  0
  •   Red    16 年前

    C和C++编程风格完全不同。C++是面向对象的编程,其中C是面向过程的编程。C++编程是使用类/对象模拟真实世界问题的最佳方法。但是,指针、结构、运算符、转换运算符、数据处理等基本概念在这两者中都是相同的。 结构和类是相似的概念,但不完全是。因此,当您在“c”中学习时,您可以集中精力使用结构、指针、运算符和内存管理进行编程。

        13
  •  -1
  •   kenny    16 年前

    函数指针。谷歌 first hit .