【自存学习笔记】Cpp自学教程(有C基础)持续更新

········自学教材:《C++ Primer Plus 中文第六版》


2.进入Cpp

2.1进入C++
Hello Wold!的C++版本

#include "iostream"
using namespace std;

int main(){
    
    cout << "hello Wold!" << endl;
    
    return 0;
}

C++的主函数

标准形式:

#include <iostream>//这里的 i 表示in ;o表示out;steam就是 流
using namespace std;

int main(int argc , char* argv[])
{


return 0;
}

C++的注释

相比较C:除了用 // 和 /……/,还可以利用if语言预处理命令进行注释:

#if 0
通常情况下0的意思就是“假”
随便写什么
多行注释
#endif

名称空间
摘录使用cout进行C++的输出
cout是一个预定义的对象。

cout << "hello wold!" << ' ' << 12
	<< ',' ; //可以连续输出 并且自动识别类型

endl 是 换行 关键字
并且 清空、刷新 缓冲区
当然,换行符 \n 也可以换行

缓冲区?:
输入的东西不会直接显示在屏幕上
内存中有缓冲区
它就是一个连续的空间

cin ,也是一个对象
输入 >> (符号前后的空格可加可不加)
输出 <<

int c;
cout << "请输入整数:" <<endl;

cin >> c;
cout << c << endl;

3.命名空间 namespace

功能:区别同名变量或者函数
(提供一种方法来区分)

创建:
(关键字 namespace)

namespace suibian
{

}//注意结尾没有分号“;”,和C里面的结构体区分开来,结构体花括号结尾有分号!

可以将同名但是功能不同的两个函数,其中一个,放进这个命名空间里面,这样就分开来。

比如上面说的 cout和cin 就都是装在
namespace std 里面的两个函数

使用方式:
方法一:
1⃣️打开命名空间:using namespace suibian
2⃣️然后紧跟着在下面调用函数名;
方法二:
调用形式:suibian+两个冒号+命名空间里面的函数成员名(记得后面的小括号要带上,有形参写参数?)
e.g.

suibian::sort();
//双冒号是 作用域运算符

所以说,如果我们在代码开头没有加上
using namespace std;
的话,后面我们使用输入输出函数的时候就需要:

std::cout<< "你学废了吗?"<< "hahaha";
  << std::endl;

方法三:(不常用)指定开放空间中某个特定成员
1⃣️ using std::cout;
2⃣️ 接下来使用cout就不需要用作用域运算符了,可以直接用名字了


数据类型
1.一些C的基本数据类型

2.构造类型:
数组
结构体
联合
枚举

其中结构体有C++的独有使用方法:
1.声明变量的时候可以不用struct关键字
2.可以放函数成员(C语言只能放函数地址)
3.是一个特殊的类

#include <iostream>
using namespace std;

struct Node
{
	int m;
	void fun()
	{
		printf("hello!");
	}
}
int main()
{
	Node a; //声明一个结构体
	a.fun();
	
	return 0;
}

3.指针
说到指针,我们就涉及到 堆区空间的申请和释放:
在C中,我们常用:malloc() 和 free()
Cpp中,我们用 : new 和 delete

区别?

使用 new 申请一块单个空间:

首先,申请一连串的连续空间的话,我们一定要有一个指针去保存它的地址:

int *p = (int*)malloc(sizeof(int));
//这里的(int*)是C中的强制类型转换

int *pp = new int;
/* new type 类型匹配非常重要!就是说,如果你申请这块空间是用来存储int类型的数据,那你就new int ; 如果你用来存储字符 ,那你就new char
*/

*pp = 12; //把12写入这块空间
cout << *pp << endl;//读取空间内容

//释放
delete pp; // delete + 指针名字

一个小tips:

int *pp = new int(10);
/*可以在申请空间的同时给这块空间初始化赋值,这里是10;注意,小括号内的类型要和前面匹配上
*/

使用new申请一个数组空间

int *pp = new int[5];
// 方括号里的 5 代表元素的个数
int *p = (int*)malloc(5*4);
//一个int 4个字节

pp[0] = 1;
pp[1] = 2;

cout << pp[0] << endl;
//最后不要忘记释放
delete[] p;
//注意数组空间需要在delete后面加上一对方括号

如何初始化申请的数组空间?
C++里面提供了一个函数:

int *p = new int[5];
memset(p,0,5*4);
//memory set :给数组里面所有的元素赋值0

cout << p[1]<<p[2]<<p[3]<<endl;
return 0;

4.C与Cpp申请空间的区别

首先,我们可以看到Cpp完全支持malloc和free函数;
对于
C与C++指针声明和空间分配方式不同,使用方式完全相同,所以,在Cpp里,除了对象空间申请之外,用malloc和free是完全可以的

malloc-free 与 new-delete 最大的区别在于:
new-delete 可以触发构造和析构;

构造和析构?
就是说,在申请对象空间的时候,需要用到new-delete

Cpp中 星号 * 的几种作用:
1⃣️用来声明指针变量

int *p = NULL;

2⃣️地址操作符(进行“读”“写”入)

int a=687;
int *p = &a;

cout << *p <<endl;

3⃣️乘法运算符

Note:
我们所写的代码,本质上都是对内存的操作:
读,写,取地址&;

4.引用变量
Cpp中特有的数据类型
(type) &+name 例如: int &c
概念:引用 是给已知变量(已定义变量)起个 别名。
(注意区分!C中的 typedef 是给 类型 起别名)

基本数据类型的引用:

//给变量起个别名
int a = 687;
int &c = a;//声明变量a的一个引用 c;
//c是变量a的一个别名,c和a用法完全一样
//&c 和 &a 的值也是完全相同的

引用变量声明的时候,必须初始化,否则报错;
所有的别名,对他们取地址,他们的地址都相同。

其他类型的引用:
-常量类型的引用

const int& a =12;

-数组的引用

int arr[12];
int (&p)[12] = arr;
//此时 p 和arr 代表的意思完全相同了
arr[0] = 687;

cout << p[0] << endl;

-指针的引用

int b = 1;
int *point = &b;
int* (&p) = point;

总结:引用变量的声明语句规则:首先这是一个引用变量(&p),其次这个是这个变量存储的数据类型type

引用和函数的关系:

引用做函数的参数

#include <iostream>
using namespace std;

void fun(int& a)
{
cout << a << endl;
}

void fun1(int a)
{
a=13;
cout << a << endl;
}

int main()
{
	int b = 6;
	fun(b);
	fun1(b);
	//两个函数运行的 本质区别是什么?
return 0;
}

区别:
fun的形参 int& a 当 调用 fun(b)的时候,是进行了一步 : int& a = b ,此时a是b的一个别名,他们的地址相同,他们均代表同一块内存空间;也就是说,我们可以在fun中,通过对a进行操作,然后更改b的值。

fun(b);
cout << b << endl;

(对比在C中是通过 地址的传递来修改值):

void fun_C(int *a)
{
*a = 13;
}
int main()
{
	int b =0;
	fun_C(&b);
	printf("%d",b);
	
return 0;
}

fun1的形参是 int a 当fun(b) 的时候,相当于,把b的值赋值给a;也就是说,a和b各自代表一块空间,只不过空间里面存储的数据将相同。不能通过a的操作改变b的值。

5.1交换两个数的值

void exchange(int& a, int& b)
{
int temp =a;
a = b;
b=temp;
}
//如果不使用 引用类型 作为形参 则无法通过函数修改函数外部的变量的值。

int main()
{
	int a;
	int b;
cin >> a >>' ' >>b;
	exchange(a,b);
	
cout << a\n <<b<<endl;

return 0;
}

5.2 引用 作为 返回值

int& fun()
{
int a = 687;
//注意 这里的a 是该函数内的 局部变量
return a;
}
int main()
{
int& b = fun();
//这里有警告,因为引用了 局部变量
cout << b <<endl;
//操作了 非法空间
return 0;
}

所以尽量不要引用局部变量

引用与指针的区别
1.声明引用变量必须要初始化,指针不是必须初始化,当然我们一般int* p = NULL
2.引用初始化之后,就不能再引用其他空间了,就定死是这个变量的别名了。而指针的指向可以后期改变
3.引用不占用存储空间,指针占空间
4.引用效率更高,指针是间接操作
5.引用更安全,指针可以偏移
6.指针更灵活,直接操作地址,指针更通用:C语言和C++都行

总结 & 的三种作用:
1⃣️声明引用变量
2⃣️取地址
3⃣️数&数 ,表示位“与”运算

运算符一览

参考网址:https://www.runoob.com/cprogramming/c-operators.html

5.3增强的for循环

C++增强的点:
变量定义的位置可以在for(……)
📒VC和VS结构内的定义循环控制变量的作用域有区别:
VS(Visual Studio)中是仅针对该循环有意义
VC(Visual C++)是对下面的全部代码有作用

5.4 函数参数缺省值

函数的类型:1)无参数+无返回值
2)有参数+有返回值
3)有参数+无/有返回值;

其中3)1⃣️传值、传址
2⃣️参数缺省值/默认值

参数如何指定默认值?
一般形式:直接在形参后面用等号赋值即可

void fun(int a = 687,char c = 'A')
{
//如果不想全部赋值指定,也可以部分指定
cout << a << ' ' << c << endl;
}

部分🈯️定必须注意⚠️的规则是:
必须按照顺序“从右向左”连续指定(保证后面调用时传参位置不会错误),
不能间隔地一会指定一会不指定!

有默认值的函数调用时,可以不用传递实参
没有指定默认值的,一定要指定实参

(如果有默认值,还强制传参,会将原来的默认值覆盖)

6.1函数重载

(Cpp新增功能)

什么叫 函数重载?
同一作用域内的,函数名字相同,但是参数列表不同的 函数,互为重载函数
(特别注意:返回值,不作为函数重载的条件!)

参数列表不同又分为 :
参数类型不同
参数个数不同

什么叫同一作用域?

#include <iostream>
using namespace std;

void fun(int a)
{
cout << '1:' << a <<endl;
}

void fun(int a , int b)
{
cout << '2:' << a <<' '<<b<<endl;
}

void fun(char c)
{
cout << '3:' <<c <<endl;
}

上面三个函数的名字都一样,这在C中是绝对不允许的,但是Cpp中引入了 函数重载的概念,就允许存在了。

重载函数的 调用:

sys会根据传入的实参 ,来进行自动匹配调用哪一个函数。比如:

int main()
{
	fun(2);
	fun('a');
	fun(5,6);
	
return 0;
}

📒!函数重载Tips:
float 类型的参数,传参的时候,小数后面必须加一个小f,不然默认是double类型的;

什么叫同一个作用域?
就是有共同的作用域的意思;
函数作用域:指该函数往下的所有代码;

返回值不作为函数重载的条件的意思是:
如果两个函数的返回值不同,但是名字和参数列表都相同的话,是不能构成 函数重载的,也就是说,会报错(重定义了)

默认参数和重载结合使用,可能会让调用不明确

6.3防止头文件重复包含

预处理:

包含头文件
防止头文件重复包含

防止头文件重复包含:
在C语言中为了防止头文件重复包含,我们用了这个结构:

#ifndef AAA
#define AAA
//在这里写头文件的代码
void fun()

#endif

Cpp里面,我们这样:

#pragma once 
//once的意思是 以下所有的代码仅编译一次
void fun()

区别?

前者都通用,后者取决于编译器,有的编译器不支持这个预处理

6.4类和对象的声明

什么叫 类 ?
类是一种语法。
定义:具有相同属性和行为的对象的集合
t.e.相同属性=数据成员、行为=函数
(例如:人类就是人这个对象的集合,小明是个人,也就是一个具体的个体,叫做“对象”; 物以类聚)

类和 面向对象 的关系:
面向对象是一种编程思想
类是一个语法
也就是,语法是实现思想的基础

class 和 struct 的区别?
在Cpp中,结构体struct 是一种特殊的类

#include <iostream>
using namespace std;

class CPeople
{
//类中可以包含两种类型的成员:数据成员和函数成员
	int a;
	void fun()
	{
	cout << "hello TZC"<<endl;
	}

};
//声明一个类,最后面有分号

int main()
{
//声明一个自定义类的对象:类名 + 对象名
	CPeople xiaoming;
//调用类中的成员,比如我们调用一下上面这个类中的hello函数:
	xiaoming.fun();
//或者我们调用里面的数据变量:
	xiaoming.a = 687;
	cout << xiaoming.a<<endl;
return 0;
}

上面这个程序会报错,因为类中没有“访问修饰符”
编译器可能会说:无法访问private成员在‘CPeople’类中的声明

创建类之后,
⚠️!声明对象有两种:
1⃣️栈区普通对象:CPeople op;
调用成员的时候 用 对象.成员 就行了。
2⃣️堆区指针对象:
CPeople* op1 = new CPeople;
(指针对象后面必须 new一块空间给它指向,new和delete是一套,不要忘记后面还要用delete释放)
调用的成员的时候,需要用 对象->成员

类中的所有成员(个别特殊static 静态成员之外),必须通过对象访问
意思就是说,比方说,我们不能直接把类中的函数的函数名拿出来,直接调用,这是无效的

什么叫 静态成员static?

7.1访问修饰符

关键字:
private
protected
public
友元

  • public : 使类里面的成员对外可见(取消私有)
    (⚠️cpp中的结构体默认是 public)
#include <iostream>
using namespace std;

class CPeople 
{
public: // 访问修饰符
	int a;
	void fun()
	{
	cout << "fun=" << a <<endl;
	
	}
};

int main()
{
	CPeople op;
	op.fun;
	


return 0;
}

private :在类中,访问修饰符默认为 private
,也就是,如果你什么关键字都不加,类里面的东西,默认私有。

作用范围:从书写关键字后面的冒号开始,一直到下一个修饰符,如果没有下一个修饰符,就到类结尾的花括号为止。

拓展功能😁:
可以作为类内成员分类的tool;
安全性

protected :受保护的;对类外不可见(主函数不可见),对子类可见;
什么叫“子类”? 有关cpp的类的继承,后面会讲。

7.3友元:

关键字:friend
针对类中的私有成员(private或者protected),如果类外函数想要使用的话,需要把想要使用的类外函数设置成 该类 的 友元函数。
方式:
友元函数:

