c语言笔记
文章平均质量分 57
c语言笔记
秦jh_
大二在读
展开
-
贪吃蛇小游戏
贪吃蛇小游戏原创 2023-12-16 23:59:04 · 986 阅读 · 21 评论 -
编译和链接
这些预定义符号都是语言内置的。举例:#define 是一种预处理指令#define 定义常量#define 定义宏定义常量时,只是简单的符号替换。#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏。举例:注意:用于数值表达式进行求值的宏定义应该尽可能加上括号,避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用。原创 2023-12-15 22:13:45 · 418 阅读 · 12 评论 -
文件版本的通讯录
【代码】文件版本的通讯录。原创 2023-12-14 15:30:21 · 240 阅读 · 7 评论 -
字符串和内存函数(1)
分析:为了不改变原始数据,我们创建了另外3个指针, cp指向str1的起始位置,s1用来遍历str1指向的字符串,每次循环结束(即查找失败)时,cp++使cp指向str1的下一位,再把cp赋给s1。如上图,strncpy函数比strcpy函数多了一个参数,参数3是指参数2字符串拷贝的字符个数,在拷贝时,不会将参数2字符串末尾的\0拷贝过去。如上图,strcmp函数是用来比较两个字符串相对位置的字符的ASCII的大小的,如果相对位置的大小相同,就往后一位比较,直到有大小不同的字符就停止比较。原创 2023-12-05 10:13:24 · 335 阅读 · 19 评论 -
指针(2)
如上图,当我们需要比较的数据是结构体类型时,我们只需要改变qsort函数的第四个参数指向的函数,做出略微的改动,就能进行排序了。qsort函数里的第4个参数是一个函数指针,指向的函数需要我们自己设计实现,函数的作用是比较两个元素,返回一个整形数据,通过返回的数据来判断两个元素的大小。qsort函数是一个库函数,底层使用的快速排序的方式,用来对数据进行排序,可以直接使用,可以用来排序任意类型的数据,它会将数据进行升序排序。如果返回值小于0(原创 2023-12-01 00:33:33 · 279 阅读 · 7 评论 -
动态内存管理
分析组2:组2的结构体中有柔性数组成员,先是申请一块空间,后来空间不够,就realloc进行调整,并把调整后的地址传给先前的ps,开辟的空间是连续的。如上图,我们释放时,只是释放了开辟的空间,但p还是指向那个地址,因此,我们会在free之后将该指针变为空指针,否则该指针就是野指针,野指针是危险的。分析:p的地址返回给str,但返回时,该空间已经销毁了,即没有了该空间的使用权,str指向了p所指向的地址,但此时str是野指针。malloc函数的返回值: 如果申请的空间开辟成功,则返回一个指向开辟空间的指针。原创 2023-12-10 19:26:45 · 613 阅读 · 13 评论 -
printf函数的返回值
分析:第三个printf先输出43,然后返回值 2 给第二个printf(因为成功输出了两个字符)。接着,第二个printf输出2,返回值是1, 最后,第一个printf输出1。因此,printf的返回值是输出的字符数量,包括数字,字母,标点符号,空格等。其实,printf函数的返回值是输出的字符总数。原创 2023-11-15 23:51:53 · 208 阅读 · 1 评论 -
整形提升和算数转换
如果我们想要打印出c的值,我们需要进行整形提升,然后从补码转换成原码。就需要把其中一个操作数的转换为另一个操作数的类型,对于小于普通整形的数,我们会先进行整形提升。分析:c只要参与表达式运算,就会发生整形提升,表达式+c和-c都会发生整形提升,sizeof(+c)和sizeof(-c)都是4个字节,而sizeof(c)不发生整形提升,因此为1个字节。注意:整形提升时,如果是有符号的,高位要补符号位,如果是无符号的,高位直接补0.a和b都是8位的,但他们要进行运算,因此我们需要先进行整形提升,然后才能相加。原创 2023-11-17 00:45:00 · 428 阅读 · 2 评论 -
位运算符和位操作符
这个例子中,a是-10,在计算机中,数字是以补码的形式存储的,我们先写出-10的原码然后保留原符号位不变,其余位取反,得到反码,接着加1,得到补码。这时就可以进行右移操作了,这里是算数右移,所以右移后,左边补原符号位,右边丢掉。算数右移:右边丢,左边补原符号位(这是多数情况),比如一个负数,左边第一位是1,那么它在算数右移后,左边补上1,如下图。按位或:|:如果对应数值其中一个是1,或者都是1,则变为1,其余依旧是0。按位取反:~:所有数值都取反,包括符号位,1变0,0变1.位运算符有:。原创 2023-11-16 15:41:20 · 236 阅读 · 3 评论 -
文件操作及函数
在程序设计中,文件有两种:程序文件和数据文件。原创 2023-12-12 21:54:56 · 989 阅读 · 19 评论 -
scanf与getchar连用注意事项
在用scanf输入后,用回车键换行,且下一语句为getchar时,getchar会被回车键(相当于'/n')使用,因为scanf不能读取回车键、空格键等。如果我们想正常使用getchar时,需要在二者之间再加上一个getchar,用来吸收'/n',以保证原本意图的getchar的正常使用。当我们输入密码回车后,将会直接结束程序,因为此时'/n'被getchar读取了,导致确认失败。原创 2023-11-07 23:52:52 · 329 阅读 · 2 评论 -
指针(1)
分析:str1和str2是两个独立的数组,有两个独立的空间,str1和str2分别表示他们首元素的地址,他们的起始地址也就不相同。对于str3和str4,因为存放相同的内容,且他们是常量字符串,无法进行修改,系统只会保存一个,这时str3和str4就会共同指向同一个地址。如上图,如果我们想用p指向add函数,可以先写出(*p),注意括号不能省略,接着查看add形参的类型和返回值的类型,按上图所示即可写出。如图,这是最简单的例子,我们利用指针p指向ch的地址,打印时,解引用p就能打印字符g啦。原创 2023-11-26 13:59:58 · 408 阅读 · 15 评论 -
const的简单用法
结论:const如果在*左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变,但是指针变量本身的内容可以改变。const如果在*右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。如果我们希望指针既不能修改指向的对象,也不能修改指向的内容,我们可以在*两边都加上const。当const在*左边时,我们不能对指针指向的内容进行修改,但可以修改指针指向的对象。当const在*右边时,我们不能修改指针指向的对象,但可以修改指针指向的内容。原创 2023-11-18 00:15:00 · 263 阅读 · 11 评论 -
结构体,自定义类型
如上图,在初始化时,我们用花括号括起来,在里面赋值。初始化时,如果我们也可乱序定义。先用.(成员运算符)然后加上成员名,再进行初始化即可,如下图。如下图,我们可以在结构体中嵌套结构体。位段的声明和结构体是类似的,但有两个不同:1.位段的成员必须是int,unsigned int,或signed int。2.位段的成员名后边有一个冒号和一个数字。如上图, 是位段的声明,a占用了两个bit位的空间,位段能节省空间的占用。原创 2023-12-07 21:21:28 · 678 阅读 · 13 评论 -
C语言中EOF的介绍
例如:scanf("%d%d",&a,&b),如果a,b均赋值成功,则返回值为2,如果只是a赋值成功则返回1,如果a失败,b成功,或者都失败则返回0。EOF全称是End Of File,是文件结束标志的标志符号。在标准库头文件中中定义为整形常量,通常定义为-1。当我们不确定需要输入多少组数据时,可以通过scanf的返回值和EOF配合循环语句使用。当我们不需要再输入时,我们可以连用三个Ctrl+Z,这样就可以结束这个输入循环啦。不过,当我们输入的数据错误时,如!原创 2023-11-08 14:40:16 · 244 阅读 · 4 评论 -
通讯录实现
【代码】通讯录。原创 2023-12-11 11:09:55 · 653 阅读 · 19 评论 -
指针(3)
因为char*类型可以更细致的比较,如果我们比较的是int类型的数据,与下一元素相距4个字节,而char*一次跳不了那么大的距离,所以我们需要加1*size(即数据类型的大小)。这样不管需要进行什么类型的数据的比较,我们只要在参数中给出数据的类型大小,就能直接比较,使这个函数更加通用。我们自己定义了一个cmp_int函数,调用它的指针的形参名为cmp,cmp用来判断两个元素的大小。如果我们想对任何数据进行排序,我们可以发现,排序的趟数是固定的,我们只需要对比较大小的方式进行改造即可。原创 2023-12-01 20:09:12 · 400 阅读 · 12 评论 -
传址与传值
可以看到,交换后的a,b并没有达到我们的预期。其实是因为,传值的时候,形参是临时创建的,在执行完swap函数后,他们又自动销毁了,从而导致a,b的值并没有交换。我们通过把a和b的地址传给了形参,形参就能通过地址,找到a,b,以此来改变a和b的值。传址:形参是实参地址的一份拷贝,形参指向的实体是实参,对形参解引用后,拿到的内容就是实参,因此,对形参解引用后的内容进行修改,改变的就是实参。总结:传值:形参是实参的一份拷贝,函数运行起来后,实参是实参,形参和实参没有任何关联,改变形参时,不会对实参造成影响。原创 2023-11-16 00:17:02 · 153 阅读 · 2 评论 -
sizeof与数组,短路操作
分析:数组传参时,传的的地址,我们用的是指针类型的形参来接收,在test1中sizeof(arr)求的是指针类型所占的字节数大小,在调用test2时也是同样的道理。不管是什么类型的指针,比如char*,int*,他们所占的字节数大小都是4或者8。分析:a初始为0,此时为假,++后变为1,继续右边的计算,b先++为3,此时为真,不再进行后边的计算,d的值也不会改变。分析:因为a初始值为0,a++时,a先使用后++,此时已经为假了,就不再进行后边的计算,因此i的值为0,b,c,d的值不变。原创 2023-11-16 18:38:24 · 213 阅读 · 3 评论 -
如何用rand产生随机数
这样,我们就不需要每次运行前,都去改变种子的值啦,不过需要注意的是,我们需要把time的类型强制转化为unsigned,time函数的参数是一个指针,我们可以直接设为NULL(空指针)。如下图,这是第一次运行。srand()括号里可放入一个数,我们称为种子,我们需要记住,当种子不同的时候,rand就可以产生不重复的随机数。当我们的种子是常量的时候,如果我们想让rand每次运行产生不重复的随机数,我们就得在运行前改变种子的值,这样很麻烦。srand在前,rand在后,按照这样的格式就可以产生随机数啦。原创 2023-11-09 15:21:11 · 172 阅读 · 4 评论 -
数据在内存中的存储
分析:我们先求出-128的补码,由于a是字符型,因此只取前面8位存储在内存中,打印a时,要进行整形提升,因为是有符号的char,所以高位补符号位1,提升后,由于是打印无符号的整数,所以就不再进行取反,加1的操作了,直接把他看成无符号的数值,打印出来就是一个很大的数了。如果将他放在低地址处,就是小端字节序存储。例如:我们进行1-1时,由于计算机内部只有加法处理器,我们可以看成1+(-1),分别写出他们的补码后,进行相加,最后得到的结果刚好是0.(最左边的1是第33位,已经超过最高位,去掉,取右边的32位)。原创 2023-11-19 01:30:00 · 708 阅读 · 32 评论