c语言(8)—函数(2)

一、变量的作用域和生存周期

1.作用域:能够使用变量的范围称为变量的作用域

(1)局部变量:变量作用域在离定义该变量最近的大括号内

(2)全局变量:变量作用域在整个工程代码中,任意位置都可以使用全局变量

2. 生存周期:变量从开辟空间到空间被回收的过程称为生存周期

(1)局部变量:执行到变量定义时,为变量开辟内存空间;代码执行超过变量作用域,回收变量空间

(2)全局变量:编译时分配全局变量空间,代码运行结束后回收变量空间

e.g.封装减法、乘法、除法函数实现从终端接收2个数,调用函数获得四则运算结果并打印

思路:现在前面定义四个加减乘除的函数,并在主调函数中调用被调函数来实现

#include <stdio.h>                                                                           

int Add(int x, int y)
{
    int s = 0;

    s = x + y;
  
    return s;
}

int Sub(int x, int y)
{
    int j = 0;
    
    j = x - y;
 
    return j;
}

int Mul(int x, int y)
{
    int i = 0;
 
    i = x * y;

    return i;
}
 
int Div(int x,int y)
{
    int c = 0;

    c = x / y;

    return c;
}

int main(void)
{
    int num1 = 100;
    int num2 = 200;
    int ret1 = 0;
    int ret2 = 0;
    int ret3 = 0;
    int ret4 = 0;

    ret1 = Add(num1, num2);
    ret2 = Sub(num1, num2);
    ret3 = Mul(num1, num2);
    ret4 = Div(num1, num2);

    printf("ret1 = %d\nret2 = %d\nret3 = %d\nret4 = %d\n", ret1, ret2, ret3, ret4);

        return 0;
}  

3. 存储类型

存储类型 数据类型 变量名;

auto(默认):自动型存储,将变量存放在栈空间中

register:寄存器存储,将变量存放在CPU内部的寄存器中

extern:声明一个变量是外部存放的

static:静态存储,将变量存放在静态区中

4.运行代码的空间分配

内存如图所示

文本段:存放函数、代码和指令

栈区:存放局部变量(auto)

栈区空间有上限的,默认(8M),不要定义太大空间,未经初始化值为0值

代码执行到变量定义时开辟空间(栈空间),代码执行超过变量作用域回收空间(栈空
间)

数据区:

(1)存放全局变量和静态变量,未经初始化时会初始化为0值,程序编译时分配空间,程序结束时回收空间

(2)区域划分:

①已初始化全局变量/静态变量区域(.data):存放初始化的全局变量和静态变量

②未初始化全局变量/静态变量区域(.bss):存放未初始化的全局变量和静态变量,在程序运行时会对.bss端初始化为0值

③字符串常量区(.rodata):区域中的内容不能修改,修改的话会导致段错误

5.static:

(1)延长变量的生存周期,在程序结束时回收空间

(2) static修饰变量,未经初始化时值为0值

(3)static限定全局变量作用域只能在本文件中使用

(4) static防止全局变量或者全局函数重名

二、函数的调用

1.实参个数与形参个数需要匹配,实参与形参类型不一致时,会将实参类型转换为形参类型

2.函数调用时参数的传递:函数调用时实参会将值传递给形参

e.g.封装一个函数传入一个年份,判断该年是否为闰年

思路:先在前面定义一个函数,这个函数中如果满足闰年条件(能被4整除且不是100的倍数或是400的倍数)就返回1,否则返回0,在主调函数中调用前面定义的函数,利用if语句输出接收的数字是否为闰年

#include <stdio.h>
  
int IsLeepYear(int tmpyear)
{
    if ((0 == tmpyear % 4 && 0 != tmpyear % 100) || 0 == tmpyear % 400)
    {
        return 1;
    }

    return 0;
}

int main(void)
{
    int y = 0;
    int ret = 0;

    scanf("%d",&y);

    ret = IsLeepYear(y);
 
    if (ret)
    {
        printf("%d为闰年\n", y);
    }
    else
    {
        printf("%d为平年\n", y);
    }
                                                                                                                                                                                   
    return 0;
}

三、递归函数

1.函数体定义时调用函数体本身称为递归函数

2.递归函数一定要有结束条件,避免深层次的递归调用

e.g.利用递归函数实现阶乘运算

思路:利用n!=n*(n-1)!来不断调用函数本身来定义被调函数,在主调函数中调用被调函数来完成计算

#include <stdio.h>

int fun(int num)
{
    if(1 == num)
    {
        return 1;
    }
    else
    {
        return num * fun(num - 1);
    }
}
 
int main(void)
{
   int n = 0;
    int ret = 0;
 
    scanf("%d", &n);

    ret = fun(n);
    printf("ret = %d\n", ret);                                                                                                                                                     

    return 0;
}

四、函数传参

值传递: 实参将值传递给形参,形参是实参的副本;形参改变,实参不会发生改变

               应用场景:函数体内部想使用函数体外部变量值的时候,使用值传递

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值