Thread: Structures in C

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    93

    Structures in C

    I am trying to write a program involving structures. The program must have a function that prints the first name and last name for a given student. This function has to calculate the student's average.

    Then I have to have one function that computes the course's average of all the students. It doesn't appear I am doing the function call right in lines 58 and 60


    I have passed the &Grades (structure)
    I have tried &Grades&t

    I am screwing something up. There is one example in the book but they don't pass a structure to a function. Any help is appreciated.


    grades.c: In function âmainâ:
    grades.c:58: error: expected expression before âGradeâ
    grades.c:60: error: âsâ undeclared (first use in this function)
    grades.c:60: error: (Each undeclared identifier is reported only once
    grades.c:60: error: for each function it appears in.)
    grades.c: At top level:
    grades.c:67: error: expected identifier or â(â before â{â token
    grades.c: In function âprintcourseavgâ:
    grades.c:91: error: âstudentfinalâ undeclared (first use in this function)
    grades.c:94: error: invalid lvalue in assignment



    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef  struct  Grade {
            char *firstname;
            char *lastname;
            int *grades;
    } Grade; 
    
    typedef struct Course {
            char *name;
            char *lastname;
            int *studentfinal;
    } Course;
    
    void printname ( Grade *t );
    
    void printcourseavg ( Course *s );
    
    
    int main (void){
    struct Grade first;
    first.firstname = "John";
    
    struct Grade last;
    
    last.lastname = "Doe";
    
    
    struct Grade data;
    
    
    data.grades = (int*) calloc(5,sizeof(int));
    data.grades [ 0 ] = 78;
    data.grades [ 1 ] = 87;
    data.grades [ 2 ] = 85;
    data.grades [ 3 ] = 86;
    data.grades [ 4 ] = 85;
    
    
    struct Course data1;
    
    data1.studentfinal = (int*) calloc ( 5,sizeof (int));
    data1.studentfinal [ 0 ] = 87;
    data1.studentfinal [ 1 ] = 89;
    data1.studentfinal [ 2 ] = 78;
    data1.studentfinal [ 3 ] = 87;
    data1.studentfinal [ 4 ] = 89;
    
    
    
    
    
    
    printname( Grade *t);
    
    printcourseavg(&s);
    
    return 0;
    }
    
    
    void printname ( Grade *t );
    {
    int i;
    int total;
    float avg;
    printf("%s\n", t->firstname);
    printf("%s\n", t->lastname);
    
    for ( i = 0; i < 4; i++ ){
            total = grades [ i ];
    
            }
    
    printf("The average grade for the course is %d\n", ( float ) avg = total /4 );
    
    
    }
    
    void printcourseavg ( Course *s)  {
    
            int i,
            total = 0;
            float avg;
    
            for ( i = 0; i < 5; i++ ) {
            total = studentfinal [ i ];
    
            printf("The course average is %d", ( float ) avg = total / 5 );
    
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Hopefully these points will help to clarify
    1. A struct is a blueprint for storing some data, grouped into one "lump" or "item". A struct instance means a variable made from the blueprint.

    2. Your code appears to create four different instances of Grade at different points in the code - this is probably not what you wanted to do.

    3. To pass the address of (or a pointer to) an instance, you use the & operator to get the address, and the name of the variable you want the address of.

    4. Also, C as a language does not allow declaring variables mixed with code - you should declare all your variables before you provide anything that "does stuff" (that is, code, as opposed to declarations). The errors you get are caused by this, but the correct fix is more related to 2.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You further need to...

    *) Indent your code.
    *) Put all function prototypes before the main function. They are not supposed to be scattered around in the code.
    *) You should study this: http://cpwiki.sourceforge.net/Common...kes_and_errors

    Usually, declaring a char* pointer and assigning a string literal means you don't know what you're doing. Make it const char* and you'll be safe from mistakes.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Feb 2008
    Posts
    93
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    typedef  struct  Grade {
            char *firstname;
            char *lastname;
            int *grades;
    } Grade; 
    
    typedef struct Course {
            char *name;
            char *lastname;
            int *studentfinal;
    } Course;
    
    void printname ( Grade *t);
    void printcourseavg (Course *s);
    
    int main (void){
    Grade student;
    
    student.firstname = "John";
    student.lastname ="Doe";
    student.grades = (int *) calloc(5,sizeof(int));
    student.grades [ 0 ] = 50;
    student.grades [ 1 ] = 70;
    student.grades [ 2 ] = 60;
    student.grades [ 3 ] = 75;
    student.grades [ 4 ] = 80;
    
    
    Course final;
    
    final.studentfinal = (int*) calloc(5,sizeof(int));
    final.studentfinal [ 0 ] = 78;
    final.studentfinal [ 1 ] = 87;
    final.studentfinal [ 2 ] = 85;
    final.studentfinal [ 3 ] = 86;
    final.studentfinal [ 4 ] = 85;
    
    printname( &student);
    
    printcourseavg(&final);
    
    return 0;
    }
    
    
    void printname ( Grade *t )
    {
    int i;
    int total = 0;
    float avg;
    Grade student;
    printf("&#37;s\n", t->firstname);
    printf("%s\n", t->lastname);  /*
    student.grades = (int *) calloc(5,sizeof(int));  */
    for ( i = 0; i < 4; i++ ){
            total += student.grades [ i ];
    
            }
    
    printf("The average grade for the course is %f\n",  avg = total / 5 );
    
    }
    
    void printcourseavg ( Course *s)  {
    
            int i,
            total = 0;
            float avg;
            Course final;
            /*
            final.studentfinal = (int*) calloc(5,sizeof(int));*/
            for ( i = 0; i < 5; i++ ) {
            total += final.studentfinal [ i ];
            }
    
            printf("The course average is %f",  avg = total / 5 );
    
    }

    John
    Doe
    Segmentation fault

    With callc in functions commented out.

    John
    Doe
    The average grade for the course is 0.000000
    The course average is 0.000000j

    With calloc working in function? I don't understand why my arrays aren't getting to my functions if my John Doe is printing.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You can't print int's using %f. And you don't want to calloc memory inside your print functions -- you'd lose the data you stored there in main.

    Edit: Just noticed you declared avg as float, so never mind. But did you ever wonder about that warning "unused parameter s"? Don't you think you should use the data that was passed into your function, instead of ignoring it?
    Last edited by tabstop; 07-30-2008 at 02:59 PM.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    It seems to work fine, except you called this function in main

    printcourseavg(&final);

    and instead of using the argument, you used a local variable.
    I would rewrite the function so that it uses the pointer you passed.

    Free your arrays in main before the program closes, too.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Dividing by floating point numbers might help as well.

    avg = total / 5.0;

  8. #8
    Registered User
    Join Date
    Feb 2008
    Posts
    93
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    typedef  struct  Grade {
            char *firstname;
            char *lastname;
            int *grades;
    } Grade;
    
    typedef struct Course {
            char *name;
            char *lastname;
            int *studentfinal;
    } Course;
    
    void printname ( Grade *t);
    void printcourseavg (Course *s);
    
    int main (void){
    
    Grade student;
    
    student.firstname = "John";
    student.lastname ="Doe";
    student.grades = (int *) calloc(5,sizeof(int));
    student.grades [ 0 ] = 50;
    student.grades [ 1 ] = 70;
    student.grades [ 2 ] = 60;
    student.grades [ 3 ] = 75;
    student.grades [ 4 ] = 80;
    
    
    Course final;
    
    final.studentfinal = (int*) calloc(5,sizeof(int));
    final.studentfinal [ 0 ] = 78;
    final.studentfinal [ 1 ] = 87;
    final.studentfinal [ 2 ] = 85;
    final.studentfinal [ 3 ] = 86;
    final.studentfinal [ 4 ] = 85;
    
    printname( &student);
    
    printcourseavg(&final);
    
    return 0;
    }
    
    
    void printname ( Grade *t )
    {
    int i;
    int total = 0;
    int avg;
    
    printf("&#37;s\n", t->firstname);
    printf("%s\n", t->lastname);
    
    for ( i = 0; i < 5; i++ ){
            total +=  *t->grades[i];
    
            }
    printf("The average grade for the student is %d\n",  avg = total / 5 );
    
    
    }
    
    void printcourseavg ( Course *s)  {
    
            int i,
            total = 0;
            int avg;
    
    
    
            for ( i = 0; i < 5; i++ ) {
            total += *s ->studentfinal[i];
    
            }
    
            printf("The course average is %d",  avg = total / 5 );
    
    }
    If I do this
    total += *t->grades[i];
    It gives me this.
    :69: error: invalid type argument of &#226;unary *&#226;
    grades.c: In function &#226;printcourseavg&#226;:
    grades.c:87: error: invalid type argument of &#226;unary *&#226;

    if I do total += *t->grades

    It will grab the first number and that's it.

  9. #9
    Registered User
    Join Date
    Feb 2008
    Posts
    93
    However it will not divide the first number by 5 which makes no sense to me. If the total = 0 and its grabbing the first number . It should atleast divide the first number by 5 not just print the first number.

  10. #10
    * noops's Avatar
    Join Date
    Jun 2008
    Posts
    108
    try (*t)->grades[i]

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Did you do *t->firstname? Or *t->lastname? Why wouldn't you also do t->grades[i]?

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by BSmith4740 View Post
    However it will not divide the first number by 5 which makes no sense to me. If the total = 0 and its grabbing the first number . It should atleast divide the first number by 5 not just print the first number.
    Except for the whole "grab the first number five times and add it up" part.

  13. #13
    Registered User
    Join Date
    Feb 2008
    Posts
    93
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    typedef  struct  Grade {
            char *firstname;
            char *lastname;
            int *grades;
    } Grade;
    
    typedef struct Course {
            char *name;
            char *lastname;
            int *studentfinal;
    } Course;
    
    void printname ( Grade *t);
    void printcourseavg (Course *s);
    
    int main (void){
    
    Grade student;
    
    student.firstname = "John";
    student.lastname ="Doe";
    student.grades = (int *) calloc(5,sizeof(int));
    student.grades [ 0 ] = 50;
    student.grades [ 1 ] = 70;
    student.grades [ 2 ] = 60;
    student.grades [ 3 ] = 75;
    student.grades [ 4 ] = 80;
    
    
    Course final;
    
    final.studentfinal = (int*) calloc(5,sizeof(int));
    final.studentfinal [ 0 ] = 78;
    final.studentfinal [ 1 ] = 87;
    final.studentfinal [ 2 ] = 85;
    final.studentfinal [ 3 ] = 86;
    final.studentfinal [ 4 ] = 85;
    
    printname( &student);
    
    printcourseavg(&final);
    
    return 0;
    }
    
    
    void printname ( Grade *t )
    {
    int i;
    int total = 0;
    float avg;
    
    printf("&#37;s\n", t->firstname);
    printf("%s\n", t->lastname);
    
    for ( i = 0; i < 5; i++ ){
            total +=  *t->grades;
    
            }
    
    printf("The average grade for the student is %f\n",  avg = (total / 5) );
    }
    
    void printcourseavg ( Course *s)  {
    
            int i,
            total = 0;
            float avg;
    
    
    
            for ( i = 0; i < 5; i++ ) {
            total += *s ->studentfinal;
    
            }
    
            printf("The course average is %f",  avg = (total / 5) );
    
    }
    John
    Doe
    The average grade for the student is 50.000000
    The course average is 78.000000j

    My problem is I am not grabbing all the number in the for statement for some reason and I am not being able total them in the for statment

    Total works for the first instant in both function but then it doesn't get divided by 5 which doesn't make sense to me.

  14. #14
    Registered User
    Join Date
    Feb 2008
    Posts
    93
    Code:
    void printname ( Grade *t )
    {
    int i;  
    int total = 0;
    float avg;
    
    printf("&#37;s\n", t->firstname);
    printf("%s\n", t->lastname);  
    
    for ( i = 0; i < 5; i++ ){
            total +=  (*t)->grades[i];
        
            }   
    
    printf("The average grade for the student is %f\n",  avg = (total / 5) );
    : error: invalid type argument of &#226;->&#226;
    grades.c: In function &#226;printcourseavg&#226;:

  15. #15
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    t->firstname
    t->lastname

    so

    t->grades[i]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  2. Structures within Structures
    By Misko82 in forum C Programming
    Replies: 2
    Last Post: 08-27-2007, 12:25 AM
  3. Structures, passing array of structures to function
    By saahmed in forum C Programming
    Replies: 10
    Last Post: 04-05-2006, 11:06 PM
  4. Structures, and pointers to structures
    By iloveitaly in forum C Programming
    Replies: 4
    Last Post: 03-30-2005, 06:31 PM
  5. Methods for Sorting Structures by Element...
    By Sebastiani in forum C Programming
    Replies: 9
    Last Post: 09-14-2001, 12:59 PM