维系C世界框架的英雄

今天是关于C语言函数的故事。我相信很多人,学习C语言的第一段代码就是:

#include <stdio.h>
int main()
{printf("Hello World!\n");return 0;
}

而从一开始,最重要的函数main(),就出现在了我们的世界。

函数是什么?

维基百科中对函数的定义:子程序

  • 在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method,subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组 成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
  • 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。

函数的分类

  1. 库函数
  2. 自定义函数

库函数

  • 库函数(Library function)是将函数封装入库,供用户使用的一种方式。方法是把一些常用到的函数编完放到一个文件里,供不同的人进行调用。调用的时候把它所在的文件名用#include<>加到里面就可以了。一般是放到lib文件里的。
  • 如我们用的输入输出函数(scanf,printf),拷贝字符串的函数(strcpy),求x的y次幂函数(pow)等等,都是我们常用的库函数。

库函数大致分类(举了下列函数类别含有的一些常见函数)

  • IO函数:printf(输出)、scanf(输入)
  • 字符串操作函数:strcmp(字符串比较)、strlen(计算字符串长度)
  • 字符操作函数:toupper(小写转大写)
  • 内存操作函数:memcpy(内存拷贝)、memset(内存初始化)
  • 时间/日期函数:time(时间)
  • 数学函数:sqrt(开平方)、pow(求x的y次幂)
  • 其他函数

我们该怎样学习库函数呢?

  1. 在日常学习C语言的过程中,我们要学会积累库函数
  2. 要学会并善于使用一些查询工具,如http://zh.cppreference.com或者www.cplusplus.com

自定义函数

自定义函数和库函数一样,有函数名,返回值和函数参数。是程序员根据需求自己定义的一种函数。

自定义函数的组成

return_type fun_name(para)
{statement;
}
//return_type   返回类型
//fun_name      函数名
//para          函数参数
//statement     语句项
例子1:(写一个函数,求两个数较大值)
#include <stdio.h>
//得到较大值函数的设计
int get_max(int x, int y)
{return (x>y)?(x):(y);
}
int main()
{int a = 10;int b = 20;//函数的调用int max = get_max(a, b);printf("max = %d\n", max);return 0;
}
//rereturn_type:    int
//fun_name:         get_max
//para:             int x,int y
//statement:        return (x>y)?(x):(y);
  • 该函数就像是你打球累了,你想去喝水,你就让你(女)朋友去帮你买瓶饮料。(女)朋友买饮料就相当于函数名,而你告诉她,你要喝的饮料名字(还有给的钱),就相当于函数参数。你女朋友去买饮料的过程就相当于函数体的语句项。而她最后把饮料给你就相当于返回类型的值,至于其他函数可能因为返回值的不同,所以函数类型就是不同的,甚至还不需要返回值,这时函数类型就是(void)
例子2:(写一个函数,打印一个直角边长为n的等腰直角三角形)
#include <stdio.h>
void print(int n)
{int i=0;for(i=0;i<n;i++){int j=0;for(j=0;j<=i;j++){printf("* ");}printf("\n");}
}
int main()
{int n = 10;print(n);return 0;
}
//rereturn_type:    void
//fun_name:         print
//para:             int n
//statement:        {int i=0...for(...)}
  • 该函数就是无返回值的函数,故函数类型就用void。而如果你不写函数类型的话,其实默认返回类型就是int,但不建议这么做。
  • 无返回值的函数就相当于你写作业一样,哦豁,你不会,你找小青蛙帮你写,但是你不要她教你方法,而是你要她帮你写,答案她就直接帮你搞定了,而不需要你自己再动笔\ (~ 、~)/

函数的参数

  • 函数的参数可以分为实际参数形式参数
  • 实参可以与形参命名一样
  • 不同函数形参的命名可以相同

实际参数(实参)

  • 真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。

形式参数(形参)

  • 形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在该函数中有效
例子3:思考下面函数是否可行(交换两个整形变量a,b的值)
#include <stdio.h>
void Swap(int x,int y)
{int tmp;tmp=x;x=y;y=tmp;
}
int main()
{int a=10;int b=20;Swap(a,b);printf("%d %d",a,b);return 0;
}
  • 其中main()函数中Swap(a,b)的a,b就是实际参数
  • void Swap(int x, int y)中的x,y就是形式参数
  • 按思路,我们将a,b的值分别传给x,y。再通过变量tmp将x,y的值交换,这样子我们就将x,y的值交换了,对吧,然后a,b的值好像完全没做改变!!!感觉跟他没有任何的关系呀!!!所以不能传值

通过比较参数的地址我们追寻原因(通过调试——窗口——监视,找到参数地址)

  • 通过上图我们知道,a,b与x,y的值没有任何联系,因为他们每个本身的地址都是不相同的。
  • 但却可以将a,b的值传递给x,y,故我们可以认为:形参实例化之后其实相当于实参的一份临时拷贝

至于我们怎样去将例3的代码修改正确呢,首先我们要们要知道什么是传值调用,什么是传址调用

函数的调用

  • 计算机编译或运行时,使用某个函数来完成相关命令。对无参函数调用时则无实际参数表。实际参数表中的参数可以是常数、变量或其它构造类型数据及表达式。各实参之间用逗号分隔。
  • 函数调用分为:传址调用传址调用
  • 函数可以实行嵌套调用,但不能嵌套定义

传值调用

  • 把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数
  • 函数的形参和实参分别占有不同内存块

大家可以参考例1,例2,以及错误的例3来理解

传址调用

  • 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
  • 这种传参方式可以让函数和函数外边的变量建立起正真的联系,也就是函数内部可以直接操作函数外部的变量

