现在我在 Varsity 学习 C 已经不到 2 个月了,明年我们将继续学习 C++。
在我的 C 编程中,我是否应该养成任何有助于将来过渡到 C++ 的习惯,或者最好将它们完全分开考虑?
当您学习 C 和 C++ 时,您用 C 编写代码的方式是否发生了任何变化?
现在我在 Varsity 学习 C 已经不到 2 个月了,明年我们将继续学习 C++。
在我的 C 编程中,我是否应该养成任何有助于将来过渡到 C++ 的习惯,或者最好将它们完全分开考虑?
当您学习 C 和 C++ 时,您用 C 编写代码的方式是否发生了任何变化?
已经有很多好的答案了。我的将更加“以心态为导向”。
虽然“数据应该表现”可以在 C 中完成(并且已经完成!),但在 C++ 中,轻松实现这一点所需的一切都已经可以访问:封装、构造函数、重载覆盖、模板等。
在用 C++ 编码时,我发现这个“数据应该表现”的想法是一个非常好的指导原则。
你会发现很多 C++ 特性可以用 C 语言完成,有些人会以此为借口不去学习它们。这种心态是危险的(这是在某些帖子中看到的“将 C++ 视为一种新语言,而不是扩展”的部分)。
避免以 C++ 方式编写 C++ 的一个副作用是,虽然 C++ 开发人员应该理解 C++ 代码,但他/她不应该理解你的小型个人框架,该框架模仿具有 C-only 功能的 C++ 糖。事实上,他/她不会对你的框架感兴趣。说实话,他/她只会对你感到同情/鄙视,因为你失去了宝贵的时间来制作它。最终,如果他/她必须使用您的框架而不是 C++ 糖,他/她会讨厌您。
诸如“我可以用 C 方式做到这一点”之类的指导原则只会让你错过这辆马车。如果你已经有这种以 C 为中心的思维模式,最好不要开始学习 C++。
您选择的语言从来都不是最好的。你应该成为最好的。如果您编写 C++ 代码,则以 C++ 方式编写它。
对结构进行类型定义以使其可被 C 编译器编译是一个糟糕的笑话。使用指针而不是引用是对你未来的自己的一记耳光。extern "C"
只会使您的代码更弱,而不是更强大。使用void *
泛型只会增加 C++ 程序员同行的数量,他们会很乐意以极其痛苦的方式移除你的头。
除非您真的真的必须这样做,否则永远不要费心编写与 C 兼容的代码。
你只会用一种你永远不会使用的功能的耗时编码风格来加重自己的负担。
低级工作对一些开发人员有奇怪的影响。他们非常相信自己对编译代码的控制。将这种控制委托给更高级别的构造对他们来说是困难的。
一个很好的例子是放弃构造函数/析构函数模式,因为“有时,构造函数需要太多时间......最好按照我的方式去做...... ”。
C++ 编译器非常有能力优化明显未优化的代码。事实上,编译器生成的代码可能与您认为自己生成的代码完全不同。
不要试图比编译器更好/更聪明,因为:
所以,相信你的编译器。
不要对代码的生成进行微观管理。做你自己的工作,让编译器自己做。
请注意,这一点不应被用来证明生产缓慢/低效的代码是合理的。如果过早优化是万恶之源,那么您仍然必须使用您对语言和编译器的了解来生成优质高效的代码(请参阅下一点)。
例如,虚拟方法在函数调用中增加了一种间接方式,这对某些人来说意味着性能会急剧下降。事实是,性能问题通常在其他地方。
无知不是借口。
了解为每个 C++ 构造生成的代码(即内联、引用、构造函数、析构函数、异常、函数重载、函数覆盖、模板、虚函数等)。知道什么会被优化掉,什么不会。
这样一来,您不仅不会为不需要的东西买单(这是 C++ 的指导原则),而且您还可以从零成本但给您带来的东西中获利。
有些人在做 C++ 研究时,在他们出生那天就比我们大多数人都更擅长 C++。即使我们忽略Stroustrup ,像Meyers、Abrahams、Alexandrescu、Sutter等名字也会经常与新想法一起出现。尽管(或作为其结果)其异类的前景,STL 是革命性的图书馆。像Boost这样的库,尽管与一些完整的框架(如 Java 或 .NET API)相比它“体积小”,但它是一个巨大的优秀代码存储库,可供您学习。
仅仅因为你发现了一些“奇怪”或“外星人”的新功能,不要小看它。试图理解它可能会给你带来另一个可供你使用的工具,并且总是会提高你对语言的掌握程度,并且总是会让你的大脑工作,这在开发业务中是一件好事。
我认识的大多数未能“转换为 C++”的人只是认为这个或这个特性是无用的,因为他们没有费心去理解它。
如果您不知道它是什么,请学习它。
如果没有 RAII,您的 C++ 代码只是避免编译错误的错误代码。
RAII 是 C++ 中最重要的一个概念。
其他一切都是相关的。
最好的建议可能是将它们视为完全独立的语言。是的,大多数 C 代码都可以由 C++ 编译器编译,但这通常不是一个好方法。
C 是一种非常低级的黑客语言。你所看到的就是你得到的。它有指针和结构,所以你使用指针和结构。它几乎没有类型安全性,因此您尽可能忽略类型安全性。
另一方面,C++ 允许大量抽象。您通常希望使用迭代器而不是指针,它在概念上表现为指针,但不是(或可能不是)。
您可以使用模板来保持类型安全,并且仍然能够重用相同的单个函数定义,而不是丢弃类型信息(例如,让函数接受 void* 以便它们可以使用任何指针类型)。
并且您将获得一个出色的标准库,它使您能够根据简单的预定义构建块来表达复杂的算法。
C++ 是一种多范式语言。这里的一些答案说 C++ 是面向对象的,这部分是正确的。它确实支持面向对象的代码,是的,但这不是 C ++。
C++还支持泛型编程,这通常优于 OOP。它对函数式编程也有一些有限的支持。当然,它仍然支持 C 风格的过程式编程。C++ 的诀窍是理解所有这些,所以你知道什么时候使用哪个。这就是 C++ 的优势,能够在所有这些范式之间切换和混合。将 C++ 称为 OOP 语言的人与将其称为改进的 C 语言的人一样,都忽略了这一点。它允许您以这两种风格中的任何一种编写代码,但它们本身都不值得。C 是一种更好的类 C 语言,并且有很多更好的 OOP 语言。如果您想坚持一种范式,请使用专为此设计的语言。
有趣的是,这里有多少人声称 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++(和面向对象)的步骤更容易。
还有更多,但我并没有声称要在一篇 SO 帖子中回答所有问题。:-)
如果你能掌握它,我推荐C++ Bjarne Stroustrup 的创建者 The C++ Programming Language的前 3 章。
特别是“读者须知”和“C++ 之旅”将使您更好地了解 C++ 与 C 的不同之处/方式,并专注于您的进一步学习。当然,在使用 C++ 时,将整本书放在身边很有用。
有趣的是,对于您的情况,在第 1 章中,Bjarne 实际上说
“在关于是否需要在 C++ 之前学习 C 的持续争论中,我坚信最好直接进入 C++”。
他当然会,不是吗,但如果你接受他的推理,你最好尽快直接跳入 C++。
保持语言分开。
C 和 C++ 可能看起来很相似,但它们是不同的语言,具有不同的相似结构规则。如果你能将一个与另一个隔离,那就更好了。
切换到 C++ 时,请准备好忘却(学习不同的、不兼容的方法)以下内容:
C++ 程序完全不同。你最好把时间花在学习 C++ 上,而不是花时间研究 C 元素,试图为 C++ 改进它们。
例如,即使是简单的“Hello World”程序,也有很大不同:
C:
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
return 0;
}
C++:
#include <iostream>
int main()
{
std::cout << "Hello, world!\n";
}
(来自此处的示例)。
因为 'printf' 是一个函数,而 'cout' 不是一个函数,而是一个 ostream 类的实例。
进一步阅读:iostream。
您正在转向 C++ 意味着您觉得您需要类或更好的库。这就是我的感觉。我也在学习更好的 C++ 特性,我的 C 背景。到目前为止,我主要研究了向量[除了类和模板]。
我觉得语言太相似了
完全分开考虑它们。
我的猜测是,你将要学习的 C++ 可能不会过于面向对象,至少它不是在我的大学里。我们基本上将 C++ 程序作为 C 程序运行。
一定要阅读如何实现类,以及了解指针的基础知识。
您的文件 I/O 处理也将有所不同......而不是 fstream 阅读实现 iostream 函数的语法。
在网上搜索有关简单 C++ 程序的教程... CodeProject始终是一个很好的资源。
尽可能使用结构和函数指针来模仿类的方法和抽象方法。
例如,如果你想定义一辆车,以及使用 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;
}
这里有几点:
1)确保你精通指针。关注数组和指针是如何工作的,它们之间有什么相同点和不同点。
2)完善c的最好方法是编写程序。尽可能多地写。对于初学者,您可以为一些库函数编写自定义函数。您可以尝试使用Strcpy、strcmp、strncpy、memcpy、memmove。
3) 学习如何调试。(Gdb 真的很酷)。
4)开始遵循特定的编码风格并尝试坚持下去。
5) 始终为您的代码提供有意义的注释。
C++是面向对象的,C不是。如此常见的事情,例如保持指针代码的清洁和对函数/方法的注释,并了解如何使用#IFDEFs 不获得无限的预处理器循环。
然而,面向对象的方法通常可以更好地实际编写考虑对象的代码。因此,您需要考虑新功能的差异。
C 和 C++ 的编程风格完全不同。C ++是面向对象的编程,而C是面向过程的编程。C++ 编程是使用类/对象模拟现实世界问题的最佳选择。但是,指针、结构、运算符、强制转换运算符、数据处理等基本概念在两者中是相同的。结构和类是相似的概念,但并不完全相同。所以您可以专注于使用结构、指针、运算符和内存管理进行编程,同时你正在学习'C'
函数指针。谷歌首创。