Подскажите, где ошибка (указатель на функцию) - C (СИ)
Формулировка задачи:
Дана программа в книге Кернигана и Ричи (5.11. Указатели на функцию)
Почему она с ошибками.
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 //max lines to be sorted
char *lineptr[MAXLINES];
int readlines(char *lineptr[], int maxlines);
void writelines(char *lineptr[], int nlines);
void qsort(void *lineptr[], int left, int right,
int (*comp) (void *, void *));
int numcmp(char *s1, char *s2);
/* sort input lines */
int main(int argc, char *argv[])
{
int nlines; //number of input lines read
int numeric; // 1 if numeric sort
numeric = 0;
if(argc > 1 && strcmp(argv[1], "-n") == 0)
numeric = 1;
if((nlines = readlines(lineptr, MAXLINES)) >= 0)
{
qsort((void**)lineptr, 0, nlines - 1,
(int (*) (void*, void*)) (numeric ? numcmp : strcmp));
writelines(lineptr, nlines);
return 0;
}
else
{
printf("input too big to sort\n");
return 1;
}
}
void swap(void *lineptr[], int i, int j);
/* qsort: sort v[left]...v[right] into increasing order */
void qsort(void *lineptr[], int left, int right,
int (*comp) (void *, void *))
{
int i, last;
if(left >= right) //do nothing if array contains
return; //fewer than two elements
swap(lineptr, left, (left + right)/2);
last = left;
for(i = left + 1; i <= right; i++)
if((*comp) (lineptr[i], lineptr[left]) < 0)
swap(lineptr, ++last, i);
swap(lineptr, left, last);
qsort(lineptr, left, last - 1, comp);
qsort(lineptr, last + 1, right, comp);
}
#include <stdlib.h>
/* numcmp: compare s1 and s2 numericalli */
int numcmp(char *s1, char *s2)
{
double v1, v2;
v1 = atof(s1);
v2 = atof(s2);
if(v1 < v2)
return -1;
else if(v1 > v2)
return 1;
else
return 0;
}
void swap(void *lineptr[], int i, int j)
{
void *temp;
temp = lineptr[i];
lineptr[i] = lineptr[j];
lineptr[j] = temp;
}
gcc -Wall -o "point_to_func" "point_to_func.c" -lm
point_to_func.c: In function ‘main’:
point_to_func.c:25:52: warning: pointer type mismatch in conditional expression [enabled by default]
Compilation failed.
In file included from point_to_func.c:56:0:
/usr/include/stdlib.h: At top level:
/usr/include/stdlib.h:761:13: error: conflicting types for ‘qsort’
point_to_func.c:39:6: note: previous definition of ‘qsort’ was here
Решение задачи: «Подскажите, где ошибка (указатель на функцию)»
textual
Листинг программы
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 //max lines to be sorted
#define BUFSIZE 5000
char *lineptr[MAXLINES];
int readlines(char *lineptr[], char *buf, int maxlines);
void writelines(char *lineptr[], int nlines);
void sort(void *v[], int left, int right,
int (*comp) (void *, void *));
int numcmp(char *s1, char *s2);
/* sort input lines */
int main(int argc, char *argv[])
{
int nlines; //number of input lines read
int numeric; // 1 if numeric sort
char buf[BUFSIZE];
numeric = 0;
if(argc > 1 && strcmp(argv[1], "-n") == 0)
numeric = 1;
if((nlines = readlines(lineptr,buf, MAXLINES)) >= 0)
{
sort((void **)lineptr, 0, nlines - 1,
(int (*) (void*, void*)) (numeric ? numcmp : strcmp));
writelines(lineptr, nlines);
return 0;
}
else
{
printf("input too big to sort\n");
return 1;
}
}
/* sort: sort v[left]...v[right] into increasing order */
void sort(void *v[], int left, int right,
int (*comp) (void *, void *))
{
int i, last;
void swap(void *v[], int i, int j);
if(left >= right) //do nothing if array contains
return; //fewer than two elements
swap(v, left, (left + right)/2);
last = left;
for(i = left + 1; i <= right; i++)
if((*comp) (v[i], v[left]) < 0)
swap(v, ++last, i);
swap(v, left, last);
sort(v, left, last - 1, comp);
sort(v, last + 1, right, comp);
}
#include <stdlib.h>
/* numcmp: compare s1 and s2 numericalli */
int numcmp(char *s1, char *s2)
{
double v1, v2;
v1 = atof(s1);
v2 = atof(s2);
if(v1 < v2)
return -1;
else if(v1 > v2)
return 1;
else
return 0;
}
void swap(void *v[], int i, int j)
{
void *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
#define MAXLEN 1000 //max lenght of any input line
int getlin(char *, int);
/* readlines: read input lines */
int readlines(char *lineptr[], char *buf, int maxlines)
{
int len, nlines;
char line[MAXLEN];
char *p = buf;
char *bufstop = buf + BUFSIZE;
nlines = 0;
while((len = getlin(line, MAXLEN)) > 0)
{
if(nlines >= maxlines || p + len > bufstop)
return -1;
else
{
line[len - 1] = '\0'; //delete newline
strcpy(p, line);
lineptr[nlines++] = p;
p += len;
}
}
return nlines;
}
/* writelines: write output lines */
void writelines(char *lineptr[], int nlines)
{
int i;
printf("\n");
for(i = 0; i < nlines; i++)
printf("%s\n", lineptr[i]);
}
int getlin(char *l, int lim)
{
int c;
char *tmp = l;
for(; --lim > 0 && (c=getchar()) != EOF && c!='\n'; l++)
*l = c;
if(c=='\n')
*l++ = c;
*l = '\0';
return l - tmp;
}
Объяснение кода листинга программы
- Объявлен массив
lineptrтипаchar *lineptr[MAXLINES], который предназначен для хранения указателей на строки, введенные пользователем. - Функция
readlinesиспользуется для чтения строк из стандартного ввода и сохранения их вlineptr. Она возвращает количество прочитанных строк. - Функция
writelinesиспользуется для вывода строк из массиваlineptrна стандартный вывод. - Функция
sortпредназначена для сортировки массива строк или чисел в порядке возрастания. Она использует функцию сравненияcompдля определения порядка сортировки. - Функция
numcmpиспользуется в функцииsortдля сравнения двух строк на числовой порядок. - Функция
swapиспользуется в функцииsortдля обмена элементов массива. - Функция
getlinиспользуется в функцииreadlinesдля чтения строки с учетом ограничения на длину строки. - Функция
mainявляется точкой входа в программу. Она обрабатывает ввод/вывод и вызывает функции сортировки и чтения/записи строк. - Переменная
nlinesиспользуется в функцииmainдля хранения количества прочитанных строк. - Переменная
numericиспользуется в функцииmainдля указания, следует ли сортировать строки в числовом порядке. - Переменная
bufиспользуется в функцииreadlinesдля временного хранения считанных строк. - Переменная
leftиспользуется в функцииsortдля указания начала подмассива для сортировки. - Переменная
rightиспользуется в функцииsortдля указания конца подмассива для сортировки. - Переменная
lastиспользуется в функцииsortдля хранения индекса опорного элемента в подмассиве. - Переменная
iиспользуется в функцииsortдля итерации по элементам подмассива. - Переменная
jиспользуется в функцииsortдля указания индекса элемента, который нужно сравнить с опорным элементом. - Переменная
tempиспользуется в функцииswapдля временного хранения значения одного из элементов массива. - Переменная
lenиспользуется в функцииgetlinдля хранения длины прочитанной строки. - Переменная
cиспользуется в функцииgetlinдля хранения считанного символа. - Переменная
lиспользуется в функцииgetlinдля итерации по символам прочитанной строки.