RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 817300
Accepted
alex-rudenkiy
alex-rudenkiy
Asked:2020-04-21 22:03:58 +0000 UTC2020-04-21 22:03:58 +0000 UTC 2020-04-21 22:03:58 +0000 UTC

如何使用结构和子程序模块间?

  • 772

请告诉我如何与结构和子程序进行联运工作?特别是,我在使用 Student 和 Marks 结构以及诸如 action 这样的函数时遇到问题,它对给定的 Student 结构数组执行给定的操作(执行作为参数传递的函数)

主程序

#include <stdio.h>
#include <rpc.h>

int main() {
    SetConsoleOutputCP(CP_UTF8); //Windows10

    size_t n;

    printf("Введите число студентов: ");
    scanf("%i", &n);

    Student *students = Read_Students(n);

    action(students, n, &Sort);

    for (size_t i=0;i<n;i++)
        printf("%i %i\n",students[i].marks.History,students[i].marks.Math);

    return 0;
}

行动.c

#include <rpcndr.h>

void InsertionSort(struct Student *students, int *arr, int n) {
    size_t tmpIntElement, location;
    Student tmpStudElement;

    for (size_t i = 1; i < n; i++) {
        tmpIntElement = arr[i];
        tmpStudElement = students[i];
        location = i - 1;
        while (location >= 0 && arr[location] < tmpIntElement) {
            arr[location + 1] = arr[location];
            students[location + 1] = students[location];

            location = location - 1;
        }
        arr[location + 1] = tmpIntElement;
        students[location + 1] = tmpStudElement;
    }
}

void Sort(Student *students, int n) {
    int *arr = getSredneeArr(students, n);
    if (!equals_el(arr, n)) {
        InsertionSort(students, arr, n);
    }
}

void action(Student *students, int n, void (*f)(Student *,int)) {
    f(students,n);
}

函数.c

#include <stdio.h>
#include <dxtmpl.h>

void Read_Student(Student *student) {
    printf("\tИмя студента : ");
    scanf("%s", student->name);
    puts("");

    printf("\tФамилия студента : ");
    scanf("%s", student->surname);
    puts("");

    printf("\tОценка студента по\n");

    printf("\t\tМатематике = ");
    scanf("%i", &student->marks.Math);

    printf("\t\tИстории = ");
    scanf("%i", &student->marks.History);
    puts("");
}

int *getSredneeArr(struct Student *students, int n) {
    int *arr = malloc(n * sizeof(int));
    for (size_t i = 0; i < n; i++)
        arr[i] = (students[i].marks.Math + students[i].marks.History) / 2;
    return arr;
}

int equals_el(int *arr, int n) {
    size_t i, j;
    for (i = 0; i < n - 1; ++i) {
        for (j = i + 1; j < n; ++j) {
            if (arr[i] == arr[j]) {
                break;
            }
        }
    }
    return arr[i] == arr[j];
}

Student *Read_Students(int n) {
    Student *students;

    students = (Student *) malloc(sizeof(Student) * n);
    puts("");

    for (size_t i = 0; i < n; i++) {
        printf("Cтудент %i\n\n", i + 1);
        Read_Student(&students[i]);
    }

    return students;
}

结构体.c

#define MAXBuffer 256

typedef struct Marks {
    int Math;
    int History;
} Marks;

typedef struct Student {
    char name[MAXBuffer];
    char surname[MAXBuffer];
    int srMark;
    Marks marks;
} Student;
c
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Gromov Anton
    2020-04-22T01:04:44Z2020-04-22T01:04:44Z

    请告诉我如何与结构和子程序进行联运工作?

    出于您的目的,您的文件系统需要稍作调整。:)

    如果我是你,我会在调整后留下以下文件:

    • 螺柱.h
    • 螺柱.c
    • 主程序

    在studs.h中,根据所有规则,将存储您在structs.c + 中您在actions.c和functions.c中实现的函数原型(稍后我将解释为什么这样做)。

    不要忘记包含守卫:)。


    结果,头文件可能如下所示(您最好阅读注释):

    #ifndef _STUDS_H_ 
    #define _STUDS_H_
    
    #include <stdint.h>
    
    #define MAX_BUFFER 256 /*такие обычно названия для препроцессорных определений */
    
    /* Забыли здесь про платформонезависимость + можете стать жертвой выравнивания.*/
    /* Хочется "int" - заменим на "int32_t".*/
    
    typedef struct Marks {
        int32_t Math; 
        int32_t History;
    } Marks;
    
    /* Если с "Marks" всё может остаться хорошо (при неизмененности типов) ,*/
    /* То со "Student" всё может получиться печально. */
    /* Допустим, я , как неопытный, захотел поменять MAX_BUFFER на 271. */
    /* Тогда sizeof(Student) мне покажет 556, а по факту размер - 554. */
    /* Таким образом, вы выделяете больше памяти, чем нужно. */
    /* Предлагаю применить директиву "#pragma", чтобы не было проблем, */
    /* возникающих из-за выравнивания */
    
    /* В некоторых случаях эта директива может быть недоступной, 
    /* но если есть возможность - почему нет? :) */
    #pragma pack ( push, 1 ) 
    typedef struct Student {
        char name[MAX_BUFFER];
        char surname[MAX_BUFFER];
        int32_t srMark;
        Marks marks;
    } Student;
    #pragma pack ( pop )
    
    
    /* При объявлении прототипов переменные аргументов использовать не обязательно. */
    /* Достаточно указать их типы. */
    
    void Read_Student( Student* );
    int* getSredneeArr( Student* , int );
    int equals_el( int* , int );
    Student* Read_Students( int );
    
    void InsertionSort( Student* , int* , int );
    void Sort( Student* , int );
    void action( Student*, int , void (*) ( Student* , int ) );
    
    /* В прототипах опять проблемы с платформозависимостью, но это вы решайте сами. */
    /* Также, в тех аргументах, где говорится о количестве, я бы на вашем месте */
    /* вместо "int" писал "size_t" */
    /* ( а у вас такие есть, но опять же давайте сами, я вас направил ) */
    
    #endif
    

    文件studs.c只是actions.c和的集合functions.c。您需要将它们组合成一个,因为每个功能都是专门为与学生一起工作而设计的(他们的“阅读”、他们的“分类”等)。

    如果您编写了一个“.c” - 一个可以对任何类型进行排序的文件(您没有,因为它是 IMO,不可能),那么它可以单独取出,所以 - “netushki”:D

    我不会复制粘贴,因为里面应该包含什么已经很清楚了(actions.c+ functions.c,正如我已经写过的那样)。


    如果studs.c您需要在其中“包含”某些内容(并且您将 100% 需要在其中包含studs.h ,并且根据代码判断,stdio.h也是如此),那么就在其中执行,不要害羞:)

    (我忍不住写了这个,因为有些是“害怕”的,只是将例如stdio.h包含在头文件中,在那里不需要它,只是不要在“.c”中包含任何内容文件)

    如果您不知道,那么以后我会注意到自定义头文件已经使用双引号连接,而不是字符 "<" 和 ">" :

    #include "studs.h"
    

    如果您有一个gcc编译器,并且您的头文件与其余代码位于同一位置,那么您可以像这样编译它:

    gcc -o main main.c studs.c
    

    -pedantic(我强烈推荐使用,-Wall和键-Werror来保持你的代码更简洁和更高效)

    一些我以前没有写给你的笔记:

    • 如果您已经将“int”传递给与无符号组件(学生人数)一起使用的函数,那么至少检查您的“int”是否不小于零(学生人数不能为负数)。
    • 你有只在一个模块中工作的函数(除了那些在同一个模块中的函数之外,你不会在任何地方调用的函数)。它们必须标有“静态”关键字。例如:您Read_Student在内部使用Read_Students但没有在其他地方使用,因此添加static. 你也可以 看这里。
    • 您在运行程序时遇到过“分段错误”吗?出于某种原因,这发生在我身上,不止一次发生在不同的地方(而且,这发生在原始形式中)。

    考虑所有情况,并正确实现您的功能。祝你好运 :)

    UPD:这是另一个链接,您可以查看头文件中的内容。

    • 4
  2. Harry
    2020-04-21T22:09:14Z2020-04-21T22:09:14Z

    为了让程序中的所有文件都知道什么结构Student和Marks是什么,您需要将其重命名为并将其structs.c包含structs.h在所有 .c 文件中

    #include "structs.h"
    

    你感兴趣吗?

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5