2016-12-20 4 views
1

Я должен объявить вектор с типом «struct», который для каждого n студентов создает значение для группы, к которой принадлежит студент (который похож на счетчик), их имена и их оценки.Правильное использование структур и указателей

Программа должна вывести имя студентов с наивысшим классом, найденным в этих группах. Я должен выделить вектор в куче (я знаю только теоретическое объяснение кучи, но я не знаю, как его применять), и я должен пройти через вектор с помощью указателей.

Например, если я дам n значение 4, будет 4 ученика, и программа выведет максимальную оценку вместе с их именами, как показано на рисунке here.

Это будет выводить Ана 10 и Ева 10.

Я дал ему попробовать, но я понятия не имею, как расширить его или исправить его, так что я ценю всю помощь я могу получить с пояснениями, если это возможно на практическое применение кучи и указателей в этом типе проблемы.

#include <stdio.h> 
#include <stdlib.h> 

struct students { 
    int group; 
    char name[20]; 
    int grade; 
}; 

int main() 
{ 
    int v[100], n, i; 
    scanf("%d", n); 
    for (i = 0; i < n; i++) { 
      v[i].group = i; 
      scanf("%s", v[i].name); 
      scanf("%d", v[i].grade); 
    } 
    for (i = 0; i < n; i++) { 
      printf("%d", v[i].group); 
      printf("%s", v[i].name); 
      printf("%d", v[i].grade); 
    } 
    return 0; 
} 

Здесь я просто пытался создать вектор, ничего не работает, хотя ..

+0

'зсапЕ ("% d", n); '->' scanf ("% d", &n); 'и' scanf ("% d", v [i] .grade); '->' scanf ("% d ", & v [i] .grade);' – kaylum

ответ

0

Вы должны заменить отдельный массив v[100] с массивом структур, ссылающихся структуру:

struct students v[100]; 

Однако, если вы хотите использовать malloc для выделения памяти в куче, то вам нужно чтобы сделать что-то вроде этого:

struct students *students = malloc(n * sizeof(struct students)); 

/* Check void* return pointer from malloc(), just to be safe */ 
if (students == NULL) { 
    /* Exit program */ 
} 

и free запрашиваемый памяти из malloc() на ан d, как это:

free(students); 
students = NULL; 

Кроме того, добавление к ответу @Sourav Ghosh, это также хорошо, чтобы проверить возвращаемое значение scanf(), особенно при работе с целыми числами.

Вместо того, чтобы просто:

scanf("%d", &n); 

Более безопасный способ заключается в следующем:

if (scanf("%d", &n) != 1) { 
    /* Exit program */ 
} 

При всем этом сказал, ваша программа может выглядеть примерно так:

#include <stdio.h> 
#include <stdlib.h> 

#define NAMESTRLEN 20 

typedef struct { /* you can use typedef to avoid writing 'struct student' everywhere */ 
    int group; 
    char name[NAMESTRLEN+1]; 
    int grade; 
} student_t; 

int 
main(void) { 
    int n, i; 

    printf("Enter number of students: "); 
    if (scanf("%d", &n) != 1) { 
     printf("Invalid input.\n"); 
     exit(EXIT_FAILURE); 
    } 

    student_t *students = malloc(n * sizeof(*students)); 
    if (!students) { 
     printf("Cannot allocate memory for %d structs.\n", n); 
     exit(EXIT_FAILURE); 
    } 

    for (i = 0; i < n; i++) { 
     students[i].group = i; 

     printf("Enter student name: "); 
     scanf("%20s", students[i].name); 

     printf("Enter students grade: "); 
     if (scanf("%d", &(students[i].grade)) != 1) { 
      printf("Invalid grade entered.\n"); 
      exit(EXIT_FAILURE); 
     } 
    } 

    printf("\nStudent Information:\n"); 
    for (i = 0; i < n; i++) { 
     printf("Group: %d Name: %s Grade: %d\n", 
       students[i].group, 
       students[i].name, 
       students[i].grade); 
    } 

    free(students); 
    students = NULL; 

    return 0; 
} 
+0

Большое спасибо за ваш подробный ответ, я пройду через него, чтобы попытаться узнать как можно больше, я прошу прощения за то, что не видел его раньше. – user2877858

+0

@ user2877858 Не стоит беспокоиться :). Дайте мне знать, если вам нужно какое-либо разъяснение. – RoadRunner

+0

Как вы могли использовать * учеников, если они не были объявлены в какой-либо форме? – user2877858

2

Оказывается, int v[100]; не совсем то, что вы хотите. Удалите это.

Вы можете следить за любым из двух способов.

  • Use a VLA. После сканирования значения n от пользователя определите массив как struct students v[n]; и продолжите.

  • Определите массив фиксированного размера, например struct students v[100];, и используйте его для ограничения условий цикла.

Тем не менее,

  • scanf("%d", n); должно быть scanf("%d", &n);, так как %d ожидает, что указатель на целочисленный тип аргумента для scanf(). То же самое касается и других случаев.
  • scanf("%s", v[i].name); должен быть лучше scanf("%19s", v[i].name);, чтобы избежать переполнения буфера чрезмерно длинными входами.
+0

@ Старшая благодарность. Обновлено. –

+0

Кажется, что исправлены мои первоначальные ошибки, теперь я должен выделить вектор в куче, используя функцию malloc, которую я думаю, и пройти через вектор с помощью указателей, затем вывести максимальную оценку и имена учеников, можете ли вы мне помочь с этим? – user2877858

+0

@ user2877858 ну, шаг за шагом учебник выходит за рамки. Пожалуйста, продолжайте писать код, если у вас возникнут какие-либо проблемы, вернитесь и задайте новый вопрос. Мы будем здесь, чтобы помочь. –

1

Даже если вы просите числа студентов (группы) с помощью scanf, вы жёстко верхней границы этого значения, используя v[100]. Итак, я передал вашу входную переменную n (количество студентов) в malloc, чтобы выделить пространство, необходимое для создания массива n студентов.

Кроме того, я использовал qsort для сортировки входного массива v, где последним элементом было бы значение max. Здесь qsort принимает массив структур и оценивает указатели, переданные функции comp, чтобы вычислить разницу в сравнении.

Наконец, я напечатал отсортированный массив структур в последнем цикле.

#include <stdio.h> 
#include <stdlib.h> 
struct students { 
    int group; 
    char name[20]; 
    int grade; 
}; 

int comp(const void *a, const void *b) 
{ 
    return ((((struct students *)a)->grade > ((struct students *)b)->grade) - 
      (((struct students *)a)->grade < ((struct students *)b)->grade)); 
} 

int main() 
{ 
    int n; 
    printf("Enter number of groups: "); 
    scanf("%d", &n); 
    printf("\n");  
    struct students *v = malloc(n * sizeof(struct students)); 
    int i; 
    for(i = 0; i < n; i++) 
    { 
     v[i].group = i; 
     printf("\nName: "); 
     scanf("%s", v[i].name); 
     printf("Grade: "); 
     scanf("%d", &v[i].grade); 
    } 
    qsort(v, n, sizeof(*v), comp); 
    for(i = 0; i < n; i++) 
    { 
     printf("Group %d, Name %s, grade %d\n", v[i].group, v[i].name, v[i].grade); 
    } 
    return (0); 
} 
Смежные вопросы