函数调用过程中通常伴随着两个函数之间的数据传递.数据传递存在两个完全相反的方向(可以从调用函数,向被调用函数传递数据也可以从被调用函数向,调用函数传递数据),任意方向的数据传递都使用被调用函数提供的存储区

/*
* 返回值练习
* */
#include <stdio.h>
int yue(void) {
int min = 0, max = 0, tmp = 0;
printf("请输入两个数字:");
scanf("%d%d", &max, &min);
while (max % min) {
tmp = max % min;
max = min;
min = tmp;
}
return min;
}
int main() {
int num = yue();
printf("最大公约数是%d\n", num);
return 0;
}

只能从被调用函数向调用函数传递一个数字,这个数字叫做被调用函数的返回值,只能在被调用函数结束的时候才能传递返回值.返回值需要记录在被调用函数提供的一个存储区里,需要把这个存储区的类型名称写在函数名称前,被调用函数里使用return关键字把返回值记录到这个存储区里.调用函数里把函数调用语句当作数字使用就可以得到函数的返回值

如果被调用函数里没有使用return关键字指定返回值,则函数的返回值是随机的.调用函数只有一次获得返回值的机会,得到返回值以后必须立刻使用或者存储到其他存储区里.如果函数不提供用来存放返回值的存储区就应该在函数名称前写void.如果函数名称前什么都没写在c89规范里表示函数提供一个整数类型存储区用来存放返回值,在C99规范里不允许这样

被调用函数不可以使用数组记录返回值

可以从调用函数向被调用函数传递多个数据,这些数据的类型可以不同,被调用函数需要为每个数据提供一个对应的存储区,在函数名称后的小括号里声明一组变量,这些变量用来代表前面提到的存储区,这些变量叫做函数的形式参数,小括号里的所有内容叫做形式参数列表,每个形式参数的类型名称都不可以省略,相邻形式参数声明之间用逗号分开,被调用函数里可以象使用变量一样使用形式参数

使用带参数的函数时需要在函数调用语句的小括号里为每个形式参数提供一个对应的数字。计算机把这些数字记录到对应的形式参数存储区里,被调用函数可以通过形式参数得到这些数字.这些数字叫做实际参数.能当作数字使用的内容都可以作为实际参数使用,如果函数不提供形式参数就应该在小括号里写void,如果函数名称后的小括号里什么都没写表示函数可以提供任意多个不确定类型的形式参数

/*
* 参数演示
* */
#include <stdio.h>
void print(int num, int num1) {
printf("%d\n", num);
printf("%d\n", num1);
}
int main() {
print(56, 30 - 7);
return 0;
}

数组可以作为形式参数使用.数组做形式参数的时候真正的形式参数并不是数组,只是把形式参数写成数组的样子.数组形式参数里包含的所有存储区都不是被调用函数提供的.声明数组形式参数的时候可以省略数组里包含的存储区个数.数组做形式参数的时候需要另外配合一个整数类型
参数用来表示数组里的存储区个数,通过数组形式参数可以让被调用函数使用其他函数的存储区.数组形式参数可以实现双向数据传递,这种参数叫输入输出参数

/*
* 数组形式参数演示
* */
#include <stdio.h>
void print(int arr[], int size) {
int num = 0;
for (num = 0;num <= size - 1;num++) {
printf("%d ", arr[num]);
}
printf("\n");
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
print(arr, 5);
return 0;
}

C语言里函数参数的个数可以不固定这种参数叫变长参数.不可以在编写函数的时候对变长参数进行命名,在被调用函数里需要使用特殊的方法才能获得变长参数的内容

/*
* 函数练习
* */
#include <stdio.h>
void neg(int arr[], int size) {
int num = 0;
for (num = 0;num <= size - 1;num++) {
arr[num] = 0 - arr[num];
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5}, num = 0;
neg(arr, 5);
for (num = 0;num <= 4;num++) {
printf("%d ", arr[num]);
}
printf("\n");
return 0;
}

