c++学习记录(一)

本文通过对比C语言和C++的编程方式,展示了从过程化编程到面向对象编程的转变,强调了C++中类的应用。同时,详细探讨了C++中的指针概念,包括指针的基本操作、指针与数组、函数以及结构体的结合使用,并提及了内存分区和对象初始化的重要性。此外,还介绍了结构体在数组和函数中的应用以及内存管理的相关知识,如new和delete操作符。
摘要由CSDN通过智能技术生成

1、从c到c++

采用c语言的方式来写一个求周长面积的工程,如下所示:

#include<iostream>
using namespace std;

void main(void)
{
	double r, girth, area;
	const double Pi = 3.1415926;

	cout << "input number\n"<< endl;
	cin >> r;  //输入
	girth = 2 * Pi * r;
	area = Pi * r * r;
	cout << "radius = " << r << endl;
	cout << "girth = " << girth << endl;
	cout << "area = " << area << endl;
}

结果如下:
在这里插入图片描述
下面改用c++的写法,代码如下:

#include<iostream>
using namespace std;

class Circle
{
	double radius;
	public:
		void Set_Radius(double r)
		{
			radius = r;
		}
		double Get_Radius()
		{
			return radius;
		}
		double Get_Girth()
		{
			return 2*3.14f*radius;
		}
		double Get_Area()
		{
			return 3.14f*radius*radius;
		}
};

void main()
{
	Circle A,B;
	A.Set_Radius(6.23);
	cout << "半径=" << A.Get_Radius() << endl;
	cout << "周长=" << A.Get_Girth() << endl;
	cout << "面积=" << A.Get_Area() << endl;
	B.Set_Radius(5.26);
	cout << "半径=" << B.Get_Radius() << endl;
	cout << "周长=" << B.Get_Girth() << endl;
	cout << "面积=" << B.Get_Area() << endl;
}

运行结果如下所示:
在这里插入图片描述
可以看到这就是c和c++的区别所在了,c的话还是比较结构化的编程方式,但是c++已经开始跟python有点像了,已经是对一个个对象进行操作了,新建对象,对对象进行赋值,调用对象里面的函数也就是方法来进行运算。

下面是我从菜鸟教程里面截取的c++的类的说明:

在这里插入图片描述

2、一些需要注意的地方

但是要注意的一点就是c++的对象里面最好要写一下方法,不然会出问题,下面的例子很好的说明了这个情况,代码如下:
在这里插入图片描述
运行结果如下所示,可以看到结果是一个乱码的情况,这当然不是我们希望看到的
在这里插入图片描述
那么到底是什么原因造成了这种情况呢,因为我们的对象里面其实只有定义,包括最后那个计算面积的其实也是定义,所以他其实就只是一个初始值的运算,就是在对象初始化之后这个结果就出来了,我们后面的输入对于结果没有影响,如下所示:
在这里插入图片描述
这里我们可以给相关变量赋一个初值看看是啥情况
在这里插入图片描述

3、c++中的指针

1、指针的基本了解