显而易见,例3是通过传值调用,故形参不能去改变形参的值。接下来,通过传址调用,修改例3

#include <stdio.h>
void Swap(int* x,int* y)
{int tmp;tmp=*x;*x=*y;*y=tmp;
}
int main()
{int a=10;int b=20;Swap(&a,&b);printf("%d %d",a,b);return 0;
}
  • 改变1:将Swap中a,b的值,改成其地址,即是将地址传给形参
  • 改变2:函数形参改用指针来接收实参传来的地址
  • 改变3:函数体的语句通过指针来将*x , *y的值交换

我们继续通过地址追寻这其中的不同 (通过调试——窗口——监视,找到参数地址)

因为指针变量x,y分别存放着a,b的地址,故解引用时,其实是将指针变量x,y地址存放的值互相交换。虽然a,b变量的地址没有改变,但是其地址存放的值发生了交换。故a,b发生交换。

结语

函数的故事还为结束,下一章C世界函数的故事(2)我们将继续深入了解函数,如果你喜欢我讲的故事,可以点赞,收藏,关注我哦!!!

【C 语言基础】C 世界函数的故事(1)相关推荐

  1. 【C 语言基础】C 世界函数的故事,今天带你详细了解各组件原理

    printf("Hello World!\n"); return 0; } 而从一开始,最重要的函数main(),就出现在了我们的世界. 函数是什么? 维基百科中对函数的定义:子程 ...

  2. R语言基础(1)-帮助函数|工作空间|IO|模块安装

    本文简要梳理R语言的帮助函数.工作空间.IO.模块安装等基础知识. 目录 1.R中帮助函数 打开R帮助文档首页 查看

  3. C语言基础之--scanf函数

    写代码的时候,我们可以看得出,几乎每一个C程序都会包括输入输出.输入输出是程序中最基本的操作之一.C语言本身并不提供输入输出的语句,输入输出操作是由C标准函数库中的函数来实现的.今天就先说说输入:sc ...

  4. GO语言基础map与函数

    1. map 1. 类似其它语言中的哈希表活着字典,以 key-value 形式存储数据 2. key 必须是支持 == 或 != 比较运算的类型,不可以是函数.map 或 slice 3. map ...

  5. Python程序设计语言基础05:函数和代码复用

    目录 1. 函数的定义与使用 1.1 函数的理解和定义 1.1.1 函数的理解 1.1.2 函数的定义 1.2 函数的使用及调用过程 1.3 函数的参数传递 1.3.1 无参数传递 1.3.2 可选参 ...

  6. C语言基础教程之函数

    C 函数 函数是一组一起执行一个任务的语句.每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数. 您可以把代码划分到不同的函数中.如何划分代码到不同的函数 ...

  7. c语言string函数的用法_C语言基础| 指针和函数

    点击蓝字关注我们 指针和函数 栈帧:当函数被调用时,系统会在stack空间上申请一块内存,用来给函数提供空间,存储形参和局部变量(定义在函数内部的变量). 当函数调用结束时,这块内存空间会被自动释放( ...

  8. C语言基础(三):函数名、函数指针、指针函数的理解

    函数指针 如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址.而且函数名表示的就是这个地址.既然是地址我们就可以定义一个指针变量来存 ...

  9. 【C语言基础】printf函数

    一.printf函数 1.printf函数被设计用来显示格式串的内容,并且在该格式串中的指定位置插入可能的值. printf函数的一般形式为: printf(格式串,表达式1,表达式2,...): 格 ...

最新文章

  1. Unity中创建本地多人游戏完整案例视频教程 Learn To Create A Local Multiplayer Game In Unity
  2. 天才少年何恺明:高考状元的开挂人生
  3. C#中的信号量---Semaphore
  4. java扫描指定package注解_java获取包下被指定注解的类
  5. 27. 移除元素 golang
  6. pycharm 运行后,如何查看变量值以及继续输入语句并运行?(非Debug , debug太慢)
  7. php求平均值的函数_最全计算机二级函数关键知识点汇总整理!
  8. 强烈的公帑意识让香港人盯紧官员的公款支出
  9. 信息学奥赛一本通1001-1005
  10. python题目-奇偶数调用函数
  11. 互联网日报 | 贾跃亭宣布破产重组完成;小米发布首款OLED电视;湖南迎来首家本土航空公司...
  12. [转]河北省生源地助学贷款流程及注意事项
  13. 基于Web的个人网页响应式页面设计与实现 HTML+CSS+JavaScript(web前端网页制作课作业)
  14. Python Crash Course读书笔记 - 第18章:GETTING STARTED WITH DJANGO
  15. Networkx如何画点图并显示边权
  16. gitee基本使用方法(Tortoisegit)
  17. html 醒目的样式,创意醒目门牌设计欣赏
  18. 社交电商的现状以及它的四种商业模式
  19. 设置局域网NTP对时
  20. 【C++】类的6个默认成员函数详解

热门文章

  1. 比百度地图.api更方便的测量面积方法
  2. Java的 Class字节码文件结构和内容全面解析【两万字】
  3. 【听】你会杀死那个胖子吗?功利与道德的选择
  4. Hibernate与JPA
  5. Richard Hamming “You and your research“演讲正文
  6. Qt 按钮控件虚线框
  7. 侏罗纪世界手游显示无法登陆到服务器,侏罗纪世界手游闪退怎么办 游戏闪退解决方法...
  8. Pycharm提示方法Method xxx may be 'static'
  9. MediaPlayer( 媒体播放器),TelephonyManager(电话管理类),MediaRecorder(媒体录音机)
  10. python分析就业率_Python就业行情和前景分析之一