C primer plus(学习笔记)—— 第九章 函数

目录

9.1 复习函数

9.1.1 创建并使用简单函数

9.1.2 分析程序 

9.1.3 函数参数

9.1.4 定义带形式参数的函数

9.1.5 声明带形式参数函数的原型

9.1.6 调用带实际参数的函数

实参和形参运用过程

9.1.7 黑盒视角

9.1.8 使用return从函数中返回值

9.1.9 函数类型

9.2 ANSI C函数原型

9.2.1 问题所在

9.2.2ANSI的解决方案

9.2.3 无参数和未指定参数

9.2.4 函数原型的优点

9.3 递归(略)

9.3.1 演示递归

9.3.2 递归的基本原理

9.3.3 尾递归

相对于循环递归的缺点

9.3.4 递归和倒序计算

9.3.5 递归的优缺点

9.4 编译多源代码文件的程序(略)(程序待复现)        

9.5 查找地址:&运算符

9.6更改主调函数中的变量

9.7 指针简介

9.7.1 间接运算符:*

9.7.2 声明指针

9.7.3 使用指针在函数间通信


9.1 复习函数


函数(function)是完成特定任务的独立代码单元。

函数让程序更加模块化,提高代码可读性,方便修改。

9.1.1 创建并使用简单函数

函数原型指明了函数的返回值类型和函数接受的参数类型。这些信息称为该函数的签名(signature)

/*letheadl.c*/
#include <stdio.h>
#define NAME "GIGATHINK,INC."
#define ADDRESS "101 Megabuck Plaza"
#define PLACE "Megapolis,CA 94904"
#define WIDTH 40

void starbar(void);

int main(void){
    starbar();
    printf("%s\n",NAME);
    printf("%s\n",ADDRESS);
    printf("%s\n",PLACE);
    starbar();

    return 0;
}

void starbar(void){
    int count;
    for(count= 1;count<=WIDTH;count++)
        putchar('*');
    putchar('\n');
}

9.1.2 分析程序 

  • 程序在3处使用了starbar标识符:函数原型(是函数的声明,它告诉编译器函数的名称、参数类型和返回值类型),函数调用(是在程序中使用函数的过程。当程序需要执行某个特定的任务时,可以调用相应的函数。),函数定义(是实现函数功能的具体代码。它包含函数的名称、参数列表和函数体。)
  • 函数的原型指明了函数的返回值和函数接受的参数类型,这些信息被称为该函数的签名
  • 程序中的starbar()和main()的定义形式相同,首先包含了函数头包括函数类型和函数名和圆括号

9.1.3 函数参数

9.1.4 定义带形式参数的函数

ANSI C风格的函数头:

void show_n_char(char ch, int num)

改行告知编译器本函数具有两个参数ch和num,类型分别是char和int。这两个参数被称为形式参数(formal parameter),简称形参。形式参数是局部变量。

注意每个变量前都要声明其类型,不能写成这样:void dibs(int x, y, z)

9.1.5 声明带形式参数函数的原型

函数原型一般是下面这种形式:

void show_n_char(char ch, int num)

也可以省略变量名:

void show_n_char(char,  num)

PS:在原型中使用变量名并没有实际创建变量,char仅代表一个char类型的变量

9.1.6 调用带实际参数的函数

函数调用中,实际参数(actual argument,简称实参)提供了ch和num的值。

show_n_char(SPACE,12)

调用时实参的值(SPACE,12)赋值给函数中相应的形式参数(ch,num)。

实参和形参运用过程

        实参是出现在函数调用圆括号中的表达式,形参是函数定义的函数头中声明的变量,调用函数时,创建了声明为形参的变量并初始化为实参的求值结果

9.1.7 黑盒视角

        基本内容概括为形参和实参的局部和全局区别(局部变量和全局变量的说明,简单略)

9.1.8 使用return从函数中返回值

这里告诉我们一个定义,对于被设计用于测试函数的程序有时被称为驱动程序

return 的用法除了返回值外,还可用与终止函数

return;

这条语句会导致终止函数,并把控制权还给主调函数,因为return后面没有任何表达式,所以没有返回值,只有在void函数中才会用到这种形式

