知识梳理:从C到C++

C++简介

C++是一种静态类型(在编译时执行类型检查,而不是在运行时执行)、通用的、支持过程化编程和面对对象编程的语言。综合了高级语言和低级语言的特点。由Bjarne Stroustrup在1979年在贝尔实验室开始设计开发。它进一步扩充和完善了C语言,1983年被命名为C++。完全支持面向对象的程序设计,包含面向对象开发的四大特性:封装 抽象 继承 多态

基本概念
C++程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。

  • 对象:具有状态和行为
  • 类:描述对象行为/状态的模板/蓝图
  • 方法:一共方法表示一种行为,一个类可以包含多个方法,可以在方法中写入逻辑、操作数据以及执行所有的动作
  • 即时变量:每个对象都有其独特的即时变量,对象的状态是由这些即时变量的值创建的。

第一个C++程序

#include <iostream>
using namespace std;//告诉编译器使用std命名空间
int main()
{
	cout<<"Hello world! I am"<<18<<" today!"<<endl;
	return 0;
}

注释的规范

C++支持单行注释和多行注释,注释中的所有字符会被编译器忽略。C++注释可以以 /* 开始,以 */ 终止,如

/*这是注释*/

/*跨行注释
 *也可以这样表示
 */

和C一样,注释也可以 // 开始,到该行行末为止。在 /* 和 /注释内部,//字符没有特殊含义,可以在一种注释内部嵌套另外一种注释。但是块注释符(//)是不可以嵌套使用的。
可以使用
**#if 0… #endif***来实现注释,且可以嵌套使用,格式为:

#if 0
	code...
#endif

code部分即被注释掉,将***#if 0***改成***#if 1*** 即可执行code部分。或者如下,condition条件为true执行code1,否则执行code2。

#if condition
	code1
#else
	code2
#endif

面向对象程序设计

程序=类+类+…类
设计的过程就是设计类的过程

  • 将某个客观事物共同特点(属性)归纳出来,形成一个数据结构,可以用多个变量描述事物的属性
  • 可以将这类事物所能进行的行为也归纳出来,形成一个个函数,用来操作数据结构,即抽象
  • 通过某种语法形式,将数据结构和操作该数据结构的函数捆绑到一起,形成一个类,从而使得数据结构和操作该数据结构的算法呈现出显而易见的联系,即封装
  • 抽象、封装、继承、多态是其四个基本结构

优点

  • 更快更正确更经济地建立软件
  • 更高效的实现函数的复用
  • 更清晰的实现变量和函数的关系使得程序更易于维护和修改

引用

基本概念
某个变量的引用等价于这个变量,相当于这个变量的别名。定义引用时,一定要将其初始化成引用某个变量;初始化后它就一直引用该变量,不会再引用别的变量了;引用只能引用变量,不能引用常量和表达式,可以引用变量的引用。
定义引用并将其初始化为某个变量:类型名 & 引用名=被引用的变量名,如

int n=4;
int &r=n;//r引用了n,r的类型是int &

简单应用

  • 引用可以作为函数的参数
void Swap(int &a,int &b)
{//用引用来作为参数 交换两个数的值
	int temp;
	temp=a;a=b;b=temp;
}
Swap(n1,n2);//即可将n1和n2的值交换
  • 引用可以作为函数的返回值
int n=3;
int &SetValue(){return n;}//引用作为函数的返回值,类型为int &
int main()
{
	SetValue()=40;//对函数调用返回的结果进行调用,等价于对n进行赋值
	cout<<n;	//此时n值为40
	return 0;
}
  • 常引用:定义引用时,前面加上const关键字,即为常引用,如
int n=100;
const int &r=n;//r的类型为const int &
r=200;//error,不可以通过常引用修改其引用的变量的值
n=300;//ok,被引用的内容可以通过其他方式修改

const T&和T &是不同的类型。T&类型的引用或T类型的变量可以用来初始化const T&类型的引用。const T类型的常变量和const T&类型的引用不能用来初始化T&类型的引用,除非进行强制类型转换。

C++常量

常量是固定值,是特殊的变量,值在定义后不能进行修改。常量类型有:整型数字、浮点数字、字符、字符串、布尔值等。

整型常量
可以是十进制、十六进制、八进制的常量,可以根据前缀判断:0x或OX表示十六进制,0表示八进制,不带前缀表示十进制。整型常量可以带一个后缀,U(unsigned)表示无符号整数,L(long)表示长整型,大小写均可。如

> 88		//十进制
>0123		//八进制
>0x5b		//十六进制
>30			//整数
>30l		//长整数
>30u		//无符号整数
>30ul		//无符号长整数

浮点常量
浮点常量由整数部分、小数点、小数和指数部分组成。可以表示成小数形式和指数形式。用小数形式来表示时,必须包含整数部分和小数部分或同时包含两者。指数形式必须包含小数点、指数或同时包含两者。

3.14		//合法
3.14E-5L	//合法
123E		//非法,指数部分不完整
210f		//非法:没有小数部分或指数部分
.e123		//非法:没有整数或分数

布尔常量
共有两个,true值为真值,false值为假,不能把true看成1,把false堪称0.

