首页 > 解决方案 > 关于使用函数、指针和动态分配的练习 (C)

问题描述

基本上,练习状态如下:

编写一个具有 3 个函数的程序:

  1. 初始化班级成绩。
  2. 计算平均分、最高分和最低分。
  3. 显示所有等级,平均,最高和最低。

我想更好地理解如何使用动态分配和函数指针来解决这个问题。学生人数和他们的成绩是未知的,应该由用户输入。

由于我只是想知道如何使用动态分配和函数指针,所以我只写了一个程序,使用了两个函数:初始化成绩,然后显示它们。我将向您展示我编写的代码。我知道这很糟糕而且没有多大意义,因为我在理解堆和堆栈内存以及它们如何与函数指针相关的工作方面有点模糊。请帮助我了解如何更正此代码。PS:我不想使用静态内存分配。

所以这里是代码:

#include <stdio.h>

#include <stdlib.h>

void init(int *n, float *a) {
    printf("How many students?\n");
    scanf("%d", n);
    int number = *n;
    a = (float *)calloc(*n, sizeof(float));
    for (int i = 0; i < number; i++) {
        printf("student %d?\n", i + 1);
        scanf("%f", &a[i]);
    }
}

void display(int n, float a) {
    for (int i = 0; i <n; i++)
        printf("%.2f  ", a[i]); // I don't know how to display an array initialized dynamically.
}

int main() {
    int m;
    float b;
    init(&m, &b);
    display(m, b);
    return 1;
}

标签: c

解决方案


在这种情况下,没有必要将指针传递给 float into init。使用整数,它可以完成分配内存并返回指向已分配内存的指针的工作。由于一个函数只能返回一个值,因此需要一个指向整数的指针,以便main知道分配的浮点数。
考虑使用fgets来读取一行。然后根据需要解析该行。如果输入无效,则它已经从输入流中删除以允许再次尝试。do/while 循环用于sscanf查看是否可以解析输入,如果 sscanf 不返回 1 表示成功,则将重试。
main然后可以传递浮点数和指向浮点数的指针以display打印每个浮点数。
free不再需要时分配的内存。

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

float *init (int *n) {//take a pointer to number of students and return pointer to float
    char line[100] = "";//for input
    int result = 0;//for return from sscanf
    do {
        printf ( "How many students?\n");
        if ( ! fgets ( line, sizeof line, stdin)) {
            perror ( "fgets problem");
            exit ( EXIT_FAILURE);
        }
        result = sscanf ( line, "%d", n);
    } while ( 1 != result || *n <= 0);

    float *a = NULL;
    if ( NULL == ( a = calloc(*n, sizeof(float)))) {//was calloc successful
        fprintf ( stderr, "calloc problem\n");
        exit ( EXIT_FAILURE);
    }
    for ( int i = 0; i < *n; i++) {
        do {
            printf ( "student %d?\n", i + 1);
            if ( ! fgets ( line, sizeof line, stdin)) {
                perror ( "fgets problem");
                exit ( EXIT_FAILURE);
            }
            result = sscanf ( line, "%f", &a[i]);
        } while ( 1 != result);
    }
    return a;
}

void display ( int n, float *a){//takes number and pointer to floats
    for ( int i = 0; i < n; i++)
        printf("%.2f  ", a[i]);//print each float
    }

int main ( void){
    int m = 0;
    float *b = NULL;
    b = init ( &m);
    display ( m, b);

    free ( b);//free the allocated memory

    return 0;
}

推荐阅读