C语言程序设计2018.10.23

这章真是又难又多

但是

怂.jpg

目前为止,只把第五章过了,后面的习题还没过,看完再补……

C函数分为两类,主函数子函数;从形式上看分为,无参函数和有参函数;从使用角度看,分为库函数和用户自定义函数。
无论main函数什么位置,程序总是从main函数开始,到main函数结束,调用其他函数后流程返回main函数。main可以调用其他函数,其他函数不可以调用main函数。C语言中函数与函数之间关系是平行的、互相独立的,不能在一个函数内部定义另一个函数,即不允许嵌套定义。调用库函数要写明相应的预处理命令。
函数定义的一般形式

[类型标识符] 函数名 ([形式参数表])//函数的首部
{
声明部分
执行部分
}//函数体

类型标识符指定函数的类型,即函数返回值的类型,int char float,也可以是用户自定义类型,若返回值是int 可以省略,若函数无返回值,可指明类型位void(无类型,空类型)形式参数表,指明参数的名字和类型,形参的类型必须单独定义,各组之间用逗号隔开。
无参函数的括号不可以省略,可以省略形式参数表。(方括号不是声明是需要写的)
无参函数定义形式

[类型标识符]函数名()
{
声明部分
执行部分
}

子函数可以单独编译,但不可以单独执行,必须被调用才能执行。
函数体内没有任何内容,成为空函数,程序设计中,常在准备扩充功能的地方写上一个空函数,表明
这里有一个函数。

函数调用
函数调用使被调函数付诸实际执行
函数调用的一般形式

函数名([实际参数表])

多个实参用逗号隔开,实参与形参个数相同,位置对应,类型一致。

函数调用方式

函数语句方式
	myprint(n);
函数表达式方式
	z=myprint(n)
函数参数方式
	m=min(a,min(b,c))
	printf("%f",min(a,b))

形参类型必须在函数定义时指定,函数未被调用时,形参不占用内存中的存储单元。只有在发生函数调用时,形参才由系统分配存储单元,并将实参传递至形参单元中。在执行函数过程中,形参单元被访问或被重新赋值,均与实参单元无关。调用结束后,形参单元被系统释放,而实参单元仍然保留且值不变。要求实参必须在调用时有确定的值。

return
return语句的语法格式

return[(表达式)]

表达式可以是常量、变量、数组元素、函数调用或其他形式的表达式。
return 后可以带括号可以不带,无返回值时,return;即可,仅仅起到返回主函数流程的作用,如果不需要返回值,可以不写return(无参函数的右花括号将返回主函数的流程)。一个函数可以有多个return语句,即多个出口。
结构化程序要求一个函数应该单入口,单出口。

函数返回值类型
定义函数时指定的函数类型决定了函数返回值的类型。若return返回类型与函数类型不一致,
系统自动将return语句中表达式的值转换为函数类型后返回。
如果无返回值,函数省略void,函数将返回一个不确定值。

问题,与引用变量类似,调用函数一般要求函数定义在前、调用在后
由此引申出解决方法,即函数声明语句
函数声明语句

格式1:类型标识符 函数名(参数类型1参数名1,……);
格式2:类型标识符 函数名(参数类型1,参数类型2……);

格式2中不写参数名,显得精简,但格式1只需要照抄函数首部再加一个分号就可以了,不易出错。
说明:若被调函数在调用前定义了,不必使用函数声明;否则,应在主调函数中对被调函数作声明,声明的作用是把函数名、函数参数的个数和参数类型通知编译系统。
如果在文件的开头(所有函数前)已对本文件中要调用的所有函数进行了声明,则在各函数中不必对其所要调用的函数再作声明。

函数调用中的参数传递
C语言在实参和形参之间传递数据时采用的是单向的“值传递”,在一个函数调用时,由实参传递给形参,被调函数执行中,改变形参不影响实参。
根据参数类型,值传递分为数值传递和地址传递。

数组名代表数组首元素的地址,也就是数组的地址。数组名作为函数参数时,实参与形参采用地址传递的方式。在函数调用时,把内容为数组地址的实参传递给形参(形参是数组名或指针变量)。这时形参改变,实参也会改变。
一维数组名作函数参数一下4种情况等效
实参形参都是数组名
实参为指向数组的指针变量,形参为数组名
实参为数组名,形参为指向数组的指针变量
实参和形参都是指向数组的指针变量