字符常量
被括在单引号中。若以大写L开头,则其为一个宽字符常量,如L‘M’,必须存储在wchar_t类型的变量中,反之为窄字符常量,可以存储在char类型的变量中。字符常量包括普通的字符、转义字符或通用的字符,如‘\u02C0’.

字符串常量
被括在双引号中。一个字符串包括普通的字符、转移序列和通用的字符。

定义常量

在编程实践中,习惯性的把常量定义为大写字母形式。两种定义方式:

使用 #define 预处理器
宏定义是可以取消的,是直接替换,不会分配内存,不能作为参数传递给函数。

#define A 10
#define B 20
#undef A	//取消A之前的常量定义
#define A	//重新进行定义

使用const关键字
可以使用const前缀声明指定类型的常量,定义成const后的常量,程序对其只能读不能修改。

  1. 定义常量
const int A=10;
const char B='\n';
  1. 定义常量指针

不可以通过常量指针修改其指向的内容,但是常量指针指向的内容是可以被修改的。

int n,m;
const int *p=&n;
*p=5;	//编译出错
n=4;	//√
p=&m;	//√,常量指针的指向可以变化

不能把常量指针赋值给非常量指针,反过来可以。

const int *p1; int *p2;
p1=p2;	//√
p2=p1;	//×,常量指针被赋值给了非常量指针,可以通过p2来改变p1,本质上错误
p2=(int *)p1; //√,强制类型转换

函数参数为常量指针时,可以避免函数内部不小心改变参数指针所指地方的内容

void MyPrint(const char *p)
{//p为常量指针,指向的内容不应该被修改
	strcpy(p,"this");	//编译出错
	//strcpy第一个参数为char型,不能用const char类型给char型赋值,所以报错
	printf("%s",p);		//ok
}
  1. 定义常引用

不能通过常引用修改其引用的变量,但可直接修改被引用的变量的值

int n;
const int &r=n; //定义常引用r,引用n
r=5;	//error,不能通过常引用修改被引用的变量值
n=4;	//ok,可以直接修改被引用的变量值

动态内存分配

用new运算符实现动态内存分配

  • 分配一个变量:P=new T 分配一个变量,T是任意类型名,P是类型为T*的指针,动态分配出一片大小为sizeof(T)字节的内存空间并将该内存空间的起始地址赋给P
int *pn;
pn=new int;//分配内存空间
*pn=5;	//往空间里写入5
  • 分配一个数组:P=new T[N] 动态分配一片大小为sizeof(T)*N字节的空间,并且将该内存空间的起始地址赋值给P
int *pn;
int i=5;
pn=new int[i*5];//动态分配内存
pn[0]=20;//ok,在第一个空间里写入数值
pn[100]=30;//error,编译时没有问题,运行时导致数组越界
  • new运算符的返回值类型
new T;//返回类型为 T*
new T[n];//返回值类型为T *
int *p=new int;//两边类型匹配

delete
用new动态分配出的内存空间,一定要用delete运算符释放动态分配的内存,否则就会一直被程序调用,占用的空间越来越多,导致系统崩溃。
用delete释放动态分配的数组,要加 [ ],不加中括号不会报错,但是会导致申请出的空间不能被完全释放产生浪费。

int *p=new int;//分配内存
*p=5;//向申请来的空间里存放数值
delete p;//delete指针,该指针必须指向new出来的空间
delete p;//error,不可以重复delete

int *p=new int[20];//动态申请数组空间内存
p[0]=1;
delete []p;//delete指针:该指针必须指向new出来数组

内联函数/重载函数/参数缺省

内联函数
函数调用是有时间开销的,如果函数本身只有几条语句,执行很快,且函数被反复执行很多次,相比之下调用函数产生的开销比较大,为了减少函数调用的开销,引入内联函数机制,编译器处理对内联函数的调用语句时,是将整个函数的代码插到调用语句处,而不会产生调用函数的语句。但同时也带来函数体积增大等坏处。
在函数定义前加上inline关键字,即可定义内联函数。

inline int Max(int a,int b)
{//inline定义内联函数,返回两数之间的较大者
	if(a>b)return a;
	else return b;	
}

函数重载
一个或多个函数,名字相同,参数个数或参数类型不同,即为函数重载。函数重载使得函数命名简单化。编译器根据调用语句中的实参个数和类型判断应该调用哪个函数。若两函数名字相同,参数表也相同,但返回值的类型不同,那不是重载,是重复定义,要区分清楚❌

int Max(double f1,double f2){}
int Max(int i1,int i2){}
int Max(int i1,int i2,int i3){}
Max(1,2);//调用第二个函数
Max(1.1,2.2);//调用第一个函数
Max(3,2.4);//error,二义性

参数缺省
定义函数时可以让最右边连续若干个参数有缺省值,则调用函数时若相应文职不写参数,参数就是缺省值。
缺省参数可以提高程序的可扩充性,若某个写好的函数要加新的参数,而原先的那些调用该函数的语句未必需要使用新增的参数,则为了避免对原先函数调用语句的修改,可以使用缺省参数。

void func(int x1,int x2=2,int x3=3){};//定义缺省函数
func(10);//ok,等效于func(10,2,3);
func(10,8);//ok,等效于func(10,8,3);
func(10,,8);//error,只能最右边连续有若干个参数缺省
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值