C语言_深入函数

// 按值传递
int test(int p1,int p2)
{
    int z;
    z = p1 + p2;
    return z;
    
    /*
     按值传递,其实就是复制数值一个副本,传给函数,所以改变的知识副本,原来的数值并没与改变,如果要改变原来的数值,请按值传递
     */
}

// 按址传递
void test1(int *p1,int *p2)
{
    int z;
    z = *p1;
    *p1 = *p2;
    *p2 = z;
}

// 数组作为函数的参数
float test2(float x[])
{
    float average = 0;
    float sum = 0;
    for (int i = 0; i < 5; i ++)
    {
        sum = sum + x[i];
    }
    
    average = sum / 5;
    return average;
}

// 将数组和长度作为函数的参数,不能在子函数里面计算数组长度,因为子函数里面数组会退化为指针
void show(char *x[],int size)
{
    int i = 0;
    for (i = 0; i < size; i ++)
    {
        puts(x[i]);
    }
}

// 数组作为函数参数
/*
 将数组作为函数的参数,实际上就是把数组名传给函数,而数组名就是数值中第一个元素的地址
 */

#include <stdio.h>

float getAverage(float x[])
{
    float average;  // 平均值
    float sum = 0;  // 总和
    
    for (int i = 0; i < 5; i ++)  // 这个的5就是数组的长度,也就是数组元素的个数,这个5必须事先知道,通过求数组的长度sizeof函数是求不出来的
    {
        sum += x[i];
    }
    average = sum / 5;
    
    return average;
}

int main()
{
    float score[5] = {78.5f,65.5f,88.7f,92.5f,100.0f};
    float aver = getAverage(score);
    printf("5门课的平均成绩为:%.2f\n",aver);
    
    return 0;
}
// 数组的长度作为函数参数
/*
 将数组的长度作为函数的参数,把数组的长度传给函数,实际上很有用处的,因为函数经常不知道数组的长度是多少,必须要传个数组长度
 */

#include <stdio.h>
#define N 5

float getAverage(float x[], int len)
{
    float average;  // 平均值
    float sum = 0;  // 总和
    
    for (int i = 0; i < len; i ++)  // 在这里,这个函数就不用担心怎么获得数组的长度了,只要使用传进来的数组长度就行了
    {
        sum += x[i];
    }
    average = sum / len;
    
    return average;
}

int main()
{
    float score[N] = {78.5f,65.5f,88.7f,92.5f,100.0f};
    float aver = getAverage(score,N);
    printf("5门课的平均成绩为:%.2f\n",aver);
    
    return 0;
}
// 数组形参退化为指针
/*
 数组作为函数的参数会退化为指针
 */

#include <stdio.h>
#define N 5

void show(int x[])
{
    printf("x保存的地址:\t%p\n",x);  // 数组已经退化为指针,这里x是一个指针了
    printf("x的地址:\t%p\n",&x);
    
    /*
     之所以数组作为函数的参数会退化为指针,是因为数组只有一个原本,不可能在函数中再创建一个该数组的副本,所以只有将数组作为形参退化为指针,然后用指针来保存原始数组的地址
     */
}

int main()
{
    int a[] = {0,1,2};
    printf("a保存的地址:\t%p\n",a);
    printf("a的地址:\t%p\n",a);
    show(a);
    
    return 0;
}
// 指针数组作为函数参数
/*
 将指针数组传给函数
 */

#include <stdio.h>

void show(char *x[], int len)
{
    for (int i = 0; i < len; i ++)
    {
        printf("%s\n",x[i]);
    }
}

int main()
{
    char *book[] = {
        "荒野的呼唤",
        "时光之轮",
        "老人与海",
        "教父",
        "基督山伯爵",
        "地海传说"
    };
    int size = sizeof(book)/sizeof(book[0]);
    show(book,size);
    
    return 0;
}
// 结构体变量作为函数参数
/*
 将结构体变量作为形参传给函数
 */

#include <stdio.h>
#include <string.h>

struct book  // 定义一个结构体book
{
    char name[20];
    float price;
};

void show(struct book sb)
{
    printf("书名:%s\n",sb.name);
    printf("价格:%.2f\n",sb.price);
}

int main()
{
    struct book book1;
    strcpy(book1.name, "中国好声音");
    book1.price = 12.30f;
    show(book1);
    
    return 0;
}
// 结构体数组作为函数参数
/*
 将结构体数组作为形参传给函数
 */

#include <stdio.h>
#include <string.h>

struct book  // 定义一个结构体book
{
    char name[40];
    float price;
};

void show(struct book sb[], int len)
{
    for (int i = 0; i < len; i ++)
    {
        printf("书名:%-20s\t价格:%.2f\n",sb[i].name,sb[i].price);
    }
}

