Loading... [update log] 23/2/6 将增加更多的手写笔记, 23/2/9 回归更新,遇到不明所以的概念时,我更像是一名孤独的开拓者。 23/3/7 我问了好几个同学,上学期那老师被指针绕晕后迷路了,希望人没事就好,终究还是错付了[狂喜]。 所以本贴停更。 **【总则】** 这篇笔记不只是献给自己的,更重要是献给屏幕前热爱学习的你,我的笔记将涵盖概念篇与代码篇两个部分,概念篇与代码篇相互穿插相辅相成。官方的词汇给我的感觉就是隐晦难懂,不利于快速的理解。鉴于此痛点,我将用“讲人话”的方式去讲述这些概念。面对于一些三言两语讲不清楚的概念,我也会提供更多的插图和我个人的手绘笔记以供您辅助理解。把学到的新东西用到实处上是一件很有成就感的事情,我会以问题引导的方式引导你去看对应的代码,新学的知识点对应的能用代码解决哪些问题。借砖引玉的同时,我也会继续为您讲述这块玉妙于何处。让C语言不是冰冷的机器语言,是我当下很想做的事情。[本来想写完再发了,不过想想要是这篇隐藏了,网站真的就没什么内容了,哦豁,主讲老师跑了,可以光明正大停更了。] #传送门 [1] <a href="#源起">源起</a> [2] <a href="#循环">循环</a> [3] <a href="#数组">数组</a> [4] <a href="#函数">函数</a> [5] <a href="#指针">指针</a> #源起 |:----: | :----: | :----: | :----: | |数据类型|类型说明符|字节|取值范围| |:----: | :----: | :----: | :----: | |字符型|char|1|C字符集| |基本整型|int|4|-32768~32767| |短整型|short int|2| -32768~32767| |长整型|long int|4|-214783647-214783647| |无符号型|unsigned|4|0~65535| |无符号长整型|unsigned long|4|0~4294967295| |单精度实型|float|4|3/4E-38~3/4E+38| |双精度实型|double|8|1/7E-308~1/7E+308| <a name="c2"></a> **常量与符号常量** 常量与之相反的叫变量,所以在运算过程中永恒不变的量称为常量。 在生活中,一周固定有七天,太阳东升西落,这种永恒不变的规则都可称为常量。 在C语言里,有分整型常量,实型常量,字符型常量。 🟢整型常量,包含整数,如-1,0,1,2,3 ··· 🟢整型常量,也包含8,10,16进制,如0101,0x208 ··· 🟡实型常量,包含小数,如-1.12,200.3 ··· 🟡实型常量,也包含指数,如:1.13e2[1.13乘10的2次方] ··· 🔵字符常量,包含字母,如‘a’,‘b’,‘c’,‘d’ ··· 🔵字符常量,也包含[ASCII码][1],如:十进制65对应字母‘A’ 🟠字符串常量,即单词,如"huaniang" "花酿" ··· **算数表达式** C语言跟数学是密不可分的,能够让C语言去处理数学的公式,是可以计算出不同公式产生的数据的。 那么我们应该怎么把数学语言的公式,变成符合C语言语法规则的式子,以便在C语言内完成数学计算呢? 乘法:1*2=2 a+b (x+r)*8-(a+b)/7 ++i sin(x)+sin(y) (++i)-(j++)+(k--) 运算符的优先级 运算符的优先级:在C语言中,运算符的运算优先级共分为15级。1级最高,15级最低。在表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。 运算符的结核性:C语言中各运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。左结合性的表达式x-y+z中,则先执行x-y运算,再执行+z的运算;右结合性运表达式中x=y=z,由于“=”为右结合性,先执行y=z再执行x=(y=z)运算,C语言运算符中右不少是右结合性,应注意区别,以避免理解错误。 <a name="c5"></a> 自增、自减运算符 自增 1,自减1运算符:自增1运算符记为“++”,其功能是使变量的值自增1.自减1运算符记为“--”,其功能是使变量值自减1. 自增1,自减1运算符均为单目运算,都具有右结合性。可以有以下几种形式: ++i i自增1后再参与其它运算。 --i i自减1后再参与其它运算。 i++ i参与运算后,i的值再自增1. i-- i参与运算后,i的值再自减1. “左自增,右后增”,在理解和使用上容易出错的是i++和i--。特别是当它们出在较复杂的表达式或语句中时,常常难于弄清,因此应仔细分析。 <a name="c6"></a> #循环 循环结构:当给定条件成立时,重复执行某程序段,直到条件不成立为止。 命令:goto、if、while、do-while、for。 goto:无条件转移语句。 loop:--设锚点,goto loop;--传送锚点 <img src="https://qqclwy.com/usr/uploads/2022/09/2756101038.jpg" height="130" /><img src="" height="130" /> while:计算表达式的值,当值为非0,重复执行。当值为0,继续向下执行。 do-while:先执行循环体语句,然后再判断表达式是否为真,如果为真则重复循环,如果为假则继续执行。 For:for(表达式1;表达式2;表达式3)语句 <img src="https://qqclwy.com/usr/uploads/2022/09/2991589111.jpg" height="130" /> 若都为真:表达式1 -> 表达式2(假跳出) -> 表达式3 -> 表达式2(假跳出) -> 表达式3(重复循环2,3) 若某环节为假,则跳出For语句,继续执行下一段语句。 break和continue:break;--强行中止,continue;--继续返回for循环。 **switch** switch(m) { case 常量表达式1: 语句组1;[break;] case 0 : y=3*x+5;break default;语句组 n;[break;]] default : printf("数据输入错误!\n") } <a name="c7"></a> #数组 数组的表现形式如下 int a[10]; 数组a里面有10个元素 float b[10],c[20]; b数组有10个float类型的元素 #define ARRAYNUM 10(宏定义) int MyArray[ARRAYNUM] = {1,2,3,4,5}; 在MyArray数组当中有10个预加载元素。 int YourArray[3+2]; int HisArray[10 + ARRAYNUM]; <a name="c8"></a> #函数 编程的函数与数学的函数不同,编程上的函数实际上是由一个个函数模块组成的。 **第一部分、如何定义并调用函数?** FunctionTest01(int a,int b){...return c;} /*定义函数中有两个参数*/ int main(void) {FunctionTest(i,i++);} /*在主函数调用函数并导入数值i,i++值*/ **第二部分、如何用数组作为参数调用函数?** [查看][2] float FindAvarage(float array[10]){...return aver;}/*类型:浮点型 参数:array[10]*/ int main(void){float score[10]/*数组score有是个10个元素,类型为浮点型*/ aver = FindAvarage(score); /*载入函数并输出这个函数的返回值*/ printf("学生的平均分数为%5.2f", aver); /*打印aver的值*/} **第三部分:全局外部局部变量** int a = 5;/*函数外的变量为外部变量*/ int Findmax(){int z;}/*函数内的变量为内部变量*/ **第四部分:static与register变量** [查看][3] 用法:static int c = 5; /*静态变量,变量值虽运算而改变*/ /*static与阶乘的运用*/ int main(void){ int i; for(i = 0,i < 5,i++){ static int a = 1; n = 5; /*阶乘为5*/ a = a * n; return a;}} 5的1!-5!的值为:5、25、125,625,3125 #指针 **指针的意义**:指针是C语言中广泛使用的一种数据类型,利用指针可以表示各种数据结构:能够很方便的使用数组和字符串;并像汇编语言那样处理内存地址,从而精炼出高效的程序,指针极大丰富了C语言的功能。 个人理解:指针更多像是门牌号,即内存地址。在C语言中有很多像浮点数,变量的数值,他们只能存在电脑的内存条里,怎么在8G,16G,32G这些偌大的运行内存里找到这些数值,就只能利用指针这个门牌号了。简单一句话,指针就是地址,地址就是内存编号,内存编号是用十六进制来表示。 **指针的概念**:刚开始会懵,多往下看发现规律就好了 <img src="https://qqclwy.com/usr/uploads/2023/01/3985187165.png" height="100"> 图中,设有字符变量C,其内容为K(int c = ‘K’),C在内存地址中占用了011A号单元。现在创建一个指针变量P(int *p = &c),指针内容和变量C一样是011A,这种情况我们称为指针P指向变量C,或说P是指向变量C的指针。[\[pointer-1 初入指针\]][4] **如何定义指针**:类型说明符 *变量名。像int *p1,表示p1指向一个整型变量,至于p1指向哪一个整型变量,应该由p1赋予的地址来决定。 **指针变量赋值**:把字符串的首地址赋予指向字符类型的指针变量。例如:int *p="C language"; 这里并不是将整个“C language”的字符串直接存入指针变量,<s>而是将该字符串的字符数组的首地址装入指针变量</s>,你也可以理解成,把“C Language”中的首字母“C”存入指针变量。这样做的意义,我猜测是通过先找字母“C”的地址,进而再找到“Language”。 **函数指针赋值**:把函数的入口地址指向函数的指针变量,这里我觉得更多只需要探讨函数和指针的关系,例如怎么去建立一个函数指针,这个函数指针怎么被赋值,浅略了解即可。 int (*pf)(); // (*pf)是新建的函数指针,()为函数指针的参数 pf = f; // f是一个函数,pf是新建的函数指针,此时pf已被赋值。 这个过程可以称作函数指针赋值。 **两指针的变量关系运算**:指向同一数组的两指针变量进行关系运算可表示它们所指数组元素的关系。我的理解是,通过对比这两个指针下的数组元素,从而确立这两个指针的关系。 pf1 == pf2: 表示指针pf1和指针pf2指向同一数组元素 一个数组下有很多个元素,如果两个指针都指向同一数组,就像我们生活中的住址一样。 同一数组(住址)下的元素(成员),它们可能是家人关系,邻居关系或者舍友关系。 这一切的一切,都是根据你实际居住的地址来推断的。 pf1 > pf2: 表示pf1处于高地址位。 pf1 < pf2: 表示pf1处于低地址位。 指针变量处于高地址位,可以理解成,我家门牌号比你家门牌号楼层要高,所以处于高地址。 以上例子暂不需要刻意的去探究其执行原理,现行阶段知道这个现象存在即可。 **空指针**:指针的值必须为0,表现手法:int *p = NULL; 那指针没有任何值的情况下是空值吗,不是的,没有任何值的指针运行时会报错。 如果这个指针你不暂时需要用,可以考虑给它赋个空值,也就是空指针。 **数组指针储存原理**: <img src="https://qqclwy.com/usr/uploads/2023/02/4012745745.png" height="280"> 一个数组是连续的一块内存单元组成的。数组名就是这块连续内存单元的首地址。一个数组也是由各个数组元素组成的。每个数组元素按其类型不同占有连续几个内存单元。一个数组元素的首地址也是指它所占有的几个内存单元的首地址。 个人理解:指针就是内存地址,内存地址存放在电脑的内存条里面,数组的代码数据存放在内存条里的内存单元,数组是由元素组成的。元素内容的<s>第一个字母或者中文</s>会作为内存单元的首地址,储存在内存条中。 [\[图-数组与元素在内存条中的存储关系\]][5] **数组赋值指针变量**: int a[10]; 定义a是一个包含10个整型元素的数组 int *p; 定义p为指向整型变量的指针 p = &a[0]; 把a数组0号元素的内存地址赋值给指针p 很愉快,我们通过完成了对内存地址的定义和传达并打印,那接下来,我们来一次反向操作。 你太craze了吧,是两极反转吗?不不不,这类似于小鸡找妈妈,就看有趣不有趣吧。 int main(void) { int a = 10; 我们大a的原始十进制值是10哦,变成%p内存地址是000000480119FC84 int * p = &a; 将指针p和我们的内存地址&a进行绑定,此时指针p的%p值还是000000480119FC84 printf("%d",a); 以十进制的方式打印我们的大a,和原始值一样还是10,一切没变真好! *p = 20; 颠覆性的来了,这里将指针p的十进制值改成了20. printf("%d",a); 也就是说与指针p十进制值改变,内存地址&a的十进制值同样也发生了改变。 导致最终大a的十进制值从原始的10变更到20,这种现象,称之为解引用。 } 噢,小鸡找妈妈的游戏有趣吗,下面来说说指针的大小,很简单就两个数字4和8。 因处理器架构不同,电脑有分32位和64位。32位是一个小房子,64位是一个大房子。 在32位的小房子电脑当中,只能容纳32bit的空间,换算成byte也就是(32÷8)= 4。 在64位的大房子电脑当中,只能容纳64bit的空间,换算成byte也就是(64÷8)= 8。 int main() { printf("%d\n", sizeof(char*)) 我们查询一下,这些常用的C语言命令所占用的指针空间。 printf("%d\n", sizeof(int*)) 如果你的电脑是32位得到的结果是4,如果是64位得到的结果是8. 所以哈,指针需要多大的空间,还是取决于你的电脑。 } *你小子,以为我不会回来吗,大声笑 [1]: https://qqclwy.com/usr/uploads/2023/02/3750147608.png [2]: https://qqclwy.com/elementaryC1-1#h1 [3]: https://qqclwy.com/elementaryC1-1#h2 [4]: https://qqclwy.com/C-C#Cpointer [5]: https://qqclwy.com/usr/uploads/2023/01/2360582991.jpg 最后修改:2023 年 10 月 03 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