自定义博客皮肤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语言中typedef关键字

与define定义宏不同,typedef这个关键字的本质是做类型重命名,由使用者自己定义一个新的类型。所以我们可以自己定义新的类型:#include<stdio.h>typedef unsigned int u_int;typedef int* int_p;typedef int a[10];//a是一种数组类型typedef struct stu { char name[20]; int age;}stu_t;int main(){ u_int x = 0; int_

2021-08-31 10:06:15 3341 8

原创 C语言中的注释和注意事项

注释在预编译阶段就会被删除掉,但是这里的删除并不是字面意义的删除,而是被替换,注释被替换,本质是替换成空格。以下面的代码为例:#include <stdio.h> int main() { int /* */ i; //正确 char *s = "abcdefgh //hijklmn"; //正确 //Is it a\ valid comment? //正确 in/* */t j; //报错 return 0; }由于被替换成了空格,所以in t j这句话是无法

2021-08-31 08:36:09 1269 1

原创 C语言中volatile关键字

volatile关键字是C语言中非常冷门的关键字,因为用到这个关键字的场景并不多。当不用这个关键字的时候,CPU可能会对我们的代码做一定的优化:内存中的数据要放入CPU中进行运算或控制,而这个数据的值是被放入寄存器中,然后再将寄存器中的数据进行运算或控制的,对于一个死循环int flag=1;while(flag);来说;如果进行优化,则下次循环则不需要再次将flag内存中的值放入寄存器中,而是直接使用寄存器中已有的值进行循环;如果不进行优化,则下次还需要将flag内存中的值放入寄存器中,然后使用寄存器

2021-08-29 21:26:15 1283 13

原创 C语言中return返回函数局部变量的问题

在计算机中,释放空间并不需要将空间中的内容全部置成0或者1,而是只要设置这一块空间的数据无效即可。比如在下载文件时需要花很长时间,但是删除文件却只要几秒钟,这是因为操作系统只是把文件标识(文件头链接)删掉了,文件原文还保留着,我们没了文件标识就找不到这个文件了。所以删除后的文件,还可以用特殊的办法被找回来。这也就意味着,当函数结束调用的时候,函数中的局部变量实际上还是在的,只是函数原来的空间还给编译器(释放)了,也就是说函数中的局部变量是可以被编译器修改的。虽然函数结束后空间还给了编译器,但是我们依然可

2021-08-29 16:05:43 2319 18

原创 C语言中的0 ‘\0‘ ‘0‘ NULL以及类型转化

文章目录0 '\0' '0' NULL真实的类型转化和强制类型0 ‘\0’ ‘0’ NULL0 '\0' NULL都是三种0值,它们在数字上是完全一样的,而且在内存中存的都是二进制0。所以,它们的值是一样的,只不过表现的形式不一样,也就是它们的类型是不同的:0在整形中表示数字0,在字符中’0’表示一个字符它的ASCII码值为48,'\0’是一个字符,表示字符串结束,在ASCII中的值为0NULL 即空指针,它表示一个指针指向地址为0的空间,可以看到这里的0被强制转化为void*指针,这也就意

2021-08-28 14:58:49 1526 8

原创 C语言中的bool变量

在一些高级语言当中,为了能够完成更好的逻辑判断,因此就有了bool类型,bool类型的变量值只有true和false两种。而在C语言中,一般认为0为假,非0为真。这是因为c99之前,c90是没有bool类型的的。但是c99引入了_Bool类型(_Bool就是一个类型,不过在新增头文件stdbool.h中,被重新用宏写成了 bool,为了保证C/C++兼容性)。目前为止大部分C语言书籍采用的标准还是c90标准,因此我们很少用bool类型。bool类型变量的大小可以看到,这里的bool类型的大小和我

2021-08-25 21:24:55 6410 5

原创 C语言中数据的存储

signed为有符号类型,unsigned为无符号类型,一般signed默认省略。文章目录一、整形在内存的存储1.1.原反补码1.2.将负数赋值给无符号数1.3.char类型截断问题和整形提升问题二、大小端的问题一、整形在内存的存储1.1.原反补码原反补码的概念在博客数据在内存中的存储中提到过,这里再回顾一下:有符号数对于有符号数,一定要能表示该数据是正数还是负数。所以我们一般用最高比特位来进行充当符号位。计算机中的有符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和

2021-08-23 14:17:57 328 8

原创 C语言的数据类型和sizeof关键字

文章目录基本数据类型sizeofsizeof可以求自定义类型大小基本数据类型在变量那一章已经说过,定义变量的本质是当程序加载到内存时,在内存中开辟一块空间用来保存数据。而语法决定,定义变量是需要类型的,这个类型就决定了变量开辟空间的大小。为什么要有类型呢?C语言的类型本质上是对内存进行合理划分,各个变量按需索取。而C语言中有多种类型的原因是应用场景不同,因此解决应用场景对应的计算方式也不同,需要空间的大小也是不同的。其本质是用最小的成本解决各种多样化的场景问题。比如对于一个人的年龄,由于年

2021-08-22 22:30:55 238 3

原创 C语言关键字---static

文章目录一、函数和变量的多文件问题1.1.为什么全局变量和函数需要跨文件访问二、static修饰变量和函数2.1.static修饰全局变量2.2.static修饰局部变量2.3.为什么局部变量具有临时性,全局变量具有全局性一、函数和变量的多文件问题.h: 头文件,一般包含函数声明,变量声明,宏定义,头文件等内容(header).c : 源文件,一般包含函数实现,变量定义等 (.c:c语言)如果在一个源文件定义一个函数,然后再另一个源文件调用,这样的方式可行吗?答案是可行的,但是在生

2021-08-22 17:43:32 1453 16

原创 C语言关键字---register

CPU主要是负责进行计算的硬件单元,但是为了方便运算,一般第一步需要先把数据从内存读取到CPU内,那么也就需要CPU具有一定的数据临时存储能力。注意:CPU并不是当前要计算了,才把特定数据读到CPU里面,那样太慢了。所以现代CPU内,都集成了一组叫做寄存器的硬件,用来做临时数据的保存。文章目录存储金字塔register修饰变量存储金字塔所以离CPU越近,读取速度越快。因此寄存器存在的原因:在硬件层面上,提高计算机的运算效率。因为不需要从内存里读取数据啦。register修饰变量.

2021-08-21 23:49:41 612 3

原创 C语言关键字---auto

在C语言中,使用 auto 修饰的变量,是具有自动存储器的局部变量。在一般情况下,局部变量都是被默认是autoC++中auto的使用和C语言有一些区别,这里仅讨论C语言。文章目录变量的分类变量的作用域变量的生命周期作用域和生命周期的区别auto关键字变量的分类变量的分类在此再说一下:局部变量:包含在代码块中的变量叫做局部变量。局部变量具有临时性。进入代码块,自动形成局部变量,退出代码块自动 释放。全局变量:在所有函数外定义的变量,叫做全局变量。全局变量具有全局性。代码块:用{}括起来的

2021-08-21 23:15:07 3846

原创 C语言变量的定义与声明,为什么全局变量不能赋值

文章目录一、对C语言程序的一些补充二、定义域声明2.1.什么是变量2.2.如何定义变量2.3.为什么要定义变量2.4.定义变量的本质2.5.变量声明的本质2.6.定义和生命的区别一、对C语言程序的一些补充对于一个代码:#include<stdio.h>#include <windows.h>int main(){ printf("hello world!\n"); system("pause"); return 0;}我们在编译运行的时候 会将这一段文本代码

2021-08-21 22:29:50 8145 5

原创 通过两道书上的题目来加深对指针变量和普通变量的理解

特别声明:这篇博客所涉及到的代码均在VS2019编译器下运行,在其他编译器下可能会报错。最近看了书上两道题目彻底给我整无语了,完全就是误导人,各位记得避雷。不过这两道题目确实挺有意思的,有一道题目还能在VS2019编译器下运行起来。用指针变量来实现两个数取大的数完整的代码是这样的:#include<stdio.h>int* max(int* x, int* y){ if (*x > * y) { return x; } else { return y;

2021-08-18 06:08:35 241 3

原创 13迷宫问题(回溯思想)

迷宫问题是回溯思想的一种运用,一般可以用栈来实现文章目录迷宫问题求解题目分析代码实现迷宫最短路径求解题目分析代码实现迷宫问题求解原题链接迷宫问题.题目分析题目要求我们先输入两个数代表迷宫的行和列,然后再输入具体的数组内容。这里的起点是左上角,终点是右下角,注意这里有可能让我们输入多组迷宫,所以此时需要用while循环来实现多次输入。另外这个题目中,1代表墙,不能走,0代表路,可以走。从起点开始走迷宫,我们得先告诉程序向哪走,这里按上下左右的顺序依次走,如果走不通就向另一个方向走,要实现这

2021-08-12 14:03:35 1633 6

原创 数据在内存中存储和取出的一些问题以及float和double型变量的精度损失问题

首先用一段代码来引出这篇文章的问题#include<stdio.h>int main(){ char a=128; char b = 'a'; char c = a + b; int d = 4193; printf("%d\n", a); printf("%d\n", a); printf("%d\n", b); printf("%d\n", c); printf("%c\n", d);}文章目录变量是什么,为什么需要变量为什么scanf要加&,而p

2021-08-11 13:31:36 467 1

原创 12八大排序算法的稳定性以及时间空间复杂度总结

