更多参考其他文档菜鸟文档W3C微软C++文档

从C到C++

C和C++的区别

/*程序文件名:test.cpp
本程序功能:输入2个整数求和
设计者: */

#include <iostream> //输入输出流对象

//using namespace std; 没有此语句就要写成下面的输出形式

int main(){
std::cout << "Enter two numbers" << std::endl; //通过输出流符 << 将字符输出到标准输出流对象cout,std是命名空间。
int v1, v2;
std::cin >> v1 >> v2;
std::cout << "the sum of" << v1 << "and" << v2 << "is" << v1 + v2 << std::endl; //可以输出不同类型的数据
return 0;
}

c++输入输出时不需要制定格式字符

通过标准输出流对象输出输入

std是命名空间,如果定义的实例名相同也不影响,因为是在命名空间中的实例

/*程序文件名:test.cpp
本程序功能:输入2个整数求和
设计者: */

#include <iostream> //输入输出流对象

using namespace std; //有此语句就可以std::,但是不能变量名不能相同,相同则函数内变量名将命名空间内示例覆盖

int main(){
cout << "Enter two numbers" << endl;
int v1, v2;
cin >> v1 >> v2;
cout << "the sum of" << v1 << "and" << v2 << "is" << v1 + v2 << endl;
return 0;
}

iostream : istream,ostream

标准输入输出对象

标准库定义了4个IO对象:

cin:istream对象,标准输入

cout:ostream对象,标准输出

cerr:标准错误。用来输出警告和错误信息给程序的使用者

clog:用于产生程序执行的一般信息

“ << ” 操作符

cout << 表达式<< 表达式<< endl

“ >>” 操作符

cin >> 表达式>> 表达式<< endl

表达式只能是变量或内存区,否则就不能将读入的数据放到表达式当中了

输入数据的几种方式

image-20210317200434446

数据类型和表达式的区别

image-20210318081153281

逻辑类型、引用类型、类 类型

  • 基本类型转换

    image-20210318081330842

  • 构造书类型

    image-20210318081523918

  • 类类型

    class abc{
    privte:

    public:

    }

引用

//类型名 & 引用名 = 其变量名

int n = 4;
int & r = n; //表示使 r 引用 n,也是初始化,r和n等价,即改变r就改变了n

//r的类型就是 int &

//例子1:

int n = 7;
int & r = n; //定义引用一定要初始化为某个变量,初始化后就一直引用该变量,不会引用别的变量了
r = 4;
cout<<r;
cout<<n;
n=5;
cout<<r

//例子2:
double a = 4,b =5;
double & r1 = a;
double & r2 = r1; //相当于传递引用了a,
r2 = 10; //相当于对指针指向的那个地方赋值,不过是,有多个指针指向这个地方
cout<<a<<endl; // 输出10
r1 = b; //这里不表示r1 引用b, 而是表示 a = b;,不能对引用进行修改

//不可以引用数组!! 但可以这样 int & B = A[0];

交换函数

//C
void swap(int *a,int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}

int main()
{
int a,b;
swap(&a,&b);
}



//C++ 用引用
void swap(int &a,int &b) //这里用了引用
{
int tmp;
tmp = a;
a = b;
b = tmp;
}

int main()
{
int a,b;
swap(a,b);
}

引用可以作为函数的返回值

int n = 4;
int & SetValue(){ return n;} //此处引用的是返回值 n
int mian()
{
SetValue()=40; // 这里就达到了修改返回值的目的
cout<<n; //输出为 40
return 0;
}

常引用

常引用 不能通过引用修改值

int n = 400;
const int & r = n; //这个r是常引用, r 的类型是 const int &
//相当于这个变量的别名,另一个该变量的名字,不能再改名

r = 200; 错误
n = 300; //正确

//T == 普通数据类型 如int

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

const关键字

