windows环境上可以直接安装visualstudio,visualstudio会自带MicrosoftVisualC++
G++也可以直接安装GCC
Mac对于Mac来说基于Linux,所以会自带GCC
C++编译器gcc/g++,GNU组织开发的开源免费的编译器
MinGW,Windows操作系统下的gcc/g++
Clang++,开源的BSD协议的基于LLVM的编译器
VisualC++::cl.exe,MicrosoftVC++自带的编译器
C++的集成开发环境Code::Blocks,开源免费的C/C++IDE
CodeLite,开源、跨平台的C/C++集成开发环境
Dev-C++,可移植的C/C++IDE
C++Builder
VisualStudio系列
概论C++的生命周期编码(Coding)-预处理(Pre-processing)-编译(Compiling)-运行(Running)
image.png在编译之前会经过预编译期(Pre-processor),预处理的目的是文字替换(有点像webpack中的loader的作用)常见的预处理命令:#include/#defined/#if
C++的编程范式面向过程
面向对象
泛型编程(在学这个课程之前都没听过这个编程范式)
模板元编程(在学这个课程之前都没听过这个编程范式)
函数式编程
面向过程:是C++里最基本的一种编程范式。它的核心思想是“命令”,通常就是顺序执行的语句、子程序(函数),把任务分解成若干个步骤去执行,最终达成目标。
面向对象:它的核心思想是“抽象”和“封装”,倡导的是把任务分解成一些高内聚低耦合的对象,这些对象互相通信协作来完成任务。它强调对象之间的关系和接口,而不是完成任务的具体步骤。在C++里,面向对象范式包括class、public、private、virtual、this等类相关的关键字,还有构造函数、析构函数、友元函数等概念。
泛型编程:泛型编程是自STL(标准模板库)纳入到C++标准以后才逐渐流行起来的新范式,核心思想是“一切皆为类型”,或者说是“参数化类型”“类型擦除”,使用模板而不是继承的方式来复用代码,所以运行效率更高,代码也更简洁。在C++里,泛型的基础就是template关键字,然后是庞大而复杂的标准库,里面有各种泛型容器和算法,比如vector、map、sort,等等。泛型编程是使用模板template,而不是继承,运行效率更高,代码更简洁。
模板元编程:这个词听起来好像很新,其实也有十多年的历史了,不过相对于前三个范式来说,确实“资历浅”。它的核心思想是“类型运算”,操作的数据是编译时可见的“类型”,所以也比较特殊,代码只能由编译器执行,而不能被运行时的CPU执行。在讲编译阶段的时候我也说了,模板元编程是一种高级、复杂的技术,C++语言对它的支持也比较少,更多的是以库的方式来使用,比如type_traits、enable_if等。
函数式编程:核心思想是“一切皆可调用”,通过一系列连续或者嵌套的函数调用实现对数据的处理。
一个简单的C++程序基本要素预处理指令
using命名空间
函数
变量
语句表达式
注释
#includeiostream//预处理语句usingnamespacestd;//using命令空间,stdintmain(){//主函数cout"HelloWorld!";//std::count是一个与插入操作符()一起使用的对象return0;}变量类型类型描述bool存储值true或false。char通常是一个字符(八位)。这是一个整数类型。int对机器而言,整数的最自然的大小。float单精度浮点值。单精度是这样的格式,1位符号,8位指数,23位小数。double双精度浮点值。双精度是1位符号,11位指数,52位小数。void表示类型的缺失。wchar_t宽字符类型。常量
C++中定义常量的方式有两种,通过预处理命令#defined(宏定义)和const关键字定义
#define宏名/标识符字符串constintvalue=1;//consttypevariable=value;#defined与const定义的区别
const定义的常量不可以直接修改,但是可以通过内存或者指针进行修改。严格意义上来讲const定义的常量属于只读变量。(后续再细说const的使用情况)
//需要加上volatile修饰,运行时才能看到效果constvolatileintMAX_LEN=;autoptr=(int*)(MAX_LEN);*ptr=;coutMAX_LENendl;//输出const常量虽然不是“真正的常数”,但在大多数情况下,它都可以被认为是常数,在运行期间不会改变。编译器看到const定义,就会采取一些优化手段,比如把所有const常量出现的地方都替换成原始值。所以,对于没有volatile修饰的const常量来说,虽然你用指针改了常量的值,但这个值在运行阶段根本没有用到,因为它在编译阶段就被优化掉了PS:volatile会禁止编译器做优化,所以除非必要,最好不要使用volatile,(除非你真的知道变量会如何被“悄悄地”改变)defined定义的常量通过内存和指针均不能修改,是真正意义上的常量#defined
一个标识符被宏定义后,该标识符便是一个宏名。这时,在程序中出现的是宏名,在该程序被编译前,先将宏名用被定义的字符串替换,这称为宏替换,替换后才进行编译,宏替换是简单的替换。
#includeiostreamusingnamespacestd;#defineVARintmain(){constintvar=;coutvar;*(int*)(var)=;//转换常量指针为非常量指针,说明constant不算真正的常量coutendlvar;coutVAR;//不能取地址进行修改return0;}
通过GCC命令仅进行预处理g++pre-