文章目录一、排序的稳定性二、八种排序方式的复杂度和稳定性一、排序的稳定性假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。至于为什么有的排序不稳定,这和排序本身的实现算法逻辑有关,以快排的挖坑法为例:如果begin[i]和key相等,begin会跳过这个数,最终交换以后key会到这个数的右边,顺序就

2021-08-09 21:36:43 2167 1

原创 11非比较排序算法---计数排序

基数排序、计数排序都属于非比较排序。文章目录一、计数排序1.1.时间空间复杂度分析一、计数排序这种排序方法并不需要比较数组中的元素大小来排顺序,而是用一个数组直接统计每个数出现的次数,然后从小到大遍历这个数组就可以了。不过这样有很大的浪费,数组中最大的元素是max,count数组的元素个数就得是max+1,比如一个数组[200,199,201],count数组的元素个数就是202,但是199前面的空间都没有用。这个时候如果让数组中最小值充当count数组中的0下标,数组中的最大值就相对于coun

2021-08-09 21:35:02 384

原创 10归并排序算法

文章目录一、归并排序1.1.归并排序的递归实现1.2.归并排序的非递归实现1.3.时间空间复杂度分析一、归并排序归并的的思路是:将数组拆分成若干个有序的子序列(一般是只有一个数的子序列),然后将已有序的子序列合并,得到完全有序的序列。1.1.归并排序的递归实现//归并排序的子函数//这个函数将左右区间进行归并void _MergeSort(int* a, int left, int right,int*tmp){ if (left >= right) { return;

2021-08-09 21:32:00 1569 1

原创 09交换排序算法---冒泡排序和快速排序

文章目录一、冒泡排序1.1.时间空间复杂度分析二、快速排序2.1.快排的递归实现2.1.1.挖坑法2.1.2.左右指针法2.1.3.前后指针法2.2.快排的非递归实现2.2.1.挖坑法2.2.2.左右指针法2.2.3.前后指针法2.2.4.用栈实现非递归2.3.快排的优化2.3.1三数取中2.3.2.小区间优化2.4.时间空间复杂度分析一、冒泡排序冒泡排序应该是最简单也是最容易理解的一种排序算法,它的逻辑是每趟将最大的数移到数组的最右边:我之前写过冒泡排序的详细说明,链接如下:冒泡排序代码实现:

2021-08-09 21:30:15 3929 17

原创 08选择排序算法---直接选择排序和堆排序

文章目录一、直接选择排序1.2.时间和空间复杂度分析二、堆排序2.1.堆和向下调整算法2.2.使用向下调整算法建堆2.3.堆排序2.4.时间空间复杂度分析一、直接选择排序它的实现方式是遍历整个数组然后找到最小和最大的数将它们放到数组的开头和结尾,然后缩小范围重复这个过程。这个动图是只找最小的数:代码实现:void SelectSort(int* a, int n){ int begin = 0, end = n - 1;//起始位置下标,最后一个元素下标 while (begin &l.

2021-08-09 21:27:20 553

原创 07插入排序算法---直接插入排序和希尔排序

文章目录一、直接插入排序1.1.时间空间复杂度分析二、希尔排序2.1.时间和空间复杂度分析一、直接插入排序直接插入排序的思路是:假设前n-1个元素已有序,则将第n个元素插入到n-1个有序元素中,这样前n个元素都已经有序,再用这样的方法插入第n+1个元素、第n+2个元素,一直到最后一个元素,这样整个数组就都有序了。但是一开始并不能确定究竟前几个元素是有序的,所以我们只能默认第1个元素是有序的,然后依次将其后面的元素依次插入。直到最后一个元素也插入,数组有序。代码实现:void Insert.

2021-08-09 21:24:31 330 1

原创 关于scanf%d读取非数字字符的问题的解释

scanf(%d,&x)在缓冲区读取有个特点:当输入abc123按回车后:scanf开始读取,发现第一个不是数字,那么它就停止,表示一个数据都没读取,所以返回失败。当输入123abc按回车后:scanf开始读取,先是1,然后是2,然后是3,然后读取a,发现a不是数字就停止读取,这个时候scanf已经读到字符123了,并把这一串字符转化成整形数据存储到x对应的地址中,所以返回成功。所以这就会导致一些非常有意思的现象,比如三子棋游戏里面玩家下棋的一段代码:如果输入字母或者/+=等非数字的字

2021-08-08 02:56:50 2931 2

原创 06树和二叉树

之前的顺序表和链表都是一种线性的结构,树是非线性的结构。文章目录一、树的概念1.1.树用代码表示二、二叉树2.1特殊的二叉树2.2.二叉树的性质2.3.二叉树的存储形式2.3.1.顺序存储2.3.2.链式存储2.4.二叉树的遍历2.4.1.前序遍历2.4.2.中序遍历2.4.3.后序遍历2.5.二叉树的一些题目三、二叉树的代码实现3.1.测试代码一、树的概念树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成,当 n=0 时,称为空树。树的起始节点是一个特殊的结点,称为根结点,

2021-08-05 22:32:36 1261 13

原创 LeetCode数据结构题---用栈实现队列

原题链接:用栈实现队列思路栈的特性是先进后出,而队列的特性是后进先出,也就是说,如果把一串数据放进栈里面,它会倒着拿出来,但是队列是会正着拿出来。这里题目给了两个栈,如果我们将数据放到一个栈里面,再从这个栈里面拿出来放到另一个栈里面,那取出来不就是成正的了吗?为了便于区分,我们将第一个栈命名为pushs,因为入队的数据都必须先放在这个栈里面,第二个栈命名为pops,因为如果要出队或者取最先入栈的数据,必须先将第一个栈的数据全部转移到这个栈里面,如果没能全部转移,那么数据就会造成混乱,无法做到先进先出

2021-08-04 00:04:44 247 1

原创 LeetCode数据结构题---用队列实现栈

原题链接:用队列实现栈思路栈的特性是后进先出,而队列的特性是后进后出,如果使用两个队列,则可以实现后进先出的特点:代码实现首先需要用到队列的数据,因此可以直接将队列的函数赋值过来:typedef int QDataType;typedef struct QueueNode{ struct QueueNode* next;//指向下一个节点 QDataType data;}QNode;typedef struct Queue{ QNode* head;//头指针,指向第一个节点

2021-08-03 17:18:22 176 3

原创 LeetCode数据结构题---有效的括号

原题链接:有效的括号思路这个题是一个类似于栈结构的问题,它需要在栈顶放入一个左括号,然后这时候有一个右括号和这个栈顶的左括号进行匹配,匹配完成后左括号出栈,如果失败则返回false,当所有括号都匹配完成以后,栈里面没有数据,这时候返回true有几个人需要注意的点:如果一开始就是右括号比如这种")(",那肯定是不匹配的,因此我们需要在读取第一个右括号时判断栈里面是否为空,如果为空则说明没有和这个右括号想匹配的左括号,这个时候返回false。最终一定是栈里面没有数据才返回true,如果是这种情况{(

2021-08-03 13:39:49 394 2

原创 05线性表之栈和队列

栈和队列也是线性表的两种不同的形式,它们的实现方式和顺序表与链表类似,但是在逻辑结构上有一些差别。文章目录栈栈的顺序表形式实现栈的测试代码队列队列的单链表实现队列测试代码栈栈是一种特殊的线性表。栈的形式类似于弹夹,其只允许在固定的一端进行插入和删除元素操作。也就是说只允许在出口(弹夹顶部)插入元素(放入子弹)和删除元素(发射子弹)。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。压栈:栈的插入操作叫做进栈/压栈/入栈,存入的数据在栈顶。出栈:栈的删除操作叫做出栈。输出数据也在栈顶。由

2021-08-03 01:48:02 526 2

原创 04线性表之带哨兵位头结点的双向循环链表

单向链表存在一些缺陷:1.无法从后往前遍历。2.无法找到节点的前一个节点。3.插入和删除数据的时间复杂度为O(N)。这对这些缺陷,双向循环链表提供了很好的解决办法,双向循环链表的插入和删除时间复杂度为O(1)。文章目录带头双向循环链表带头双向循环链表代码实现带头双向循环链表带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。这个链表的结构如下:箭头的指向就代

2021-08-01 21:58:03 655 1

原创 EasyX实现贪吃蛇

成品展示:文章目录实现思路代码实现game.hgame.cpptest.cpp实现思路贪吃蛇的实现思路并不复杂,由于我们需要将数据展示在图形窗口上,因此就不需要之前那种用数组表示整个游戏地图的方法。贪吃蛇的蛇有X坐标和Y坐标,而且不止一节,因此需要一个坐标结构体数组来保存,蛇的移动思路是除了第一节以外,后面每一节都是前面一节的坐标,然后通过键盘的输入输出使蛇的X或Y坐标加或者减来起到上下左右移动的作用。通过判断蛇与食物的坐标是否重合绝对是否吃到食物,吃到食物以后,蛇的长度加一,分数增加,食物重

2021-08-01 01:16:19 4411 4

原创 03线性表之单向链表

顺序表存在一些问题没法解决:空间不够增容以后会有一定的性能消耗,可能存在空间浪费;头部或者中部左右的插入删除效率低,时间复杂度为O(N)。因此链表就很好的解决了这些问题。文章目录链表的定义单向链表的代码实现链表的定义链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。链表并不需要像线性表一样动态开辟连续的空间,链表每个节点的空间不一定连续,它们之间通过结构体指针相互访问。单向链表的代码实现单向链表的结构如下:定义链表type

2021-08-01 00:14:33 286

空空如也

空空如也

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

TA关注的人

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