函数接口

来源:互联网 发布:js设置div背景颜色 编辑:程序博客网 时间:2024/05/18 00:10

1. strcpy与strncpy
#include <string.h>

char *strcpy(char *dest, const char *src);
    chasr *strncpy(char *dest, const char *src, size_t n);
把src所指向的字符串copy到des所指向的内存空间,看参数也知道,因为dest是char*类型的,而src是const char*,说明src所只相当内存空间在函数中只能读不能改写,而dest所指向的内存空间在函数中是可以改写的
Eg:  char buf[10];
  strcpy(buf,”hello”;) 
     printf(buf);
strcpy在copy字符串时会把结尾的’\0’也复制到dest中,因此保证了dest中是以’\0’结尾的字符串,但是,strcpy只知道src字符串的首地址,不知道长度,它会一直拷贝到’\0’为止,所以dest所指向的内存空间要足够大,否则可能写越界

char *strncpy(char *dest,const char *src,size_t n)
{
  size_t  i;
  for(i+0;i<n&&src[i]!=’\0’;i++)
  dest[i]=src[i];
  for(;i<n;i++)
  dest[i]=’\0’;

 return dest;
}


 Strncpy可以用截断的方式保证写不越界,但是有可能产生读越界
   char buf[10];
 strncpy(buf,”hello world”,sizeof(buf));
 buf[sizeof(buf)-1]=’\0’;

 

2. malloc与free
c标准库函数malloc可以在堆空间动态分配内存,它的底层
它的底层通过brk系统调用像操作系统申请内存。动态分配的内存用完之后可以用free释放,癸亥给malloc,这样下次调用malloc时可以再次被分配

 #include <stdio.h>
 Void *malloc(size_t,size);
//成功返回所分配内存空间的首地址,出错返回NULL
 Void free(void *ptr);
内存泄露:每次分配完了不释放,导致最后内存耗尽
 Void foo(void)
{
  char *p =malloc(10);
  …
}
foo函数返回时要释放局部变量p的内存空间,它所指向的内存地址就丢失了,这10个字节也就没法释放了。一定要保存好malloc返回的指针。


3. 传入参数与传出参数
如果函数借口有指针参数,可以把指针所指向的数据传给函数使用,称为传入参数,也可以由函数填充指针所指的内存空间,传回给调用者使用,称为传出参数

传入参数示例:
   void func(const unit_t *p)
调用者:
(1) 分配p所指的内存空间
(2) 在p所指的内存空间中保存数据
(3) 调用函数
(4) 由于有const限定符,调用者可以确信p所指的内存空间不会被改变
实现者:
(1) 指定指针参数的类型unit_t *
(2) 读取p所指的内存空间

传出参数示例:
调用者:
(1) 分配p所指的内存空间
(2) 调用函数
(3) 读取p所指的内存空间
实现者:
(1) 规定指针参数的类型unit_t *
(2) 在p所指的内存空间中保存数据

 

 

4. 两层指针的参数

 

5. 返回值是指针的情况
返回指向已分配内存的指针示例:unit_t *func(void)
调用者:
(1) 调用函数
(2) 将返回值保存下来以备后用
实现者
(1) 规定返回值指针的类型unit_t *
(2) 返回一个指针

动态分配内存并返回指针
//ret_allocator.h
#ifndef RET_ALLOCATOR_H
#define RET_ALLOCATOR_H

  typedef struct{
  int number;
  char *msg;
} unit_t;

  extern unit_t *alloc_unit(void);
  extern void free_unit(unit_t *);
#endif

//ret_allocator.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include “ret_allocator.h”

  unit_t *alloc_unit(void)
{
  unit_t *p=malloc(sizeof(unit_t));
  if(p==NULL){
printf(“out of memory\n”);
exit(1);
}
p->number=3;
p->msg=malloc(20);
strcpy(p->msg,”hello world!”);
return p;
}

  void free_unit(unit_t *p)
{
 free(p->msg);
 free(p);
}

//main.c
#include <stdio.h>
#include “ret_allocator.h”

Int main(void){
 unit_t *p=alloc_unit();
 
 printf(“number:%d\nmsg:%s\n”,p->number,p->msg);
 free_unit(p);
 p=NULL;
 return 0;
}


6. 回调函数
如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它,
这叫做回调函数callback fuction
示例:void func(void(*f)(void *),void *p);
调用者:
(1) 提供一个回调函数,再提供一个准备传给回调函数的参数
(2) 把回调函数传给参数f,把准备传给回调函数的参数按void *类型传给参数p

实现者:
在适当的时候根据调用者传来的函数指针f调用回调函数,将调用者传来的参数p转交给回调函数,就是调用f(p);

原创粉丝点击