Программирование для Linux. Профессиональный подход
Шрифт:
0.00 0.00 1/1806 make_zero [16]
34846 even <cycle 1> [13]
Выражение
1+69693
в секции 10 сообщает о том что цикл 1 выполнялся один раз и в нем насчитывается 69693 обращений к функциям. Первой в цикле вызывалась функция even
, а из нее — функция odd
. Обе функции вызывались по 34847 раз. Утилита
gprof
располагает рядом полезных опций. ■ При задании опции
– s
будут суммироваться результаты нескольких запусков программы. ■ С помощью опции
– c
можно
■ При задании опции
– l
отображается построчная профильная информация. ■ При задании опции
– A
будет отображен исходный текст программы, сопровождаемый процентными показателями времени выполнения. А.3.4. Как работает утилита gprof
Схема работы утилиты
gprof
выглядит следующим образом. Когда в ходе выполнения программы происходит вызов функции, счётчик обращений к функции увеличивается на единицу. Утилита периодически прерывает программу, чтобы выяснить, какая функция выполняется в данный момент. На основании этих '"выборок" и определяется время выполнения. В Linux тактовые импульсы генерируются с интервалом 0,01 с, следовательно, это наименьший промежуток между прерываниями. Таким образом, профильные данные о слишком быстро выполняющихся функциях могут оказаться неточными. Во избежание погрешностей рекомендуется запускать программу на длительные периоды времени или суммировать профильные данные по результатам нескольких запусков (это делается с помощью опции – s
). А.3.5. Исходные тексты программы-калькулятора
В листинге А.3 показан текст программы, вычисляющей значения постфиксных выражений.
Листинг А.3. (calculator.c) Основная часть программы-калькулятора
/* Вычисления в унарном формате. */
/* На вход программы подаются однострочные выражения
в обратной польской (постфиксной) записи, например:
602 7 5 - 3 * +
Вводимые числа должны быть неотрицательными
десятичными числами. Поддерживаются операторы
"+", "-" и "*". Унарные операторы "even" и "odd"
возвращают значение 1 в том случае, когда операнд
является четным или нечетным соответственно.
Лексемы разделяются пробелами. Отрицательные числа
не поддерживаются. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "definitions.h"
/* Эта функция выполняет указанную бинарную операцию над
операндами, извлекаемыми из стека, помещая результат
обратно в стек, в случае успеха возвращается
ненулевое значение. */
int apply_binary_function(number (*function)(number, number),
Stack* stack) {
number operand1, operand2;
if (empty_stack(*stack))
return 0;
operand2 = pop_stack(stack);
if (empty_stack(*stack))
return 0;
operand1 = pop_stack(stack);
push_stack(stack, (*function)(operand1, operand2));
destroy_number(operand1);
destroy_number(operand2);
return 1;
}
/*
Эта функция выполняет указанную унарную операцию над
операндом, извлекаемым из стека, помещая результат
обратно в стек. В случае успеха возвращается
ненулевое значение. */
int apply_unary_function(number (*function)(number), Stack* stack) {
number operand;
if (empty_stack(*stack))
return 0;
operand = pop_stack(stack);
push_stack(stack, (*function)(operand));
destroy_number(operand);
return 1;
}
int main {
char command_line[1000];
char* command_to_parse;
char* token;
Stack number_stack = create_stack;
while (1) {
printf("Please enter a postfix expression:\n");
command_to_parse =
fgets(command_line, sizeof (command_line), stdin);
if (command_to_parse = NULL)
return 0;
token = strtok(command_to_parse, " \t\n");
command_to_parse = 0;
while (token != 0) {
if (isdigit(token[0]))
push_stack(&number_stack, string_to_number(token));
else if (((strcmp(token, "+ ") == 0) &&
!apply_binary_function(&add, &number_stack)) ||
((strcmp(token, "-") == 0) &&
!apply_binary_function(&subtract, &number_stack)) ||
((strcmp(token, "*") == 0) &&
!apply_binary_function(&product, &number_stack)) ||
((strcmp(token, "even") == 0) &&
!apply_unary_function(&even, &number_stack)) ||
((strcmp(token, "odd") == 0) &&
!apply_unary_function(&odd, &number_stack)))
return 1;
token = strtok(command_to_parse, " \t\n");
}
if (empty_stack(number_stack))
return 1;
else {
number answer = pop_stack(number_stack);
Поделиться с друзьями: