• c++学习记录(一)


    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    结果如下:
    在这里插入图片描述
    下面改用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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    运行结果如下所示:
    在这里插入图片描述
    可以看到这就是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");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

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

    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");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    运行结果如下所示:
    在这里插入图片描述
    这里注意如果是老版本的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");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

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

    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");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

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

    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");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

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

    5、内存分区

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

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

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

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

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

    • new的基本语法

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

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

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

  • 相关阅读:
    java实现数据库自动异地备份
    什么是区块链的“智能合约”
    【C++】静态库动态库
    驱动开发5 阻塞IO实例、IO多路复用
    27、Flink 的SQL之SELECT (select、where、distinct、order by、limit、集合操作和去重)介绍及详细示例(1)
    如何确保ChatGPT的文本生成对特定行业术语的正确使用?
    Centos7卸载minio
    LeetCode·76.最小覆盖子串·滑动窗口
    GBase 8c获取结果集中的数据
    人工神经网络优化算法,人工智能神经网络模型
  • 原文地址:https://blog.csdn.net/m0_51220742/article/details/125130297