//定义常量
建议少用 define 因为 用const定义有数据类型的检验
const int MAX_VAL = 23
const double Pi = 3.14 ;
const char *SCHOOL_NAME = "Peking University"; //字符指针

//指向常量的指针
const int * p = & n; //不能通过指针修改 n的值,但可以指向其他变量(易错)

const int *name ="chen";
name[3] ="a"; //错误 不能修改name的值
name ="zhang"; //正确 可以改变name指向

//在函数定义时,用指向常量的指针
void MyPrintf(const char * p) // 使得指针指向的值进入函数后不会被改变
{
strcpy(p,"this");//此时会编译出错
printf("%s",p);
}

//常指针
int * const name="chen" ; //不能改变地址,即指针所指的指向

//指向常量的常指针
const char * const name="chen"; //不能改变指向,也不能改变值

动态内存分配

C 使用malloc , c++ 使用new


//分配整形空间
P = new T ;
//P是指针,T是数据类型,T是任意类型名,P是类型为T*的指针,动态分配出一片大小为sizeof(T)的空间,并且将该内存空间的起始地址赋值给P。
例:
int *pn;
pn = new int;
*pn = 5;


//分配数组
P = new T[N];
//T:任意类型名 P: 类型为T*的指针 N:要分配的数组元素的个数,可以是整型表达式
//动态分配出一片大小为N * sizeof(T)字节的内存空间,并且将该空间的其实地址赋值给P
例:
int * pn;
int i = 5;
pn = new int[i * 20];
pn[0] = 20;
pn[100] = 30; //这里数组越界了


//注意:int * p = new int; //返回类型,都为int * 即 指针


使用delet运算符进行释放

delete 指针 ; //释放的指针必须是new出来的,只能做一次
//例:
int *p = new int;
*p = 5;
delete p;
delete p; //释放两次


//释放数组
delete [] 指针; //该指针必须指向new出的数组
例:
int*p = new int[20];
p[0] = 1;
delete [] p ; //没有[] 会导致空间没有被完全释放

内联函数

//由来:调用函数时的额外开销
//调用函数过程: 把参数和返回地址放到栈里面去,函数执行完返回后,还要从栈里取回返回地址,然后跳转到返回地址去执行
//为了减少开销


//将整个函数体的代码插入到调用语句处,而不会产生调用函数的语句,不会进行参数传递

//定义

inline int Max(int a, int b)
{
if(a>b) return a;
return b;
}

//缺点
会增大空间,因为调用时相当于将函数的内部语句插入直接使用,根据程序的体积会有体良上的影响

函数重载

//一个或多个函数,名字相同,然而参数或参数类型不相同,这叫做函数的重载

int Max(double f1, double f2){}
int Max(int f1, int f2){}
int Max(int f1, int f2 , int f3){}

//编译器根据调用参数的形式来匹配函数的声明,从而找到对应的函数

Max(3,2.4); //有二义性 错误 ,编译器找不到该函数

函数缺省参数

//定义参数的时候可以给函数参数一个预先的值,如果在调用参数的时候没有写该参数,则可以使用预定义的值,但是注意只能最右边缺省,不能中间缺省

void func(int x1, int x2 = 2,,int x3 = 3){}