(这块儿不是很懂)
一脸懵逼

实参数组名代表一个已分配存储单元的数组的地址,实质上是一个指针常量,可定义一个指针变量指向实参数组,故无论用数组名还是指向数组的指针变量作为实参,向形参传递的均是数组的地址。
形参是从接受实参传递过来的数组地址,编译器把形参数组名当作指针变量来处理,无论指针变量还是数组名作形参都是等效的。
形参数组实质是一个指针变量,指定其大小不起任何作用,因此通常性参数组不指定大小。通常另设一参数用于传递需要处理的数组的元素的个数。

多维数组名作函数参数(第一维长度可以不指定,其他维必须指定)
数组名作函数参数的进一步说明
用数组名作函数参数,应该在主调函数和被调函数中分别定义数组
实参数组与形参数组类型应一致
在被调函数中说明形参数组的大小(为了符合数组说明的有关规定)但实际上,指定其大小不起任何作用,C编译对形参数组大小不做检查,只是将实参数组得首元素地址传递给性参数组。(其大小由实参决定?)

C语言不允许嵌套定义,但允许嵌套调用。嵌套调用,一个函数中调用另一个函数。
递归调用,直接递归调用和间接递归调用。直接递归,在函数内部直接调用函数本身;间接递归,
两个函数,func1中调用func2,func2中再调用func1。

递归函数经典题型,斐波那契数列,求阶乘。递归算法简单,但计算的时间复杂度会随着n承
指数级增长。

C语言中完整的变量定义应该有以下内容

变量的数据类型
变量的作用域
变量的存储类别

作用域指变量在程序中的有效范围。从作用域角度分,变量分为局部变量和全局变量。
存储类别,也指存储方法。C语言程序在计算机内占用的存储空间分为3部分,程序区、静态存储区、动态存储区。程序区中存放可执行程序的机器指令,静态区存储区中放需要占用固定存储单元的变量,动态存储区中放不需要占用固定存储单元的变量。不同的存储方法影响变量值的存在时间(生存期)。从存储类别角度,变量有动态存储和静态存储两种类型。

局部变量的作用域仅限于定义他的函数。(主函数中定义的变量x、y和z只在主函数中有效,不会因为在主函数中定义,就在整个文件中都有效)不同函数中可以使用相同名字的变量,互不干扰。形参是局部变量。在一个函数内部,复合语句中定义的变量,只在复合语句中有效。

局部变量有3种存储类型,自动类,静态类和寄存器类
自动类(关键字auto)
在动态存储区内分配单元(也称动态变量),函数返回时,编译系统将释放这些存储单元,调用结束时,自动类变量不复存在。(在运行时赋值,若未赋值,自动变量将有一个不确定的值)
静态类(关键字static)
在函数调用结束后,仍然保留其值。分配静态存储单元,程序运行期间不释放,其值能保持连续性。在编译阶段赋初值(若未赋值,则自动赋初值0{对数值型变量}或空字符{对字符变量}),且只赋一次,以后调用不再赋初值,而是保留上一次函数调用时的结果。
为了提高计算机内存空间使用效率,只在必要时定义静态存储变量。
寄存器变量(关键字register)
为了提高执行效率,方便计算机对一些常用(频繁使用)的值直接取出参加运算,省去在内存中取值。
关键字应该在定义变量的类型标识符前面使用。
只有局部自动变量和形参可以定义为寄存器变量,其他变量均不允许。(重点)
当CPU中寄存器不够时,编译程序将认为不合适存放在寄存器中的变量自动按auto处理。
寄存器变量无地址!(重点)

函数外定义的变量叫外部变量(全局变量、全程变量)
为了增加函数间数据联系的渠道。
不成文规定,将全局变量名的第一个字母大写。
建议必要时在使用全局变量,因为程序运行全程都占用存储空间。
全局变量降低了函数的通用性和程序的可靠性。结构化程序设计要求程序模块的内聚性强,与其他模块的耦合性要弱,全局变量不符合这个原则。尽量避免函数间的除了实参-形参外的联系,可以提高程序可读性,可靠性,可移植性。
允许全局变量与局部变量同名,局部变量的作用域内全局变量会被屏蔽,不起作用。
所有的全局变量都是静态存储的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥羊也

感谢给肥羊投喂!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值