- 博客(37)
- 收藏
- 关注
原创 【落羽的落羽 C++】内存区域、C++的内存管理
实际上,new的使用是调用了一个全局函数operator new,这个函数的内部其实还是用malloc实现申请空间的,但当malloc申请失败为NULL时,函数不会报错,而是抛异常。new T[n]的原理是,调用operator new[]函数,在这个函数中调用operator new函数完成对n个对象空间的申请,并在申请的空间上执行n次构造函数。new自定义类型的原理是,调用operator new函数申请空间,并在申请的空间上执行构造函数,完成对象的初始化。一言以蔽之,内置类型的申请很好理解。
2025-03-29 15:41:00
812
原创 【落羽的落羽 C++】C++入门基础:引用,内联,nullptr
用inline修饰的函数叫做内联函数,编译时C++编译器会在调用函数的地方展开内联函数,这样调用函数时就需要建立栈帧了,可以提高效率。当然,C语言中的宏函数也会在预处理时替换展开,但是宏函数在实现中很复杂容易出错,且不容易调试。,我们本想调用参数是int*的Fun函数,但由于NULL被定义成0,会调用成参数是int的Fun函数;比如,“萨姆”是流萤的别名,“萨姆”就是对流萤的引用,当我们称呼萨姆时,指的仍然是流萤这个人。它继承了宏函数的优点,但没有宏函数的缺点。这两个函数构成了函数重载,编译时没有问题。
2025-03-06 16:54:48
787
1
原创 【落羽的落羽 C++】C++入门基础:输入与输出,缺省参数,函数重载
这一部分知识涉及到后面C++的类和对象的概念,这里我们只能简单理解:直接来看一般使用实例:现在能看懂理解就好,之后我们会深入学习C++的类和对象。缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果我们没有给函数传实参,则函数的形参直接采用这个缺省值,有实参则优先采用实参值。缺省参数分为全缺省和半缺省(有些地方也把缺省参数叫做默认参数)。但是,当函数的声明和定义不再一个文件中时,缺省参数值就不能在声明和定义中同时出现了,规定必须在函数声明中给定缺省值。比如:缺省参数分为全缺省和半
2025-03-04 23:22:51
635
原创 【落羽的落羽 C++】C++入门基础:C++简介,命名空间
C++起源于1979年的贝尔实验室,Bjarne Stroustrup(本贾尼博士)在那里从事计算机科学和软件工程的研究工作。面对项目中复杂的软件开发任务,他感受到了现有编程语言(如C语言)在表达能力、可维护性、可扩展性方面的不足。他在1983年在C语言的基础上添加了面对对象编程的特性。设计出了C++的雏形,此时的C++已经有了类、封装、继承等核心概念。随后的几年中,C++在学术界和工业界的应用逐渐增多,一些大学和研究所开始将C++作为教学和科研的首选语言,一些公司开始在产品开发中尝试使用C++。
2025-02-28 23:39:47
989
原创 【落羽的落羽 数据结构篇】顺序结构的二叉树——堆
相比刚才所有结点位置大乱套,这样只要调整一个结点的位置就好了。向下调整算法和向上调整类似:它是比较结点和其较大或较小孩子的值,不断往下交换调整位置直至满足大堆或小堆:向下调整算法有三个参数:要被调整的堆数组、要调整的结点的下标、堆的数据个数。
2025-02-23 21:20:13
813
原创 【落羽的落羽 数据结构篇】树、二叉树
从一个结点到另一个结点的结序列,结点之间只能通过父子关系连接、如上图,A到L的路径为A-C-H-L,G到O的路径为G-C-A-E-J-O。:以一个结点为根结点的子树中的所有结点都称为该结点的子孙。如上图,除A外所有结点都是A的子孙,I、J、O都是E的子孙。:若一个结点含有子树,则子树的根结点称为该结点的子结点。如上图,B、C、D、E是A的子结点,K是F的子结点。如上图,A是B、C、D、E的父结点,C是H的父结点。:从根结点开始定义,根结点在第1层,根结点的子结点在第2层,以此类推。:树中结点的最大层次。
2025-02-22 00:26:16
841
1
原创 【落羽的落羽 数据结构篇】栈和队列
int top;//指向栈顶的位置//栈容量}ST;typedef struct QueueNode //队列节点结构}QueueNode;typedef struct Queue //队列结构//队头//队尾//有时也需要来一个int size;记录有效元素个数}Queue;
2025-02-19 22:21:06
910
6
原创 【落羽的落羽 数据结构篇】双向链表
所以,理论上我们能把链表分为2×2×2=8种:带头单向不循环链表、不带头双向不循环链表、带头双向循环链表……上次我们学习的“单链表”,全称应该就是“不带头单向不循环链表”而我们这次要学习的“双向链表”,全称是“。链表的分类实际上要从这三个方向分析:是否带头、单向还是双向、是否循环。值得注意的是,单链表为空时,链表一个节点都没有。这里的“尾部”,是头结点的prev指针指向的位置。循环就很好理解了,节点的指针成员循环指向。“头部”是头结点的next指向的位置。这是双向链表的每一个节点的结构。
2025-02-13 16:18:25
643
原创 【落羽的落羽 数据结构篇】单链表
链表是一种物理存储结构上非连续、非顺序的存储结构,链表由一个个节点(node)组成,数据结构的逻辑顺序是通过链表中的指针链接次序实现的。链表的节点通常是一个结构体变量,每一个节点都是独立的空间,它们在内存中的地址不一定是连续的。而把他们串联在一起的便是结构体中的指针。第一个节点的指针成员指向第二个节点,第二个节点的指针成员指向第三个节点……最后一个节点的指针成员是空指针:也就是说,链表是一种逻辑上线性,物理(地址)上非线性的数据结构。链表也包括很多种,如单链表、双向链表等等,今天我们学习单链表。顾名思义
2025-02-06 10:38:49
734
原创 【落羽的落羽 数据结构篇】算法复杂度
数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。没有一种单一的数据结构对所有用途都有用,所以我们要学习各种各样的数据结构,比如线性表、树、图、哈希等等。算法,是定义良好的计算过程。简单来说,算法就是一系列的计算步骤,用来将输入数据转换成输出结果。衡量一个算法的好坏,需要从算法的复杂度来分析。
2025-01-24 22:26:55
965
原创 【落羽的落羽 C语言篇】项目的编译和链接、预处理
宏常常被应用于执行简单的运算,不用函数的原因是宏的运算速度和程序规模更胜一筹,而且宏的参数可以不考虑类型,但函数必须指明参数类型。链接是一个复杂的过程,它要把一堆文件链接在一起生成可执行程序,这个过程主要包括地址和空间分配、符号决议、重定义等。不过用” "包含库函数头文件,查找的效率就低一点,而且也不好区分库文件和本地文件了。C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的,,利用这一点,它能做到函数做不到的事情,比如。,后面的使用中我们需要重新定义MAX,就要先。
2025-01-22 16:34:10
803
原创 【落羽的落羽 C语言篇】文件操作
简单来说,程序需要跟各种外部设备交互,外部设备包括键盘、显示器、磁盘、U盘、网络等等,程序的数据需要输出到各种外部设备上,也需要从各种外部设备获取数据,不同的外部设备的输入输出操作各不相同。每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息,比如文件的名字、状态、位置等等。可以使pf指向某个文件的文件信息区,通过该文件信息区的信息来操作该文件,换句话说,通过文还指针能够间接找到与它相关联的文件。一般情况下,我们想要往流里写数据,或者从流里读取数据,都是先打开流,然后再操作。
2025-01-16 00:02:47
852
原创 【落羽的落羽 C语言篇】动态内存管理·下
但str的值没有被改变,它还是指向着那一块空间,但那块空间已经不属于它了,str已经是一个野指针了。传参str时,p是形式参数,是str的一份拷贝,在这个函数里面对p的申请空间不会影响str的空间。虽然返回指针p,但p指向的空间会在退出函数的时候就被释放,返回的p变成了野指针,str也变成了野指针。唯一的问题是:使用malloc后没有free掉开辟的空间,会造成内存泄漏,在test函数的最后加一句。上期讲过,free释放不是动态开辟的内存,结果是未知的,换句话说,是错误的。重复free,无意义。
2024-12-26 17:54:52
1087
原创 【落羽的落羽 C语言篇】自定义类型——联合体、枚举
联合体像结构体一样,也是由一个或多个成员构成,这些成员可以是不同的类型。它和结构体的区别在于:编译器只为联合体的最大的成员分配足够的内存空间,所有成员共用这一块内存空间。所以,联合体有时也叫共用体。它的声明形式是:道理和结构体极为相似,union是C语言中的一个关键字,name自起,member是成员。使用方法也和结构体很相似。因为联合体的成员是共用一块内存空间的,所以给其中一个成员赋值,其他成员的值也会跟着变化。一个联合体变量的地址和其中任意一个成员的地址都是相同的。结构体成员同一时间只能使用一个。
2024-12-24 17:25:04
883
原创 【落羽的落羽 C语言篇】自定义类型——结构体
结构是一些值的集合,这些值被称为成员变量。结构的每个成员可以是不同类型的变量,如指针、字符、数组,甚至是又一个结构体。结构体的声明为:其中,struct是C语言中的一个关键字,name是结构体变量的名字,里面的member是成员。举个栗子,我想从名字、年龄、身高描述一个人,写成结构体类型就是:除此之外,还有一种结构体的匿名声明,在声明结构体类型时不写出名字,这个类型的变量只能在声明后紧接着创建,结构体变量创建好后它的声明直接销毁,也就是只能用一次。在实际应用中,这种特殊的声明方式其实完全没必要使用,大家
2024-12-23 23:21:07
1271
2
原创 【落羽的落羽 C语言篇】数据存储简介
但%u说明这是一个无符号整数,最高位的1也要计算,最后这个32个二进制位换算成十进制就是42亿多的一个数。如果之后的整数运算用到了变量a,就要先对a进行整型提升,11111111的符号位是1,高位补充1,结果是11111111 11111111 11111111 11111111(补码),即十进制数-1。如果之后的整数运算用到了变量b,就要先对b进行整型提升,00000001的符号位是0,高位补充0,结果是00000000 00000000 00000000 00000001(补码),即十进制数1。
2024-12-22 16:57:34
1066
原创 【落羽的落羽 C语言篇】一些常见的字符函数、字符串函数、内存函数
出现的位置,如果找不到就返回空指针NULL。值得注意的是,指定字符的参数是int类型。
2024-12-16 19:32:22
510
原创 【落羽的落羽 C语言篇】指针·其之六(完结练习篇)
++cpp是该元素,即c+1。这么一看,在内存中&p[4][2]处于低地址处,&a[4][2]处于高地址处,&p[4][2]-&a[4][2]的结果是负数,结果的绝对值是这两个地址中间的元素个数—— 4个。就是c+3指向的内容,是数组c的第四个字符指针元素,它存放的是字符串“FIRST\0”的首字符“F”的地址,+3使这个指针指向字符“S”,%s打印出来结果是ST。,是数组c的第二个字符指针元素,这个指针存放的是字符串“NEW\0”的首字符“N”的地址,+1使其指向了字符“E”,%s打印出来结果是EW。
2024-12-07 14:42:11
996
2
原创 【落羽的落羽 C语言篇】指针·其之四
我们知道,数组也有各种各样的类型,比如int arr1[10],char arr[8]等等,它们在元素类型和数组大小上都是不同的,所以数组指针变量也有不同的具体类型,怎么得到这些类型呢?我们已经学了指针数组、函数指针,那么试试把它们组合起来吧——将函数的地址存放到数组中,这就是函数指针数组,它该如何定义呢?比如,创建一个数组parr,能存放3个元素,元素类型是“有一个整型参数,无返回类型”的函数指针类型。但实际上,地址0是无法使用的,这其实是一个非法操作,仅仅是用来展示函数指针概念的。
2024-11-27 00:53:04
1218
1
原创 【落羽的落羽 C语言篇】指针·其之三
arr是int*的指针类型,占8个字节(64位环境下),arr[0]是int类型的数据,占4个字节,sz就算成了2。parr[i]是访问parr的元素,parr[]找到的元素指向了一个一维数组,parr[i][j]就是一维数组的元素。除此之外,二级指针的地址存放在三级指针里,三级指针的地址存放在四级指针里,等等。不过二级以上这些指针,不常用就是了。实际上,编译器处理数组元素的访问时,都是转换成首元素的地址+偏移量求出元素的地址,然后解引用来实现的。正如整型数组是存放整型的数组,字符数组是存放字符的数组,
2024-11-20 22:04:24
1262
2
原创 【落羽的落羽 C语言篇】指针·其之二
众所周知,变量是可以修改的。但有时候,我们希望一个变量不能被修改,这就需要使用关键字const 了如上,如果执意修改这个n,那么程序运行后,就会报错:但是我们绕过n,而利用n的地址去修改n,也能做到:但是这一通操作下来,我不禁思考,const的目的本来就是防止变量被修改,但使用地址还是能修改它。const单纯修饰变量并不完善,应该让p拿到n的地址也不能修改n,那么该怎么做呢?我们可以让const修饰存有地址的指针变量,一般来讲,const可以写在*的左边,也可以写在它的右边,意义是不一样的。con
2024-11-15 22:32:44
816
原创 【落羽的落羽 C语言篇】指针·其之一
它并不是计算机把每个字节记录下来,而是在硬件层面上实现的:计算机内有许多的硬件单元,它们需要相互协同工作传递数据,这一过程是靠硬件与硬件间的“线”实现的,而与地址有关的就是地址总线。其实很好理解,上面也提到了数组中元素内存是连续的,p1是arr[0]的地址,那么p1+9就是arr[9]的地址,也就是p2,即 p1 + 9 = p2,那么p1 - p2 = -9。而在计算机中,数据是存储在内存中的,处理后的数据也存储在内存里,内存就像“一栋楼”一样,分为一块块内存单元,每个内存单元的大小是。
2024-11-12 18:30:26
925
1
原创 【落羽的落羽 C语言篇】操作符、二进制·其之一
就是n的补码每一位向右移动2位,右边2位丢弃,左边2位用1填充,即11111111 11111111 11111111 11111101,转换为原码是10000000 00000000 00000000 00000011,即m= -3,n不变。此外,补码和原码相互转换,其运算过程是相同的,不需要额外的硬件电路。,就是n的补码的每一位向左移动2位,左边2位抛弃,右边2位补0,即00000000 00000000 00000000 00101000,转换为原码还是这个,即 m=40,n不变。
2024-11-05 21:32:36
1279
1
原创 【落羽的落羽 C语言篇】函数递归
知道了这些,我们就可以构造一个函数PRINT来实现了,PRINT(n)用来实现得到n的最后一位数,PRINT(n/10)就能得到n/10的最后一位数。
2024-11-03 22:20:24
1049
原创 【落羽的落羽 C语言篇】数组
又因为数组中所有元素类型都是相同的,所以我们只要算出数组所占的总内存,除以该类型的数据应占的内存,不正是这个数组里的元素个数了吗?,arr 就是一个变长数组,编译器没办法事先知道 n 的值,只有开始运行后通过上面的某些代码确定 n 是多少。而数组的类型,就是指它的元素类型和大小,比如上面的数组 arr ,它的类型就是 int [5]它的好处是我们不必在一开始就估计数组的大小,而是在程序运行时为数组分配好精确的大小。明白了数组的下标和访问,我们也可以根据具体需求,给数组输入想要的数据。
2024-10-24 21:46:38
1084
原创 【落羽的落羽 C语言篇】分支和循环语句的应用举例——猜数字小游戏
这里的void menu意思是我们设置了一个叫menu的函数,在后面的代码中我们就可以直接引用menu来打印菜单,最后我们也会将游戏运行的本体封装到一个game的函数里。具体思路就是:定义一个变量(我下面就用a)作为每次玩家输入的数字的储存地址,根据a和答案的大小情况输出“猜到了”或“猜大了”或“猜小了”,循环五次(当然猜对的话就停止)总之,今天的任务就算圆满完成了,但我的代码也不算简洁,大家学习后一定也可以写出更漂亮的!也就是说,如果srand的seed是随机的,rand就能生成随机数。
2024-10-22 02:37:38
803
原创 【落羽的落羽 C语言篇】C语言的结构——分支和循环
C语言是一种结构化的程序设计语言,包括三种结构:顺序结构、分支结构、循环结构。其中,顺序结构是最简单的一种,即按照代码语句的上下顺序依次执行。今天着重介绍另外两种。
2024-10-19 18:30:13
948
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人