COMP1911 23T2 Introduction to Programming
  1. Design a struct and a typdef to store information about a pet. The information should include the pet's name, type of animal and its age. Create a variable of this type and assign information to it to represent a dog named "Boris" of age 7.
    typedef struct pet Pet;
    
    struct pet {
        char name[MAX_LEN];
        char breed[MAX_LEN];
        int age;
    };
    
    int main(void){
        Pet myPet;
        strcpy(myPet.name,"Boris"); 
        strcpy(myPet.breed,"dog"); 
        myPet.age = 7;
        
        etc...
    
  2. Modify your struct from the previous question to include a date of birth instead of an age for each pet. You should create and use a date struct to do this. Create a variable of this type and assign information to it to represent a dog named "Boris" born on 1/4/1988.
    typedef struct date Date;
    
    struct date {
        int day;
        int month;
        int year;
    };
    
    typedef struct pet Pet;
    
    struct pet {
        char name[MAX_LEN];
        char breed[MAX_LEN];
        Date dateOfBirth;
    };
    
    int main(void){
        Pet myPet;
        strcpy(myPet.name,"Boris"); 
        strcpy(myPet.breed,"dog"); 
        myPet.dateOfBirth.day = 1;
        myPet.dateOfBirth.month = 4;
        myPet.dateOfBirth.year = 1988;
        
        etc...
    
  3. A point in two dimensional space can be stored as an array with two entries, or as a structure with two components x and y:
        typedef struct point Point;
    
        struct point {
          double x;
          double y;
        };
    
    • For each of these two representations, write a function which, given two points p and q, returns the distance between them.
          double distA( double p[2], double q[2] );
      
          double distS( Point p, Point q );
      
      Recall that the formula for the distance between 2 points is
      distance =  sqrt ((x2-x1)^2 + (y2-y1)^2)
      
      #include <math.h>
      
      double distA( double p[2], double q[2] ) {
        return( sqrt( ( p[0] - q[0] )*( p[0] - q[0] )
                     +( p[1] - q[1] )*( p[1] - q[1] )));
      }
      
      double distS( Point p, Point q ) {
        return( sqrt(  ( p.x - q.x )*( p.x - q.x )
                     + ( p.y - q.y )*( p.y - q.y ) ));
      }
      

      Do you find one version of the function "easier to read" than the other?

    • Using the struct representation, write a function that reads in points from standard input and stores them in an array. It should return how many points it successfully read in. We will assume points are read in as pairs of integers separated by spaces and/or newlines.

      It should have the following prototype

      int readPoints(Point points[], int maxPoints);
      
      int readPoints(Point points[],int maxPoints){
          int i = 0;
          while ( i < maxPoints && 
                  scanf("%lf %lf",&(points[i].x), &(points[i].y)) == 2){
                                     
              i = i + 1;
          }
          return i;
      }
      
    • Write a function to print out an array of points. Print them out to 1 decimal place and in this format (4.5,9.0)
      void printPoints(Point points[], int numPoints){
          int i = 0;
          while ( i < numPoints ){
              printf("(%.1lf,%.1lf)",points[i].x,points[i].y);
              i = i + 1;
          }
          printf("\n");
      
      }
      
    • Write a program that uses these 2 functions to read in a maximum of 100 points and print them out again.
      #define MAX_POINTS 100
      
      int main(void){
          Point points[MAX_POINTS];
          int numPoints = readPoints(points, MAX_POINTS);
          printPoints(points,numPoints);
          return EXIT_SUCCESS;
      }
      
    • Write a function furthestFromOrigin that finds and returns the point in the array that is furthest from the origin. You can use your distS function from earlier.
      Point furthestFromOrigin(Point points[], int numPoints){
          Point origin;
          origin.x = 0;
          origin.y = 0;
         
          int maxIndex = -1;
          double maxDist;
          
          double dist;
          int i = 0; 
          while ( i < numPoints ) {
              dist = distS(origin, points[i]);
              if( maxIndex == -1 || dist > maxDist ){
                  maxDist = dist;
                  maxIndex = i;
              }
              i = i + 1;
          }
          if(maxIndex != -1 ){
              return points[maxIndex];
          } else {
              //will only happen if numPoints <= 0
              return origin;
          }
      }
      
  4. What is wrong with the following code and how could we fix it?
    #define MAX_PLATE
    typedef struct parkingFine ParkingFine;
    struct parkingFine{
        double amount;
        char numberPlate[MAX_PLATE];
    };
    
    
    int readParkingFine ( ParkingFine fine );
    
    int main(void){
        ParkingFine f;
        if(readParkingFine(f)){
            printf("%lf %s\n",f.amount, f.numberPlate);
        } else {
            fprintf(stderr,"Invalid Input\n");
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
    }
    
    // Returns 1 if valid input was read in
    // Returns 0 otherwise
    int readParkingFine ( ParkingFine fine ){
        if ( scanf("%lf",&fine.amount) != 1 ||
             fgets(fine.numberPlate,MAX_PLATE,stdin) == NULL){
            return 0;
        } else {
            return 1;
        }
    }
    
    structs are passed by value, so a copy of the struct has been passed into the function, 
    so any changes made to it do not affect the variable in the main function. 
    To change this we could do the following and pass it in by reference by  passing in the address of the struct.
    
    int readParkingFine ( ParkingFine * fine );
    
    int main(void){
        ParkingFine f;
        if(readParkingFine(f)){
            printf("%lf %s\n",f.amount, f.numberPlate);
        } else {
            fprintf(stderr,"Invalid Input\n");
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
    }
    
    // Returns 1 if valid input was read in
    // Returns 0 otherwise
    // Note: fine->numberPlate is shorthand for (*fine).numberPlate
    int readParkingFine ( ParkingFine * fine ){
        if ( scanf("%lf",&fine->amount) != 1 ||
             fgets(fine->numberPlate,MAX_PLATE,stdin) == NULL){
            return 0;
        } else {
            return 1;
        }
    }
    
  5. Given the following definition of a Student
    #define MAX_LEN 100
    
    typedef struct student Student;
    
    struct student{
        int zid;
        char name[MAX_LEN];
    }
    
    Write a function to return a pointer to a Student with the given zid from an array of Student. It should return NULL otherwise. Your function should have the following prototype
     Student * findStudent(Student class[], int size, int zid);   
    
    Student * findStudent(Student class[], int size, int zid) {
        int i;
        
        for ( i = 0 ; i < size; i++){
            if( class[i].zid == zid){
                return &(class[i]);
            }
        }
        
        return NULL;
    }