繁体   English   中英

C 与结构、指针和 malloc

[英]C with structures, pointers and malloc

我正在尝试编写一个 c 程序,该程序使用 malloc 作为结构,然后使用另一个 function 扫描结构。 之后,该结构的字母数字值也使用 malloc。 最后,它计算了结构的浮点值的平均值。

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

#define MAX_ARRAY 20
#define MAX_STRUCT_ARRAY 30
#define MIN_STRUCT_ARRAY 0
#define NULL_CHAR '/0'
#define NULL_NUM 0
#define MAX_MARKS 10

struct students
{   char name[MAX_ARRAY];
    int id;
    float marks;
};
typedef struct students studentsDef;

void scanStruct(int numofStructs,struct students listOfstudents);
float mesosOros(int numofStructs,float grades[MAX_STRUCT_ARRAY]);
int main()
{
    int structNum;
   studentsDef* pStudents = NULL;

    do{
        printf("Dwse ton arithmo ton mathiton: ");
        scanf("&d",&structNum);
        if(structNum > MAX_STRUCT_ARRAY || structNum < MIN_STRUCT_ARRAY)
        {
            printf("Oriste arithmo domwn apo %d ews %d. \n",MIN_STRUCT_ARRAY,MAX_STRUCT_ARRAY);
        }
    }while(structNum > MAX_STRUCT_ARRAY || structNum < MIN_STRUCT_ARRAY);

    pStudents=(studentsDef*)malloc(structNum * sizeof(studentsDef));
    if(pStudents==NULL)
    {
        printf("Adunati i dunamiki desmefsi mnimis. \n");
    }
    else
    {
        scanStruct(structNum,*pStudents);
        mesosOros(structNum,*pStudents.marks);
    }
    return 0;
}

void scanStruct(int numofStructs,struct students listOfstudents)
{
    int i,j,sizeOfChar;
    for(i=0;i < numofStructs;i++)
    {
        do{
            printf("Dwse plithos haraktirwn tou onomatos: ");
            scanf("%d",&sizeOfChar);
            if((sizeOfChar<MIN_STRUCT_ARRAY) || (sizeOfChar>MAX_ARRAY))
            {
                printf("Apodekti eisagwgi haraktirwn ews %d.\n",MAX_ARRAY);
            }
        }while((sizeOfChar<MIN_STRUCT_ARRAY) || (sizeOfChar>MAX_ARRAY));
//        listOfstudents[i].name = (char*)malloc((sizeOfChar + 1) * sizeof(char));
        printf("Onoma mathiti: ");
        scanf("%s", listOfstudents[i].name);

        do{
            printf("dwse to id tou mathiti: ");
            scanf("%d",&listOfstudents[i].id);
            if((listOfstudents[i].id < NULL_NUM) || (listOfstudents[i].id == NULL_NUM))
            {
                printf("Adunatio gia arnitiko i mideniko id.\n");
            }
        }while((listOfstudents[i].id < NULL_NUM) || (listOfstudents[i].id == NULL_NUM));

        do{
            printf("dwse bathmo: ");
            scanf("%f",&listOfstudents[i].marks);
            if((listOfstudents[i].marks < NULL_NUM) || (listOfstudents[i].marks == NULL_NUM) || listOfstudents[i].marks > MAX_MARKS)
                {
                    printf("Adunatio gia arnitiko i mideniko id");
                }
        }while((listOfstudents[i].marks < NULL_NUM) || (listOfstudents[i].marks == NULL_NUM) || listOfstudents[i].marks > MAX_MARKS);
    }
}

float mesosOros(int numofStructs,float grades[MAX_STRUCT_ARRAY])
{
    int i;
    for(i=0; i<numofStructs;i++)
    {
        grades[i]+=0;
    }
    return grades[i]/numofStructs;
}

到目前为止,我无法在第二个 function 中利用 malloc,也无法通过 function 调用传递结构。 提前致谢。 对不起,我对结构不熟悉。

试试这个代码,它可能会让你开始。

下面是一个补丁文件,您可以使用它来将代码示例更改为newmain.c ,它会快速解释每个更改。 并非所有问题都对您的问题很重要,也并非所有问题都会产生所需的结果。 希望能有所帮助,一点点。

祝你好运!

main < input是将输入从文件input重定向到程序main的一种方法,符号<用于重定向。 也显示了来自此特定运行的 output。

gcc -o main main.c
main < input


Dwse ton arithmo ton mathiton: structNum: 1
Dwse plithos haraktirwn tou onomatos: sizeOfChar: 10
10
Onoma mathiti: listOfstudents[i].name: ABCD EFGH
dwse to id tou mathiti: listOfstudents[i].id: 1
dwse bathmo: listOfstudents[i].marks: 9.000000
RES: 9.000000