如果编译器在编译的时候首先遇到函数调用语句就会猜测函数的格式。编译器认为函数有一个整数类型的存储区用来存放返回值,函数可以有任意多个不确定类型的形式参数。这个猜测结果叫做函数的隐式声明,隐式声明里参数的类型只能是整数类型或双精度浮点类型.如果隐式声明的格式和函数的真实格式不一致编译就会出错.函数大括号前面的部分可以单独写成一条语句,这种语句叫做函数声明语句.函数声明语句里可以省略形式参数名称,把函数声明语句写在文件开头叫做函数的显式声明,显式声明可以避免隐式声明的问题,除了主函数以外的所有函数都应该进行显式声明

exit标准函数可以随时结束整个程序的执行,为了使用这个标准函数需要包含stdlib.h头文件,这个函数需要一个整数作为实际参数使用,这个整数的作用和主函数返回值的作用一样

/*
* exit标准函数演示
* */
#include <stdio.h>
#include <stdlib.h>
void func(void) {
printf("2\n");
exit(0);
printf("3\n");
}
int main() {
printf("1\n");
func();
printf("4\n");
return 0;
}

C语言里函数可以调用自己,这种函数叫做递归函数

/*
* 递归函数演示
* */
#include <stdio.h>
void print(int max) {
if (max == 1) {
printf("1 ");
return ;
}
print(max - 1);
printf("%d ", max);
}
int main() {
int max = 0;
printf("请输入一个数字:");
scanf("%d", &max);
print(max);
printf("\n");
return 0;
}

如果一个问题可以分解成多个小问题,至少一个小问题和原来的问题本质上一样,只是稍微简单一点。这种问题就适合采用递归函数解决。

递归函数编写步骤
  1.编写语句解决分解后的每个小问题(假设递归函数已经可以使用)
  2.在递归函数的开头编写分支负责处理不可分解的情况(这个分支必须保证函数可以结束)

采用递归函数解决问题的思路叫递归,采用循环解决同样问题的思路叫递推

检验递归函数的时候首先用最简单的参数检验,然后逐渐把参数变得复杂再检验,如果所有参数的检验结果都正确就说明函数编写正确

能够使用某个变量的所有语句叫做这个变量的作用域,声明在函数里面的变量叫局部变量,局部变量的作用域包含函数里面的所有语句,声明在所有函数外边的变量叫全局变量,全局变量的作用域包含程序里的所有语句.没有初始化的全局变量自动被初始化成0,全局变量和局部变量可以重名,这个变量名优先代表局部变量,如果全局变量和局部变量都能解决问题应该优先采用局部变量

存储区的使用不受作用域限制(可以跨函数使用存储区),存储区的使用受到生命周期的限制生命周期是一段时间,在生命周期开始的时候计算机给程序分配存储区,在生命周期结束的时候,计算机把分配给程序的存储区收回,全局变量的生命周期是整个程序的执行时间,局部变量的生命周期是函数某一次执行的时间范围,在函数开始执行的时候计算机给局部变量分配存储区,在函数结束的时候计算机把局部变量的存储区收回.每次函数执行的时候局部变量被分配的存储区都可能是新的

静态变量的生命周期和作用域跟普通变量不一样,声明静态变量的时候需要使用static关键字.不论全局变量还是局部变量都可以声明成静态变量.静态局部变量的生命周期是整个程序的执行时间,没有初始化的静态变量自动被初始化成0.静态局部变量的存储区可以被任何函数使用,静态局部变量的作用域也是函数内部的所有语句,静态变量的初始化只在程序开始的时候执行一次,静态全局变量的生命周期还是整个程序执行时间,静态全局变量的作用域被压缩成只包含声明它的文件里的所有语句(不可以跨文件使用静态全局变量)

变量的作用域分为三种情况:局部变量,静态全局变量和非静态全局变量.变量的生命周期分为两种情况:非静态局部变量和其它

标准C语言(7)的更多相关文章

  1. 关于标准C语言的预定义宏【转】

    标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来. __LINE__  当 ...

  2. 【部分原创】标准C语言的优先级、结合性、求值顺序、未定义行为和非确定行为浅析

    零. 优先级    在C++ Primer一书中,对于运算符的优先级是这样描述的:     Precedence specifies how the operands are grouped. It ...

  3. 标准SQL语言的用法

    原文链接:http://www.ifyao.com/2015/05/18/%E6%A0%87%E5%87%86%E7%9A%84sql%E8%AF%AD%E8%A8%80%E4%BD%BF%E7%94 ...

  4. 关于标准C语言的预定义宏

    标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来.__LINE__  当前 ...

  5. UML标准建模语言与应用实例

    一.基本信息 标题:UML标准建模语言与应用实例 时间:2012 出版源:科技创新导报 领域分类:UML标准建模语言 面向对象 系统分析与设计 二.研究背景 问题定义:UML建模语言用图形来表现典型的 ...

  6. UML(统一建模语言)是通用的可视化标准建模语言。由构造块、公共机制、构架三部分组成。

    UML UML(统一建模语言)是通用的可视化标准建模语言.由构造块.公共机制.构架三部分组成. 1.构造块:包括基本的UML建模元素(类.接口.用例等).关系(关联关系.依赖关系.泛化关系.实现关系) ...

  7. 标准C 语言总结

    ***************C语言****************** --day01-- Linux是一个和Windows类似的操作系统 通常通过终端软件使用Linux操作系统 终端软件里只能使用 ...

  8. 标准C语言(1)

    C语言程序的绝大部分内容应该记录在以.c作为扩展名的文件里,这种文件叫源文件,C语言里还包含以.h作为扩展名的文件,这种文件叫做头文件 C语言程序里可以直接使用数字和加减乘除四则运算符号(*代表乘法, ...

  9. 【M35】让自己习惯于标准C++语言

    1.最近一些年C++语言增加的特性有: a.RTTI,namespace,bool,关键字mutable和explicit,enums,以及const static int可以直接初始化. b.扩充了 ...

  10. 标准C语言的输入输出流(i/o)方法详解

    cppreference.com -> 标准 C I/O ->详细说明 标准 C I/O clearerr 语法: #include <stdio.h> void cleare ...

随机推荐

  1. jQuery页面加载完毕事件及jQuery与JavaScript的比较

    1.jQuery概述 jQuery是一个JavaScript库,它集成了JavaScript.DOM.CSS和Ajax,简化了JavaScript编程,提倡write less, do more. 2 ...

  2. react-redux provider组件

    provider组件概念图   react-redux provider组件概念图 provider组件的作用 provider包裹在根组件外层,使所有的子组件都可以拿到state.示例: impor ...

  3. redis安装及遇到的坑-linux

    获取Redis安装包“redis-4.0.8.tar.gz”,上传Linux服务器; 使用root用户解压: tar zxvf redis-4.0.8.tar.gz -C /usr/local/; 进 ...

  4. 【HANA系列】SAP HANA中null变成问号的问题

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA中null变成问 ...

  5. 【ABAP系列】【第五篇】SAP ABAP7.50 之用户接口

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列][第五篇]SAP ABAP7.5 ...

  6. 【Lua程序设计第四版练习题答案】ch01 Lua语言入门

    联系1.1: 运行阶乘的示例并观察,如果输入负数,程序会出现什么问题?试着修改代码来解决问题.   -- 定义一个计算阶乘的函数 function fact (n) if n == 0 then re ...

  7. javascrit-function中this的指向问题

    javascrit中this的指向 全局作用域或者普通函数中 this 指向全局对象 window. //直接打印 console.log(this) //window //function声明函数 ...

  8. 编译FFMPEG错误对策

    在MINGW32下编译ffmpeg-2.1.1.tar.bz2 step1: ./configure   --prefix=/home/Administrator/install --extra-cf ...

  9. spring boot 框架根據 sql 創建語句自動生成 MVC層類代碼

    GITHUB: https://github.com/lin1270/spring_boot_sql2code 會自動生成model.mapper.service.controller. 代碼使用No ...

  10. spark教程(12)-生态与原理

    spark 是目前非常流行的大数据计算框架. spark 生态 Spark core:包含 spark 的基本功能,定义了 RDD 的 API,其他 spark 库都基于 RDD 和 spark co ...