This commit is contained in:
Dmitry Sudarenko 2024-11-14 08:39:22 +03:00
parent cd6a6b2682
commit 36e537a26f
23 changed files with 580 additions and 35 deletions

Binary file not shown.

Binary file not shown.

BIN
03_Lecture03/gmon.out Normal file

Binary file not shown.

View File

@ -1,13 +1,13 @@
all: prog
prog: main.o func.o
gcc -g -o main main.o func.o
gcc -o prog main.o func.o
main.o: main.c
gcc -g -c -o main.o main.c
gcc -c -o main.o main.c
func.o: func.c
gcc -g -c -o func.o func.c
gcc -c -o func.o func.c
clean:
del *.o

View File

@ -3,7 +3,7 @@
{
"type": "cppbuild",
"label": "C/C++: gcc.exe build active file",
"command": "C:\\msys64\\ucrt64\\bin\\gcc.exe",
"command": "D:\\msys64\\ucrt64\\bin\\gcc.exe",
"args": [
"-fdiagnostics-color=always",
"-g",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 30
@ -11,7 +12,8 @@ struct sensor {
int8_t t;
};
void cgangeIJ(struct sensor* info,int i, int j){
void cgangeIJ(struct sensor info[],int i, int j)
{
struct sensor temp;
temp=info[i];
info[i]=info[j];
@ -27,16 +29,33 @@ void SortByT(struct sensor* info,int n){
unsigned int DateToInt(struct sensor* info){
return info->year << 16 | info->month << 8 | info->day;
//~ return info->year*366+info->month*12+info->day;
}
//~ int Compare(struct sensor* a,struct sensor* b)
int Compare(const void* ta,const void* tb)
{
struct sensor* a = (struct sensor*)ta;
struct sensor* b = (struct sensor*)tb;
if(a->year != b->year)
return a->year - b->year;
else if (a->month != b->month)
return a->month - b->month;
else
return a->day - b->day;
}
//упорядочивающую его по дате
void SortByDate(struct sensor* info,int n){
for(int i=0; i<n; ++i)
for(int j=i; j<n; ++j)
if(DateToInt(info+i)>= DateToInt(info+j))
if(Compare(info+i,info+j)>0)
//~ if(DateToInt(info+i)>= DateToInt(info+j))
cgangeIJ(info,i,j);
}
void AddRecord(struct sensor* info,int number,
void AddRecord(struct sensor info[],int number,
uint16_t year,uint8_t month,uint8_t day,int8_t t){
info[number].year = year;
info[number].month = month;
@ -80,7 +99,7 @@ void save_bin_d(struct data* d)
{
FILE* f = fopen("sensor.bin","wb");
fwrite(&d->number,sizeof(d->number),1,f);
fwrite(d->info,d->number*sizeof(struct sensor),1,f);
fwrite(d->info,d->number*sizeof(d->info[0]),1,f);
fclose(f);
}
@ -105,16 +124,17 @@ void print(struct sensor* info,int number){
int main(void)
{
d.number=AddInfo(d.info);
d.number=AddInfo(d.info);// ctrl+e
print(d.info,d.number);
save_bin(d.info,d.number);
save_bin_d(&d);
printf("\nSort by t\n");
SortByT(d.info,d.number);
print(d.info,d.number);
printf("\nSort by date\n");
SortByDate(d.info,d.number);
//~ SortByDate(d.info,d.number);
qsort(d.info,d.number,sizeof(d.info[0]),Compare);
print(d.info,d.number);
load_bin(d.info,d.number);
load_bin_d(&d);
print(d.info,d.number);
return 0;
}

View File

@ -9,7 +9,7 @@ enum {PATH_LENGTH=256};
#define STR255 "%255s"
void convert_path_to_full(char *full_path, const char *dir) {
if(dir[0]=='/') {
if(dir[0]=='/') {
strcpy(full_path, dir);
} else if (dir[0]=='.') {
getcwd(full_path,PATH_LENGTH);
@ -67,19 +67,19 @@ void ls(const char *dir) {
DIR *folder;
struct dirent *entry;
int files_number = 0;
char full_path[PATH_LENGTH]={0};
char full_path[PATH_LENGTH]= {0};
convert_path_to_full(full_path, dir);
folder = opendir(full_path);
if(folder == NULL){
if(folder == NULL) {
perror("Unable to read directory");
printf("%s\n",full_path);
return;
}
while( (entry=readdir(folder)) ) {
while( (entry=readdir(folder)) ) {
if( entry->d_name[0]=='.' )// пропускаем поддиректории
continue;
char full_filename[PATH_LENGTH]={0};
files_number++;
char full_filename[PATH_LENGTH]= {0};
files_number++;
print_tab(tab_count);//отступы при рекурсии
printf("%4d : ",files_number);
//print_filetype(entry->d_type);
@ -88,7 +88,7 @@ void ls(const char *dir) {
strcat(full_filename, entry->d_name);
printf("%s", entry->d_name);
print_space(20, entry->d_namlen);
if (!stat(full_filename, &file_stats)){
if (!stat(full_filename, &file_stats)) {
print_file_size(file_stats.st_size);
printf("\n");
}
@ -101,13 +101,31 @@ void ls(const char *dir) {
tab_count--;
}
int main(void)
{
int main(int argc, char *argv[]) {
char dir[PATH_LENGTH], buf[PATH_LENGTH];
printf("Input dir: ");
scanf(STR255,dir);
convert_path_to_full(buf, dir);
printf("ls for folder %s\n",buf);
ls(dir);
int rez=0;
// opterr=0;
while ( (rez = getopt(argc,argv,"hf:")) != -1) {
switch (rez) {
case 'h':
printf("This is example of list directory\n");
printf("Usage: clear [options]\n\
-h This help text\n\
-f Specify folder.\n");
printf("Example: %s -f /tmp\n",argv[0]);
return 0;
case 'f': //printf("folder is \"f = %s\".\n",optarg);
strcpy(dir, optarg);
convert_path_to_full(buf, dir);
printf("ls for folder %s\n",buf);
ls(dir);
return 0;
break;
case '?':
printf("Unknown argument: %s Try -h for help\n", argv[optind-1]);
return 1;
};
};
printf("-h help text\n");
return 0;
}

View File

@ -1,14 +1,15 @@
#include <stdio.h>
#define SWAP(type,a,b) {type t = a; a = b; b = t;}
#define SWAP(type,a,b) do {type a##1 = a; a = b; b = a##1;}while(0)
int main(void)
{
int a=5, b=7;
if (a<b)
SWAP(int, a,b)//{...}
int a=5, t=7;
printf("a = %d b = %d\n", a, t);
if (a<t)
SWAP(int, a,t);//{...}
else
a = 1000;
printf("a = %d b = %d\n", a, b);
printf("a = %d b = %d\n", a, t);
return 0;
}

View File

@ -1,6 +1,6 @@
#include <stdio.h>
#include "sensor.h"
#include <string.h>
#include <inttypes.h>
void cgangeIJ(struct sensor *info, int i, int j)
{
@ -18,7 +18,7 @@ void SortByT(struct sensor *info, int n)
cgangeIJ(info, i, j);
}
int CompareDate(const void *x,const void *y)
int CompareDate(const void *x, const void *y)
{
struct sensor *a = (struct sensor *)x;
struct sensor *b = (struct sensor *)y;
@ -39,13 +39,25 @@ unsigned int DateToInt(struct sensor *info)
{
return info->year << 16 | info->month << 8 | info->day;
}
uint64_t DateToInt64(struct sensor *info)
{
uint8_t h = 1, m = 2, s = 3;
uint64_t result;
result = (uint64_t)info->year << 40 | (uint64_t)info->month << 32 |
(uint64_t)info->day << 24 |
h << 16 | m << 8 | s;
printf("%"PRIx64"\n",result);
return result;
}
// упорядочивающую его по дате
void SortByDate(struct sensor *info, int n)
{
for (int i = 0; i < n; ++i)
for (int j = i; j < n; ++j)
if (CompareDate(info + i, info + j) > 0)
//~ if(DateToInt(info+i)>= DateToInt(info+j))
// if (CompareDate(info + i, info + j) > 0)
if (DateToInt64(info + i) >= DateToInt64(info + j))
cgangeIJ(info, i, j);
}
void AddRecord(struct sensor *info, int number, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, int8_t t)

View File

@ -0,0 +1,105 @@
/* XPM */
static char *dummy[]={
"100 100 2 1",
"# c #000000",
". c #ffffff",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"######..............................................................................................",
"......######........................................................................................",
"............######..................................................................................",
"..................##................................................................................",
"...................#................................................................................",
"...................#................................................................................",
"...................#................................................................................",
"....................#...............................................................................",
"....................#...............................................................................",
"....................#...............................................................................",
".....................#..............................................................................",
"......................#.............................................................................",
"......................#.............................................................................",
".......................#............................................................................",
".......................##...........................................................................",
"........................#...........................................................................",
"........................##..........................................................................",
".........................##.........................................................................",
"..........................##........................................................................",
"...........................##.......................................................................",
"............................#.......................................................................",
".............................#......................................................................",
"..............................##....................................................................",
"...............................#....................................................................",
"................................#...................................................................",
".................................##.................................................................",
"..................................##................................................................",
"....................................###.............................................................",
".......................................#............................................................",
"........................................##..........................................................",
"..........................................##........................................................",
"............................................###.....................................................",
"...............................................###..................................................",
"..................................................#.................................................",
"...................................................#######..........................................",
"..........................................................###.......................................",
".............................................................####################...................",
".................................................................................##########.........",
"..........................................................................................##........",
"............................................................................................###.....",
"...............................................................................................#....",
"................................................................................................#...",
".................................................................................................#..",
".................................................................................................#..",
".................................................................................................#..",
".................................................................................................##.",
"..................................................................................................##",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"....................................................................................................",
"...................................................................................................."};

View File

@ -0,0 +1,57 @@
//~ 1. Написать пару функций, одна из которых будет устанавливать все биты, а другая — снимать по маске.
//~ Возможное решение: bits.c
//~ Простейшая вещь, но довольно полезная (особенно в контексте того, что именно так работает большинство флешек).
#include <stdio.h>
#include <stdint.h>
//Начало решения
void set_all_bits (void *arg)
{
//Писать 0xFFFFFFFFFFFFFFFF тоже не очень,
//так как мы вообще говоря не знаем длину типа.
//~0 гарантирует единичные биты.
* (unsigned int*)arg = ~0;
}
int reset_some_bits(void *dest, unsigned int val)
{
*(unsigned int*)dest &= val;//приведение типов
return (*(unsigned int*)dest == val);
}
int set_some_bits(void *dest, unsigned int val)
{
*(unsigned int*)dest |= val;//приведение типов
return (*(unsigned int*)dest == val);
}
// Конец решения
int main()
{
float var = 0;
uint32_t a=4095;
uint32_t b=2000;
uint32_t c=4095;
uint32_t d=0xffff;
int status = 0;
//~ scanf("%x%x%x%x", &a, &b, &c, &d); //a=4095, b=2000, c=4095, d=0xffff
set_all_bits(&a);
printf("set_all_bits a: %#X\n",a);
status = reset_some_bits(&a, 0x25);
status = printf("reset_some_bits 0x25 %d %#X\n",status, a);
set_all_bits(&a);
printf("set_all_bits a: %#X\n",a);
status = reset_some_bits(&var, b);
printf("reset_some_bits %d %#X %f\n",status, a, var);
status = reset_some_bits( &var, c );
printf("reset_some_bits %d %#X %f\n",status, a, var);
set_all_bits(&var);
status = reset_some_bits(&var, d);
printf("reset_some_bits %d %#X %f\n",status, a, var);
return 0;
}

View File

@ -0,0 +1,58 @@
//~ 2. Прочесть из потока ввода число типа float и затем вывести его на экран в формате a*2\^b,
//~ где a и b — десятичные числа, причём а в диапазоне от [0,1; 1).
//~ Возможное решение: float.c. думал спервадать задачу на полноценный вывод, но сложновато получится на мой взгляд.
//~ Пример решения: float.c
#include <stdio.h>
#include <stdint.h>
int main ()
{
float a=0;
uint32_t* pa = (uint32_t*)&a;
int o=0;
scanf("%f", &a);
if(a<0)
{
putchar('-');
}
float m_f = (*pa & 0x7FFFFF ) / (float)0x800000 ;
o = (((*pa) >> 23) & 0xFF) - 127 ;
putchar ('1');
putchar (',');
for (int i = 0; i < 9; i++)
{
m_f*=10;
putchar ('0'+ m_f);
m_f = m_f - (int)m_f;
}
putchar ('*');
putchar ('2');
putchar ('^');
if(o<0)
{
putchar ('-');
o=-o;
}
if ( o >= 100)
{
putchar ('1');
o%=100;
}
if(o>=10)
{
putchar('0' + o/10);
o%=10;
}
putchar('0' + o);
return 0;
}

View File

@ -0,0 +1,40 @@
//~ 3. Реализовать работу с битовым массивом. функции
//~ int setbit(int index, int bit, uint32_t array[])
//~ int getbit(int index,uint32_t array[])),
//~ устанавливали (забирали) index-й бит по счёту в массиве array.
#include <stdio.h>
#include <stdint.h>
int setbit(int index, int bit, uint32_t array[]) //index=0..8*sizeof(array)
{
bit = (bit != 0);
int byte_number = index/8/sizeof(uint32_t);
array [byte_number] &= ~(1 << (index%32)) ;
array [byte_number] |= (bit << (index%32)) ;
return bit;
}
int getbit(int index,uint32_t array[])
{
int byte_number = index/8/sizeof(uint32_t);
uint32_t bit = array[byte_number] & (1 << (index%32));
return bit != 0;
}
//Конец решения
int main()
{
uint32_t array[100] = {0};
int index=0,b=0;
scanf ("%d%d",&index, &b);
if (index<0 || index > 8*sizeof(array))
return 1;
setbit (index,b,array);
printf("%u\n", array[index/32]);
printf("%d\n", getbit(index,array));
return 0;
}

View File

@ -0,0 +1,30 @@
//Пример: address.c. Написать функцию set_value, устанавливающую значение по заданному в виде целого числа адресу.
#include <stdio.h>
#include <stdint.h>
int var[100];
// Начало решения
void set_value(uint64_t addr, uint32_t val)
{
*(uint32_t*) addr = val;
}
// Конец решения
int main()
{
int a,b;
scanf("%d%d", &a,&b);
set_value( (size_t) & var[b], a );
printf("%d\n", var[b]);
set_value( (size_t) (var+b), a );
printf("%d\n", var[b]);
set_value( (size_t) var+b, a );
printf("%d\n", var[b]);
//~ set_value( var+b, a );//ОШИБКА!!!
printf("%d\n", var[b]);
return 0;
}

View File

@ -0,0 +1,46 @@
//~ 2. Пример: union.c. Написать typedef для 32-битного типа с названием my_type таким образом,
//~ чтобы можно было обращаться к байтам(поле с названием byte),
//~ полусловам(u16), словам (u32) и числам с плавающей запятой (f)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//Начало решения
typedef union
{
uint32_t u32;
uint16_t u16[2];
uint8_t byte[4];
float f;
} my_type;
//Конец решения
int main()
{
my_type var;
float f;
uint16_t u16;
uint8_t u8;
uint32_t u32;
scanf ("%d%ld%lu%f", &u8, &u16, &u32, &f);
var.f = f;
printf("%lu\n", var.u32);
var.u32 = 0;
var.byte[2] = u8;
printf("%lu\n", var.u32);
var.u32 = 0;
var.u16[1] = u16;
printf("%lu\n", var.u32);
var.u32 = u32;
printf("%f\n", var.f);
return 0;
}

View File

@ -0,0 +1,50 @@
//~ 3. Пример: ihex.c.
//~ Написать функцию print_array_similarly_to_intel_hex(void* addr, int len) (название условное, естественно),
//~ выводящую на экран массив в следующем текстовом формате (все числа выводятся шестнадцатеричными числами в верхнем регистре, по два символа на байт):
//~ 1. Первая строка: двоеточие, затем все байты адреса, кроме двух младших;
//~ 2. Каждая следующая строка содержит данные, разложенные по полям:
//~ 1. Двоеточие (`':'`)
//~ 2. Первое поле — два байта (младшие два байта тех данных,
//~ которые выводятсяв данной строке — для первой строки данных это будут просто два младших байта переменной `addr`,
//~ для каждой следующей строки прибавляем к предыдущему адресу число байтов данных, записанных в предыдущей строке).
//~ 3. Второе поле — число 00
//~ 4. Третье поле — данные (не более 16 байтов, подряд)
//~ 5. Четвёртое поле — один байт, считающийся как сумма всех предыдущих байтов в строке (с переполнением, разумеется).
#include <stdio.h>
#include <stdint.h>
uint32_t array[100];
void print_array_similar_to_intel_hex(void* addr, int len)
{
int i=0;
uint8_t checksum = 0;
printf(":%04X\n", ((uint64_t)addr >> 16) &0xFFFF );
for( i = 0; i < len; ) // Здесь я не инкрементирую i, так как удобнее делать проверку внутри тела, но после инкрементирования
{
if( i % 16 == 0) // т.к. пишем не более 16 байтов на строку по условию, i%16 - признак начала строки
{
printf( ":%04X00", (uint64_t)addr & 0xFFFF );
checksum = ((uint64_t)addr & 0xFF) + ( ((uint64_t)addr >> 8) & 0xFF);
}
printf("%02X", *(uint8_t*)addr);
checksum += *(uint8_t*)addr;
addr++;
i++; /// А вот тут увеличиваем i и смотрим, не закончилась ли строка
if( i % 16 == 0 || i == len) // т.к. пишем не более 16 байтов на строку по условию, i%16 - признак конца строки, либо - если завершили всю записб
{
printf( "%02X\n", checksum );
}
}
}
int main()
{
array[0] = 0x12345678;
array[1] = 0xABCDEF12;
print_array_similar_to_intel_hex(array, 100);
return 0;
}

View File

@ -0,0 +1,66 @@
// В файле 1.xpm должен быть определён рисунок с именем dummy
// В нём — двухцветный рисунок, чёрная линия на любом (непрозрачном) фоне
#define NAME dummy
#include "1.xpm"
#include <stdint.h>
#include <stdio.h>
#define MAX_W (1000)
uint16_t array[MAX_W];
int parse_xpm(char** xpm, uint16_t *result)
{
int width=0, height=0, colors=0, syms_per_pixel=0;
char black; // Сюда запомним, каким символом обозначается чёрный цвет (цвет линии)
int color = 1; // 0 - чёрный цвет, а нам нужно его найти как раз. Поэтому инициализируем любым ненулевым значением
int line = 0; // Текушая строка файла при его разборе
sscanf (xpm[line++], "%d%d%d%d", &width, &height, &colors, &syms_per_pixel); // читаем первую строку
// width = width<MAX_W ? width : MAX_W; // /Дли примера считаем, что в этом отношении файл корректен, но можно и передавать в функцию размер массива для оценки
if(colors != 2 || syms_per_pixel != 1) // если больше двух цветов или не один символ на элемент изображения (хм) — нафиг такое, лень парсить
{
return 0;
}
while (color != 0 && line < colors+1) //Ищем чёрный цвет
{
sscanf(xpm[line++], "%c c #%x", &black, &color);
}
if (color != 0) // Чёрный цвет не найден
{
return 0;
}
for (; line < height; line++)
{
for (int pos = 0; pos < width ; pos ++)
{
if (NAME[line][pos] == black) // Как только на данной высоте наткнулись на чёрный цвет, тут же запоминаем высоту в массив; таким образом мы получаем форму сигнала,
// снятую с нижней части чёрной линии на одноцветном фоне
{
array[pos] = height - line + 3; //+3, так как здесь у нас номер строки в файле, которая на три больше, чем номер строки в изображении (первые три строки - служебная информация: строка с размером и две строки с цветами)
}
}
}
return width;
}
int main (int arc, char ** argv)
{
int width = parse_xpm(NAME, array);
for (int i = 0; i < width; i++)
{
printf("%d ", array[i]);
}
putchar('\n');
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -0,0 +1,42 @@
# 1. Процесс сборки
По сборке (препроцессирование → компиляция → линковка) на удивление вопросов особо нет. Есть один уже на курсе Владмира (STM32),когда нужно к своему проекту подлкючить библиотеку, собранную без поддержки FPU (есть такой прикол у ST), но там так и надо.
# 2. Битовые операции
Тут все всё знают, но часто не очень понимают. На самом деле полезны будут задачи такого рода:
1. Написать пару функций, одна из которых будет устанавливать все биты, а другая — снимать по маске. Возможное решение: bits.c
Простейшая вещь, но довольно полезная (особенно в контексте того, что именно так работает большинство флешек).
2. Прочесть из потока ввода число типа float и затем вывести его на экран в формате a*2\^b, где a и b — десятичные числа, причём а в диапазоне от [0,1; 1). Возможное решение: float.c. думал спервадать задачу на полноценный вывод, но сложновато получится на мой взгляд. Пример решения: float.c
3. Реализовать работу с битовым массивом. Ну, то есть функции setbit(uint8_t *array, index, value), int getbit (uint8_t * array, index), тиакие, чтобы устанавливали (забирали) index-й бит по счёту в массиве array. Тоже несложно, но мозг прочистит. Пример, bit_array.c (там немного другие прототипы, т.к. я не понял, как удобнее формулировать задание).
# 3. Адресная арифметика и указатели
Тоже — все всё знают, а сказать не могут.
1. Пример: address.c. Написать функцию set_value, устанавливающую значение по заданному в виде целого числа адресу.
2. Пример: union.c. Написать typedef для 32-битного типа с названием my_type таким образом, чтобы можно было обращаться к байтам(поле с названием byte), полусловам(u16), словам (u32) и числам с плавающей запятой (f). Ибо это туда же.
3. Пример: ihex.c. Написать функцию print_array_similarly_to_intel_hex(void* addr, int len) (название условное, естественно), выводящую на экран массив в следующем текстовом формате (все числа выводятся шестнадцатеричными числами в верхнем регистре, по два символа на байт):
1. Первая строка: двоеточие, затем все байты адреса, кроме двух младших;
2. Каждая следующая строка содержит данные, разложенные по полям:
1. Двоеточие (`':'`)
2. Первое поле — два байта (младшие два байта тех данных, которые выводятсяв данной строке — для первой строки данных это будут просто два младших байта переменной `addr`, для каждой следующей строки прибавляем к предыдущему адресу число байтов данных, записанных в предыдущей строке).
3. Второе поле — число 00
4. Третье поле — данные (не более 16 байтов, подряд)
5. Четвёртое поле — один байт, считающийся как сумма всех предыдущих байтов в строке (с переполнением, разумеется).
# 4. Работа с текстом
1. Это посложнее, но для тренирвоки перед курсовиком… Ну, в идеале: сделать парсер файла (функцию с прототипом `int parse_xpm(char ** xpm, uint16_t *result)` ) формата XPM (с одной стороны, PBM проще, с другой — есть две его версии, что не очень удобно в учебных целях). Задача: есть ~~текстовый файл~~ массив строк заданного формата с xpm внутри (один символ на точку, два цвета), необходимо найти строку, определяющую чёрный цвет и проанализировать файл, записывая в массив форму кривой — то есть её координату y для каждой координаты x (считаем, что эта зависимость однозначна). Возвращаемое значение функции — ширина изображения. Например, xpm.c