zoukankan      html  css  js  c++  java
  • C语言的函数

    "函数"在英文的翻译是"function",无论在自然科学还是计算机科学都是这个词,而"function"的本意是"功能",可能是在汉语的习惯中,"这是一个函数"比"这是一个功能"听起来更专业,更正常一点,所以才使用了这个翻译。但是,如果把"function"或者"函数"理解为"功能"将为对这个词的理解提供很大帮助。 So,何为“功能”? “功能”其实就是"来料加工,需要的话再输出",这里面有三个部分,一个是"来料",一个是"加工",一个是"输出",比如,肝脏的功能就是将"来"的有毒物质进行"加工"成无毒的物质再"输出"。热水器的功能就是将"来"的冷水"加工"成热水。
    C语言函数驱动的语言,所有的功能都被封装在一个个函数中,也就是一个个"功能"中。比如,main()函数是所有C语言程序的入口函数,所有的C的功能必须直接或间接通过main()来调用。再比如,ANSI C的标准事先封装好了很多常用的函数,你可以直接拿来用。但就像公司会给你配一台电脑用来工作,而你一定要台屏幕30寸还能随身携带的笔记本,那很无奈,你得自己造一个。在实际编程中,不幸的是这种自己造笔记本的情况再普通不过,幸运的是,造这样一台满足你需要的笔记本再简单不过。
    C语言的函数分为四种:main函数标准库函数STL系统调用SCI,和自定义函数。这里说的就是自定义函数。

    定义

    返回值类型 函数名(形参列表){
        函数体
    }
    

    在这个定义中,形参列表即函数的"输入",函数体即函数的"加工过程",返回值类型即函数的"输出",函数名即这个函数的标识符。

    形式参数

    "形式参数",即"不存在的参数",它只是让你在写函数体的时候一个标识符来表示你要处理的对象,编译器不会给形式参数的分配内存,形式参数可以没有,此时最好写void关键字。
    无论是传入参数"值"还是传入"地址",调用函数的时候都会把相应的参数在被调用函数的栈中复制一份,只是"值"并不能唯一的标识内存中的变量,但"地址"可以,所以只要"地址"指向的内容还没有被释放,就可以通过"地址"在正确的读取相应的变量。所以以"地址"的形式传入参数可以将参数从函数内部带出来,因为"地址"是内存唯一的(参见 返回地址)。

    函数体

    我们的所有的"加工"过程都在这里,如果函数需要返回值,需要return关键字

    函数名

    即函数的标识符,本质是函数的指针

    返回值

    函数处理结束后需要传出的数据,可以没有,此时需要写void关键字,

    //举个栗子,实现对传入的两个参数的作和,
    int sum(int x,int y){
        return x+y;
    }
    

    返回地址

    返回一个变量的地址有5种方法,但绝没有返回栈区局部变量的指针,因为栈区局部变量在函数执行完毕后就随着函数栈一起被销毁了,指针指向的内容是不确定的

    1. 返回全局变量的指针
    int x;
    int* fcn(){
            return &x;
    } 
    
    1. 使用静态变量的指针
    int* fcn(){
            static int x=5;
            return &x;
    }
    
    1. 返回传入参数的指针
    int* fcn(int x){
            return &x;
    }
    
    1. 不返回任何指针,将目标当作参数传入
    void fcn(int arg, int* result){
            result = &arg;
    }
    
    1. 返回指向堆区的指针
    int* fcn(){
            int* ptr=(int*)malloc(sizeof(int));
            return ptr;
    }
    

    声明

    如果一个函数在调用前没有定义,那么需要专门的声明语句

    返回值类型 函数名(形参类型列表);
    

    调用

    函数名(实参列表);
    

    函数的调用就是"使用"一个函数,就是把我们要处理的数据传入到函数中

    //栗子
    int x=1,y=2,z=0;
    z=sum(x,y);
    

    函数指针

    即指向函数的指针,

    定义

    返回值类型 (*函数名)(形参类型列表);
    

    程序很简单的时候,不写形参类型列表也会编译通过,但这是错误的,一旦程序略大,就会出错。

    //定义一个函数指针并初始化
    int add(int a, int b){
        return a+b;
    }
    int (*pAdd)(int, int)=add;
    
    //定义一个函数指针数组,并初始化
    int add(int a, int b){
        return a+b;
    }
    int sub(int a,int b){
        return a-b;
    }
    
    int (*pAS[2])(int, int)={add,sub};
    //pAS[0]=add;
    //pAS[1]=sub;
    

    回调函数

    即利用函数指针将一个函数当作参数进行调用

    //定义一个回调函数
    int calc(int (*fcn)(int ,int ), int a, int b){
        return fcn(a,b)
    }
    //调用一个回调函数
    calc(padd,12,342);
    calc(psub,12,123);
    
  • 相关阅读:
    MyEclipse10.7 10.6导出war文件报错 “SECURITY ALERT: INTEGERITY CHECK ERROR”
    基于ssh框架的highcharts前后台数据交互实例
    java自定义注解知识实例及SSH框架下,拦截器中无法获得java注解属性值的问题
    新特性:postgresql的vacuum漫谈
    postgresql vacuum操作
    __declspec(dllexport) 的意思与DEF导出函数的区别(转)
    一个睡五分钟等于六个钟头的方法(转)
    【转】应届毕业生要知道的几个小东西,,三方协议,,报到证,,干部身份
    测试word客户端发布Blog
    66句震撼人心的禅语(转)
  • 原文地址:https://www.cnblogs.com/xiaojiang1025/p/5881265.html
Copyright © 2011-2022 走看看