认清函数的真面目

本文深入探讨C语言中的函数概念,包括函数的定义与声明、参数传递方式、递归及模块化编程等内容,并解析顺序点对变量修改的影响。

函数(C语言的核心)

专题六:函数(C语言的核心)。包括以下章节:

  • 认清函数的真面目
  • 可变参数列表
  • 李逵和李鬼
  • 函数调用行为
  • 函数递归详解
  • 函数设计技巧

C语言中的函数

函数的由来

这里写图片描述

函数的意义

1、模块化程序设计

这里写图片描述

2、C语言中的模块化

这里写图片描述

面向过程的程序设计

  1. 面向过程是一种以过程为中心的编程思想
  2. 首先将复杂的问题分解为一个个容易解决的问题
  3. 分解过后的问题可以按照步骤一步步完成
  4. 函数是面向过程在C语言中的体现
  5. 解决问题的每个步骤可以用函数来实现

声明和定义

  1. 程序中的声明可理解为预先告诉编译器实体的存 在,如:变量,函数,等等//声明
  2. 程序中的定义明确指示编译器实体的意义//实现

实例分析1-1

1-1.c

// global.c
// int g_var = 0;

#include <stdio.h>

//声明文件外部的变量
extern int g_var;
//声明函数
void f(int i, int j);

int main()
{
    //在函数中可以声明变量g_var,g_var仍是一个全局变量
    //但g_var只能在main函数中起作用,其他地方不起作用
    //extern int g_var;

    //声明g函数
    int g(int x);
    //编译器编译到此处不会报错,因为已经声明了该变量
    //但是如果没有定义该变量,在运行时会使程序崩溃
    //声明只是让编译通过,具体运行必须定义。
    g_var = 10;

    f(1, 2);

    printf("%d\n", g(3));

    return 0;
}
//定义函数(实现函数)
void f(int i, int j)
{
    //在此处可以直接调用g函数,不需要声明
    //如果调用函数文件外部的函数,也不是必需声明的;但变量必须先声明
    g(5);
    printf("i + j = %d\n", i + j);
}

 //定义g函数
int g(int x)
{
    return 2 * x + g_var;
}

函数参数

1、函数参数在本质上与局部变量相同,都是在栈上分配空间
这里写图片描述
2、函数参数的初始值是函数调用时的实参值

1-2.c

#include <stdio.h>

int f(int i, int j)
{
    printf("%d, %d\n", i, j);
}

int main()
{
    int k = 1;

    //顺序点");"
    //1,传入k
    //2,传入个k++:记录,有一次操作,k自增1,但不立即生效
    //3,到顺序点";"后,发现记录有一个操作k自增1,所以k自增1次,k = 2, 而k++在传入是就完成=1
    //所以传入的函数内部后,参数为(2,1)
    f(k, k++);

    printf("%d\n", k);

    return 0;
}

结果:
这里写图片描述
3、函数参数的求值顺序依赖于编译器的实现!!!
C语言中大多数运算符对其操作数求值的顺序都是依赖于编译器的实现的 !!!
int i = f()*g():
编译器可以先计算f(),也可以先计算g()。不同的编译器实现不同

程序中的顺序点!

  1. 程序中存在一定的顺序点
  2. 顺序点指的是执行过程中修改变量值的最晚时刻
  3. 在程序达到顺序点的时候,之前所做的一切操作必须反映到后续的访问中

C语言中的顺序点

  1. 每个完整表达式结束时
  2. &&, ||, ?:, 以及逗号表达式的每个运算对象计算之后
  3. 函数调用中对所有实际参数的求值完成之后(进入函数体之前)

1-3.c

#include <stdio.h>

int main()
{
    int k = 2;
    int a = 1;

    //";"是顺序点
    //1,第一个k++:记录,有一个操作,k自增1,但没有生效
    //2,第二个k++:记录,有一个操作,k自增1,但没有生效
    //3,k = 4;
    //4,到顺序点";"后,发现记录有两个操作k自增1,所以k自增两次,k = 6.

    //++k立即完成操作,不会到顺序点再完成操作

    //不要这么写:这是一个盲点,不容易读,易出错;但要明白有这个知识点
    k = k++ + k++;

    printf("k = %d\n", k);

    //"&&"是顺序点
    //1,a--:记录,有一个操作,a自减1,但没有立即生效
    //2,a = 1
    //3,到顺序点"&&"后,发现记录有一个操作,a自减1,立即a=0,然后跳出了if条件表达式
    if( a-- && a )
    {
        printf("a = %d\n", a);
    }

    return 0;
}

结果:
这里写图片描述

函数的缺省认定

  1. C语言会默认没有类型的函数参数为int
  2. 不鼓励这么写。这是为了兼容旧版本C

这里写图片描述

小结

  1. C语言是一种面向过程的语言
  2. 函数可理解为解决问题的步骤
  3. 函数的实参并没有固定的计算次序
  4. 顺序点是C语言中变量改变的最晚时机
  5. 函数定义时参数和返回值的缺省类型为int
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值