C-函数的由浅入深

1.函数的定义
数据类型 函数名 (【数据类型 形参名,数据类型 形参名, …】)
2.函数的传参
值传递
地址传递
全局变量
3.函数的调用
嵌套调用
递归
4.函数与数组
5.函数与指针
指针函数
函数指针
函数指针数组

函数的定义

#include<stdio.h>
#include<stdlib.h>int main(int argc,char *argv[])
//argc 是计算一共传递参数的个数
//argv 字符指针数组的首地址   输入参数都会保存在这个字符数组里面,最后一个元素是NULL (存放char * 类型的数组)
{printf("argc = %d\n",argc);//for(i = 0;i<argc;i++)for(i = 0;argc[i] != NULL;i++)//等价于上述表达式puts(argv[i]);printf("hello!\n");//返回值 长度7return 0;//当没有返回值时,默认返回最后一条语句的返回值
}
#include<stdio.h>
#include<stdlib.h>
/*
void print_value(void)
{printf("hello world!\n");return ;
}int main()
{print_value();return 0;
}
*/
void print_value(void);
int main()
{print_value();return 0;
}
void print_value(void)
{printf("hello world!\n");return ;
}
//main函数是主调函数,其它被调函数需要写在主调函数上方实现,或者在上方声明才能在下方实现

一个进程的返回状态是给他的父进程看的

值传递

#include<stdio.h>
#include<stdlib.h>int print_value(int a,int b)
{printf("%d %d\n",a,b);return 0;
}int main()
{int i=3, j=5;print_value(i,j);return 0;
}

地址传递 (间接引用)

#include<stdio.h>
#include<stdlib.h>void swap(int *p,int *q)
{int tmp;tmp =*p;*p = *q;*q = tmp;
}int main()
{int i=3, j=5;swap(&i,&j);printf("i = %d,j = %d\n",i,j);return 0;
}

嵌套调用

#include<stdio.h>
#include<stdlib.h>max(int a,int b,int c)
{int tmp;tmp = a > b ? a : b;return tmp > c ? tmp : c;
}
min(int a, int b,int c)
{int tmp;tmp = a < b ? a : b;return tmp < c ? tmp : c;
}
dist(int a,int b,int c)
{return max(a,b,c) - min(a,b,c);
}
int main()
{int a=3,b=5,c=10;int res;res =  dist(a,b,c)printf("res = %d\n",res);return 0;
}

递归 一个函数嵌套的调用自己

#include<stdio.h>
#include<stdlib.h>void c(void)
{printf("[%s]begin!\n",__FUNCTION__);printf("[%s]end!\n",__FUNCTION__);
}
void b(void)
{printf("[%s]begin!\n",__FUNCTION__);printf("[%s]call c()!\n",__FUNCTION__);c();printf("[%s]c() returned!\n",__FUNCTION__);printf("[%s]end!\n",__FUNCTION__);
}
void a(void)
{printf("[%s]begin!\n",__FUNCTION__);printf("[%s]call b()!\n",__FUNCTION__);b();printf("[%s]b() returned!\n",__FUNCTION__);printf("[%s]end!\n",__FUNCTION__);
}
int main()
{printf("[%s]begin!\n",__FUNCTION__);printf("[%s]call a()!\n",__FUNCTION__);a();printf("[%s]a() returned!\n",__FUNCTION__);printf("[%s]end!\n",__FUNCTION__);return 0;
}
[main]begin!
[main]call a()!
[a]begin!
[a]call b()!
[b]begin!
[b]call c()!
[c]begin!
[c]end!
[b]c() returned!
[b]end!
[a]b() returned!
[a]end!
[main]a() returned!
[main]end!

递归解决阶乘和斐波那契数列
递归 能够抽象出来一个类似公式的递推
汉诺塔 / 二叉树 /阶乘 /斐波那契数列

#include<stdio.h>
#include<stdlib.h>int func(int n)
{if(n<0)return -1;if(n == 0 || n ==1)return 1;return n * func(n-1);//一层一层的压栈 出栈
}int main()
{int n;int res;scanf("%d",&n);res = func(n);printf("%d! = %d\n",n,res);return 0;
}
#include<stdio.h>
#include<stdlib.h>int fib(int n)
{if(n<1)return -1;if(n ==1 ||n ==2)//已知条件return 1;return fib(n-1) + fib(n-2);//公式
}int main()
{int n;int res;scanf("%d",&n);	res = fib(n);printf("fib[%d] = %d\n",n,res);return 0;
}

函数与一维数组

#include<stdio.h>
#include<stdlib.h>
/*
int a[N] = {1,2,3,4,5,6};
int *p = a;//一维数组 a和p除了一个常量一个变量 其他等价
传参形式--->a   		*a  		 a[0] 		 &a[3] 		 p[i] 		 p		  *p 		 p+1*(a+0)
函数形参-->int *     int 		 int 		int * 		 int		 int * 	  int 		 int *
*//*方法一
void print_arr(int *p,int n)
{int i;printf("%s:%d\n",__FUNCTION__,sizeof(p));  for(i =0;i < n;i++)printf("%d ",*(p+i));printf("\n");
}
*/
void print_arr(int p[],int n)//int p[] 形参和定义的时候是不一样的  可以理解一个 [] 等价于一个 *
{int i;printf("%s:%d\n",__FUNCTION__,sizeof(p));  for(i =0;i < n;i++)printf("%d ",*(p+i));printf("\n");
}
void func(int *p,int n)
{int i = 0,m,j,tmp;m = (n-1)/2;for(; i<= m;i++){j = n-1-i;tmp = p[i];p[i] = p[j];p[j] = tmp;}}int main(int argc,char **argv)
//int main(int argc,char *argv[])
{int a[] = {1,3,5,7,9};printf("%s:%d\n",__FUNCTION__,sizeof(a));print_arr(a,sizeof(a)/sizeof(*a));//一维数组传参是传递了数组的起始位置,因此还需要告诉数组的长度func(a,sizeof(a)/sizeof(*a));//逆序数组print_arr(a,sizeof(a)/sizeof(*a));return 0;
}

函数和二维数组

