C 的本质 函数接口

  • 传入参数与传出参数

    如果函数接口有指针参数,既可以把指针所指向的数据传给函数使用(称为传入参数),也可以由函数填充指针所指的内存空间,传回给调用者使用(称为传出参数),例如strcpysrc参数是传入参数,dest参数是传出参数。有些函数的指针参数同时担当了这两种角色,如select(2)fd_set *参数,既是传入参数又是传出参数,这称为Value-result参数
1.传入参数示例:void func(const unit_t *p);
C语言本质鈥斺07--函数接口

2.传出参数示例:void func(unit_t *p);
C语言本质鈥斺07--函数接口

3.Value-result参数示例:void func(unit_t *p);
C语言本质鈥斺07--函数接口
    传出参数举例:
C语言本质鈥斺07--函数接口

  • 两层指针的参数
    两层指针也是指针,同样可以表示传入参数、传出参数或者Value-result参数,只不过该参数所指的内存空间应该解释成一个指针变量

#ifndef REDIRECT_PTR_H
#define REDIRECT_PTR_H
extern void get_a_day(const char **);
#endif



#include "redirect_ptr.h"

static const char *msg[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
            "Thursday", "Friday", "Saturday"};
void get_a_day(const char **pp)
{
     static int i = 0;
     *pp = msg[i%7];
     i++;
}




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

int main(void)
{
     const char *firstday = NULL;
     const char *secondday = NULL;
     get_a_day(&firstday);
     get_a_day(&secondday);
     printf("%s\t%s\n", firstday, secondday);
     ret
urn 0;
}

    两层指针作为传出参数还有一种特别的用法,可以在函数中分配内存,调用者通过传出参数取得指向该内存的指针
    通过参数分配内存示例:void alloc_unit(unit_t **pp); void free_unit(unit_t *p);
C语言本质鈥斺07--函数接口
C语言本质鈥斺07--函数接口

C语言本质鈥斺07--函数接口

C语言本质鈥斺07--函数接口


  • 返回值是指针
    如果返回值传出的是指针,分为两种情况:第一种是传出指向静态内存或已分配的动态内存的指针,例如localtime(3)inet_ntoa(3),第二种是在函数中动态分配内存并传出指向这块内存的指针,例如malloc(3),这种情况通常还要实现一个释放内存的函数。其实质就相当于一个指针函数。
1.返回指向已分配内存的指针示例:unit_t *func(void);
C语言本质鈥斺07--函数接口
C语言本质鈥斺07--函数接口

2.动态分配内存并返回指针示例:unit_t *alloc_unit(void);
                            void free_unit(unit_t *p);

C语言本质鈥斺07--函数接口

C语言本质鈥斺07--函数接口
C语言本质鈥斺07--函数接口



  • 回调函数

    如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它,这称为回调函数(Callback Function) 实质即是函数指针
       回调函数示例:void func(void (*f)(void *), void *p);
C语言本质鈥斺07--函数接口

例1:实现了一个repeat_three_times函数,可以把调用者传来的任何回调函数连续执行三次

#ifndef PARA_CALLBACK_H
#define PARA_CALLBACK_H

typedef void (*callback_t)(void *);
extern void repeat_three_times(callback_t, void *);

#endif


#include "para_callback.h"

void repeat_three_times(callback_t f, void *para)
{
     f(para);
     f(para);
     f(para);
}


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

void say_hello(void *str)
{
     printf("Hello %s\n", (const char *)str);
}

void count_numbers(void *num)
{
     int i;
     for(i=1; i<=(int)num; i++)
      printf("%d ", i);
     putchar('\n');
}

int main(void)
{
     repeat_three_times(say_hello, "Guys");
     repeat_three_times(count_numbers, (void *)4);
     return 0;
}


  • 可变参数

   只见过一个带有可变参数的函数printf
                        int printf(const char *format, ...);
C语言本质鈥斺07--函数接口

       确定可变参数的个数,在参数列表的末尾传一个Sentinel,例如NULL。下面实现一个printlist函数,可以打印若干个传入的字符串。
C语言本质鈥斺07--函数接口







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值