自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(30)
  • 收藏
  • 关注

原创 c语言编译和链接

当可执行程序被操作系统加载到内存中时,由于所有的符号已经在链接过程中被重定位,因此程序可以直接使用这些符号,而不需要再进行地址绑定。在静态链接过程中,链接器会在编译后的目标文件中将所有的符号(函数名、变量名等)和它们的地址进行绑定,并将这些地址填写到可执行文件中。在C语言程序链接过程中,重定位是一种重要的步骤,它涉及将不同的目标文件中的符号(函数或变量)的地址合并到一个单独的可执行文件中。C语言的链接过程中,地址和空间分配是一个重要的环节,它涉及到程序的内存布局,即程序在内存中如何分布及其各自的地址范围。

2024-02-01 21:30:57 1714 31

原创 字符串相关函数【超详细】(strcpy,strstr等string.h中的函数)

size_tstrlen返回值【size_t】:无符号整型函数参数【str】:要计算长度的字符串的首地址char*strcpy返回值:目标字符串(destinatuon)的首地址第一个参数(destinatuon):目标字符串的首地址第二个参数(source):源字符串的首地址char *strcat返回值【char*】:目标字符串的首地址参数1【destination】:目标字符串的首地址参数2【 source】:源字符串的首地址intstrcmp。

2024-01-25 11:02:49 1608 6

原创 排序算法进阶——归并排序【详细图解,递归和非递归】

再比较两个序列的第一个元素的大小,将小的那一个元素放在申请的空间的第一个【假设排升序】,再让放入的那个元素之后的一个元素与那个第一次比较时没放入的元素比较,再把小的那一个放入申请空间的第二个位置上…归并算法一般应用于合并两个已经有序的序列,使合并后的序列也有序,是一个时间复杂度为O(N)的算法,不过一般要借助两个要排序的序列的元素个数个额外的空间。归并排序采用分治策略,将序列递归地分成短序列,然后将各个有序的短序列合并成一个有序的长序列,不断合并直到原序列全部排好序。

2024-01-23 17:28:58 1818 6

原创 详解C语言单链表接口函数

创建一个头文件(SList.h),两个源文件(SList.c和test.c)上图包含了以下3个操作1.库函数的头文件的包含:2.给链表节点的数据域的数据类型重命名为什么要重命名呢?这是为了以后如果改变了SL结构体中数据存储的类型时,不用到处改函数参数等地方的数据类型,只要改typedef后的int 为对应要改成的数据类型就可以。3.链表节点结构体定义因为打印链表不会改变头指针,所以传输一级头指针【方框的上方框为数据域,下方框为指针域】先动态内存申请一个节点的空间如果链表为空,就让新的节点成为第一个

2023-12-29 22:12:54 1541 3

原创 详解结构体(包含结构体内存对齐,柔性数组,位段)【尊嘟很详细】

(struct+结构名+{})int a;char b;//分号不能少//结构体成员不能在结构体内赋初值关键字struct与结构名一起构成结构类型名例struct books是一个结构类型名结构体可以嵌套定义但结构体定义时不允许将成员的数据类型定义成自身的结构类型,这是因为结构类型的声明是构造阶段,系统还不知道需要分配多少内存空间。但是结构类型中可以含有指向自身类型的指针变量。①在结构体定义时定义,此时变量位于结构体{}之后的;之前②在结构体定义完后定义③在匿名结构体定义时定义。

2023-12-25 13:28:42 1627

原创 手把手教你用C语言写扫雷(包含递归,数组,随机数等知识点)

①定义两个二维数组,一个mine,一个show(为什么定义两个数组?因为扫雷的时候,总得给别人看一个要扫雷的区域吧,只有一个数组+printf会很麻烦)mine用来存放雷,show用来存储标记和一个坐标周围雷的个数。②数组的行列,扫雷的时候,扫一个位置,该位置就会显示它周围一圏雷的个数,既然是周围的一圏,那么处理角/边缘上的位置扫的时候就要分类讨论,这样太麻烦,不如。

2023-12-18 10:59:47 995 2

原创 类和对象【三】析构函数和拷贝构造函数

析构函数(destructor) 与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如:在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。来自百度百科拷贝构造函数是C++中一种构造函数的重载用已有对象创建一个新对象,并将已存在的同类对象的数据成员拷贝到新对象中。拷贝构造函数的形参是一个对该已有对象的引用,并且通常会被声明为const,以防止通过引用修改原对象。

2024-04-27 16:10:34 1134 65

原创 字符型(char)数据在内存中的存储

最高位(最左端的那一位)为符号位,符号位只表示正负(0为正,1为负)不存储数据。所以有符号char的在内存中取值范围为10000000~01111111。char,int,short int类型的值的加减其实是一个循环。那么怎么判断自己的电脑用的编译器char是有符号还是无符号的呢?所以我的电脑的编译器中只写char时char是有符号的。虽然数据在内存中都是以二进制的方式进行存储的,但是。在内存中存储的11111111其实存储的是-1。所以有符号char(signed char)

2024-04-27 09:43:02 435 9

原创 浮点数在内存中的存储

比如,2^10的E是10, 所以保存成32位浮点数时,E必须保存成10+127=137 即二进制的。即 浮点数的小数的二进制表示是1(或0)*2的-k + 1(或0)2的-(k+1)以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。,因为凑不出二的几次方加二的几次方,正好等于小数点后的那几个数。有效数字M不再加上第一位的1, 而是还原为0.*xxxx的小数。浮点数的小数点后数的二进制表示是以2的-k加出来的。,double的E也是无符号数,所以E的范围为。

2024-04-27 09:34:43 466 3

原创 类和对象【二】this指针,构造函数和成员初始化列表【超详细】

C++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),这个指针就是this指针在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成在创建对象时调用的特殊方法。其主要作用是给对象的成员赋值。在C++中,构造函数通常没有返回类型,并且不能被声明为const。在创建类的对象时,构造函数自动被调用此外,构造函数可以重载,即可以有多个名字相同的构造函数,但参数列表必须不同。

2024-04-20 17:30:30 1059 60

原创 类和对象【一】类和对象简介

类体 };记得加分号class是类的关键字ClassName是自定义的类名类体所处的作用域是一个新的作用域,即类域每一个类都有自己的类域例。

2024-04-12 20:18:05 1231 51

原创 函数重载和引用【C++】

函数重载:重载函数是函数的一种特殊情况。为方便使用,C++允许在同一作用域中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指1.参数的个数 2.类型 3.顺序)必须至少有一个不同根据这些同名函数的参数表的不同,达成传入参数类型不同,调用的函数不同的效果引用是给已存在变量取一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。即使用一个变量的引用就是使用该变量,修改它的引用也是修改变量自己例。

2024-04-05 17:00:39 1575 49

原创 函数参数缺省和内联函数【C++】

直接在函数定义//声明的返回值前+一个关键字inline即可例内联函数的调用方法和普通函数一样因为被包含的头文件会在预处理时展开,所以包含了头文件的文件就内使用该头文件中定义的东西c语言编译和链接例。

2024-04-03 12:24:09 984 43

原创 链表的极致——带头双向循环链表

双向带头循环链表是链表结构最复杂,但使用最方便的链表。[图中phead表示链表的头节点(哨兵);d1,d2等表示链表存储的数据;d1,d2等左侧的方框存储是指向该节点的上一个节点的指针(prev),右侧方框存储指向该节点的下一个的指针(next)]

2024-03-30 19:44:42 1626 23

原创 命名空间【C++】(超详细)

命名空间关键字(namespace)+命名空间的名字+{ 定义的东西 }int b = 0;void dfs();命名空间中可以定义很多类型的东西如 变量,函数,结构体,类,其他的命名空间等等只要可以定义的东西都可以放到命名空间中定义命名空间只能在全局或者另一个命名空间中定义再没有用作用域指定该变量是哪一个作用域时先在局部域中寻找是否有变量/函数的定义在局部域中找不到定义,再去全局域和展开 的命名空间中寻找【不分相后再使用作用域指定该变量是哪一个作用域时直接去该作用域去寻找该变量的定义。

2024-03-30 19:34:04 1376 31

原创 用堆解决Top k问题

例:世界500强企业,即是世界上综合实力最强的前500个企业这就是一个Top K问题,此时K=500;

2024-03-27 19:05:19 563 16

原创 堆排序详解

虽然交换之后的顺序表不是堆了,但是只需要将交换到堆顶的数据,进行一次向下调整算法,得到的就又是一个大(小)堆,而且。

2024-03-23 09:59:19 1360 21

原创 详解(实现)堆的接口函数

为什么要将队列里的数据的数据类型重命名?这是为了以后如果改变了SL结构体中数据存储的类型时,不用到处改函数参数等地方的数据类型,只要改typedef后的int 为对应要改成的数据类型就可以。至于给结构体重命名则仅是为了方便使用。

2024-03-16 17:30:56 1358 23

原创 树和二叉树的介绍

树是一种数据结构,它是由n(n≥0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:每个节点有零个或多个子节点;没有父节点的节点称为根节点;每一个非根节点有且只有一个父节点;除了根节点外,每个子节点可以分为多个不相交的子树。

2024-03-16 14:40:31 782 5

原创 详解队列的接口函数

为什么要将队列里的数据的数据类型重命名?这是为了以后如果改变了SL结构体中数据存储的类型时,不用到处改函数参数等地方的数据类型,只要改typedef后的int 为对应要改成的数据类型就可以。至于给结构体重命名则仅是为了方便使用定义该结构体后,使用该结构体再定义一个结构变量,将其初始化后便可用其操作队列。

2024-03-02 16:31:49 710 16

原创 用C语言手把手教你写贪吃蛇

定义一个结构体Snake将贪吃蛇游戏的状态和蛇的状态放入其中,方便管理pSnake:我们使用单链表来维护蛇的身体,pSnake就指向蛇身单链表的第一个节点SnakeSpeed:因为程序执行得太快,所以需要停顿给玩家反应时间,停顿时间越长蛇的速度越慢,停顿时间越短!!

2024-02-03 16:51:37 1390 15

原创 文件指针及文件操作函数

失败返回EOF。

2024-01-21 17:57:43 897 1

原创 希尔(Shell)排序

原因是,当n值很大时数据项每一趟排序需要移动的个数很少,但数据项的距离很长。将要排序的序列按一定间隔(增量)分组,将每一组的数据按插入排序进行排序,再缩小间隔,再分组,再将每一组的数据按插入排序进行排序,希尔排序根据增量不同,分组不同,相等的元素可能会被分到不同的组,进而可能在不同的插入排序过程中相等的元素的相对位置改变。希尔排序代码实现其实很简单,就是把直接插入的代码中的增量1,全部换成变化的增量,希尔排序的时间的时间复杂度为O(N^1.5),希尔排序时间复杂度的下界是。与插入排序的代码比较。

2024-01-19 17:36:40 496 2

原创 详解栈的接口函数

栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为出栈/退栈(POP)。

2024-01-18 18:43:14 1215 1

原创 排序算法(初阶)【冒泡,插入,选择排序】

比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+…插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。比较是相邻的两个元素比较,交换也发生在这两个元素之间。

2024-01-17 22:26:55 1217

原创 #define定义宏

定义是宏名必须于它的参数括号紧挨,中间不能有任何符号,空格都不行。向宏中传参的时候是直接把传进去的参数直接替换,而不是先计算表达式再传参。所以如果你的参数只有一个,但你却传了一个表达式,他会把这个表达式直接替换进去,这个时候如果不加括号,肯定就会出现错误。例因为*的优先级大于+,所以他得到的结果不是36,而是11。此时加上括号就可以解决即 square(x) (X)*(X)其实光给X打括号还不够安全例我们想要的来是,3传进去得到6,6在与10相乘得到60。

2023-12-28 17:07:13 1082 1

原创 枚举体和共用体

enum是枚举关键字{}内的量是枚举常量,枚举常量之间用逗号分隔(最后一个枚举常量后什么符号也不放)枚举常量都有值,默认为第一个创建的枚举常量的值为0,第二个为1,以此类推(如上图)也可以改变默认枚举常量的值同一程序不能有同名的枚举类型(enum 枚举名),且不同的枚举类型中不能存在同名的枚举成员不能将一个数值直接赋值给枚举变量,如enum sb aa=3是错误的但是可以强制类型转换,将常数转换为对应枚举类型,同类型的枚举数据可以进行关系运算和算术运算。

2023-12-27 09:59:29 543

原创 详解顺序表的接口函数

新建一个头文件(SL.h)和两个源文件(SL.c和test.c)SL.h用来包含头文件,结构体的定义还有接口函数的声明SL.c用来放顺序表的接口函数的实现test.c用来测试代码将对头文件的包含和结构体的定义都放在SL.h中为什么要将int 重命名为SLDataType呢?这是为了以后如果改变了SL结构体中数据存储的类型时,不用到处改函数参数等地方的数据类型,SL结构体中的a是用来接收malloc的空间的指针,用来存放顺序表要存放的数据size用于表示当前顺序表中有多少个数据。

2023-12-24 10:38:41 1115 1

原创 C语言分支结构和循环结构

因为第一个if的()中的a==1为假,所以第二个if不会被执行,第二个if的()中的语句不会被判断真假,else也就不会执行。if,else,else if如果它没有紧随其后的{},那么它们都只能掌控一条紧跟其后语句。只有它的前一个if不执行时else if才会判断它后面的()中的语句的真假。因为else执行的条件是与它对应的if的()中的语句为假,else才执行。,并依据此判断执不执行else if的{}中的语句。2.判断部分,即while的()中的预句,if条件判断语句,判断后面的()内的。

2023-12-02 21:27:44 179 1

原创 整型提升和截断

CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。每次char,short类型计算都要用整型提升后的补码运算不会太麻烦了吗?难道每次char,short类型计算都要用整型提升后的补码运算吗?我也不是特别懂,所以我结合了我的理解和我查找到的资料总结了以下。对int类型的数值作运算时,CPU的运算速度是最快的。整型提升是直接在char的8个比特位的补码前。,要发生截断(截断也是用补码),截断时是补码。如char a=3,在内存中存储的补码是。

2023-11-20 10:02:07 182 2

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除