C 正确使用结构和指针

C 正确使用结构和指针,c,struct,scanf,C,Struct,Scanf,我必须声明一个具有“struct”类型的向量,对于每n个学生,它为学生所属的组(类似于计数器)、他们的姓名和成绩创建一个值 程序必须输出这些组中成绩最高的学生的姓名。我必须在堆上分配向量(我只知道堆的理论解释,但我不知道如何应用它),我必须使用指针遍历向量 例如,如果我给n值4,将有4名学生,程序将输出最大分数以及他们的姓名,如图所示 这将输出Ana 10和Eva 10 我尝试了一下,但我不知道如何扩展它或修复它,因此我非常感谢您对堆和指针在这类问题中的实际应用提供的所有帮助,如果可能的话 #i

我必须声明一个具有“struct”类型的向量,对于每n个学生,它为学生所属的组(类似于计数器)、他们的姓名和成绩创建一个值

程序必须输出这些组中成绩最高的学生的姓名。我必须在堆上分配向量(我只知道堆的理论解释,但我不知道如何应用它),我必须使用指针遍历向量

例如,如果我给n值4,将有4名学生,程序将输出最大分数以及他们的姓名,如图所示

这将输出Ana 10和Eva 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;
}
#包括
#包括
结构学生{
int组;
字符名[20];
国际等级;
};
int main()
{
int v[100],n,i;
scanf(“%d”,n);
对于(i=0;i

在这里,我只是试图创建向量,但没有任何效果。

看起来,
intv[100]不是您想要的。去掉那个

您可以采用两种方法中的任何一种

  • 。从用户扫描
    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)以避免过长输入导致缓冲区溢出的可能性

即使您使用
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);
}
#包括
#包括
结构学生{
int组;
字符名[20];
国际等级;
};
内部组件(常数无效*a,常数无效*b)
{
返回(((结构学生*)a)->成绩>((结构学生*)b)->成绩)-
(((结构学生*)a)->成绩<((结构学生*)b)->成绩);
}
int main()
{
int n;
printf(“输入组数:”);
scanf(“%d”和“&n”);
printf(“\n”);
结构学生*v=malloc(n*sizeof(结构学生));
int i;
对于(i=0;i
您需要将独立数组
v[100]
替换为引用您的结构的结构数组:

struct students v[100];
但是,如果要使用在堆上分配内存,则需要执行以下操作:

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

/* Check void* return pointer from malloc(), just to be safe */
if (students == NULL) {
     /* Exit program */
}
free(students);
students = NULL;
#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;
}
最后是从
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(students);
students = NULL;
#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;
}
此外,除了@Sourav Ghosh的答案之外,还可以检查
scanf()
的返回值,特别是在处理整数时

而不是简单地:

scanf("%d", &n);
更安全的方法是:

if (scanf("%d", &n) != 1) {
     /* Exit program */
}
综上所述,您的程序可能如下所示:

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

/* Check void* return pointer from malloc(), just to be safe */
if (students == NULL) {
     /* Exit program */
}
free(students);
students = NULL;
#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;
}
#包括
#包括
#定义名称TRLEN 20
typedef struct{/*您可以使用typedef来避免在任何地方都写“struct student”*/
int组;
字符名[NAMESTRLEN+1];
国际等级;
}学生;;
int
主(空){
int n,i;
printf(“输入学生人数:”);
如果(scanf(“%d”,&n)!=1){
printf(“无效输入。\n”);
退出(退出失败);
}
学生=malloc(n*sizeof(*学生));
如果(!学生){
printf(“无法为%d个结构分配内存。\n”,n);
退出(退出失败);
}
对于(i=0;i
scanf(“%d”,n)-->
scanf(“%d”&n)
scanf(“%d”,v[i].等级)-->
scanf(“%d”和&v[i].grade)这似乎修复了我最初的错误,现在我必须使用malloc函数在堆中分配向量,并使用指针遍历向量,然后输出最大分数和学生姓名,你能帮我吗