【C语言】08-函数调用

此笔记由个人整理

塞上苍鹰_fly

课程来自:尚观C语言

一、函数的定义

格式

  • 数据类型 函数名 ([数据类型 形参名,数据类型 形参名,…])
#include "stdio.h"
#include "stdlib.h"

//argc:从终端计算传递多少个参数过来
//argv:用来保存从命令行传入传输的列表
int main(int argc,char *argv[])
{
    int i;
    printf("argc = %d\n",argc);
    
    //for(i = 0;i < argc;i++)
    for(i = 0;argv[i] != NULL;i++)
       puts(argv[i]);
	return 0;
}
  • 案例
#include "stdio.h"
#include "stdlib.h"

void print_hello(void)
{
    printf("Hello!\n");
}

int main()
{
    print_hello();
    
    return 0;
}
  • 如果主调函数在上被调函数在下,则应该在被调函数应该在主调函数之前声明
#include "stdio.h"
#include "stdlib.h"

void print_hello(void);//声明

int main()
{
    print_hello();
    
    return 0;
}

void print_hello(void)
{
    printf("Hello!\n");
}

二、函数的传参

形参和实参

  • 形参:不是实际存在变量,又称虚拟变量。
  • 实参:在调用有参函数时,函数名后面括号中的参数为“实际参数”

值传递

  • 直接传递数值,在被调用的函数中只能使用这个值,不能改变这个原始的值
  • 案例
#include "stdio.h"
#include "stdlib.h"

int printf_value(int a,int b)
{
    printf("i = %d,j = %d\n",a,b);
    return 0;
}

int main()
{
    int i = 3,j = 5;
    
    printf_value(i,j);
    
    exit(0);
}
  • 结果

【C语言】08-函数调用_第1张图片

地址传递

  • 通过直接操作地址,来使用和更改这个值
  • 案例
#include "stdio.h"
#include "stdlib.h"

int swap(int *p,int *q)
{
    int tmp;
    
    tmp = *p;
    *p = *q;
    *q = tmp;
    return 0;
}

int main()
{
    int i = 3,j = 5;
    printf("befor-->i = %d,j = %d\n",i,j);
    swap(&i,&j);
    printf("after-->i = %d,j = %d\n",i,j);
    exit(0);
}
  • 结果

【C语言】08-函数调用_第2张图片

三、函数的调用

嵌套调用

  • 嵌套多个函数实现一个功能
  • 案例
#include "stdio.h"
#include "stdlib.h"
int maxfunc(int a,int b,int c)
{
    int tmp;
    tmp = a > b ? a : b;
    return tmp > c ? tmp : c;
}

int minfunc(int a,int b,int c)
{
    int tmp;
    tmp = a < b ? a : b;
    return tmp < c ? tmp : c;
}

int dist(int a,int b,int c)
{
    return maxfunc(a,b,c) - minfunc(a,b,c);
}

int main()
{
    int a = 3,b = 5,c = 10;
	int res;
    
    printf("a = %d,b = %d,c = %d\n",a,b,c);
    res = dist(a,b,c);
    printf("dist = %d\n",res);
    exit(0);
}
  • 结果

【C语言】08-函数调用_第3张图片

递归

  • 函数直接或间接的嵌套自身
  • 案例1
#include "stdio.h"
#include "stdlib.h"
int a()
{
    printf("[a]begin!\n");
    printf("[a]call b()!\n");
    b();
    printf("[a]b() returned!\n");
    printf("[a]end!\n");
}
int b()
{
    printf("[b]begin!\n");
    printf("[b]call c()!\n");
    c();
    printf("[b]c() returned!\n");
    printf("[b]end!\n");
}
int c()
{
    printf("[c]begin!\n");
    printf("[c]end!\n");
}
int main()
{
    printf("[main]begin!\n");
    printf("[main]call a()!\n");
    a();
    printf("[main]a() returned!\n");
    printf("[main]end!\n");
    return 0;
}
  • 结果

【C语言】08-函数调用_第4张图片

递归解决阶乘

#include "stdio.h"
#include "stdlib.h"

int func(int n)
{
    if(n < 1)//非法条件
        return -1;
    
    if(n == 1 || n == 2)//已知条件
        return 1;
    
    return n * func(n - 1);
}

int main()
{
    int n;
    int res;
    
    printf("please enter a number:");
    scanf("%d",&n);
    
    res = func(n);
    if(res == -1)
		printf("enter error\n");
    else
		printf("%d! = %d\n",n,res);
    
    return 0;
}
  • 结果

【C语言】08-函数调用_第5张图片

递归解决斐波那契

#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;
    
    printf("please enter a number:");
    scanf("%d",&n);
    
    res = fib(n);
    
    if(res == -1)
		printf("enter error\n");
    else  
		printf("fib[%d]= %d\n",n,res);
    
    return 0;
}
  • 结果

【C语言】08-函数调用_第6张图片

四、函数与数组

函数与一维数组

  • 在传参中不光要传送数组的地址,还要传送这个数组有多少元素

传参案例

int a[N] = {1,2,3,4,5,6};
int *p = a;

->a		*a		a[0]	&a[3]	p[i]	p		*p		p+1		
    
->int*	int 	int		int *	int		int*	int		int*

案例1:传参显示

#include "stdio.h"
#include "stdlib.h"

//void printf_arr(int *p,int n)
void printf_arr(int p[],int n)
{
    int i;
    for(i = 0;i < n;i++)
        printf("%d ",*(p+i));
    printf("\n");
}

int main()
{   
	int a[] = {1,3,5,7,9};
 	
    printf_arr(a,sizeof(a)/sizeof(*a));
    
    exit(0);
}
  • 结果