fun(10);//相当于func(10,2,3)
fun(108;//相当于func(10,2,8)

fun(10,,8);//函数调用错误

//提高程序的可扩充性

作用域运算符

::  变量名相同时,::可使全局变量在局部变量的作用域内使用

int a;
int main(){
int a;
::a ;//此时的a为全局变量a
}

结构化程序设计

//程序 = 数据结构 + 算法
//程序由全局变量以及众多相互调用的函数组成
//算法以函数的形式实现,用于对数据结构进行操作

//不足
数据结构和函数操作关系不清、
函数和函数的关系不清
不方便重用函数

面向对象程序设计

面向对象程序 = 类 + 类 + 类

//方法
//归纳事物共同属性、形成数据结构

//抽象
//这类函数能进行的行为也归纳出来,形成函数,这些函数也可以操作数据结构

//封装
//将数据结构和操作该数据结构的函数捆绑在一起,形成了类,通过类可以看出数据结构和函数的关系

抽象、封装、继承、多态

image-20210313200955552

类和对象基本概念

写一个程序,输入矩形的长和宽,输出面积和周长
//属性: 长 和 宽
//行为: 面积 和 周长

//从客观事物的特性出发,设计定义变量和函数,封装为类

//封装为类
矩形类
{
长 、 宽 变量 //成员变量
计算矩形周长函数; //成员函数
计算矩形面积函数; //成员函数 和 成员变量 统称为 类的成员
输出矩形长宽函数; //成员函数
}

例:

class CRectangle //类型的名字,用户自定义
{
public:
int w,h; //成员变量
int Area(){
return w * h;
}
int Perimeter(){
return 2* (w + h);
}
void Init( int w_,int h_){
w = w_; h = h_;
}
}; //必须有分号!!!!!
//必须有分号!!!!!
int main()
{
int w,h;
CRectangle r; //r 是一个对象,类型的名字可以定义变量,通过类定义的变量即为对象
cin >> w >> h;
r.Init(w,h); //调用了r的成员函数,作用到了r的成员变量中
cout<< r.Area() << endl << r.Perimeter();
return 0;
}

对象的内存分配

类似C中的结构体

和结构变量相同,对象所占用的内存空间的大小,等于所有成员变量的大小之和

对象,只包含了成员变量,不包含成员函数

//因此,sizeof(上述类CRectangle) = 8;
//每个用类定义的对象,都有自己的存储空间,不共用,因此改变相同类的对象的成员变量的值,不会影响另一个对象。对象中的函数是共用的,成员变量不共用。

对象之间的运算

//类似C语言的结构体,可以整体赋值
如果使用了“重载”,则可以进行其他类型操作、判断、算数运算等
//使用类的成员变量和成员函数

//用法1: 对象名.成员名
class CRectangle
{
public:
int w,h;
int Area(){
return w * h;
}
int Perimeter(){
return 2* (w + h);
}
void Init( int w_,int h_){
w = w_; h = h_;
}
};

int main()
{
Crectangle r1,r2;
r1.w = 5; // 将对象r1中的 w 变量 赋值为5
r2.Init(5,4); // 调用对象r2中的函数.Init传入5和4两个参数
return 0;
}

//用法2 指针->成员名
int main()
{
Crectangle r1,r2;
Crectangle * p1 = & r1;
Crectangle * p2 = & r2;
p1->w = 5; //p1 指针指向的对象的成员变量赋值
p2->Init(5,4); //Init作用在p2指针的对象上
return 0;
}
//用法3 引用名.成员名
int main()
{
Crectangle r2;
Crectangle & rr = r2; //rr 引用了 对象r2
rr.w = 5;
rr.Init(5,4); //和引用概念相同,rr引用的r2一同变
return 0;
}

//另

void PrintRectangle(CRectangle & r)
{
cout<<r.Area()<<","<<r.perimeter();
}
int main()
{
Crectangle r3;
r3.Init(5,4); //和引用概念相同,rr引用的r2一同变
PrintRectangle(r3);
return 0;
}

实例

//1  输出一个水平中轴为n的菱形
#include <iostream>

using namespace std;

void PrintStar(int n)
{
int i, j;
for ( i = 1; i <= n;++i)
{
for ( j = 0; j < n - i;++j)
{
cout << " ";
}
for ( j = 0; j < i;++j)
{
cout << "*"
<< " ";
}
cout << endl;
}
for ( i = 1; i <=5;++i)
{
for ( j = 0; j < i; ++j)
{
cout << " ";
}
for ( j = n-i; j > 0;--j)
{
cout << "*"
<< " ";
}
cout << endl;
}
}

int main()
{
PrintStar(5);
return 0;
}


//2