C语言学习(7)-- 函数(1)

1. 什么是函数?

  • 函数也叫做子程序,是某部分代码,负责完成某部分代码,具有相对独立性。一般会输入参数并有返回值。
  • c语言函数的分类:① 库函数 ② 自定义函数 

库函数:C语言本身提供给我们的函数,例如:printf( ), scanf( ) ...可以在cplusplus.com/cppreference.com中找到C语言所有的库函数相关信息。C语言常用的库函数有:

  • IO函数
  • 字符串操作函数 eg. strcpy( ) -- string copy -- 字符串拷贝
  • 内存操作函数,eg. memset( ) -- memory set -- 内存设置
  • 时间/日期函数
  • 数学函数
  • 其他库函数

如何利用文档学习呢?举两个例子

① strcpy():利用以上网址了解到strcpy()函数的相关信息,例如:如何使用、参数类型...在查阅文档时,我们发现参数放的是目的地与源头地,可以通俗理解为从后往前传。参数类型为char,传参内容包含\0。具体信息如下。

#include<stdio.h>
#include<string.h>
int main()
{
  
    char arr1[] = "bit";
    char arr2[] = "######";
    strcpy(arr2,arr1);
    printf("%s\n",arr2);
    return 0;
}

② memset( ): 分析方法与strcpy()相同,此处不过多赘述。如下。

#include<stdio.h>
#include<string.h>
int main()
{
    //memset()
    char arr[] = "hello world";
    memset(arr,'*',5);
    printf("%s\n",arr);

    return 0;
}

自定义函数:程序员自己编写的函数程序。函数命名规范如下。

#include<stdio.h>
int get_max(int x, int y)
{
    if (x > y)
    {
        return x;
    }else return y;
    
}
int main()
{
    int a = 10;
    int b = 20;
    int max = get_max(a,b);
    printf("%d\n",max);

    return 0;
}

练习1: 写一个函数交换两个整型变量的内容。先做尝试,参考程序在文章结尾。

函数参数:实参(实际参数)和形参(形式参数)。实参是指在主函数中调用函数输入的参数。形参是在自定义函数构建中所使用的参数,形式参数只有在函数被调用的时候才实例化,调用完后就会自动销毁。

函数调用:传值调用传址调用,具体使用可以看练习1。

练习2:

  • 写一个函数,判断一个数是否为素数。
  • 写一个函数,判断是否为闰年
  • 写一个函数,实现在整型有序数组中的二分查找
  • 写一个函数,每调用一次函数就实现num+1

练习2中主要对3进行详细解析。1.2和前面文章的练习一样,不过多赘述。4中需要注意的是函数调用方式,分清楚是传值还是传址。

函数的嵌套调用和链式访问

  • 嵌套调用:函数与函数可以有机组合
    #include<stdio.h>
    void new_line()
    {
        printf("hehe\n");
    }
    void three_line()
    {
        for (int i = 0; i < 3; i++)
        {
            new_line();
        }
        
    }
    
    int main()
    {
    
    three_line();
    
    return 0;
    }
  • 链式访问:把一个函数的返回值作为另外一个函数的参数
        int len = 0;
        len = strlen("abc");
        printf("%d\n",len);
        //链式访问
        printf("%d\n",strlen("abc"));

练习3:以下代码的打印结果是什么?

printf("%d",printf("%d",printf("%d",43)));

分析:该语句使用了嵌套调用,打印的是printf()的返回值。那我们就需要知道printf()的返回值是什么?通过上述网址,我们可以轻易的查到printf()返回值为所打印字符的个数。 

2. 函数的声明和定义

函数声明:

  • 如果函数放在主函数后面,需要函数声明。不要忘记后面的分号。
  • 函数源文件(.c)+头文件(.h)构成一个函数模块,要在头文件中声明函数,在源文件中做函数定义。在主程序源文件中引入#include“。。。.h”包含一下即可,(此处自己定义的头文件用双引号,库函数用<>)
  • 函数声明一般要在函数使用之前,先声明再使用。

函数定义:函数功能的具体实现。

 在头文件中要声明。#ifndef——if no define + 文件名;以下语句就是表示如果没有定义文件名,就定义。结尾加#endif

练习1参考程序:

分析:看到交换变量内容,首先想到的就是前面练习中出现的排序算法。根据这个思路就可以写出函数。如下例所示。实际操作后可以发现,其实是有问题的。原因就是自定义函数中参数与主函数中参数不共用一个地址,这就导致,在自定义函数中开辟一处地址并完成了内容交换,但实际主函数中的调用参数却没有改变。

#include<stdio.h>

void swap(int x, int y)
{
    int temp = 0;
    temp = x;
    x = y;
    y = temp;
}
int main()
{

    //写一个函数可以交换两个整型变量的内容
    int a = 10;
    int b = 20;
    printf("a = %d,b = %d\n",a,b);
    //函数调用--传值调用
    swap(a,b);
    printf("a = %d,b = %d\n",a, b);


    return 0;
}
  • 当实参传给形参的时候,形参其实是实参的一份临时拷贝,此时,对形参的修改不会影响实参。
  • 于是,我们可以发现是因为x,y与a,b的值没有关系,那改正就需要把两者建立联系。
#include<stdio.h>

void swap2(int* pa, int* pb)
{
    int temp = 0;
    temp = *pa;
    *pa = *pb;
    *pb = temp;
}
int main()
{
   
    //把x,y和a,b是相同地址
    int a = 10;
    int b = 20;
    //函数调用--传址调用
    swap2(&a,&b);
    printf("\na = %d,b = %d",a,b);


    return 0;
}

             

练习2:写一个函数,实现在整型有序数组中的二分查找

分析:按照之前练习中的程序,可以很容易的写出代码,但此处需要注意的是程序报错的原因,以及此处的arr是个指针,所以不能再函数中用常规的方式计算数组的长度。而且在主函数中调用的arr传递的是首元素地址。进行如下改进。

#include<stdio.h>

int Binary_search(int arr[], int k, int sz)
{
    int left = 0;
    //int sz = sizeof(arr)/sizeof(arr[0]);
    int right = sz - 1;
    
    while(left <= right)
    {
        int mid = (left + right)/2;
        if (k > arr[mid])
        {
            left = mid + 1;
        }
        else if (k < arr[mid])
        {
            right = mid - 1;
        }
        else{
            return mid;
        }
    }

    return -1;
    }


int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    int key = 7;
    int sz = sizeof(arr)/sizeof(arr[0]);
    int ret = Binary_search(arr,key,sz);    
    
    if(ret == -1)
    {
        printf("找不到\n");
    }else
    {
        printf("找到了,下标是%d\n",ret);
    }

return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贪睡脑子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值