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");//返回值 长度7
	return 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));//8
	
	for(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));//48
	print_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反复看

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值