int main()
{
    struct book myBook[] =
    {
        {"<荒野的呼唤>",11.20f},
        {"<伏尔加河上的小房子>",3.00f},
        {"<国富论>",50.0f},
        {"<麦田里的守望者>",9.50f}
    };
    int size = sizeof(myBook)/sizeof(myBook[0]);
    show(myBook,size);
    
    return 0;
}
// 函数指针
/*
 每个函数都有一个入口地址,即函数代码段在内存中的首地址,可用指针来保存该地址
 */

#include <stdio.h>

int add(int x, int y)
{
    int z;
    z = x + y;
    
    return z;
}

int main()
{
    int (*p) (int x, int y);
    p = add;
    
    int x = p(3,5);
    printf("x:%d\n",x);
    
    return 0;
    
    /*
     函数指针保存的是函数第1条代码的地址,而不是数据的地址,因此不能对函数指针执行算术运算,即没有++和--等运算,用时要格外小心
     */
    
    /*
     注意:*p两侧的括号不能省略,它表示p先与*结合,然后再与后面的一对括号结合;假如省略了括号,那么p先与后面的一对括号结合,再与*结合,p就成了函数,而不是函数指针
     */
}
// 函数指针应用
/*
 函数名是死的,它代表一个函数的地址,而函数指针则是活的,它可以保存任意一个符合要求的函数的地址,因此函数指针要比函数名更加灵活
 */

#include <stdio.h>
#include <string.h>

int max(int,int);
int min(int,int);
int add(int,int);
int (*p)(int,int);

int max(int x, int y)
{
    int z;
    
    if (x > y)
    {
        z = x;
    }
    else
    {
        z = y;
    }
    
    return z;
}

int min(int x, int y)
{
    int z;
    
    if (x > y)
    {
        z = y;
    }
    else
    {
        z = x;
    }
    
    return z;
}

int add(int x, int y)
{
    int z;
    
    z = x + y;
    
    return z;
}

int main()
{
    int x,y;
    int select;
    char ch[20];
    while (1)
    {
        printf("(0)退出(1)求最大数(2)求最小数(3)两数相加:");
        scanf("%d",&select);
        
        if (select == 0)
        {
            break;
        }
        else if (select < 0 || select > 3)
        {
            printf("请输入0-3之间的数字!\n");
            continue;
        }
        
        printf("请输入第1个数:");
        scanf("%d",&x);
        
        printf("请输入第2个数:");
        scanf("%d",&y);
        
        switch (select)
        {
            case 1:
                p = max;
                strcpy(ch, "最大数为:");
                break;
            case 2:
                p = min;
                strcpy(ch, "最小数为:");
                break;
            case 3:
                p = add;
                strcpy(ch, "两数相加的和为:");
                break;
            default:
                break;
        }
        
        printf("%s%d\n",ch,p(x,y));
    }
    
    return 0;
}
// 函数指针作为函数参数
/*
 指针可以作为函数的参数,函数指针也不例外
 */

#include <stdio.h>

int add(int,int);
void func(int x, int y, int (*p)(int,int));

int add(int x, int y)
{
    int z;
    
    z = x + y;
    
    return z;
}

void func(int x, int y, int (*p)(int,int))
{
    int z;
    z = p(x,y);
    printf("%d\n",z);
}

int main()
{
    int x,y;
    
    printf("请输入第1个数:");
    scanf("%d",&x);
    
    printf("请输入第2个数:");
    scanf("%d",&y);
    
    func(x, y, add);
    
    return 0;
}
// 函数指针数组
/*
 可以声明一个由多个函数指针组成的数组,这个数组就是函数指针数组
 */

#include <stdio.h>

int max(int,int);
int min(int,int);
int add(int,int);
int (*p[3])(int,int);  // 函数指针数组

int max(int x, int y)
{
    int z;
    
    if (x > y)
    {
        z = x;
    }
    else
    {
        z = y;
    }
    
    return z;
}

int min(int x, int y)
{
    int z;
    
    if (x < y)
    {
        z = x;
    }
    else
    {
        z = y;
    }
    
    return z;
}

int add(int x, int y)
{
    int z;
    
    z = x + y;
    
    return z;
}

int main()
{
    int x,y;
    
    p[0] = max;
    p[1] = min;
    p[2] = add;
    
    printf("请输入第1个数:");
    scanf("%d",&x);
    
    printf("请输入第2个数:");
    scanf("%d",&y);
    
    printf("最大数为:%d\n",p[0](x,y));
    printf("最小数为:%d\n",p[1](x,y));
    printf("两数相加之和为:%d\n",p[2](x,y));
    
    return 0;
}
















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值