这是文件input ,内容。 我选择格式,你的格式需求可能不一样,CSV,空格分隔值等等。 希望这足够接近以提供帮助。

1
10
ABCD EFGH
1
9.0

这是代码,当输入被重定向到stdin以供scanf function 将数据读入malloc memory 时,它会生成上面显示的 output。

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

#define MAX_ARRAY 20
#define MAX_STRUCT_ARRAY 30
#define MIN_STRUCT_ARRAY 0
#define NULL_CHAR '/0'
#define NULL_NUM 0
#define MAX_MARKS 10

struct students
{   char name[MAX_ARRAY];
    int id;
    float marks;
};
typedef struct students studentsDef;
typedef struct students* studentsDefPTR;

void scanStruct(int numofStructs, studentsDefPTR listOfstudents);
float mesosOros(int numofStructs, studentsDefPTR listOfstudents);
int main()
{
    int structNum;
    studentsDefPTR pStudents = NULL;

    do{
        printf("Dwse ton arithmo ton mathiton: ");
        scanf("%d%*c",&structNum);
        if(structNum > MAX_STRUCT_ARRAY || structNum < MIN_STRUCT_ARRAY)
        {
            printf("Oriste arithmo domwn apo %d ews %d. \n",MIN_STRUCT_ARRAY,MAX_STRUCT_ARRAY);
        }
    }while(structNum > MAX_STRUCT_ARRAY || structNum < MIN_STRUCT_ARRAY);
    printf("structNum: %d\n",structNum);

    pStudents=(studentsDefPTR)malloc(structNum * sizeof(studentsDef));
    if(pStudents==NULL)
    {
        printf("Adunati i dunamiki desmefsi mnimis. \n");
    }
    else
    {
        scanStruct(structNum,pStudents);
        printf( "RES: %f\n", mesosOros(structNum,pStudents));
    }
    return 0;
}

void scanStruct(int numofStructs,studentsDefPTR listOfstudents)
{
    int i,j,sizeOfChar;
    for(i=0;i < numofStructs;i++)
    {
        do{
            printf("Dwse plithos haraktirwn tou onomatos: ");
            scanf("%d%*c",&sizeOfChar);
            printf("sizeOfChar: %d\n",sizeOfChar);
            if((sizeOfChar<MIN_STRUCT_ARRAY) || (sizeOfChar>MAX_ARRAY))
            {
                printf("Apodekti eisagwgi haraktirwn ews %d.\n",MAX_ARRAY);
            }
        }while((sizeOfChar<MIN_STRUCT_ARRAY) || (sizeOfChar>MAX_ARRAY));
        printf("%d\n",sizeOfChar);
        printf("Onoma mathiti: ");
        memset(listOfstudents[i].name,0,MAX_ARRAY);
        scanf("%[^\n]s%*c",listOfstudents[i].name);
        printf("listOfstudents[i].name: %s\n",listOfstudents[i].name);

        do{
            printf("dwse to id tou mathiti: ");
            scanf("%d",&(listOfstudents[i].id));
            printf("listOfstudents[i].id: %d\n",listOfstudents[i].id);
            if((listOfstudents[i].id < NULL_NUM) || (listOfstudents[i].id == NULL_NUM))
            {
                printf("Adunatio gia arnitiko i mideniko id.\n");
            }
        }while((listOfstudents[i].id < NULL_NUM) || (listOfstudents[i].id == NULL_NUM));

        do{
            printf("dwse bathmo: ");
            scanf("%f%*c",&listOfstudents[i].marks);
            printf("listOfstudents[i].marks: %f\n",listOfstudents[i].marks);
            if((listOfstudents[i].marks < NULL_NUM) || (listOfstudents[i].marks == NULL_NUM) || listOfstudents[i].marks > MAX_MARKS)
                {
                    printf("Adunatio gia arnitiko i mideniko id");
                }
        }while((listOfstudents[i].marks < NULL_NUM) || (listOfstudents[i].marks == NULL_NUM) || listOfstudents[i].marks > MAX_MARKS);
    }
}

float mesosOros(int numofStructs, studentsDefPTR listOfstudents)
{
    int i;
    float total = 0;
    for(i=0; i<numofStructs;i++)
    {
        total += listOfstudents[i].marks;
    }
    return total/numofStructs;
}

审查

以 hash #开头的行是关于随后的特定代码更改的注释。 将补丁保存到文件main.patch并应用到代码示例main.c就像这个patch -o newmain.c -i main.patch main.c output 文件将是newmain.c