#include <iostream>
using namespace std;

class Cstu
{
private:
	int age;
	void fun()
	{
		age = 12;
		cout << age << endl;
	}//给类中的变量初始化,尽量不要直接在变量后面用赋值符号=,而是在后面用一个赋值函数进行初始化值。
	
	friend void fun1();
	//设置fun1 为该类的 友元函数;此时,该类中的private私有成员对fun1可见。
};

void fun1()
{
	Ctu stu;
	stu.fun();//Cstu类外使用类内的私有函数,需要将fun1设置为Cstu的友元函数。
}

int main()
{
	fun1();
return 0;
}

友元类:

class Cstu
{
private:
	int age;
	void fun()
	{
		age = 12;
		cout << age << endl;
	}
	friend class CTeach;//生成友元类
};


class CTeach
{
public:
	Cstu stu2;
	void fun2()
	{
	stu2.fun();//使用Cstu中的私有fun需要 将Cteach类生成为友元类
	}
};

特点:
不受访问修饰符的限制;
破坏了类的封装性,不是迫不得已不要去使用;

不使用友元,怎么访问私有成员呢?

类中的接口函数:

class Cstu
{
private:
int age;

public:
		int Get()
		{
			return age;//实现间接调用访问
		}
		int Set()
		{
			age = 687;
		}
};

利用调用public中的 Get和Set函数,来访问private中的成员

8.1构造函数

构造函数: 方便对类内的数据成员进行初始化,在声明类后,会自动调用。

#include <iostream>
using namespace std;

class CStu
{
	int age;
	float f;
	CStu()//构造函数,函数名直接用类名,且没有返回值
	{
		age = 12;
		f = 12.12f;
	}

};

int main()
{
	CStud Lihua;//创建一个类的(栈区)对象
	//其中的 构造函数会在 对象创建的时候自动调用
	cout << Lihua.age <<endl;

	CStud *p = new CStud;// 创建一个(堆区)的对象 ;一个指针对象
	//指针变量后面一定要new一块空间;

return 0;
}

Conlusion :
1.构造函数的作用
2.构造函数执行的时间

8.2构造函数的类型

(带参数列表的构造函数)

class CStu
{
	int age;
	float f;
	CStu(int a, float b) // 带参数的构造函数,一定要记得后面创建对象的时候,要传入实际参数;当然也可以直接指定参数的默认值
	{
		age = a;
		f =b;
	}
};
int main()
{
	CStu Lihua(12,6.78f);
	cout << Lihua.age << endl;
	//普通栈区变量的声明和输出
	
	CStu *Xiaohua = new CStu(18,13.4f);
	cout << Xiaohua->age <<endl;
	//指针变量的参数传递和输出
return 0;
}

一个类里面的 构造函数 可以是多个
多个构造函数之间 是 函数重载关系

成员函数:的类外定义;
也可以在类外定义,在类内声明即可:

class CStu 
{
	int age;
	CStu(int a );
	void fun();
}
CStu::CStu(int a) //注意在前面加上类名作用域
{
	age = a;
}

void CStu::fun() // 普通的成员函数的类外声明,一样的
{
	cout << age << endl;
}

类外定义,主要是方便 多个头文件的时候

8.3初始化和赋值的区别

对于基本数据类型,初始化一个值和声明之后再赋值,作用效果完全一样:

int main()
{
	int a = 12;//初始化
	
	int b;
	b=14;//赋值
return 0;
}

对于数组 初始化:

int a[12] = {1,2,3};//初始化可以批量赋值

对于 结构体 :

struct stu
{
	int a;
	int b;
};
stu c = {12,3};//初始化

c.a =12;
c.b = 3;//赋值

以上 数组和 结构体 的初始化和赋值 仅仅是形式上的区别,初始化可以减少代码量而已,作用完全一样。

对于 引用 和 const:(⚠️!!只能初始化,不能赋值):

int a = 12;
int &b = a;

const int c = 13;

9.1初始化列表

作用:给数据成员进行初始化(构造函数是“赋值”)

注意!成员初始化的顺序只和 声明的顺序有关!

形式:构造函数 名 后面直接 :变量1(初始化值),变量2……

class CStu
{
	int a;
	float f;
	CStu () : a(18),f(60.5) //对成员a和f进行初始化
	{
		cout << a << f << endl;//由于我们写在了构造函数里面,所以下面我们在主函数中声明对象Lihua的时候,会自动调用
	}
};

int main()
{
	CStu Lihua;
return 0;
}

9.2引用和const的初始化

9.3数组和结构体使用初始化列表

class CStu
{
int a[4];
CStu(): a()
{

}

void Show()
{
for(int i =0,i<3 ,i++){
cout << a[i] << endl;
}

};

10.1析构函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值