C语言
文章平均质量分 72
梦想 与 现实
普通大学生
展开
-
43.数据在内存中的存储
其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分 为⼤端字节序存储和⼩端字节序存储,下⾯是具体的概念:⼤端(存储)模式:是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存 在内存的低地址处。⼩端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存 在内存的⾼地址处。上述概念需要记住,⽅便分辨⼤⼩端。原创 2024-04-06 19:21:56 · 1143 阅读 · 0 评论 -
42.C语⾔内存函数
memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。对于重叠的内存,交给memmove来处理。原创 2024-04-06 00:08:42 · 269 阅读 · 0 评论 -
41.字符函数和字符串函数
在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明 的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动 的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应 的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是 有对应的错误信息的。C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。原创 2024-04-05 22:12:40 · 818 阅读 · 0 评论 -
40.深⼊理解指针(5)
sizeof 计算变量所占内存内存空间⼤⼩的,单位是 字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的⼤⼩。统计的是从 strlen 函数的参数 str 中这个地址开始向后, \0 之前字符串中字符的个数。strlen 函数会⼀直向后找 \0 字符,直到找到为⽌,所以可能存在越界查找。sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据。strlen 是C语⾔库函数,功能是求字符串⻓度。原创 2024-04-05 00:07:57 · 287 阅读 · 0 评论 -
39.深⼊理解指针(4)
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。我们可以把调⽤的函数的地址以参数的形式 传递过去,使⽤函数指针接收,函数指针指向什么函数就调⽤什么函数,这⾥其实使⽤的就是回调函 数的功能。注意:这⾥第⼀次使⽤ void* 的指针,讲解 void* 的作⽤。使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。原创 2024-04-04 22:48:15 · 305 阅读 · 0 评论 -
38.深⼊理解指针(3)
所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀ 维数组的地址。根据上⾯的例⼦,第⼀⾏的⼀维数组的类型就是 int [5] ,所以第⼀⾏的地址的类 型就是数组指针类型 int(*)[5]。⾸先我们再次理解⼀下⼆维数组,⼆维数组起始可以看做是每个元素是⼀维数组的数组,也就是⼆维 数组的每个元素是⼀个⼀维数组。那么⼆维数组的⾸元素就是第⼀⾏,是个⼀维数组。确实打印出来了地址,所以函数是有地址的,函数名就是函数的地址,当然也可以通过 &函数名 的⽅ 式获得函数的地址。原创 2024-04-04 00:20:08 · 1085 阅读 · 0 评论 -
37.深⼊理解指针(2)
这⾥我们发现&arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,是因为&arr[0] 和 arr 都是 ⾸元素的地址,+1就是跳过⼀个元素。同理arr[i] 应该等价于 *(arr+i),数组元素的访问在编译器处理的时候,也是转换成⾸元素的地址+偏移 量求出元素的地址,然后解引⽤来访问的。这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,⽽且 是数组⾸元素的地址,我们来做个测试。我们发现数组名和数组⾸元素的地址打印出的结果⼀模⼀样,原创 2024-04-03 21:47:33 · 872 阅读 · 0 评论 -
36.深⼊理解指针(1)
如果明确知道指针指向哪⾥就直接赋值地址,如果不知道指针应该指向哪⾥,可以给指针赋值NULL. NULL 是C语⾔中定义的⼀个标识符常量,值是0,0也是地址,这个地址是⽆法使⽤的,读写该地址 会报错。上述代码中n是不能被修改的,其实n本质是变量,只不过被const修饰后,在语法上加了限制,只要我 们在代码中对n就⾏修改,就不符合语法规则,就报错,致使没法直接修改n。同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要 8个字节的空间,指针变的⼤⼩就是8个字节。原创 2024-04-03 00:00:31 · 755 阅读 · 0 评论 -
35.函数栈帧的创建和销毁
函数参数和函数返回值临时变量(包括函数的非静态的局部变量以及编译器自动生产的其他临时变量)保存上下文信息(包括在函数调用前后需要保持不变的寄存器)。栈(stack)是现代计算机程序里最为重要的概念之一,几乎每一个程序都使用了栈,没有栈就没有函 数,没有局部变量,也就没有我们如今看到的所有的计算机语言。原创 2024-04-02 22:11:22 · 833 阅读 · 0 评论 -
34.操作符的属性:优先级、结合性
即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯⼀的 计算路径,那这个表达式就是存在潜在⻛险的,建议不要写出特别负责的表达式。原创 2024-04-02 00:03:32 · 1039 阅读 · 0 评论 -
33.操作符详解
已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单⽬操作 符,今天继续介绍⼀部分。>> 右移操作符原创 2024-04-01 20:18:29 · 799 阅读 · 0 评论 -
32.原码、反码、补码
在计算机系统中,数值⼀律⽤补码来表⽰和存储。原因在于,使⽤补码,可以将符号位和数值域统⼀ 处理;同时,加法和减法也可以统⼀处理()此外,补码与原码相互转换,其运算 过程是相同的,不需要额外的硬件电路。直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。将原码的符号位不变,其他位依次按位取反就可以得到反码。符号位都是⽤0表⽰“正”,⽤1表⽰“负”。反码+1就得到补码。原创 2024-04-01 09:52:39 · 456 阅读 · 0 评论 -
31.⼆进制和进制转换
其实我们经常能听到2进制、8进制、10进制、16进制这样的讲法,那是什么意思呢?其实2进制、8进 制、10进制、16进制是数值的不同表⽰形式⽽已。原创 2024-04-01 00:01:15 · 345 阅读 · 0 评论 -
30.函数递归
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。其运行效率变高是因为所使用的栈空间大大减小;当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。因为递归调用是当前活跃期内最后一条待执行的语句,于是当这个调用返回时栈帧中并没有其他事情可做,因此也就没有保存栈帧的必要了。原创 2024-03-31 18:10:34 · 1047 阅读 · 0 评论 -
29.简易扫雷游戏
【代码】29.简易扫雷游戏。原创 2024-03-31 13:32:40 · 313 阅读 · 1 评论 -
28. static 和 extern
static 和 extern 都是C语⾔中的关键字。extern 是⽤来声明外部符号的。在讲解 static 和 extern 之前再讲⼀下:作⽤域和⽣命周期。是程序设计概念,通常来说,⼀段程序代码中所⽤到的名字并不总是有效(可⽤) 的,⽽限定这个名字的可⽤性的代码范围就是这个名字的作⽤域。指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的⼀个时间段。原创 2024-03-31 00:01:13 · 1208 阅读 · 0 评论 -
27.函数的声明和定义
这是因为C语⾔编译器对源代码进⾏编译的时候,从第⼀⾏往下扫描的,当遇到第7⾏is_leap_year 函数调⽤的时候,并没有发现前⾯有is_leap_year的定义,就报出了上述的警告。就是函数调⽤之前先声明⼀下is_leap_year这个函数,声明函数只要交代清 楚:函数名,函数的返回类型和函数的参数。⼀般情况下,函数的声明、类型的声明放在头⽂件(.h)中,函数的实现是放在源⽂件(.c)⽂件中。上⾯代码中橙⾊的部分是函数的定义,绿⾊的部分是函数的调⽤。⼀般我们在使⽤函数的时候,直接将函数写出来就使⽤了。原创 2024-03-30 20:02:08 · 330 阅读 · 0 评论 -
26.函数的嵌套调⽤和链式访问
上⾯的例⼦中,我们就第⼀个printf打印的是第⼆个printf的返回值,第⼆个printf打印的是第三个 printf的返回值。前⾯的代码完成动作写了2条语句,把如果把strlen的返回值直接作为printf函数的参数呢?所谓链式访问就是将⼀个函数的返回值作为另外⼀个函数的参数,像链条⼀样将函数串起来就是函数 的链式访问。嵌套调⽤就是函数之间的互相调⽤,正是因为函数之间有效的互相调⽤,最后写出来了相对⼤型的 程序。稍微⼤⼀些代码都是函数之间的嵌套调⽤,但是函数是不能嵌套定义的。第⼀个printf打印1。原创 2024-03-30 11:01:40 · 364 阅读 · 0 评论 -
25.函数
了解了库函数,我们的关注度应该聚焦在⾃定义函数上,⾃定义函数其实更加重要,也能给程序员写 代码更多的创造性。原创 2024-03-30 00:03:07 · 641 阅读 · 1 评论 -
24.打印多个字符从两端移动,向中间汇聚
编写代码,演⽰多个字符从两端移动,向中间汇聚。原创 2024-03-29 21:59:26 · 130 阅读 · 1 评论 -
23.⼆分查找
在⼀个升序的数组中查找指定的数字n,很容易想到的⽅法就是遍历数组,但是这种⽅法效率⽐较低。⽐如我买了⼀双鞋,你好奇问我多少钱,我说不超过300元。你还是好奇,你想知道到底多少,我就让 你猜,你会怎么猜?你会1,2,3,4...这样猜吗?⼀般你都会猜中间数字,⽐如:150,然 后看⼤了还是⼩了,这就是⼆分查找,也叫折半查找。求中间元素的下标,使⽤。原创 2024-03-29 20:23:23 · 169 阅读 · 1 评论 -
22.C99中的变⻓数组
它的好处是程 序员不必在开发时,随意为数组指定⼀个估计的⻓度,程序可以在运⾏时为数组分配精确的⻓度。有 ⼀个⽐较迷惑的点,变⻓数组的意思是数组的⼤⼩是可以使⽤变量来指定的,在程序运⾏的时候,根 据变量的⼤⼩来指定数组的元素个数,⽽不是说数组的⼤⼩是可变的。遗憾的是在VS2022上,虽然⽀持⼤部分C99的语法,没有⽀持C99中的变⻓数组,没法测试;在C99标准之前,C语⾔在创建数组的时候,数组⼤⼩的指定只能使⽤常量、常量表达式,或者如果我 们初始化数据的话,可以省略数组⼤⼩。原创 2024-03-29 12:55:27 · 186 阅读 · 1 评论 -
21.二维数组
从输出的结果来看,每⼀⾏内部的每个元素都是相邻的,地址之间相差4个字节,跨⾏位置处的两个元 素(如:arr[0][4]和arr[1][0])之间也是差4个字节,所以。图中最右侧绿⾊的数字表⽰⾏号,第⼀⾏蓝⾊的数字表⽰列号,都是从0开始的,⽐如,我们说:第2 ⾏,第4列,快速就能定位出7。其实⼆维数组访问也是使⽤下标的形式的,⼆维数组是有⾏和列的,只要锁定了⾏和列就能唯⼀锁定 数组中的⼀个元素。像⼀维数组⼀样,我们如果想研究⼆维数组在内存中的存储⽅式,我们也是可以打印出数组所有元素 的地址的。原创 2024-03-29 10:29:02 · 269 阅读 · 1 评论 -
20.一维数组
我们⼜知道数组中所有元素的类型都是相同的,那只要计算出⼀个元素所占字节的个数,数组的元素 个数就能算出来。有了前⾯的知识,我们其实使⽤数组基本没有什么障碍了,如果我们要深⼊了解数组,我们最好能了 解⼀下数组在内存中的存储。以后在代码中需要数组元素个数的地⽅就不⽤固定写死了,使⽤上⾯的计算,不管数组怎么变化,计 算出的⼤⼩也就随着变化了。学习了⼀维数组的基本语法,⼀维数组可以存放数据,存放数据的⽬的是对数据的操作,那我们如何 使⽤⼀维数组呢?数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。原创 2024-03-29 00:04:22 · 1078 阅读 · 1 评论 -
19.猜数字游戏
程序中在调⽤ rand 函数之前先调⽤ srand 函数,通过 srand 函数的参数seed来设置rand函数⽣成随 机数的时候的种⼦,只要种⼦在变化,每次⽣成的随机数序列也就变化起来了。之所以前⾯每次运⾏程序产⽣的随机数序列是⼀样的,那是因为rand函数⽣成随机数的默认种⼦是1。我们可以看到虽然⼀次运⾏中产⽣的5个数字是相对随机的,但是下⼀次运⾏程序⽣成的结果和上⼀次 ⼀模⼀样,这就说明有点问题。在程序中我们⼀般是使⽤程序运⾏的时间作为种⼦的,因为时间时刻在发⽣变化的。原创 2024-03-28 18:19:39 · 590 阅读 · 1 评论 -
18.goto语句
goto 语句如果使⽤的不当,就会导致在函数内部随意乱跳转,打乱程序的执⾏流程,所以我们的建 议是能不⽤尽量不去使⽤;但是 goto 语句也不是⼀⽆是处,在多层循环的代码中,如果想快速跳出 使⽤ goto 就⾮常的⽅便了。本来 for 循环想提前退出得使⽤ break ,⼀个 break 只能跳出⼀层 for 循环,如果3层循环嵌套 就得使⽤3个 break 才能跳出循环,所以在这种情况下我们使⽤ goto 语句就会更加的快捷。跳转到设置好的标号处。原创 2024-03-28 11:51:28 · 173 阅读 · 1 评论 -
17.循环的嵌套
三种循环 while , do while , for ,这三种循环往往会嵌套在⼀起才能更好的解决 问题,就是我们所说的:循环嵌套,这⾥我们就看⼀个例⼦。找出100~200之间的素数,并打印在屏幕上。注:素数⼜称质数,只能被1和本⾝整除的数字。原创 2024-03-28 09:50:40 · 136 阅读 · 1 评论 -
16.break和continue语句
在循环执⾏的过程中,如果某些状况发⽣的时候,需要提前终⽌循环,这是⾮常常⻅的现象。C语⾔中 提供了 break 和 continue 两个关键字,就是应该到循环中的。原创 2024-03-28 00:28:10 · 882 阅读 · 1 评论 -
15.do-while 循环
在 do while 循环中先执⾏图上的“语句”,执⾏完语句,在去执⾏“判断表达式”,判断表达式的 结果是!⽽ do while 循环则是先直接进⼊循环体,执⾏循环语句,然后再执⾏ while 后的判断表达式,表 达式为真,就会进⾏下⼀次,表达式为假,则不再继续循环。这⾥并⾮必须使⽤ do while 语句,但是这个代码就⽐较适合使⽤ do while 循环,因为n即使是 0,也是1位数,要统计位数的。所以在 do while 语句中循环体是⾄少执⾏⼀次的,这是 do while 循环⽐较特殊的地⽅。原创 2024-03-27 23:34:37 · 216 阅读 · 1 评论 -
13.while循环
C语⾔提供了3种循环语句, while 就是其中⼀种,接下来就介绍⼀下 while 语句。while 语句的语法结构和 if 语句⾮常相似。原创 2024-03-27 14:37:08 · 343 阅读 · 1 评论 -
14.for循环
⾸先执⾏ 表达式1 初始化循环变量,接下来就是执⾏ 表达式2 的判断部分, 表达式2 的结果如果 ==0,则循环结束;=0则执⾏循环语句,循环语句执⾏完后,再去执⾏表 达式 3 ,调整循环变量,然后再去 表达式2 的地⽅执⾏判断, 表达式2 的结果是否为0,决定循环是否继续。for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部 分⾮常集中,便于代码的维护,⽽如果代码较多的时候 while 循环的三个部分就⽐较分散,所以从形 式上 for 循环要更优⼀些。原创 2024-03-27 21:58:12 · 574 阅读 · 0 评论 -
12. switch 语句
switch 语句是⼀种特殊形式的 if...else 结构,⽤于判断条件有多个结果的情况。它把多重 的 else if 改成更易⽤、可读性更好的形式。原创 2024-03-27 08:57:54 · 850 阅读 · 1 评论 -
11.if语句
if语句为真,则打印成年了, if语句为假,则不打印,对于 printf("可以谈恋爱了\n");只要带上适当的⼤括号,代码的逻辑就会更加的清晰,所以⼤家以后在写代码的时候要注意括号的使 ⽤,让代码的可读性更⾼。,也就是表达式的结果如果是0,则语句不执⾏,表达式的结果如果是 不是0,则语句执⾏。输⼊⼀个整数,如果是正数,再判断是奇数还是偶数,并输出;上⾯的代码中橙⾊背景的代码也是嵌套在 if 语句中的,构成了嵌套的 if 语句。输⼊⼀个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印数偶数。原创 2024-03-27 08:40:00 · 312 阅读 · 1 评论 -
10.操作符
C 语⾔⽤于⽐较的表达式,称为 “关系表达式”(relational expression),⾥⾯使⽤的运算符就称 为“关系运算符”(relational operator),主要有下⾯6个。例: 关系表达式通常返回 0 或 1 ,表⽰真假。C 语⾔中, 0 表⽰假,所有⾮零值表⽰真。⽐如, 20 > 12 返回 1 , 12 > 20 返回 0 。 关系表达式常⽤于 if 或 while 结构。注意:相等运算符 == 与赋值运算符 = 是两个不⼀样的运算符,不要混淆。有时候,可能会不⼩⼼写 出下⾯的原创 2024-03-27 00:15:36 · 882 阅读 · 2 评论 -
9.占位符
printf() 的占位符有许多种类,与 C 语⾔的数据类型相对应。下⾯按照字⺟顺序,列出常⽤的占位 符,⽅便查找。原创 2024-03-26 20:15:18 · 320 阅读 · 2 评论 -
8.scanf()函数
scanf() 的语法跟 printf() 类似。原创 2024-03-26 18:17:42 · 714 阅读 · 2 评论 -
7.printf()函数
使⽤这个函数之前,必须在源码⽂件头部引⼊这 个头⽂件。原创 2024-03-26 17:32:10 · 940 阅读 · 2 评论 -
6.操作符(运算符)
在写代码时候,⼀定会涉及到计算。C语⾔中为了⽅便运算,提供了⼀系列操作符,其中有⼀组操作符叫:算术操作符。,这些操作符都是。原创 2024-03-26 16:26:43 · 681 阅读 · 2 评论 -
5. 变量
C语⾔中把经常变化的值称为,不变的值称为。原创 2024-03-26 07:17:53 · 240 阅读 · 2 评论 -
4.C语言数据类型
sizeof 在代码进⾏编译的时候,就根据表达式的类型确定了,类型的常⽤,⽽表达式的执⾏却要在 程序运⾏期间才能执⾏,在编译期间已经将sizeof处理掉了,所以在运⾏期间就不会执⾏表达式了。每⼀种数据类型有⾃⼰的取值范围,也就是存储的数值的最⼤值和最⼩值的区间,有了丰富的类 型,我们就可以在适当的场景下去选择适合的类型。不同的系统中,返回值的类型有可能是 unsigned int ,也有可能是 unsigned long ,甚⾄是 unsigned long long ,这样不利于程序的可移植性。原创 2024-03-25 21:24:39 · 1146 阅读 · 1 评论