21-11-25函数

函数

1、函数基础语法(函数定义、调用、声明)
2、函数的使用注意事项(传值、返回值)
3、企业级函数(复用性、维护性、扩展性)——华为编码
函数基础语法:
1、函数三要素:函数名、函数形参、函数返回值
函数名:命名提现自注释性,提高代码可读性:动词_名词[4]
函数形参:传什么类型就用什么类型的变量来接;(a == 元素指针 aa == int (*a)[] aaa = int (*aa)[][]
函数的返回值:return 0;——结束当前函数 exit(1);——结束整个程序
2、函数使用形式:函数的声明(在调用函数前需要声明函数)、函数的定义、函数调用
函数定义:函数名、函数的返回值、形参的类型及变量名
函数调用:函数名、实参的变量名或者实参的地址
函数声明:函数名、函数返回值、形参的类型(变量名可以不提供):不分配内存空间
函数的注意事项:
1、函数的传参:
传值(传实参变量名) VS 传地址(传实参变量的地址)
当只使用不修改实参变量内存空间的值,在函数调用时传实参变量名;(只能使用不能修改)
当即使用也修改实参变量内存空间的值,在函数调用时传实参变量的地址;(既能使用又能修改)
练习:编写一个函数,实现交换两个整数变量的值
swap_int.c文件中:

void swap_int(int *left,int *right)
{
    *left = *left ^ *right;
    *right = *left ^ *right;
    *left = *left ^ *right;
}

swap_int.h:

extern void swap_int(int *,int *);

main.c:

#include <stdio.h>
#include "swap_int.h"

int main(int argc,char *argv[])
{
    int left = 5;
    int right = 6;
    swap_int(&left,&right);
    printf("left = %d right = %d\n",left,right);
    
    return 0;
}

在这里插入图片描述
传值(传实参变量名) VS 传地址(传实参变量的地址)
当只使用不修改实参变量内存空间的值,在函数调用时传实参变量名;(只能使用不能修改)
当即使用也修改实参变量内存空间的值,在函数调用时传实参变量的地址;(既能使用又能修改)

#include <stdio.h>
int main(int argc,char *argv[])
{
void func(char *ptr)
{
    ptr++;
}
    char *ptr = "hello world";
    func(ptr);

    printf("%s\n",ptr);

    return 0;
}

打印结果还是helloworld(ptr传的是实参变量名,只能使用不能修改)

#include <stdio.h>
int main(int argc,char *argv[])
{
void func(char **ptr)
{*ptr)++;
}
    char *ptr = "hello world";
    func(&ptr);

    printf("%s\n",ptr);

    return 0;
}

打印结果为elloworld
判断:修改指针变量对应内存空间值(指针变量的地址),还是要修改指针变量指向内存空间的值(传指针变量名)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void get_mem(char *ptr)
{
    ptr= (char *)malloc(sizeof(char) * 100);
}

int main (int argc,char **argv)
{
    char *ptr;
    get_mem(ptr);

    strcpy(ptr,"hello world");
    printf("ptr = %s\n",ptr);

    return 0;
}

**出现段错误:**get_mem(ptr)传的是实参变量名,只能使用不能修改,ptr是野指针

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void get_mem(char **ptr)
//char * get_mem(char *ptr)
{
    *ptr= (char *)malloc(sizeof(char) * 100);
    if(NULL == ptr)
    {
    printf("malloc error!\n");
    exit(1);
}

int main (int argc,char **argv)
{
    char *ptr;
    get_mem(&ptr);
//ptr = get_mem(ptr);
    memset(ptr,0,sizeof(char)*100);//初始化
    strcpy(ptr,"hello world");
    printf("ptr = %s\n",ptr);
    free(ptr);//释放
    ptr = NULL;//置空
    return 0;
}

2、传出参数,传入参数(大多数函数实参)
传入参数:传递给函数只使用不修改的实参
传出参数:传递给函数修改的实参(相当于函数返回值)
函数如何返回多个值?利用传出参数

int func(char * ptr)
{
*ptr = 'a';//实参op
result = 5;
}
char op;
int result = func(&op);

统计字符串中最长连续数字子串的长度并获得最长连续数字子串:

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

int continue_max_str(char *dest,char *src)
{
    int len = 0;
    int max_len = 0;
    
    while(*src != '\0')
    {
        while((*src >= '0' && *src <= '9') && *src != '\0')
        {
            len++;
            src++;
        }
        
        if(len > max_len)
        {
            strncpy(dest,src - len,len);
            *(dest + len) = '\0';
            max_len = len;
        }

        len = 0;

        src++;
    }

    return max_len;
}

int main(int agrc, char *argv[])
{
    char *src = (char *)malloc(sizeof(char) * 100);
    char *dest = (char *)malloc(sizeof(char) * 100);

    printf("Plesae input src:\n");
    scanf("%s", src);

    printf("src = %s\n", src);

    int max_len = continue_max_str(dest,src);

    printf("the max len = %d\n", max_len);
    printf("the max str = %s\n",dest);
    return 0;
}

3、主函数参数(命令行参数
argc:保存参数的个数
argv:参数保存在argv指针数组里
在这里插入图片描述
atoi函数:将字符串转成整型

4、函数返回值
不能返回局部变量的地址

char func3()
{
char src[100] = "hello world";
return src;
}
char *temp = func3();
printf("temp = %s\n,temp);

结果为temp = NULL;栈空间局部变量执行完函数会释放

企业级函数的编写:低耦合高内聚
编写一个函数,该函数可以实现将一个整数转为字符串:
int2str.h

#include <stdio.h>
#include <string.h>
extern char * int2str(int num);
#define MAX_SIZE 1024

main.c

#include <stdio.h>
#include "int2str.h"
int main(int argc,char **argv)
{
    int num;
    printf("please input num:\n");
    scanf("%d",&num);
    char *result = int2str(num);
    printf("result = %s\n",result);
    return 0;
}

int2str.c

#define MAX_SIZE 1024
static void reverse_str(char *src)
{
    if(NULL == src)
    {
        return;
    }
    char temp;
    int len = strlen(src);
    for(int i = 0;i<=len/2;i++)
    {
        temp = *(src + i);
        *(src + i) = *(src + len -1 - i);
        *(src + len -1 - i) = temp;
    }
    return;
}
char * int2str(int num)
{int i = 0;

    static char src[MAX_SIZE]
    while(num != 0)
    {
        src[i]=num % 10 + '0';
        num = num / 10;
        i++;
    }
    src[i] = '\0';
    reverse_str(src);
    return src;
    
}

函数指针变量:变量,保存地址,地址是函数的地址(函数的入口地址)
函数名:指针,保存函数地址(函数入口地址)
函数指针的作用,什么时候用?做形参
函数指针的工程应用作用:
1、隐藏调用接口和调用形式(提高统一的调用方式);2、间接体现多态,提高代码的扩展性;
函数指针数组:数组,数组里的每个元素都是函数指针
int ((fp1)(int))[10]:
fp1:函数指针变量,指向的函数形参int,返回值是一个数组指针,该指针指向的数组里的每个元素都是int

int ((*arr[5])())();
arr:函数指针数组,数组里的每个元素都是函数指针,指向一个形参为空返回值为函数指针,该指针指向一个形参为空,返回值为int
float (
(*b())[])();
b:b是一个函数,形参为空,返回值为指针,指向一个数组,数组里每个元素都是指针,返回值为float
可变参数:在这里插入图片描述
可变参数的实现原理:
1、形参在栈空间上是连续存储的
2、第一个形参用来说明后面参数类型或者个数
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值