函數指針和指針函數一直在工做中會用到,如今mark下。部份內容是參考其餘人的總結。ide
int (*f) (int x); /* 聲明一個函數指針 */函數
f=func; /* 將func函數的首地址賦給指針f */spa
指向函數的指針包含了函數的地址,能夠經過它來調用函數。指針
聲明格式以下:
類型說明符 (*函數名)(參數)
其實這裏不能稱爲函數名,應該叫作指針的變量名。這個特殊的指針指向一個返回整型值的函數。指針的聲明類型和它指向函數的聲明保持一致。
指針名和指針運算符外面的括號改變了默認的運算符優先級。若是沒有圓括號,就變成了一個返回整型指針的函數的原型聲明。
例如:
void (*fptr)();
把函數的地址賦值給函數指針,能夠採用下面兩種形式:
fptr=&Function;
fptr=Function;
取地址運算符&不是必需的,由於單單一個函數標識符就標號表示了它的地址,若是是函數調用,還必須包含一個圓括號括起來的參數表。
能夠採用以下兩種方式來經過指針調用函數:
x=(*fptr)();
x=fptr();code
在FFMPEG 3.2 版本中找到一個函數指針:orm
/** * Read the format header and initialize the AVFormatContext * structure. Return 0 if OK. 'avformat_new_stream' should be * called to create new streams. */ int (*read_header)(struct AVFormatContext *);
定義函數flv_read_header();ip
static int flv_read_header(AVFormatContext *s) { FLVContext *flv = s->priv_data; int offset; avio_skip(s->pb, 4); avio_r8(s->pb); // flags s->ctx_flags |= AVFMTCTX_NOHEADER; offset = avio_rb32(s->pb); avio_seek(s->pb, offset, SEEK_SET); avio_skip(s->pb, 4); s->start_time = 0; flv->sum_flv_tag_size = 0; flv->last_keyframe_stream_index = -1; return 0; }
把函數的地址賦值給函數指針:get
AVInputFormat ff_flv_demuxer = { .name = "flv", .long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"), .priv_data_size = sizeof(FLVContext), .read_probe = flv_probe, .read_header = flv_read_header, .read_packet = flv_read_packet, .read_seek = flv_read_seek, .read_close = flv_read_close, .extensions = "flv", .priv_class = &flv_class, };
經過指針調用函數:input
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options) { ... ... if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header) if ((ret = s->iformat->read_header(s)) < 0) goto fail; ... ... }
函數指針本質上是一個指針變量,能夠經過它來調用函數原型
類型標識符 *函數名(參數表)
int *f(x,y);
首先它是一個函數,只不過這個函數的返回值是一個地址值。函數返回值必須用同類型的指針變量來接受,也就是說,指針函數必定有函數返回值,並且,在主調函數中,函數返回值必須賦給同類型的指針變量。
表示:
float *fun();
float *p;
p = fun(a);
在FFMPEG 3.2 版本中找到一個指針函數:
static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc, OutputStream *ost) { AVStream *st = ost->st; if (ost->filters_script && ost->filters) { av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for " "output stream #%d:%d.\n", nb_output_files, st->index); exit_program(1); } if (ost->filters_script) return read_file(ost->filters_script); else if (ost->filters) return av_strdup(ost->filters); return av_strdup(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? "null" : "anull"); }
//定義指針變量 char *avfilter; //函數返回值指向指針變量 avfilter = get_ost_filters(o, oc, ost);
指針函數:本質上是函數,返回值爲指針變量。