2013-03-22 2 views
1

Недавно я читаю ядро ​​Linux. Я обнаружил, что во многих случаях они используют структуру «typedef xxx f (xxx)», но я не могу понять, как это работает. (что-то вроде функции указатель?)Проблемы с указателями функций в C/C++

Вот мой тестовый код.

#include<stdio.h> 
typedef int Myfunc(int); 
typedef int (*point_to_myfunc)(int); 
static Myfunc example; 
static int example(int a){ 
    printf("example a=%d\n", a); 
    return 1; 
} 
static void example2(Myfunc* f){ 
    printf("example2\n"); 
    f(2); 
} 
static void example3(int (*)(int)); 
static void example3(int (*point_to_Myfunc)(int)){ 
    printf("example3\n"); 
    point_to_Myfunc(3); 
} 
int main(){ 
    point_to_myfunc f=&example; 
    example2(f); 
    example3(f); 
    return 0; 
} 

Может ли кто-нибудь дать мне краткое объяснение? Thx ~

+0

Является ли 'typedef int Myfunc (int);' даже законным? – Shoe

+2

@Jueecy Почему бы и нет? Это имеет очень очевидное значение, так почему бы Стандарт не разрешить это? если вы хотите узнать, является ли typedef законным, просто удалите «typedef» и посмотрите, является ли это юридическим объявлением. 'int MyFunc (int);' ... yup. –

ответ

3
#include <stdio.h> 
typedef int Myfunc(int); 

Myfunc - название типа; это функция, принимающая аргумент int и возвращающая int.

typedef int (*point_to_myfunc)(int); 

point_to_myfunc является указателем на функцию принимает int аргумент и возвращающая int. Вы также можете: typedef Myfunc *ptr_to_myfunc;, если хотите (другое имя для одного и того же типа).

static Myfunc example; 

Это говорит: "существует функция называется example типа Myfunc.

static int example(int a) 
{ 
    printf("example a=%d\n", a); 
    return 1; 
} 

Это возможная реализация example. Вы не можете использовать имя typedef как Myfunc в определении функции этого типа.

static void example2(Myfunc *f) 
{ 
    printf("example2\n"); 
    f(2); 
} 

Это функция, которая принимает указатель на Myfunc. Строка f(2); вызывает функцию, указанную аргументом 2, и игнорирует возвращаемое значение.

static void example3(int (*)(int)); 

example3 Объявляет как функция принимает указатель на функцию, которая принимает int аргумент и возвращает int результат. Он может быть написан как static void example3(point_to_myfunc); или static void example3(ptr_to_myfunc); или static void example3(Myfunc *);.

static void example3(int (*point_to_Myfunc)(int)) 
{ 
    printf("example3\n"); 
    point_to_Myfunc(3); 
} 

Это реализация example3.

int main(void) 
{ 
    point_to_myfunc f = &example; 
    example2(f); 
    example3(f); 
    return 0; 
} 

Эта программа имеет переменную f это указатель на функцию. Интересно, что вы могли бы:

point_to_myfunc f2 = example; 
    point_to_myfunc f3 = *example; 

И т. Д. И все они означают одно и то же.

Вы также можете вызвать их с помощью:

(*f2)(101); 
    (**f3)(103); 

Стандартное обозначение для инициализации будет использовать ни &, ни *. Если вы старый программист C программы, вы можете вызвать указатель функции, используя нотацию (*f2)(101); до стандарта C89, это был единственный способ вызвать указатели на функции. Современный стиль обычно составляет f2(101);.

+0

Большое спасибо за ваше четкое объяснение. Это использование действительно мощное. – zhoutall

1
typedef int Myfunc(int); 

Это означает, что Myfunc является типом функции, которая принимает параметр int и возвращает int.

Эта линия:

static Myfunc example; 

то же самое, как говорят

static int example(int); 

, который вперед-объявляющий примера функцию.

Одно из них заключается в том, чтобы уточнить, что определенный набор функций используется для определенной цели.

typedef char CharacterConverter(char); 

extern CharacterConverter make_upper_case; 
extern CharacterConverter make_lower_case; 

extern void process_string(char *s,CharacterConverter *f); 
    // easier to see that make_upper_case and make_lower_case are valid arguments. 
+0

Что было бы практическим использованием такого typedef? –

+0

@ Koushik: Я добавил одно возможное использование. –

+0

+1. хорошо. есть опечатка. его символConverte (r) не (d). –

0

typedef полезен при определении типа.

Например: char *a, b; определен указатель «a» и символ b. char *a, *b определены два указателя на символ. Если использование ЬурейеЕ, будет ясно:

typedef char* PCHAR; 
PCHAR a,b; 

Теперь, как а и Ь является указателем символ.

typedef int Myfunc(int); 
typedef int (*point_to_myfunc)(int); 

две линии определили пару, формат функции и тип указателя, который может указывать на функции, так что это будет ясно и более очевидным при их использовании.

+0

ОП не спрашивал, что такое 'typedef' или пример того, для чего он хорош. –

+0

Ты прав, моя ошибка. – Bing

1

Vaughn Катон является правильным, Кроме того,

typedef int (*point_to_myfunc)(int); 

определяет указатель на функцию, это означает, что point_to_myfunc является тип, мы можем использовать его как это:

point_to_myfunc f=&example; 

Теперь е только например, пример(), мы могли бы использовать f() для вызова метода

Смежные вопросы