![](https://i-blog.csdnimg.cn/direct/249f38c21453413c8ebed7a5b2edc3aa.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
C语言从入门到起飞
文章平均质量分 76
本专栏是C语言的知识学习,从基础知识到动态内存管理,文件读写
24k纯甄
本人在校大学生一枚,致力于研究学习C/C++,Linux操作系统,AI人工智能等,愿与各位大佬共同学习,还望各位多多指教。
展开
-
【C语言】:预处理详解
C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的。1.__FILE__ //进⾏编译的源⽂件2.__LINE__ //⽂件当前的⾏号3.__DATE__ //⽂件被编译的⽇期4.__TIME__ //⽂件被编译的时间5.__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义int main()return 0;;) //⽤更形象的符号来替换⼀种实现2.2 续行符的使用如果定义的 stuff过⻓,可以分成⼏⾏写,除了最后⼀⾏外,原创 2024-04-16 07:43:30 · 1622 阅读 · 138 评论 -
【C语言】:浅谈函数 fscanf/sscanf 和 fprintf/sprintf
把数据以格式化的形式写入指定的输出流上。1.2 参数:该函数的参数与 printf 函数的参数类似,只是多了一个文件流。从指定的输入流上读取格式化数据。1.2 参数:该函数的参数与 scanf 函数的参数类似,只是多了一个文件流。把格式化的数据写入到字符串中。其实就是把格式化的数据转化成字符串了。1.2 参数:该函数的参数与 printf 函数的参数类似,只是多了一个字符串指针。在字符串中读取格式化的数据。1.2 参数:该函数的参数与 scanf 函数的参数类似,只是多了一个字符串指针。原创 2024-04-15 07:37:43 · 956 阅读 · 96 评论 -
实现offsetof宏以及交换一个整数二进制奇偶位的宏
(1)功能:用来计算。原创 2024-04-01 21:12:17 · 454 阅读 · 20 评论 -
C语言实战 -- 经典贪吃蛇游戏(含完整源码)
贪吃蛇是久负盛名的游戏,它也和俄罗斯⽅块,扫雷等游戏位列经典游戏的⾏列。在编程语⾔的教学中,我们经常以贪吃蛇为例,从设计到代码实现来提升学⽣的编程能⼒和逻辑能⼒。本次实现贪吃蛇会使⽤到的⼀些Win32 API知识,接下来我进行介绍。原创 2024-05-23 21:05:18 · 1426 阅读 · 70 评论 -
【C语言】:4大内存函数
参数类型与返回值类型都是void*,这是因为这个函数不仅可以拷贝字符串,也可以拷贝整型,浮点型等,所以需要泛型指针接收。(注:若想了解void* 指针的使用,请移步我的主页浏览文章《深入理解指针变量》)。函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。这个函数在遇到 ‘\0’ 的时候并不会停下来。如果source和destination有任何的重叠,复制的结果都是未定义的。注意:这个函数只负责拷贝两块独立空间的数据。原创 2024-02-19 16:33:30 · 1084 阅读 · 6 评论 -
【C语言】:练手题
【代码】C语言之练手题。原创 2024-03-09 11:29:06 · 639 阅读 · 19 评论 -
【C语言】:atoi函数的使用及其模拟实现
1.函数功能把字符串转换为整数。2.函数介绍(2)函数参数const – 保证在函数运行的过程中,str指向的字符串不被改变,是一种保护措施。str – 指针变量,指向的是需要转换字符串的首地址。(3)返回值若转换成功,函数则返回转换后的整数;若转换失败,则返回0。3.函数的使用atoi为库函数,使用时要包含头文件//情况1 //char* str = "1234";//1234 //情况2:含前导空格 //char* str = " 1234";原创 2024-03-24 17:07:51 · 814 阅读 · 34 评论 -
【C语言】:自定义类型:结构体的使用及其内存对齐
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。注意:例如描述一个学生:注意:上述代码没有创建变量,也没有初始化,只是声明了一个结构体类型,就像int,float一样,只是一种类型。接下来我们可以用结构体类型创建变量方式1:声明类型的同时创建,这是全局变量方式2:我们也可以在函数内部创建局部变量我们再对结构体变量进行初始化:方式1:直接初始化方式2:也可以再函数内部进行初始化当然,也有结构体的嵌套:我们也可以将其打印出来:打印结果:在声明结构的时候,可以不原创 2024-02-22 17:18:11 · 1104 阅读 · 12 评论 -
C语言实战——扫雷游戏
再继续分析,我们在棋盘上布置了雷,棋盘上雷的信息(1)和非雷的信息(0),假设我们排查了某⼀个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录存储,并打印出来,作为排雷的重要参考信息的。那这个雷的个数信息存放在哪里呢?假设我们排查(8,6)这个坐标时,我们访问周围的⼀圈8个黄色位置,统计周围雷的个数时,最下面的三个坐标就会越界,为了防止越界,我们在设计的时候,给数组扩大一圈,雷还是布置在中间的9*9的坐标上,周围⼀圈不去布置雷就行,这样就解决了越界的问题。原创 2024-03-10 10:20:58 · 2655 阅读 · 25 评论 -
找出单身狗1,2
思路:通过上面的题目,我们不难想到,如果我们可以把数组中的数据分离开,再分别进行异或,就可以找出那两个数字。原创 2024-03-08 20:37:42 · 871 阅读 · 20 评论 -
【C语言】:递归题
思路:同样的,我们首先要判断递归的结束条件,当输入值n原创 2024-03-11 16:46:05 · 500 阅读 · 20 评论 -
有关【指针运算】的经典笔试题
【代码】有关【指针运算】的经典笔试题。原创 2024-03-19 09:50:17 · 700 阅读 · 20 评论 -
【C语言】: 快速排序——qsort函数的介绍
首先qsort是库函数,使用时要包含头文件。void* base:指针,指向的是待排序的数组的第一个元素size_t num:是base指向的待排序数组的元素个数size_t size:base指向的待排序数组的元素的大小int (* compar)(const void * p1 ,const void * p2):函数指针,指向的就是两个函数的比较函数(排序函数名)。待排序的数组,元素的个数,每个元素的大小都能看懂,不需要解释。那排序函数名是什么呢?排序函数。原创 2024-03-03 19:02:17 · 1136 阅读 · 22 评论 -
【C语言】:字符分类与转换函数
C语言中有⼀系列的函数是专门做字符分类的,也就是⼀个字符是属于什么类型的字符的。这些函数的使用都需要包含⼀个头文件是。上面的代码,我们将小写转大写,是-32完成的效果,有了转换函数,就可以直接使用 tolower 函数。例如:写⼀个代码,将字符串中的小写字母转大写,其他字符不变。原创 2024-03-18 15:51:10 · 506 阅读 · 19 评论 -
【C语言】:柔性数组和C/C++中程序内存区域划分
也许你从来没有听说过柔性数组这个概念,但是它确实是存在的。C99中,结构体中的最后⼀个元素允许是未知大小的数组,这就叫做柔性数组成员。int arr[];//柔性数组成员。原创 2024-03-01 21:16:15 · 674 阅读 · 13 评论 -
【C语言】:图形打印
【代码】C语言 —— 图形打印。原创 2024-03-12 20:46:12 · 784 阅读 · 14 评论 -
【C语言】:枚举和联合
enum Day //星期 {enum Sex //性别 {以上定义的enum Day,enum Sex都是枚举类型。{}大括号里的内容是枚举类型的可能取值,叫做枚举常量。这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。别漏了逗号。enum Day//星期Mon,Tues,Wed,Thur,Fri,Sta,Sunint main()return 0;输出结果:enum Sex//性别MALE=2,原创 2024-02-28 16:26:13 · 1178 阅读 · 10 评论 -
【C语言】:10大字符串函数
要引头文件字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。参数指向的字符串必须要以 ‘\0’ 结束。注意:函数的返回值为size_t,是无符号的(易错源字符串必须以 ‘\0’ 结束。会将源字符串中的 ‘\0’ 拷贝到目标空间。目标空间必须足够大,以确保能存放源字符串。目标空间必须可变。返回值是指向目标字符串的第一个字符的地址。源字符串必须以 ‘\0’ 结束。原创 2024-02-18 23:06:55 · 1151 阅读 · 6 评论 -
【C语言】:探索位段的秘密
位段的成员必须是int,unsigned int,或signed int。只要是整型家族都可以,如char)位段的成员名后面有一个冒号和一个数字。数字表示该成员所占空间的比特位的多少,并且不能超过该类型的大小。int _b : 5;A就是一个位段类型。那有人会产生疑问,int不是4个字节,32个比特位吗,怎么_a是2个比特位呢?int确实是32bit没错,但是:2的意思是_a不需要那么多的空间,只要分配2bit就可以啦。原创 2024-02-26 21:34:40 · 1179 阅读 · 8 评论 -
【C语言】:编译与链接
我们写一个程序,例如test.c或是test.h这些源文件,头文件,事实上这些代码都是文本文件,但是计算机能够看得懂,并且直接执行这些C语言代码吗?答案是不能。计算机能够执行的是二进制指令。所以文本文件需要通过编译,链接等一系列处理变成二进制文件。实际上计算机的编译和链接是一个十分复杂的过程,这篇文章只是非常简洁的讲解了一个C的程序是如何编译和链接,到最终生成可执行程序的过程,其实很多内部的细节无法展开讲解。如果你有兴趣,可以看《程序的自我修养》一书来详细了解。原创 2024-03-26 15:24:15 · 1444 阅读 · 38 评论 -
【C语言】:整型提升,算术转换与大小端的介绍
C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获取足够精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这个转换过程称为整型提升。//补码的16进制表示:0x00 00 00 14//补码的16进制表示:0xff ff ff f6return 0;我们对a和b进行内存监视:通过观察,我们可以发现,在内存中存储的a和b的补码是倒着存储的。这是为什么呢?大端【字节序】存储。原创 2024-02-27 20:59:00 · 995 阅读 · 10 评论 -
【C语言】:详解函数指针变量,函数指针数组及转移表
什么是函数指针变量呢?前面我们已经了解了整型指针与函数指针,通过类比我们可以知道:函数指针变量是用来存放函数的地址的,未来通过地址能够调用函数。那么函数是否有地址呢?并且通过类比数组,函数名与&函数名的值是否有区别呢?我们来测试一下:输出结果:我们发现两者的值是一模一样的。我们知道数组名一般表示首元素地址,&数组名表示整个数组的地址,两者的值虽然一样,但是意义是完全不同的。而函数名和&函数名表示的都是函数的地址,两者的意义完全相同,没有区别。如果我们要将函数的地址存放起来,就必须要创建函数指针变量原创 2024-02-16 16:35:55 · 885 阅读 · 13 评论 -
【C语言】:const的使用方法
就是为了不能被修改,如果p拿到n的地址就能修改n,这样就了const的限制,这是不合理的,所以应该让p拿到n的地址也不能修改n,那接下来怎么做呢?众所周知,变量是可以被修改的,但是如果我们希望给变量加上一些限制,不能被修改,怎么做呢?一般来讲const修饰指针变量,可以放在 * 左边,也可以放 * 右边,其意义是完全不同的。这是因为当a被const修饰后,在语法上加上了限制,使a具有了。但是如果我们绕过a,使用a的地址,去修改a就可以做到。,保证了指针变量的内容不能修改,但是指针指。原创 2024-02-08 18:26:28 · 376 阅读 · 2 评论 -
详解用二分法查找有序数据中的指定数字
其中要注意的地方是如何求中间元素的下标,我们通常定义两个变量left和right,left表示数组ky最左端的元素下标,right表示数组最右端的元素下标,那么中间元素的下标为mid=(left+right)/2,为了避免数据溢出,我们计算中间元素的下标时也可用mid=(right-left)/2+left。(1)二分法的核心思想是用数组中(假设是一维数组)的中间元素和要查找的数字进行比较,每次比较都可以去掉一半的数据筛选的效率非常高。二分法是C语言中一种常用的查找指定数据的算法思想,使用二分法的。原创 2024-02-01 23:42:26 · 182 阅读 · 1 评论 -
【C语言】:sizeof操作符的使用和各种常见数据类型的大小
C语言提供了一个解决方法,创造了一个类型别名size_t,用来统一表示sizeof的返回值类型,对应 系统的 sizeof的返回值类型,可能是unsigned int,也可能是unsigned long long。如图所示,虽然a是int型,5也是整型,但是s是short类型,首先在sizeof中的表达式并没有真实的运算,s的值仍是4,其次是整个表达式仍是short类型,大小为两个字节。sizeof是一个关键字,也是一个操作符,是专门用来计算类型的大小的,3.sizeof 的计算结果是。原创 2024-01-29 17:49:31 · 301 阅读 · 1 评论 -
【C语言】:中移位操作符,位操作符详运算规则详解
原码:直接将数值按照正负的形式翻译成二进制得到的就是原码。反码:原码的符号位不变,其他位依次按位取反就是反码。对于整型来说:数据存放在内存中其实存放的是补码。整数的二进制表示方法又三种:原码,反码,补码。补码得到原码也可以使用:取反,+1的操作。,而正数的三码相同,所以b=12。所以最后打印出来是b=3,a=6。但是a自己的值不变,a=6。打印结果b=-3,a=-6。最后打印出来的结果c=-8。此时b=-12,a=-6。最后打印的结果是c=-5。最后打印的结果为c=3。最后打印结果是b=-1。原创 2024-02-05 23:29:51 · 1109 阅读 · 26 评论 -
【C语言】:static和extern的详细介绍和使用
static和extern都是C语言中的关键字。static是静态的意思。原创 2024-02-02 15:31:22 · 991 阅读 · 0 评论 -
C语言初阶:如何判断是否为素数并且输出
首先第一层循环是让i产生100~200之间是数字,第二层循环是让j从2开始,每一个数字都让i试除,除到第i-1个,如果其间有数字被整除,则i肯定不是素数,直接跳出循环;如果所有数字都不能整除i,则i就是素数。上述代码中定义了一个标记变量flag,用于判断i是否为素数。题目:找出100-200之间的素数并输出。原创 2024-01-29 16:58:00 · 196 阅读 · 0 评论 -
【C语言】:巧用移位操作符,位操作符解决问题
如有不清楚者,请移步我的主页浏览文章《C语言中移位操作符,位操作符运算规则详解》,里面有非常详细的介绍。这与10进制类似,可以按照10进制里%10,/10的思想去思考。: 上述代码中,当n为负整数时是有问题的。类型,这样在我们输入负整数时,n会把它当成无符号整型处理。2的次方数(设为n)的二进制中,必定有一位是1,其余全是0。:虽然这个方法可以符合要求的交换两个整数,但是有问题的,根据这个算法,我们也可以衍生一个思考题,我们可以利用2的次方数的二进制进行判断,&(n-1)若是等于0,则是,否则不是。原创 2024-02-06 21:31:28 · 373 阅读 · 0 评论 -
【C语言】:详解指针数组,数组指针及(二维)数组传参(2)
p1首先和下标引用操作符结合,因为下标引用操作符([])的优先级比解引用操作符(*)的优先级更高。指针数组---->存放指针的数组 int* arr[5],char* arr[5];存放的是浮点型变量的地址,能够指向浮点型型数据的指针。前面我们认识了指针数组,指针数组是一组数组,数组里存放的是地址(指针)。数组指针变量是用来存放数组的地址的,那么怎样获得数组的地址呢?存放的是整型变量的地址,能够指向整型数据的指针。整型数组---->存放整型的数组 int arr[5];指针数组是指针函数数组呢?原创 2024-02-15 22:33:48 · 895 阅读 · 10 评论 -
【C语言】:深入理解指针变量
32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号0或者1,那我们把32根地址线产生的二进制序列当作一个地址,那么一个地址就是32个bit位,需要4个字节才能储存。同理64位机器,假设有64根地址线,一个地址就是64位二进制位组成的二进制序列,需要64个bit位,就是8个字节,指针变量的大小就是8个字节。我们可以看出,int* 类型的指针变量+1跳过了4个字节,char* 类型的指针变量+1跳过了1个字节。指针变量是用来存放地址的,那么指针变量的大小就得是4个字节的空间储才可以。原创 2024-02-08 17:17:20 · 498 阅读 · 3 评论 -
OJ刷题:杨氏矩阵
看见这个题目,很多人的第一反应是遍历整个数组查找数字,但是这种方法不仅效率低,而且远远不能满足题目要求。原创 2024-02-15 13:40:52 · 212 阅读 · 3 评论 -
【C语言】:总结动态内存的常见错误
原因是第一个free时p所指向的空间已经还给系统了,但是p中存的还是刚刚开辟那块空间的起始地址,p是个野指针,执行到第二个free时会有问题。这也是十分典型的错误,在for循环中p++后,p的地址已经改变了,此时p不在这块空间起始位置,一定是不能释放这块空间的!原因是,当我们调用test函数时,输入5,该函数直接结束,开辟的空间没有释放,这时会造成内存泄漏。原因是这里开辟空间后并没有对p进行检查判断,若此时p=NULL,则程序会崩溃。原因只开辟了40个字节的空间,但在使用时用了44个,形成了越界访问。原创 2024-01-27 16:43:10 · 312 阅读 · 5 评论 -
【C语言】:VS实用调试技巧和举例详解
1.什么是bugbug的本意是“昆虫”或“虫子”,现在一般是指在电脑或程序中,隐藏着的一些未被发现的缺陷或问题,简称程序漏洞。2.什么是调试当我们发现程序中存在的问题的时候,那下一步就是找出问题,并修复问题。这个找问题的过程叫做调试,英文叫debug(消灭bug)的意思。Debug和Release在VS的编译器上,我们能够看到debug和release两个选项:他们分别是什么意思呢?Debug通常称为调试版本,它包含调试信息,并且不做任何优化,便于程序员调试程序。原创 2024-02-04 22:06:22 · 1319 阅读 · 5 评论 -
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
C语言动态内存管理malloc,calloc,realoc,free函数的介绍和使用原创 2024-01-22 23:10:16 · 1107 阅读 · 33 评论 -
《剑指offer》--字符串左旋
例如当k=7时,我们要旋转7次,但是当旋转第6次时字符串变回原样了,这就相当于还需旋转一次即可,k%len=1。这里我们需要注意,我们定义的left和right是下标,在Reverse函数中我们也是对str的下标进行操作。这种方法是比较简便的,我们要了解strcpy和strncat函数的使用。这是循环执行一次的过程。上述代码中还要注意的是。原创 2024-02-15 12:04:29 · 239 阅读 · 5 评论 -
【C语言】:对(一维)数组与指针的深入理解(1)
要讨论(一维)数组传参的本质,我们可以先从一个问题开始,我们之前都是在函数外部计算数组的元素个数,那我们可以把数组传给一个函数后,在函数内部求数组的元素个数吗?我们可以发现&arr[0]和arr 加1都相差4个字节,是因为&arr[0]和arr都是首元素地址,+1就是跳过一个元素,这里的元素是整型。从输出结果我们可以知道,在函数内外计算元素个数的两个程序运行的结果不同,代码2明显与我们的预期结果不相符,这是为什么呢?三个打印出来的值都一模一样,这下我们又迷了,arr和&arr到底有啥区别呢?原创 2024-02-14 23:46:58 · 1030 阅读 · 4 评论 -
【C语言】:详解随机数的生成和猜数字游戏的实现
rand函数会返回一个伪随机数(因为它是由算法生成的,不能算做纯粹的随机),这个随机数的范围是0~RAND_MAX之间,大部分编译器上的RAND_MAX是32767。那也就是说,只要seed是随机值,那rand每次运行也将产生随机数,在生成随机数的时候又需要一个随机数,那这不是矛盾了吗,要如何解决这个问题呢?所以说,我们想要用rand函数产生随机数,就必须要让它的种子不断的发生变化,从而每次运行产生的随机数都不相同,那我们该如何做呢?由上图可知,多次运行产生的数据不同了,这就实现了随机数的生成。原创 2024-01-31 23:13:16 · 990 阅读 · 6 评论 -
OJ刷题:猜名次和找凶手
嵌套5层循环,把a,b,c,d,e五人的所有名次的可能性全部枚举出,再利用条件进行筛选。根据题目设置判断条件,筛选出相加等于3的即可。原创 2024-02-15 14:42:46 · 215 阅读 · 0 评论 -
【C语言】:野指针和assert断言
如果表达式为假(返回值为0),assert()就会报错,在stderr 中写入一条错误信息,显示没有通过的表达式,以及包含这个表达式的文件名和行号。当指针变量指向⼀块区域的时候,我们可以通过指针访问该区域,后期不再使⽤这个指针访问空间的时候,我们可以把该指针置为NULL。我们可以把野指针想象成野狗,野狗放任不管是⾮常危险的,所以我们可以找⼀棵树把野狗拴起来,就相对安全了,概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)。当p访问至下标为10的时候,越界访问,此时p就是野指针!原创 2024-02-08 22:23:21 · 593 阅读 · 2 评论