简体   繁体   English

C 与结构、指针和 malloc

[英]C with structures, pointers and malloc

I am trying to write a c program that uses malloc for a struct, then uses another function to scan the struct.我正在尝试编写一个 c 程序,该程序使用 malloc 作为结构,然后使用另一个 function 扫描结构。 Afterward, the alphanumeric values of the struct use malloc as well.之后,该结构的字母数字值也使用 malloc。 In the end, it calculated the average of the float values of the struct.最后,它计算了结构的浮点值的平均值。

#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;
}

So far I am unable to take advantage of malloc in the second function and also can't pass the struct through the function calls.到目前为止,我无法在第二个 function 中利用 malloc,也无法通过 function 调用传递结构。 Thanks in advance.提前致谢。 Sorry for any eyesores I am new to structures.对不起,我对结构不熟悉。

Try this code, it may get you started.试试这个代码,它可能会让你开始。

Further below is a patch file you can use to change the code sample into newmain.c and it quickly explains each change.下面是一个补丁文件,您可以使用它来将代码示例更改为newmain.c ,它会快速解释每个更改。 Not all are significant to your question and not all will produce results required.并非所有问题都对您的问题很重要,也并非所有问题都会产生所需的结果。 Hoping that it helps, a little bit.希望能有所帮助,一点点。

Good luck!祝你好运!

main < input is one way to redirect input from the file input to the program main , the symbol < is used for redirection. main < input是将输入从文件input重定向到程序main的一种方法,符号<用于重定向。 The output from this specific run is shown too.也显示了来自此特定运行的 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

Here is the file input , contents.这是文件input ,内容。 I choose the format, your format needs may be different, CSV, space separated values, and so on.我选择格式,你的格式需求可能不一样,CSV,空格分隔值等等。 Hope this is close enough to be helpful.希望这足够接近以提供帮助。

1
10
ABCD EFGH
1
9.0

This is the code, it produces the output shown above when the input is redirected to stdin for the scanf function to read data into the malloc memory.这是代码,当输入被重定向到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;
}

Review审查

The lines that begin with hash # are comments about the specific code change that follows.以 hash #开头的行是关于随后的特定代码更改的注释。 Save the patch to a file main.patch and apply to code sample main.c like this patch -o newmain.c -i main.patch main.c the output file will be newmain.c .将补丁保存到文件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