Том дал вам хороший ответ, чтобы решить вашу проблему целочисленного продвижения, но есть ряд проблем, которые просто приглашают Неопределенное поведение и ряд других гнид, которые вы можете очистить.
Во-первых, вы должны всегда проверять ВСЕ ввод. В противном случае вы не сможете понять, произошел ли сбой , соответствующий или input , с scanf
, и вы слепо используете значения, которые будут неопределенными в случае любого сбоя. Просто подтвердите возвращение scanf
, например
if (scanf("%d", &n) != 1) { /* validate every input */
fputs ("error: invalid formate - 'n'.\n", stderr);
return 1;
}
...
for (int i = 0; i < n; i++)
if (scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c) != 3) {
fputs ("error: invalid format - a,b,c.\n", stderr);
return 1;
}
Вы должны проверять каждое распределение (используя malloc, calloc
или realloc
) по той же самой причине. Это не вопрос "if"
, и распределение не удастся, это вопрос "when"
. Поскольку ошибка выделения устанавливает errno
, сообщение об ошибке представляет собой тривиальный вызов perror
, например
triangle *tr;
...
if (!(tr = malloc (n * sizeof *tr))) { /* validate every allocation */
perror ("malloc-tr");
return 1;
}
гнид. В C, когда вы объявляете функцию и оставляете круглые скобки пустыми ()
, вы указали, что функция принимает неопределенное количество аргументов, а не ноль. Чтобы сделать заявление о соответствии main()
, вы должны использовать:
int main (void) {
См .: C11 Standard - §5.1.2.2.1 Запуск программы (p1)
В area
нет необходимости ни в одном из ваших приведений, просто решите проблему целочисленного деления, добавив '.'
после 2
и позвольте промоушенам по умолчанию обрабатывать все остальное, например,
double area (int a, int b, int c) /* remove all casts, add '.' after 2 */
{
double p = (a + b + c) / 2.;
return sqrt (p*(p-a)*(p-b)*(p-c));
}
Хотя вы можете декларировать struct
и typedef
отдельно, вы можете сделать это и в одной декларации, например,
typedef struct { /* you can simply create the typedef */
int a, b, c;
} triangle;
После того, как вы исправите проблему с целочисленным делением, ваш код будет работать нормально, но вы должны исправить другие проблемы, чтобы убедиться, что вы не столкнетесь с Undefined Behavior из-за предсказуемого ввода ошибки распределения , С фиксированным целочисленным делением работа с тестовым вводом приведет к:
Пример использования / Вывод
$ ./bin/triangle_sort_area < dat/triangles_20.txt
22 18 5
31 41 14
20 23 21
54 62 11
26 41 65
58 31 31
20 39 32
26 41 62
44 48 18
23 37 47
53 18 54
28 36 40
31 46 39
33 45 49
57 33 45
28 56 56
41 38 55
55 44 44
48 49 67
58 61 50