【C语言】08-函数调用_第7张图片

案例2:数组传参倒序显示

#include "stdio.h"
#include "stdlib.h"

void func(int *p,int n)
{
    int i = 0,j,tmp;
	int 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 a[] = {1,3,5,7,9};
    int i;
 	for(i = 0;i < sizeof(a)/sizeof(*a);i++)
        printf("%d ",a[i]);
    printf("\n");
    
    func(a,sizeof(a)/sizeof(*a));
    
    for(i = 0;i < sizeof(a)/sizeof(*a);i++)
        printf("%d ",a[i]);
    printf("\n");
    
    exit(0);
}
  • 结果

【C语言】08-函数调用_第8张图片

函数与二维数组

传参案例

int a[M][N] = {...};
int *p = *a;
int (*q)[N] = a;

->		a[i][j]		*(a+i)+j		a[i]+j		p[i]		*p
		q[i][j]		*q				q			p+3			q+2

->		int			int *			int *		int			int
		int			int *			int (*)[N]	int *		int (*)[N]

案例1:

#include "stdio.h"
#include "stdlib.h"
#define M	3
#define N	4

void printf_arr(int *p,int n)
{
    int i;
    for(i = 0;i < n;i++)
    {
		printf("%4d ",p[i]);  
    }
	printf("\n");
}

int main()
{
	int a[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};

    printf_arr(&a[0][0],M*N);//*a	a[0]	*(a+0)
    
	exit(0);
}

案例2:

#include "stdio.h"
#include "stdlib.h"
#define M	3
#define N	4

void printf_arr(int (*p)[N],int m,int n)
{
    int i,j;
    for(i = 0;i < m;i++)
    {
        for(j = 0;j < n;j++)
        {
  			printf("%4d ",*(*(p+i)+j));            
        }
        printf("\n");
    }
	printf("\n");
}

int main()
{
	int a[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};

    printf_arr(a,M,N);
    
	exit(0);
}

案例3:二维数组学生成绩

#include "stdio.h"
#include "stdlib.h"
#define M	3
#define N	4

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("%d",*(*(p+num)+i));
    printf("\n");
}

int main()
{
    float ave;
	int a[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};
	int num = 1;
    
    ave = average_score(*a,M*N);
    printf("ave = %f\n",ave);
	
    find_num(a,num);
    exit(0);
}
  • 结果

【C语言】08-函数调用_第9张图片

函数与字符数组

案例1:实现strcpy

#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;
}

int main()
{
	char str1[] = "helloworld";
    char str2[128];
    
    mystrcpy(str2,str1);
    
    puts(str2);
    exit(0);
}
  • 结果

【C语言】08-函数调用_第10张图片

案例2:实现strncpy

#include "stdio.h"
#include "stdlib.h"

char *mystrcpy(char *dest,const char *src,size_t n)
{
    int i;
    for(i = 0;i < n && (dest[i] = src[i]);i++);
    
    dest[i] = '\0';
    for(;i < n;i++)
        dest[i] = '\0';
    return dest;
}

int main()
{
	char str1[] = "helloworld";
    char str2[128];
    
    mystrncpy(str2,str1,5);
    
    puts(str2);
    exit(0);
}
  • 结果

【C语言】08-函数调用_第11张图片

五、函数与指针

指针函数

  • 返回值为指针的函数

格式

  • 返回值 *函数名(形参)
int *fun(int);

案例1:优化学生成绩案例

#include "stdio.h"
#include "stdlib.h"
#define M	3
#define N	4

int *find_num(int (*p)[N],int num)
{
    if(num > M-1)
      return NULL;
    return *(p+num);
}

int main()
{
	int a[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};
	int num = 1;
	int *res;
    int i;
    res = find_num(a,num);
	
    if(res != NULL)
    {
        for(i = 0;i <  N;i++)
            printf("%d ",res[i]);
        printf("\n");
    }
    else
    {
        printf("Can not find!\n");
    }
    exit(0);
}
  • 结果

【C语言】08-函数调用_第12张图片

函数指针

  • 指向函数的指针

格式

  • 类型 (*指针名) (形参)
int (*p)(int)

案例

#include "stdio.h"
#include "stdlib.h"

int add(int a,int b)
{
    return a+b;
}

int sub(int a,int b)
{
    return a-b;
}

int main()
{
    int a = 3,b = 5;
    int ret;
    int (*p)(int,int);
    int (*q)(int,int);
    
    p = add;
    q = sub;
    
    ret = p(a,b);
    printf("add = %d\n",ret);
    
    ret = q(a,b);
    printf("sub = %d\n",ret);
    
    exit(0);
}
  • 结果

【C语言】08-函数调用_第13张图片

函数指针数组

  • 存放指向函数的指针

格式

  • 类型 (*数组名[下标]) (形参)
int (*arr[N])(int)

案例

#include "stdio.h"
#include "stdlib.h"

int add(int a,int b)
{
    return a+b;
}

int sub(int a,int b)
{
    return a-b;
}

int main()
{
    int a = 3,b = 5;
    int ret;
    int i;
    
    int (*funcp[2]) (int,int);
    
    funcp[0] = add;
    funcp[1] = sub;
    
    for(i = 0;i < 2;i++)
    {
        ret = funcp[i](a,b);
        printf("%d\n",ret);
    }
    
    exit(0);
}
  • 结果

【C语言】08-函数调用_第14张图片

指向指针函数的函数指针数组

格式

int *(*funcp[N])(int)

你可能感兴趣的:(c语言,c语言,sizeof,指针,算法)