C语言笔记(4)

函数

模块化程序设计:便于维护和阅读,设计较大程序的时候,将其分为若干模块,每个模块包含一个或多个函数,每个函数实现一个特定功能。C程序由一个主函数和多个其它函数组成,主函数可以调用其他函数,其他函数也可以相互调用。以减少工作量。

函数分类

1、库函数:由C系统提供,用户无须定义,也不必在程序中作类型说明,只需在程序前包含有该函数原型的头文件即可在程序中直接调用。
2、用户定义函数:由用户按需要写的函数。对于用户自定义函数,不仅要在程序中定义函数本身,而且在主调函数模块中还必须对该被调函数进行类型说明,然后才能使用。
其他类型:有返回值和无返回值,有参函数和无参函数,字符型分类函数,转换函数,字符串函数,数学函数,日期和时间函数等。

函数定义

  1. 无参函数的定义形式:
    类型标识符 函数名()
    {声明部分
    语句
    }
    C语言笔记(4)

  2. 有参函数定义的一般形式
    类型标识符 函数名(形式参数表列)
    {声明部分
    语句
    }
    C语言笔记(4)

函数的参数和函数的值

1、 形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。
2、实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。
3、实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配”的错误。
4. 函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

函数的返回值

  1. 函数的值只能通过 return 语句返回主调函数。
    return 语句的一般形式为:
    return 表达式; 或者为: return (表达式);
    该语句的功能是计算表达式的值,并返回给主调函数。在函数中允许有多个 return语句,但每次调用只能有一个 return 语句被执行,因此只能返回一个函数值。
  2. 函数值的类型和函数定义中函数的类型应保持一致。如果两者不一致,则以函数类型为准,自动进行类型转换。
  3. 如函数值为整型,在函数定义时可以省去类型说明。
  4. 不返回函数值的函数,可以明确定义为“空类型”,类型说明符为“void”。

函数的调用

  1. 函数表达式:函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数是有返回值的。
  2. 函数语句:函数调用的一般形式加上分号即构成函数语句。例如:printf ("%d",a);scanf ("%d",&b);都是以函数语句的方式调用函数。
  3. 函数实参:函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为 实 参 进 行 传 送 ,因 此 要 求 该 函 数 必 须 是 有 返 回 值 的 。例 如 :printf("%d",max(x,y)); 即是把 max 调用的返回值又作为 printf 函数的实参来使用的。

函数声明

其一般形式为:
类型说明符 被调函数名(类型 形参,类型 形参…);
或为:
类型说明符 被调函数名(类型,类型…);

函数的嵌套调用

C语言笔记(4)执行 main 函数中调用 a 函数的语句时,即转去执行 a 函数,在 a 函数中调用 b 函数时,又转去执行 b 函数,b 函数执行完毕返回 a函数的断点继续执行,a 函数执行完毕返回 main 函数的断点继续执行。

函数的递归调用

一个函数在它的函数体内调用它自身称为递归调用。这种函数称为递归函数。C语言允许函数的递归调用。在递归调用中,主调函数又是被调数。执行递归函数将反复调用其自身,每调用一次就进入新的一层。
例如有函数 f 如下:
int f(int x)
{
int y;
z=f(y);
return z;
}
这个函数是一个递归函数。但是运行该函数将无休止地调用其自身,这当然是不正确的。为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回。
数组作为函数参数
数组可以作为函数的参数使用,进行数据传送。数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用;另一种是把数组名作为函数的形参和实参使用。C语言笔记(4)
用数组名作为函数参数时还应注意以下几点
a. 形参数组和实参数组的类型必须一致,否则将引起错误。
b. 形参数组和实参数组的长度可以不相同,因为在调用时,只传送首地址而不检查形参数组的长度。当形参数组的长度与实参数组不一致时,虽不至于出现语法错误(编译能通过),但程序执行结果将与实际不符,这是应予以注意的。
局部变量和全局变量
局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。
全局变量也称为外部变量,它是在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。 只有在函数内经过说明的全局变量才能使用。全局变量的说明符为 extern。但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。
变量的存储类别 :从变量值存在的作时间(即生存期)角度来分,可以分为静态存储方式和动态存储方式
静态存储方式:是指在程序运行期间分配固定的存储空间的方式。
动态存储方式:是在程序运行期间根据需要进行动态的分配存储空间的方式。
static 变量:变量有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,这时就应该指定局部变量为“静态局部变量”,用关键字 static 进行声明。
auto :在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。这类局部变量称为自动变量。自动变量用关键字 auto 作存储类别的声明。
register变量:为了提高效率,C 语言允许将局部变量得值放在 CPU 中的寄存器中,这种变量叫“寄存器变量”,用关键字 register 作声明。
extern外部变量:(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字 extern对该变量作“外部变量声明”。