#include<stdio.h>
#include<stdlib.h>
#define M 3
#define N 4
/*
int a[M][N]= {...};
int *p = *a;
int (*q)[N] = a;//数组指针  指向数组的指针  q 也可以称行指针main传参	  -->  a[i][j]    *(a+i)+j		a[i]+j		p[i] 		*p		q[i][j]		*q 			q 				P+3		q+2*(q+0)函数定义形参接收-->  int 	  int *			int *		int			int		int 		int *		int (*)[N]		int *		int (*)[N]	
*/void print_arr(int *p,int n)
{int i;for(i =0;i<n;i++){printf(%4d ",p[i]);//此时,把二维数组当成大的一维数组}printf("\n");
}void print_arr1(int (*p)[N],int m,int n)
//void print_arr1(int p[][N],int m,int n)
{int i,j;printf("sizeof(p) = %d\n",sizeof(p));//8for(i =0;i<m;i++){for(j = 0;j<n;j++)printf("%4d ",*(*(p+i)+j));//printf("%4d ",p[i][j]);printf("\n")}
}float average_score(int *p,int n)
{int i;float sum =0;for(i = 0;i<n;i++)sum += p[i];return sum/n;
}void find_num(int (*p)[N],int num)
{int i;for(i = 0;i < N; i++)printf("",*(*(p+num)+i));printf("\n");
}int main()
{int a[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};print_arr(*a,M*N);//print_arr(&a[0][0],M*N); //*a  a[0]  *(a+0)  行指针转换成列指针printf("sizeof(a) = %d\n",sizeof(a));//48print_arr1(a,M,N);//同样需要传递行列数float ave;ave = average_score(*a,M*N);//此时,需求 不需要区分行列 所以按照一个大的一维数组处理printf("ave = %f ",ave);int num = 0;find_num(a,num);return 0;
}

函数与字符数组

#include<stdio.h>
#include<stdlib.h>char *mystrcpy(char *dest,const char *src)
{	char *ret = dest;if(dest! = NULL && src != NULL)while((*dest++ = *src++) != '\0');return ret;
}
char *mystrncpy(char *dest,const char *src,size_t n)
{	int i;for(i = 0;i < n && (dest[i] = src[i]); i++);for(;i <n;i++)dest[i] = '\0';return dest;
}int main()
{char str1[]="helloworld";char str2[128];mystrcpy(str2,str1);mystrncpy(str2,str1,5);puts(str2);return 0;
}

函数与指针关系的详细剖析

指针函数:一个函数的返回值是指针
返回值 * 函数名(形参)
如:int *fun(int);

#if 0
void find_num(int (*p)[N],int num)
{int i;for(i = 0;i < N; i++)printf("",*(*(p+num)+i));printf("\n");
}
#endif
int *find_num(int (*p)[N],int num)//函数的功能越简单越好 和其他函数减少依赖关系
{if(num > M-1)return NULL;return *(p + num);
}

函数指针:指向函数的指针 指向和函数指针相同类型的函数
类型 (*指针名)(形参)
如:int (*p)(int);

#include<stdio.h>
#include<stdlib.h>int add(int a, int b)//函数名是一段代码所关联的入口地址
{return a+ b;
}
int sub(int a,in b)
{return a-b;
}int main()
{int a = 3, b = 5;int ret;int (*p)(int,int);//别忘记括号   指向函数的指针 指向和函数指针相同类型的函数  并通过指针调用函数int (*q)(int,int);//int (int,int) (*q)p = add;q = sub;//ret = add(a,b);ret = p(a,b);printf("%d\n",ret);return 0;
}

函数指针数组:
类型 (*数组名【下标】) (形参)
如:int (*arr[N])(int); 数组中的N个元素 都是指向函数的指针

#include<stdio.h>
#include<stdlib.h>int add(int a, int b)//函数名是一段代码所关联的入口地址
{return a+ b;
}
int sub(int a,in b)
{return a-b;
}int main()
{int a = 3, b = 5,i;int ret;//int (*p)(int,int);//int (*q)(int,int);int (*funcp[2])(int,int);// int (int,int)  *funcp[2];//p = add;//q = sub;funcp[0] = add;funcp[1] =sub;//ret = add(a,b);//ret = p(a,b);for(i = 0;i<2;i++){ret = funcp[i](a,b);printf("%d\n",ret);}//printf("%d\n",ret);return 0;
}

p59反复看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/12946.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

醉了,面个功能测试,还问我Python装饰器

Python 装饰器是个强大的工具&#xff0c;可帮你生成整洁、可重用和可维护的代码。某种意义上说&#xff0c;会不会用装饰器是区分新手和老鸟的重要标志。如果你不熟悉装饰器&#xff0c;你可以将它们视为将函数作为输入并在不改变其主要用途的情况下扩展其功能的函数。装饰器可…

dhcp(接口和全局地址池模式)

接口地址池和全局地址池 dhcp应用 1.全部开启dhcp功能 2.ar5 0口接口地址池 1口全局地址池 3.ar6和ar7配置&#xff0c;查看能否自动获取ip 左右不同两个网络&#xff0c;接口和全局地址池的区别 部分截图 ar6 ar7 ar5

(实测验证)【移远EC800M-CN 】TCP 透传

引言 本文章使用自研“超小体积TTL转4GGPS集成模块”进行实测验证&#xff1b; 1、配置移远EC800M-CN TCP 透传 串口助手发送&#xff1a; ATQIOPEN1,0,"TCP","36.137.226.30",39755,0,2 //配置服务器地址和端口号&#xff1b; 4G模组返回…

07-Fortran基础--Fortran指针(Pointer)的使用

07-Fortran基础--Fortran指针Pointer的使用 0 引言1 指针&#xff08;Poionter&#xff09;的有关内容1.1 一般类型指针1.2 数组指针1.3 派生类(type)指针1.4 函数指针 2 可运行code 0 引言 Fortran是一种广泛使用的编程语言&#xff0c;特别适合科学计算和数值分析。Fortran 9…

java代码混淆工具ProGuard混淆插件

java代码混淆工具ProGuard混淆插件 介绍 ProGuard是一个纯java编写的混淆工具&#xff0c;有客户端跟jar包两种使用方式。可以将程序打包为jar&#xff0c;然后用工具进行混淆&#xff0c;也可以在maven中导入ProGuard的插件&#xff0c;对代码进行混淆。 大家都知道 java代…

【华为OD机试-C卷D卷-200分】田忌赛马(C++/Java/Python)

【华为OD机试】-(A卷+B卷+C卷+D卷)-2024真题合集目录 【华为OD机试】-(C卷+D卷)-2024最新真题目录 题目描述 给定两个只包含数字的数组a,b,调整数组 a 里面的数字的顺序,使得尽可能多的a[i] > b[i]。 数组a和b中的数字各不相同。 输出所有可以达到最优结果的a数组的…

SadTalker 自定义容器化部署配置

Docker 环境检查 执行docker info 查看环境种是否有安装docker&#xff0c;否则首先安装好docker 运行环境。在线环境安装执行执行两条指令即可 sudo apt install docker sudo apt-get install docker-ce sudo apt-get install docker-composesudo systemctl restart dockerG…

langchain源码

itemgetter&#xff1a;返回一个函数&#xff0c;函数取输入dict的某个指定key Runnable 的基本方法有 invoke、 batch、 await、 ainvoke、 abatch 同步转异步 Runnable 还具有的方法&#xff1a;bind、 with_config。 input_schema 属性、output_schema 属性 with_retry方…

Uniapp H5开发常见问题解析

引言 在移动应用开发领域&#xff0c;Uniapp已经成为一个备受瞩目的技术框架&#xff0c;其跨平台能力和高效开发特性使得开发者能够更加便捷地构建出功能丰富、性能优越的应用程序。特别是在H5开发中&#xff0c;Uniapp的应用场景日益广泛&#xff0c;然而&#xff0c;随之而…

Vue2之使用provide和inject实现两个不相干组件之间的通信

Vue2之使用provide和inject实现两个不相干组件之间的通信 文章目录 Vue2之使用provide和inject实现两个不相干组件之间的通信1. 祖先组件中使用provide提供数据2.后代组件A中使用inject注入并使用数据3.后代组件B中使用inject注入并使用数据 在Vue 2中以使用provide和inject来实…

[ciscn 2022 东北赛区]math

1.题目 import gmpy2 from Crypto.Util.number import * from flag import flag assert flag.startswith(b"flag{") assert flag.endswith(b"}") messagebytes_to_long(flag) def keygen(nbit, dbit):if 2*dbit < nbit:while True:a1 getRandomNBitIn…

编辑器目录树的设计,一点也不简单

朋友们好&#xff0c;我是优秀的大鹏 今天花了很长时间思考一个网页文档编辑器&#xff0c;云端目录树要怎么设计 这个看似简单的需求&#xff0c;技术上和产品上的思考却非常复杂 下面以几种编辑器为例&#xff0c;讲一下各种编辑器在技术上和产品的思考 1、以Vscode为代表的本…

Delphi DataSet转JSon (使用SuperObject)

Delphi中将TDataSet转换为JSon字符串。 with ATM.LoadDataSet() dobeginif IsEmpty thenbeginLogObj.WriteLog(未查询到该视图名称下该时间段内的上传数据&#xff0c;视图名称&#xff1a; AViewname 开始时间&#xff1a; AStartdate 结束时间&#xff1a; AEnddate);exit…

【神经网络与深度学习】Transformer原理

transformer ENCODER 输入部分 对拆分后的语句x [batch_size, seq_len]进行以下操作 Embedding 将离散的输入&#xff08;如单词索引或其他类别特征&#xff09;转换为稠密的实数向量&#xff0c;以便可以在神经网络中使用。位置编码 与RNN相比&#xff0c;RNN是一个字一个字…

Django Rest Framework 全局异常处理

在Django Rest Framework&#xff08;DRF&#xff09;中&#xff0c;全局异常处理是一种重要的机制&#xff0c;它可以帮助我们更好地管理API中的异常情况&#xff0c;并返回统一的错误响应。本文将详细介绍两种全局异常处理的方法&#xff1a;使用中间件&#xff08;Middlewar…

机器学习(3)

目录 3-1线性回归 3-2最小二乘解 3-3多元线性回归 3-4广义线性模型 3-5对率回归 3-6对率回归求解 3-7线性判别分析 3-8LDA的多类推广 3-9多分类学习基本思路 3-10类别不平衡 3-1线性回归 线性模型为什么重要&#xff1f; 人类在考虑问题时&#xff0c;通常…

用python写一个自动生成android开机动画的工具

要创建一个自动生成Android开机动画的工具&#xff0c;你需要一些基本的知识&#xff0c;比如Python编程、图像处理和Android开机动画的格式。以下是一个简单的Python脚本示例&#xff0c;它可以生成一个基本的Android开机动画&#xff0c;具体效果可能需要更多的调整和优化。 …

记录glide加载图片,设置圆角

支持所有角的圆角&#xff0c;自动计算合适的半径&#xff0c;不用担心图片比预定值小导致的圆角过大的问题 修改自&#xff1a;https://blog.csdn.net/qq_15059163/article/details/97613790 增加了指定图片尺寸、解决了图片某些情况下圆角过大的问题 public class GlideRou…

先有JVM还是先有垃圾回收器?很多人弄混淆了

是先有垃圾回收器再有JVM呢&#xff0c;还是先有JVM再有垃圾回收器呢&#xff1f;或者是先有垃圾回收再有JVM呢&#xff1f;历史上还真是垃圾回收更早面世&#xff0c;垃圾回收最早起源于1960年诞生的LISP语言&#xff0c;Java只是支持垃圾回收的其中一种。下面我们就来刨析刨析…

外卖系统的JWT实现登录

1、什么是JWT jwt可以生成一个加密的token&#xff0c;作为用户登录的令牌&#xff0c;当用户登陆成功之后&#xff0c;发放给客户端。请求需要登录的资源或者接口的时候&#xff0c;将token携带&#xff0c;后端验证token是否合法。jwt有三部分组成&#xff1a; A&#xff1a;…