初识函数调用、嵌套调用、链式访问、函数递归
C语言学习记录日期 8.15今日知识点 ——1.函数是什么维基百科中对函数的定义是 —— 子程序在计算机科学中子程序是一个大型程序中的某部分代码有一个或多个语句块组成。它负责完成某项特定任务而且相较于其它代码具备相对独立性。一般会有输入参数并有返回值提供对过程的封装和细节的隐藏。这些代码通常被集成软件库。函数的分类库函数、自定义函数memory —— 记忆 —— 内存memset —— 内存设置2.库函数使用库函数必须包含#include对应的头文件在我们学习C语言编写的时候总在一个代码编写完成之后迫不及待地想知道结果想把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能将信息按照一定的格式打印到屏幕上printf。在编程的过程中我们会频繁的做一些字符串的拷贝工作strcpy。在编程中会计算n的k次方这样的运算pow常用库函数IO函数 printf scanf getchar字符串操作函数 strcmp strlen字符操作函数 toupper内存操作函数 memcpy memcmp memset时间/日期函数 time数字函数 sqrt pow其他库函数3.自定义函数自定义函数和库函数一样有函数名返回值类型和函数参数。但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间。函数的组成ret_type fun_name(para1, * ){statement;//语句项}ret_type 返回类型fun_name 函数名para1 函数参数4.函数参数实际参数实参真实传给函数的参数叫实参。实参可以是常量、变量、表达式、函数等。无论实参是何种类型的量在进行函数调用时他们都必须有确定的值以便把这些值传送给形参。形式参数形参形式参数指函数名括号中的变量因为形式参数只有在函数被调用的过程中才实例化分配内存单元所以叫形式参数。形式参数当函数调用完成后就自动销毁了。因此形式参数只在函数中有效。5.函数调用传值调用函数的形参和实参分别占有不同内存块对形参的修改不会影响实参传址调用传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数方式这种传参方式可以让函数和函数外边的变量建立起真正的联系也就是函数内部可以直接操作函数外部的变量。6.函数的嵌套调用和链式访问函数不可以嵌套定义但是可以嵌套调用//函数可以嵌套调用void text3(){printf(“hehhe\n”);}int text2{text3(); return 0;}int main(){text2(); return 0;}链式访问7.函数的声明和定义函数声明告诉编译器有一个函数叫什么参数是什么返回类型是什么但是具体是不是存在无关紧要函数的声明一般出现在函数使用之前。要满足先声明后使用函数的声明一般要放在头文件中函数定义函数的定义是指函数的具体实现交代函数的功能实现。如果定义在使用前就不用声明了8.函数递归什么是递归程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解递归策略只需少量的程序就可以描述出解决过程做需要的多次重复计算大大地减小了程序的代码量。递归的主要思考方式在于把大事化小递归的两个必要条件存在限制条件当满足这个限制条件的时候递归便不再继续每次递归调用之后越来越接近这个限制条件写递归代码的时候不能死递归要有跳出条件每次递归逼近跳出条件递归层次不能太深练习代码今日知识点 ——函数递归2上面有count变量现在要求不允许创建变量采用递归思想大事化小my_strlen(“bit”);1my_strlen(“it”);11my_strlen(“t”);111my_strlen(“”);11103练习代码#include stdio.h//求n的阶层不考虑溢出//n!123…*nint main(){int n 0; scanf(%d,n); int i 0; int ret 1; //循环是一种_**迭代**_ for (i 1; i n; i) { ret ret * i; } printf(%d\n,ret); return 0;}递归的方式//_递归_的方式解决求n的阶层不考虑溢出int Fac(int n){if (n 1) return 1; else return n * Fac(n-1);}int main(){int n 0; scanf(%d,n); int ret Fac(n); printf(%d\n,ret); return 0;}效率太低了因为重复大量的计算。int count 0;//递归可以求解但是可能效率太低int Fib(int n){//统计第3个斐波那契数的计算次数 if (n 3) count; if (n 2) return 1; else return Fib(n-1) Fib(n-2);}int main(){int n 0; scanf(%d,n); int ret Fib(n); printf(%d\n,ret); printf(count %d\n,count); return 0;}高效率不考虑溢出#includestdio.h//编写程序数一下 1 到 100 的所有整数中出现多少个数字9//9 19 29 …99//90 91 92…99int main(){int i 0; int count 0; for (i 1;i 100;i) { if(i % 10 9) count; if(i / 10 9) count; } printf(%d,count); return 0;}//计算1/1-1/21/3-1/41/5…1/99-1/100的值打印出结果int main(){int i 0; double sum 0; for (i 1; i 100; i) { if (i % 2 0) sum - 1.0 / i; else sum 1.0 / i; } printf(%1f,sum); return 0;}更简单的做法//计算1/1-1/21/3-1/41/5…1/99-1/100的值打印出结果int main(){int i 0; double sum 0; int flag 1; // 符号标记1表示当前项取正号-1表示当前项取负号 for (i 1; i 100; i) { // flag * 1.0 / i // 如果flag1就是 (1.0/i) // 如果flag-1就是 -(1.0/i) // 这样就能实现 - - 交替 sum flag * 1.0 / i; // 每加完一项把符号取反 // 1 变成 -1下一次就是减 // -1 变成 1下一次又是加 flag -flag; } printf(%f, sum); return 0;}//求十个整数中最大的值int main(){int arr[10] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; int max arr[0];//这里不应该为int max 0;因为要是数组里的为负数就比不了了 int i 0; for (i 0; i 10; i) { if (arr[i] max) { max arr[i]; } } printf(%d\n,max); return 0;}注释版//在屏幕中输出9*9乘法口诀表//1*11//212 224//313 326 3*39//…int main(){** int i 1; // i行号**** for (i 1; i 9; i) // 外层循环打印 9 行**** {**** int j 0; // j每行第几列**** for (j 1; j i; j) // 内层循环第 i 行打印 i 列**** {**** printf(%d*%d%-2d , i, j, i * j);**** // 三个 %d 依次对应左因数 i、右因数 j、乘积 i*j**** // %-2d左对齐至少占 2 格**** }**** printf(“\n”); // 一行打完换行**** }**** return 0;**}****第 1 题单选题题目能把函数处理结果的二个数据返回给主调函数在下面的方法中不正确的是AA. return 这二个数 C 语言 return 只能返回 1 个值不能直接 return 两个数B. 形参用数组C. 形参用二个指针D. 用二个全局变量第 2 题单选题题目关于函数调用说法不正确的是 A. 函数可以传值调用传值调用的时候形参是实参的一份临时拷贝 B. 函数可以传址调用传址调用的时候可以通过形参操作实参 C. 函数可以嵌套定义但是不能嵌套调用 D. 函数可以嵌套调用但是不能嵌套定义C 语言函数不能嵌套定义可以嵌套调用第 3 题单选题题目在函数调用时以下说法正确的是A. 函数调用后必须带回返回值B. 实际参数和形式参数可以同名C. 函数间的数据传递不可以使用全局变量D. 主调函数和被调函数总是在同一个文件里第 4 题单选题题目关于函数的声明和定义说法正确的是A. 函数的定义必须放在函数的使用之前B. 函数必须保证先声明后使用C. 函数定义在使用之后也可以不声明D. 函数的声明就是说明函数是怎么实现的第 5 题单选题题目关于实参和形参描述错误的是A. 形参是实参的一份临时拷贝B. 形参是在函数调用的时候才实例化才开辟内存空间C. 改变形参就是改变实参D. 函数调用如果采用传值调用改变形参不影响实参第 6 题单选题题目函数调用 exec ((v1, v2), (v3, v4), v5, v6); 中实参的个数是A.3B.4C.5D.6答案 简要解析第 3 题B解析A void 函数无返回值C 全局变量可以用来传数据D 函数可以分在不同.c 文件。实参形参可以同名作用域互不干扰。第 4 题B解析C 语言规则先声明后调用。定义就是实现代码声明只告诉编译器函数原型。第 5 题C解析传值调用时形参只是实参拷贝修改形参不会影响实参C 说法错误。第 6 题B解析逗号运算符(v1,v2)整体是1 个实参(v3,v4)是第 2 个v5 第 3v6 第 4 → 一共 4 个实参。递归