这里首先要明确一点就是c++是完全兼容c的,也就是说,c的语法c++全部适用,但是反过来不行,所以这里c++的指针和c的基本上是一样的,在c语言中,指针就是指向变量的地址,c++中也是一样的,下面是指针指向地址的描述:(指针记录的就是地址
在这里插入图片描述
下面来使用指针:(解引用
在这里插入图片描述

2、指针的一些小知识

  • 指针占用的内存空间

在32位系统下,一般都是占用4个字节的空间(64位下就是8个字节
在这里插入图片描述
编写函数进行输出,可以看到是四个字节
在这里插入图片描述
同时无论是整数还是浮点数都是四个字节,因为这里只是存一个变量地址,所以就不像变量那个大小会改变的。
在这里插入图片描述

  • 空指针和野指针

首先看一下概念:
空指针:指针变量指向内存中编号为0的空间,一般用于初始化指针变量,不可以被访问,如果访问空指针就会报错(空指针是系统占用的,一般用于这个变量前期不用,后面需要修改的时候使用
在这里插入图片描述
野指针:指针指向非法的内存空间,程序中要避免野指针,野指针也会引发程序报错等异常现象
在这里插入图片描述

  • const修饰指针,指针常量和常量指针

主要用常量指针和指针常量,下面是常量指针,常量指针指针指向的值不可以改,但是指针指向可以修改
在这里插入图片描述
下面是指针常量
在这里插入图片描述
下面是同时进行修饰的情况,简单总结下就是const修饰谁,谁就不可以被修改,所以真实情况下就看const离谁更近一点了
在这里插入图片描述

3、指针和数组结合

这里需要注意的就是数组是一串地址,并且数组名是这一串地址的开头,如下所示
在这里插入图片描述
如果要看看其他元素的话,这里注意指针变量+1其实就是偏移4个字节。
在这里插入图片描述
下面来分别使用数组的基本方法和指针来进行遍历查看效果,如下所示:
在这里插入图片描述

4、指针和函数

这里主要就是值传递和址传递相关的知识,值传递不会改变值,址传递才会改变,在一些交换的函数中比较常见
在这里插入图片描述
但是地址传递可以改变,如下所示:
在这里插入图片描述

5、指针数组函数进行联合

这里实现了一个冒泡排序,代码如下:

int arr[10] = { 4,5,8,6,7,4,88,5,5,4 };

void maopao(int *arr,int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
int main()
{
	int len = sizeof(arr) / sizeof(arr[0]);//获取数组的长度
	maopao(arr, len);
	for (int i = 0; i < len; i++)
	{
		cout << *(arr + i) << endl;
	}
	system("pause");
}

运行结果如下:
在这里插入图片描述
冒泡排序是很经典的排序方式了,很多人认为是最简单的排序方式,其基本原理为,先第一个数逐个和后面的数进行比较,如果大于后面的就进行置换,反正就不变,这样第一轮选出最大的一个数,然后第二轮一样的,只是不和最后的一个数进行比较,因为已经知道了最后的一个数是最大的数字了,这样一直下去就可以了,如果要进行逆序排列,还是根据这个思路对代码进行简单修改,只要修改判断条件为小于一个数就行了,最终代码如下所示:
在这里插入图片描述

4、结构体

c++的结构体和c的结构体基本是一样的,这里就不机械记录了,直接写结构体数组函数相关的一些内容,首先是结构体数组,代码如下:

struct MyStruct//定义一个学生结构体
{
	string name;
	int age;
	int score;
};


int main()
{
	struct MyStruct stuarr[4] = 
	{
		{"11",15,85},
		{"12",25,75},
		{"13",63,96},
		{"13",63,96}
	};

	stuarr[3].name = "dfsd";
	stuarr[3].age = 56;
	stuarr[3].score = 74;

	for (int i = 0; i < 4; i++)
	{
		cout << "姓名" << stuarr[i].name 
			<< "年龄" << stuarr[i].age 
			<< "分数" << stuarr[i].score << endl;
	}

	system("pause");
}

运行结果如下所示:
在这里插入图片描述
这里注意如果是老版本的vs的话要加上引用,因为用到了字符型变量(新版的忽略,没有这个问题,我这里是vs2017是需要加上的
在这里插入图片描述
下面是结构体指针,利用指针访问地址来访问结构体的成员:

struct MyStruct//定义一个学生结构体
{
	string name;
	int age;
	int score;
};


int main()
{
	MyStruct stu = { "dsfsd",18,45 };

	MyStruct *p = &stu; //定义一个结构体指针指向我们准备好的结构体

	cout << "姓名" << p->name << "年龄" << p->score << "分数" << p->age << endl;

	system("pause");
}

运行结果如下:
在这里插入图片描述
下面是结构体之间进行嵌套,代码如下所示:

struct student//定义一个学生结构体
{
	string name;
	int age;
	int score;
};
struct MyStruct//定义一个学生结构体
{
	int id;
	string name;
	int age;
	struct student stu; //嵌套的学生结构体
};


int main()
{
	MyStruct teacher;
	teacher.age = 45;
	teacher.id = 85;
	teacher.name = "fsfds";
	teacher.stu.age = 52;
	teacher.stu.name = 48;
	teacher.stu.score = 85;

	cout << "学生的考试分数" << teacher.stu.score << endl;

	system("pause");
}

运行结果如下:
在这里插入图片描述
下面是结构体作为函数参数,代码如下所示:

struct student//定义一个学生结构体
{
	string name;
	int age;
	int score;
};
void printf_stu(struct student s) //结构体值传递
{
	cout << "考试分数" << s.score << endl;
}
void printf_stu01(struct student *s) //结构体址传递
{
	cout << "考试分数" << s->score << endl;
}
int main()
{
	struct student s;
	s.name = "fsfdfs";
	s.age = 20;
	s.score = 45;

	printf_stu(s);
	printf_stu01(&s);

	system("pause");
}

下面是是值传递的修改状况
在这里插入图片描述
下面是址传递带来的修改
在这里插入图片描述
这里要注意就是址传递和值函数的改变的变化仍然存在!
在这里插入图片描述

5、内存分区

之前在单片机部分也提到过,没想到学c++的时候又看到了:堆栈记录(stm32为例)
c++在程序执行时,会将内存大方向划分为四个区域:(其中代码区和全局区是在代码执行前就有,堆栈是在代码执行之后才会产生的。)

  • 代码区:存放函数代码
    这里的代码是二进制代码,就是cpu的机器指令,是经过编译器编译出来的,代码区是共享的,也是只读的,是不可以被修改的。
  • 全局区:全局变量,静态变量还有常量
    存放了上面说的一些变量,这块区域的数据在程序结束之后会由操作系统进行释放。
  • 栈区:编译器自动分配释放,存放函数的参数值和局部变量
  • 堆区:程序员分配和释放,程序员如果没有分配和释放会在程序结束之后操作系统进行回收

使用栈来操作,要注意用了一次之后会被释放掉,这里编译器帮保存了一下,但是也只会保存一下:
在这里插入图片描述

使用堆来进行操作,利用new关键字,可以将数据开辟到堆区
在这里插入图片描述
这里指针本质上也是局部变量,因此函数中我们定义的指针放在栈上面,指针保存的数据放在了堆区。

上面提到了new关键字,这里new是我们向系统申请内存,这路继续介绍下一下相关的操作符,主要是new和delete操作符

  • new的基本语法

这里我们使用new重复下上面的测试,可以看到他可以一直都在
在这里插入图片描述
使用delete可以删除掉它,这样就不会再出现了,再次输出会显示异常
在这里插入图片描述

  • 下面我们尝试在堆区来开辟数组

测试代码如下:
在这里插入图片描述
同时,这里释放数组这样写
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桃成蹊2.0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值