嵌入式-----c语言学习(3)函数

目录

1.函数:

1.函数的三种形式:

        1.函数的定义:

        2.函数的调用:

        3.函数的声明:

    2.变量的作用域和生存周期:

        1.作用域:

            1.局部变量:

            2.全局变量:

          2.生存周期:

     3.变量的存储类型:

                1.自动型存储(局部存储)(默认存储类型)

                2.静态存储

                3.寄存器存储:

                  4.外部存储:

       

        4.函数传参:

            1.值传递:

            2.全局变量传递:

            3.整形数组的传递:

                4.注意:

        5.递归函数

6.预处理命令:

1.宏定义:

    1.不带参宏

    2.带参宏(宏函数)

2.头文件包含

3.条件编译:


1.函数:


     1.能够让程序模块化
     2.可以减少重复性代码

   

1.函数的三种形式:


        1.函数的定义:


            函数类型  函数名(数据类型1 形参1, 数据类型2 形参2, ...)
            {
                函数体;

                return 返回值;
            }

            函数名:和变量名要求保持一致
            函数类型:函数运行结果的类型(如果返回值类型与函数类型不一致,会将返回值强制类型                              转换成函数类型返回) 
                     不写函数类型默认为int类型
                     如果没有返回值,函数类型应该为void类型 
            返回值:函数的运行结果
            形参:形式参数(做个样子)

            注意:
                函数没有返回值,return后面什么都不写

        2.函数的调用:


            函数名(实参1, 实参2, ...);

            注意:
                1.实参个数必须与形参个数一致,并一一对应
                2.实参可以是常量、变量、表达式
                3.实参与形参类型不一致时,会将实参强制类型转换为形参类型,传入函数中
                4.函数调用时会发生传参的过程(实参将值传递给形参)

        3.函数的声明:


            声明和定义的区别:
                1.声明:声明一个已经存在的变量或函数
                2.定义:定义一个之前不存在的变量或函数,需要开辟新的空间

            注意:
                被调函数在主调函数下方定义,需要声明该函数

    2.变量的作用域和生存周期:


        1.作用域:


            变量能够使用的范围

            1.局部变量:


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


            2.全局变量:


                全局变量作用域在整个文件中

          2.生存周期:


            变量从开始被创建,到空间被回收的整个过程 

     3.变量的存储类型:


                存储类型 数据类型 数组名;
                int a;

                1.自动型存储(局部存储)(默认存储类型)


                    auto 

                    auto int a;
                    int a;

                    将变量存放到栈区中:
                        1.未经初始化值为随机值
                        2.代码执行到变量定义时为变量开辟空间
                        3.超过变量的作用域回收变量空间

                2.静态存储


                    static 

                    static int a;
                    
                    将变量存放到数据区中:
                        1.未经初始化前值为0值
                        2.编译时为变量开辟空间
                        3.代码执行结束回收变量空间

                    除了修饰静态变量,还有2个功能:
                        1.限定变量的作用域只能在本文件中使用
                        2.可以防止多个文件中的全局变量重名

                3.寄存器存储:


                    register 

                    register int a;

                    优先存放到CPU内部的寄存器中,如果寄存器存满了,等价于auto存放在栈区中
                


                  4.外部存储:


                    extern

                    extern int a;

                    声明一个变量或函数是在外部存储的

       


作业:
    1.封装三个函数
        函数1:封装函数实现传入一个年份,判断该年为闰年还是平年?
        int IsLeepYear(int year);
        函数2:封装函数实现传入年、月、日,获得该天是该年的第几天?
        int GetDayOfYear(int year, int month, int day);
        函数3:封装函数实现传入年、月、日,获得该年剩余多少天?
        int GetLeftDayOfYear(int year, int month, int day);
    
    2.封装一个函数,给定一个数,判断该数是否为素数
        int IsPrimeNum(int num);

        4.函数传参:


            1.值传递:


                实参将值传递给形参,形参是实参的副本,对形参做的操作,实参不会受影响

                函数体内部想使用函数体外部变量值的时候可以使用值传递 
                函数体内想修改函数体外部变量的时候不能使用值传递

            2.全局变量传递:

            3.整形数组的传递:


                int a[5];

                1.形式1:
                    int fun(int array[5]);
                2.形式2:
                    int fun(int array[], int len);

                在调用函数的时候数组不能写  [  ],如  int fun (array);直接写数组名即可。

                4.注意:


            1.形式1只能操作5个元素的数组,形式2可以操作不同类型长度的数组
            2.函数体内部的数组会随函数结束被回收,如果后续还想操作该数组必须在外部定义传到函                      数中
            3.数组传递中,形参操作和实参操作的是同一个数组

        练习:封装三个函数实现对数组的操作:
        int InputArray(int array[], int len);
        int BubbleSortArray(int array[], int len);
        int OutputArray(int array[], int len);

            4.字符型数组和字符串的传递
                char str[32] = {"hello world"};
                int fun(char str[]);

    练习:封装一个函数实现strlen的功能
        int MyStrlen(char str[]);
    封装一个函数实现strcpy的功能
        int MyStrcpy(char dst[], char src[]);       

        5.递归函数

 
            1.函数定义时调用函数本身
        注意:
            1.递归一定要有结束条件
            2.避免深层次的递归

练习:封装一个函数获得斐波那契数列的第n项的值(使用递归实现)
        1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 ..

        int Fun(int n);

6.预处理命令:


1.宏定义:


    #define

    只是代码的替换

    1.不带参宏


        #define PI  3.1415926 
        #define M   50


    2.带参宏(宏函数)


        带参宏与函数的区别:
            1.函数有参数类型、返回值、传参的概念
            2.带参宏没有参数类型、返回值、传参的概念
            3.带参宏是在程序编译阶段加载到程序中 
                带参宏可能改变运算符的优先级,记得加括号
            4.函数是在程序运行阶段加载到程序中
            5.带参宏会使代码体积增大
            6.函数不会使代码体积增大    
            7.带参宏执行效率高
            8.函数执行效率低 

2.头文件包含


    #include <stdio.h>
    在预处理阶段将stdio.h头文件展开到文件中

    在/usr/include目录下查找stdio.h 

    #include "stdio.h"
    在当前目录下查找stdio.h,如果当前目录找不到则在系统目录/usr/include目录下查找头文件

    头文件以.h结尾:
        1.头文件中存放宏定义 
        2.头文件中存放声明的全局变量和全局函数
        3.头文件中存放自定义的数据类型 

    项目工程根据功能划分成不同的文件
        jisuanqi ------- main.c         主函数的实现
                    |--- add.h          add.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明 
                    |--- add.c          加法相关的函数接口的实现
                    |--- sub.h          sub.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明 
                    |--- sub.c          减法相关的函数接口的实现
                    |--- mul.h          mul.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明 
                    |--- mul.c          乘法相关的函数接口的实现
                    |--- div.h          div.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明 
                    |--- div.c          除法相关的函数接口的实现

    
    jisuanqi--------src ----- main.c         主函数的实现  
                |            |--- add.c          加法相关的函数接口的实现
                |            |--- sub.c          减法相关的函数接口的实现             
                |            |--- mul.c          乘法相关的函数接口的实现            
                |            |--- div.c          除法相关的函数接口的实现
                |
                |----include ---- add.h          add.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明     
                            |--- sub.h          sub.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明 
                            |--- mul.h          mul.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明 
                            |--- div.h          div.c中用到的数据类型的定义、宏定义、全局变量的声明、全局函数的声明

3.条件编译:

        #if   0
        #elif   0
        #endif 

        #ifndef   宏名   
        如果没有定义后面的宏则将后续代码加入编译中
        #ifdef      宏名   
        如果定义后面的宏则将代码加入编译中

        head.h

        #ifndef __HEAD_H__
        #define __HEAD_H__

        #endif


    
作业:
1.封装一个函数实现strlen的功能
    int MyStrlen(char str[]);
  封装一个函数实现strcpy的功能 
    int MyStrcpy(char dst[], char src[]);
  封装一个函数实现strcat的功能
    int MyStrcat(char str1[], char str2[]);
  封装一个函数实现strcmp的功能
    int MyStrcmp(char str1[], char str2[]);

2.封装一个函数获得两个数的最大公约数
  封装一个函数获得两个数的最小公倍数

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值