При решении задач в методических целях нельзя использовать выражение вида a[i] и
вообще квадратные скобки (только в этой лабораторной работе). Вместо него используется
выражение *pa, где pa - указатель на i-ый элемент массива (именно на i-ый элемент, а не
выражение вида *(pa + i)). Также нельзя передавать как аргумент размер массива в элементах,
если массив уже создан. Вместо этого предлагается использовать пару указателей: на первый элемент
массива и на элемент массива, расположенный за последним. Ситуация когда эти массивы совпадают,
означает пустоту обрабатываемого массива.
Написать программу, которая считывает из текстового файла целые числа в массив и выполняет обработку этого массива (см. распределение вариантов). Память под массив выделяется динамически. Число элементов в массиве определяется в первом проходе по текстовому файлу, во время второго прохода числа считываются в массив. Имя файла передается через параметры командной строки.
- ✅ Вычислить значение
max(x[0] + x[n-1], x[1] + x[n-2], x[2] + x[n-3], ..., x[(n-1)/2] + x[n/2])
, гдеn
размер массива. - Вычислить значение
x[0]*y[0]+x[1]*y[1]+ ... + x[k]*y[k]
, гдеx[i]
– отрицательные элементы массива a из n элементов, взятые в порядке их следования;y[i]
– положительные элементы этого массива, взятые в обратном порядке;k = min(p,q)
, гдеp
– количество положительных элементов массива a,q
– количество отрицательных элементов этого массива. - Вычислить значение
x[0] + x[0]*x[1] + x[0]*x[1]*x[2] + ... + x[0]*x[1]*x[2] ... x[m]
, гдеx[i]
- элементы массива x изn
элементов,m
- индекс первого отрицательного элемента этого массива либо числоn-1
, если такого элемента в массиве нет. - Вычислить значение
min(x[0]*x[1], x[1]*x[2],x[2]*x[3], ..., x[n-3]*x[n-2], x[n-2]*x[n-1])
, гдеx[i]
- элементы массиваx
изn
элементов. - Найти количество различных чисел в файле.
Практически каждый процессор имеет специальный встроенный регистр - счетчик тактов, значение которого можно получить специальной командой процессора. Команда процессора RDTSC
(Read Time Stamp Counter) возвращает в регистрах EDX
и EAX
64-разрядное беззнаковое целое, равное числу тактов с момента запуска процессора. Вызвав эту команду до и после участка программы, для которого требуется вычислить время исполнения, можно вычислить разность показаний счетчика. Оно равно числу тактов, затраченных на исполнение замеряемого участка. Для перехода от числа тактов к времени требуется умножить число тактов на время одного такта (величина, обратная тактовой частоте процессора). Для процессора с тактовой частотой 1ГГц время такта - 1 нс.
Достоинством этого способа является максимально возможная точность измерения времени, недостатком - команда получения числа тактов зависит от архитектуры процессора.
Недостатки способа и подходы к борьбе с ними описаны в работе «Использование Time-Stamp Counter для измерения времени выполнения кода на процессорах с архитектурой Intel 64 и IA-32» Михаила Курносова.
#include <stdio.h>
unsigned long long tick(void)
{
unsigned long long d;
__asm__ __volatile__ ("rdtsc" : "=A" (d) );
return d;
}
void test(void)
{
long double test = 0.0;
for(unsigned long long i = 0; i < 10000; i++)
test += 0.5;
}
#define N 5
int main(void)
{
unsigned long long tb, te;
tb = tick();
for(int i = 0; i < N; i++)
test();
te = tick();
printf("test 'time': %llu\n", (te - tb) / N);
return 0;
}