# Adding string.h b/c using memset to init name string
2a3
> #include <string.h>
# Creating typedef for pointer to struct students for readability
16a18
> typedef struct students* studentsDefPTR;
# Changing function arguments to accept pointer to struct students
# this allows the functions to access allocated memory b/c the function
# is told the address where the memory was allocated
18,19c20,21
< void scanStruct(int numofStructs,struct students listOfstudents);
< float mesosOros(int numofStructs,float grades[MAX_STRUCT_ARRAY]);
---
> void scanStruct(int numofStructs, studentsDefPTR listOfstudents);
> float mesosOros(int numofStructs, studentsDefPTR listOfstudents);
# insignifcant change, these are both equal and valid
23c25
<    studentsDef* pStudents = NULL;
---
>     studentsDefPTR pStudents = NULL;
# ensuring scanf reads newline, may not be the right thing, depends on input
# format, I choose to put each value on a newline, not significant to question
27c29
<         scanf("&d",&structNum);
---
>         scanf("%d%*c",&structNum);
# printing value read, good practice for ensuring initial coding does
# what is expected and is using the values you expect
32a35
>     printf("structNum: %d\n",structNum);
# insignificant change, statements are equal, calling attentiong to PTR
34c37
<     pStudents=(studentsDef*)malloc(structNum * sizeof(studentsDef));
---
>     pStudents=(studentsDefPTR)malloc(structNum * sizeof(studentsDef));
# functions need the address of allocated memory
# pStudents is enough and holds the value returned by malloc
# this is a design change, my choice to make this problem 
# easier for me, it may not be what is needed
41,42c44,45
<         scanStruct(structNum,*pStudents);
<         mesosOros(structNum,*pStudents.marks);
---
>         scanStruct(structNum,pStudents);
>         printf( "RES: %f\n", mesosOros(structNum,pStudents));
# changing scanStruct function to utilize pointer to allocated memory
# the allocated memory comes from malloc which provides the address to
# the first allocated struct in argument listOfstudents
47c50
< void scanStruct(int numofStructs,struct students listOfstudents)
---
> void scanStruct(int numofStructs,studentsDefPTR listOfstudents)
# ensuring scanf reads newline, may not be the right thing, depends on input
# format, I choose to put each value on a newline, not significant to question
# printing value read, good practice for ensuring initial coding does
# what is expected and is using the values you expect
54c57,58
<             scanf("%d",&sizeOfChar);
---
>             scanf("%d%*c",&sizeOfChar);
>             printf("sizeOfChar: %d\n",sizeOfChar);
# oops, this is a duplicate
60c64
< //        listOfstudents[i].name = (char*)malloc((sizeOfChar + 1) * sizeof(char));
---
>         printf("%d\n",sizeOfChar);
# initialize the name string before setting, maybe consider initializing
# entire allocation after malloc instead, coders choice
#
# ensuring scanf reads newline, may not be the right thing, depends on input
# format, I choose to put each value on a newline, not significant to question
#
# printing value read, good practice for ensuring initial coding does
# what is expected and is using the values you expect
62c66,68
<         scanf("%s", listOfstudents[i].name);
---
>         memset(listOfstudents[i].name,0,MAX_ARRAY);
>         scanf("%[^\n]s%*c",listOfstudents[i].name);
>         printf("listOfstudents[i].name: %s\n",listOfstudents[i].name);
# ensuring scanf reads newline, may not be the right thing, depends on input
# format, I choose to put each value on a newline, not significant to question
#
# printing value read, good practice for ensuring initial coding does
# what is expected and is using the values you expect
66c72,73
<             scanf("%d",&listOfstudents[i].id);
---
>             scanf("%d",&(listOfstudents[i].id));
>             printf("listOfstudents[i].id: %d\n",listOfstudents[i].id);
# ensuring scanf reads newline, may not be the right thing, depends on input
# format, I choose to put each value on a newline, not significant to question
#
# printing value read, good practice for ensuring initial coding does
# what is expected and is using the values you expect
75c82,83
<             scanf("%f",&listOfstudents[i].marks);
---
>             scanf("%f%*c",&listOfstudents[i].marks);
>             printf("listOfstudents[i].marks: %f\n",listOfstudents[i].marks);
# changing mesosOros function to utilize pointer to allocated memory
# the allocated memory comes from malloc which provides the address to
# the first allocated struct in argument listOfstudents
84c92
< float mesosOros(int numofStructs,float grades[MAX_STRUCT_ARRAY])
---
> float mesosOros(int numofStructs, studentsDefPTR listOfstudents)
# new local scope value to hold total of all marks
86a95
>     float total = 0;
# total up all marks into local variable
89c98
<         grades[i]+=0;
---
>         total += listOfstudents[i].marks;
# return computed result, maybe what is needed, not sure
# not significant to question though
91c100
<     return grades[i]/numofStructs;
---
>     return total/numofStructs;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM