20250731的学习笔记
一、函数(function)
(1)函数的实现
语法
类型标识符 函数名(形式参数) --- 函数头
{
//声明部分
//语句部分
函数体
return 表达式;//返回函数处理的结果。
}
(2)函数头
①类型标识符 ---int/shoet/long…
返回值类型 //说明函数返回的结果的数据类型。
注意:
1.返回值结果和设计的类型标识符可能不一致,此时,返回值结果会被转换成类型标识符指定的类型。
2.如果返回信类型省略不写,默认 int类型。
3.如果不需要带出返回值,使用void--- 空类型,对应的 return 后面不能有值。
②函数名 ---标识符,体现函数的功能(见名知义)
注意:
1.形参与实参,类型匹配,个数相同。
2.每个形参变量都必须明确指定类型。
3.如果函数功能,不需要传入数据时,形参一般设计为 void。
③形式参数 ---本质是是变量
作用--用来接受 实际的参数。
语法:
类型 形参变量名1,形参变量名2…
④函数体:函数对应功能,具体代码。
(3)函数定义的位置
c语言中所有标识符--先定义,后使用,main的数是整个程序的入口函数,定义的位置在main之前,如果在main之后,在使用前在做一下函数声明(将函数头复制加上分号)。
(4)函数基本模型
实参 --->[功能模块] --->结果
eg:
实现函数,对两个整形数据求和。
step1:从功能出发,确定函数名---add。
step2:从函数模型(数据处理的模型)出发,考虑,要处理那些数据(形参的个数,类型)。
eg:int a,int b
step3:考虑数据处理的功能 ---具体代码。
eg:
int sum;
sum=a+b;
step4:考虑结果的处理。
eg:
return sum;
(5)函数调用
---使用函数 //使用这个功能。
函数名 (实际参数)
(6)函数设计原则
①单一职责。
②高内聚,低耦合。
(7)函数传递数据
全局变量 --- 不建议使用,会破坏c语言的结构化编程。
形参变量 ---推荐。
二、函数的嵌套调用
(1)特殊的嵌套调用
--- 自己调用自己。
(2)函数为什么会嵌套调用
函数能够实现层层调用,本质上是因为有栈这个空间存在。
(3)栈
1.是内存上的一块空间。
2.Linux系统下,栈默认大小为8MB(可更改)。
(4)C语言的程序(五个区)
①栈
函数调用的相关信息。
局部变量 --- 自动申请,自动释放。
②堆
空间非常大。
手动申请,手动释放。
③全局区/静态区
放全局变量,静态变量 ---默认初始化为0。
④字符串常量区
存放字符串常量。
⑤代码区
机器指令。
三、递归
(1)递归注解
①本质上是个循环。
②这种循环 一定会结束,因为栈的空间有限。
③递加的效率并不高,因为有些问题的解决,使用递归将变得很简单。
④倒着看问题。
(2)递归解决问题
①递归关系
问题n和问题n-1之间的递推关系
②递归的基本形式
返回值类型 递归函数(形参)
{
if(是否到达结束条件)
{
return 表达式//是,回归
}else
{
return 问题n和n-1的递推结果//假,递推
}
}
四、数组作为函数参数
(1)数组元素做形参
数组元素做形参和常量没有区别
整个数组作为函数参数从类型角度:
eg:printfArray(int a[10])
printfArray(int *a)
//编译器的理解 --- int *a//指针类型 ---需要的是一个地址
//从值的角度 --- 数组名代表首元素的地址,因为数组的特点:连续性,有序性,单一性。
(2)写法
①形参
printArray(int a[10],int len);//可以写成这个形式 ---提高可读性
printArray(int *a,int len);//编译器实际理解的形式
②实参 ---数组名 数组长度
printfArray(a,len);
五、心得体会
函数设计让我体会到“边界即质量”。以前随手写大段 main,现在遵循“单一职责 + 高内聚低耦合”,把“读数据、处理数据、输出结果”拆成独立函数;形参代替全局变量,既避免副作用,又便于单元测试。尤其把数组名当指针传递后,我真正理解了“地址 + 长度”这对黄金搭档:数组连续存放的本质让 int *a 与 int a[] 等价,而长度参数则补足了指针丢失的维度信息。
递归让我第一次“看见栈”。当 factorial(n) 层层压栈,再层层弹栈返回时,我意识到栈不仅是内存空间,更是“状态保存与回滚”的自动化机制。递归写法简洁,却因函数调用开销和栈深度限制,并不总是最优解;把递归改循环或尾递归优化,是性能与可读性的平衡艺术。
内存五区模型让我对“变量生命周期”有了全景视角:
栈区:函数帧、局部变量随调用自动生成和销毁,像快递柜的临时格子;
堆区:需要 malloc/free 手动管理,像长期租用的仓库;
全局区、字符串常量区、代码区分别存放长期数据、只读文本和机器指令。
理解了这些,再写 char s[5][10] 时,就能预判它全落在栈上,读写高效却容量有限;若改为动态二维数组,则需 malloc 到堆,再手动释放,避免内存泄漏。
一句话总结:函数让代码模块化,递归让算法优雅化,数组指针让数据高效化,而内存模型则是这一切的地基。
更多推荐
所有评论(0)