9.1.9 函数类型

声明函数时必须声明函数的类型,带返回值的函数类型和其返回值类型相同,

不带返回值的函数应该声明为void类型。

9.2 ANSI C函数原型

int imin();

之前的声明会出现问题没有给出imin()函数的参数个数和类型,当调用它时使用参数个数不对或类型不匹配,编译器根本不会察觉出来

9.2.1 问题所在

//misuse.c--错误地使用函数
#include <stdio.h>
int imax();

int main(void){
    printf("The maximum of %d and %d is %d\n",3,5,imax(3));
    printf("The maximum of %d and %d is %d\n",3,5,imax(3.0,5.0));
}

int imax(n,m)
int n,m;{
    return (n>m?n:m);
}

 主调函数把它的参数存储在被称为栈的临时存储区,被调函数从栈中读取这些参数

9.2.2ANSI的解决方案

针对参数不匹配的问题,ANSI C要求函数声明时还要声明变量的类型,即 使用函数原型来声明函数的返回类型、参数的数量和每个参数的类型。有了这些信息,编译器可以检查函数调用是否和函数原型匹配。

9.2.3 无参数和未指定参数

为了表明函数没有参数,应该在圆括号内使用void

void print_name(void);

一些函数接受许多参数,ANSI C允许使用部分原型:

int printf(const char *, ...)

表明第一个参数是字符串,可能还有其他参数。

9.2.4 函数原型的优点

让编译器在第1次执行到该函数前就知道如何使用它。

将整个函数定义放在第1次调用该函数之前,也有同样的效果。

此时,函数定义也相当于函数原型。

9.3 递归(略)


C允许函数调用自己,这种调用称为递归(recursion)。

9.3.1 演示递归

PS:每次递归的变量n都属于本级递归私有

9.3.2 递归的基本原理

  1. 每级的函数调用都有自己的变量
  2. 每次函数调用都会返回一次
  3. 递归函数中位于递归调用之前的语句,均按被调用函数的顺序执行
  4. 递归函数中位于递归调用之后的语句,均按被调函数相反的顺序执行
  5. 虽然每级递归都有自己的变量,但是并没有拷贝函数的代码1
  6. 递归函数必须包含能让递归调用停止的语句

9.3.3 尾递归

最简单的递归形式是把递归调用置于函数的末尾,即return之前。这种形式的递归称为尾递归。

相对于循环递归的缺点

  1. 每次递归都会创建一组变量,所以递归使用的内存更多,而且每次递归调用都会把创建的一组新变量放在栈中。递归调用的数量受限于内存空间。
  2. 由于每次函数调用要花费一定的时间,所以递归的执行速度较慢

9.3.4 递归和倒序计算

9.3.5 递归的优缺点

优点:

        递归为某些编程问题提供了最简单的解决方案

缺点:

        是一些递归算法会快速消耗计算机的内存资源

9.4 编译多源代码文件的程序(略)(程序待复现)
        

在这个代码演示中,scanf("%*s")跳至下一个空白字符处(在本段代码里表示跳过第一个字符串)

9.5 查找地址:&运算符


指针(pointer)是C语言最重要的概念之一,用于存储变量的地址。

&运算符给出变量的地址,pooh是变量,&pooh就是变量pooh的地址。

PS:PC地址通常用十六进制形式表示

        %p是输出地址的转换说明

9.6更改主调函数中的变量


9.7 指针简介


指针(pointer)是一个值为内存地址的变量。

9.7.1 间接运算符:*

假设ptr指向bah:

ptr = &bah;

使用简介运算符* 可以找出bah中的值

val = *ptr;

9.7.2 声明指针

声明指针变量时必须指定指针所指向变量的类型,因为不同的变量类型占用不同的存储空间。

下面是一些指针的声明:

int * pi; //pi 是指向int变量的指针

float * pf, *pg

9.7.3 使用指针在函数间通信

使用指针的函数

void interchange(int * u, int * v)

调用:interchange(&a,&b);

当被调用时;该函数传递的不是a b 的值,而是它们的地址,这意味着出现在interchange()原型和定义中的形参u v 将把地址作为它们的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值