2016-11-14 2 views
0

Я местный программист в Дании, пытающийся помочь другу с его C exsam.Как читать этот код? exsam, подготовка

Ему нужно научиться читать определенные проекты кода, как этот. Однако я не могу сделать головы или хвосты в том, где результаты приходят из ... кто-то пожалуйста, помогите мне понять это, так что я могу помочь ему:

#include <stdio.h> 
#include <stdlib.h> 
int func1(int); 
void func2(int(*fp)(int), int); 
void main(){ 
    int (*fp)(int); 
    fp = func1; 
    (*fp)(1); 
    func2(fp,(*fp)(2)); 
} 
int func1(int arg){ 
    printf("Func1 %d\n", arg); 
    return arg; 
} 
void func2(int(*fp)(int), int arg){ 
    printf("Func2 %d\n",arg+fp(arg)); 
} 

Я знаю, что Anser является: Func1 1 Func1 2 Func1 2 Func2 4

однако почему это есть! Это путь выше моего платного аккаунта.

Я понимаю, что в void main() мы распыляем int ... однако этот взгляд выглядит странно.

Затем мы вызываем fp = func1;, что эффективно работает printf("Func1 %d\n", arg); текст должен быть «Func 1 (вставка агд здесь). Я не могу понять, почему это дают номер 1.

это то делает что-то здесь (*fp)(1); meaby какой-то указатель материал ???

я не понимаю, почему он работает printf("Func1 %d\n", arg); 3times подряд и снова, откуда эти цифры берутся?

и остальная часть кода не лучше

+0

Посмотрите на это снова: 'printf (" Func1% d \ n ", arg)'. Что он печатает? –

+1

'int (* fp) (int)' является указателем на функцию, которая принимает int и возвращает int, поэтому сигнатурой функции будет int some_name (int). Во второй строке 'fp = func1' мы присваиваем адрес' func1' 'fp' (обратите внимание, что сигнатура func1 является' int func1 (int) ', которая соответствует указанному выше объявлению. Следующая строка имеет эффект вызова func1 с аргументом 1. Я предлагаю, чтобы вы оба нажимали на указатели на функции и их использование :). – thurizas

ответ

0

int (*fp)(int); создает новый указатель на функцию, принимающий целое с именем fp

fp = func1; Устанавливает fp в func1

(*fp)(1); вызовы *fp, который является func1, с 1 => гравюра Func1 1

func2(fp,(*fp)(2)); звонками *fp , который составляет func1, с 2. Затем она вызывает func2 с результатом того, что 2 и fp, который в настоящее время 2 => печатает Func1 2 Func1 2 Func2 4

+0

'int (* fp) (int);' - указатель на функцию, принимающую целое число и возвращающее целое число, а не указатель int. –

+0

@MadPhysicist Спасибо! Я не очень острый с моим знанием указателя. Отредактировано, чтобы показать, что это указатель на funciton. – camiblanch

+0

'int (* fp) (int)' является указателем на функцию, которая принимает int и возвращает int, поэтому сигнатурой функции будет int some_name (int). Во второй строке 'fp = func1' мы присваиваем адрес' func1' 'fp' (обратите внимание, что сигнатура func1 является' int func1 (int) ', которая соответствует указанному выше объявлению. Следующая строка имеет эффект вызова func1 с аргументом 1. Я предлагаю, чтобы вы оба нажимали на указатели на функции и их использование :). – thurizas

0

Самым запутанным аспектом этого кода является запутанным использование указателей на функции.

void func2(int(*fp)(int), int); Является объявлением функции func2, которая принимает указатель на функцию с именем fp и целое число в качестве аргумента. fp - это указатель на функцию, которая принимает аргумент int и возвращает int. Поскольку эта строка является декларацией, ее можно было бы перефразировать как void func2(int(*)(int), int);. Имя указателя функции здесь не является строго необходимым (но оно будет включено в определение позже).

main объявляет указатель на функцию int (*fp)(int); и устанавливает ее на func1. Это возможно, потому что объявление func1 соответствует типу, ожидаемому указателем.

Затем мы вызываем функцию, на которую указывает fp: (*fp)(1);.Обратите внимание, что первый набор круглых скобок группирует звезду с именем указателя вместо возвращаемого значения функции. Другими словами, он говорит разыменовать указатель и вызвать функцию в этом месте, вместо того, чтобы вызвать функцию и разыменовать возвращаемое значение.

В большинстве версий C обозначение указателя может быть опущено, а указатели функций могут быть вызваны, как если бы они были самими функциями. Эта строка может быть переписана как fp(1);. Фактически, это обозначения, используемые для вызова fp в func2.

Далее мы вызываем func2 с fp (== func1) и результатом fp(2).

В целом, ожидаемая распечатка (с комментировали пояснения):

Func1 1 // (*fp)(1); in main() 
Func1 2 // Evaluating the argument (*fp)(2) to func2() in main() 
Func1 2 // Evaluating the argument fp(arg) to printf() in func2() 
Func2 4 // Printing the result of arg==2 + fp(arg)==2 in func2() 
0

Принимая это построчно, с некоторыми изменениями форматирования и несколько исправлений:

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

/** 
* Declarations for func1 and func2 
*/ 
int func1(int); 
void func2(int(*fp)(int), int); 

int main(void)  // main always returns int 
{ 
    int (*fp)(int);  // fp is a *pointer* to a function taking a single int parameter 
         // and returning an int value 
    fp = func1;   // assign the *address* of func1 to fp 
    (*fp)(1);   // call func1 through the pointer fp with an argument of 1 
    func2(fp,(*fp)(2)); // call func1 through fp again with a value of 2; 
         // pass that result, along with the value of fp 
         // (which is the address of func1) to func2. 
} 

/** 
* Print the input argument, return the value of the input argument 
*/ 
int func1(int arg){ 
    printf("Func1 %d\n", arg); 
    return arg; 
} 

/** 
* Call the function pointed to by fp with the input argument, add the 
* result to the input argument, print out the final value 
*/ 
void func2(int(*fp)(int), int arg){ 
    printf("Func2 %d\n",arg+fp(arg)); 
} 

В коде выше , fp - это указатель на функцию, принимающую параметр int и возвращающий результат int. Мы назначаем адрес от func1 до fp, а затем мы вызываем func1через указатель fp. Этот код в основном эквивалентна:

int main(void) 
{ 
    func1(1); 
    func2(func1, func1(2)); 
} 

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

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