Week 09 Laboratory Sample Solutions

Objectives

  • reading a line of input with fgets
  • introduction of pointers
  • using structs and pointers

Activities To Be Completed

The following is a list of all the activities available to complete this week...

Worth 0.7 mark(s) in total:

  • print_address
  • debug_increment
  • array_sum_prod
  • swap_pointers
  • my_scanf

Worth 0.7 mark(s) in total:

  • summation

Worth 0.4 mark(s) in total:

  • stellar_information

Problem sets are capped at 15 marks (there are 4 possible bonus marks from the three-dot exercises that can bring you up to a total of 15 if you missed out on any other marks in the one- or two-dot exercises).

Completing just the one and two-dot exercises every week can give you the full 15 marks needed in this component.

For more details, see the course outline.

Exercise
(●◌◌)
:

Print Address

Download print_address.c here, or copy it to your CSE account using the following command:

cp -n /import/reed/A/dp1091/public_html/24T3/activities/print_address/print_address.c .

In this activity, you will complete the C program print_address.c which attempts to print a memory address and value at that address, using pointers.

In main, you are provided with a variable number of type int and a supposed pointer to number called number_pointer.

Your main should do the following;

  1. Correctly initialise the pointer number_pointer to point to the address of number. In the provided code, the pointer is declared incorrectly, you will need to fix this before you can initialise it.
  2. Print the memory address stored in number_pointer.
  3. Call the function print_at_address and pass the memory address stored in number_pointer to it.

The print_at_address will need to be implemented by you and it should;

  1. Print the memory address passed to it.
  2. Print the value at that memory address.

You must not change the function signature of print_at_address.

Examples

dcc print_address.c -o print_address
./print_address
Passing the memory address 0x16b44b028 to the function
The memory address passed to this function is 0x16b44b028
The value at the memory address is 42

Assumptions/Restrictions/Clarifications

  • You must not change the function signature of print_at_address.
  • You must use the function print_at_address to print the second and third lines of the output.
New! You can run an automated code style checker using the following command:
1091 style print_address.c
    

When you think your program is working, you can use autotest to run some simple automated tests:

1091 autotest print_address

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give dp1091 lab09_print_address print_address.c
    

Note, even though this is a pair exercise, you both must run give from your own account before Monday 28 October 09:00 to obtain the marks for this lab exercise.

Sample solution for print_address.c
// Print the memory address of a variable
// Created by: Ibrahim Ghoneim z5470570 03/2024
// print_at_address.c

#include <stdio.h>

void print_at_address(int *memory_address);

int main(void) {

    int number = 42;

    ////////////////////////////////////////////////////////////////////////////
    ////////////////////////// ONLY MODIFY CODE BELOW //////////////////////////
    ////////////////////////////////////////////////////////////////////////////
    
    int *number_pointer = &number;
    printf("Passing the memory address %p to the function\n", number_pointer);
    print_at_address(number_pointer);

    return 0;
}

/*
param: memory_address - is an integer pointer that points to a memory address
return: void
Prints the memory address and the value at the memory address
*/
void print_at_address(int *memory_address) {
    printf("The memory address passed to this function is %p\n", memory_address);
    printf("The value at the memory address is %d\n", *memory_address);
    return;
}

Exercise
(●◌◌)
:

Debugging - increment

Download debug_increment.c here, or copy it to your CSE account using the following command:

cp -n /import/reed/A/dp1091/public_html/24T3/activities/debug_increment/debug_increment.c .

Note that this exercise is not marked or worth marks!

Debugging Tips!

Some debugging tips for you:

  • dcc output - as you run into issues, dcc will point you to where the errors are. Remember that dcc gives you the line number the issue is on, and will give some sort of explanation. Make sure you read everything dcc gives you. Sometimes we get “errors carried forward”, so find your first error, fix that, then recompile.
  • print statements - sometimes it can be handy to see if the flow of your code puts you in the spot you expect it to be (ie. inside the right if statement, or going through a loop the correct amount of times). A quick way you can check this is by putting print statements in your code for testing purposes, like "the value of x is %d and y is %d". This lets you check that you got against what you expected.
  • DPST1091 debugging guide

The Task

This exercise takes in a number and intends to increment the value of the number using a function increment(), which takes a pointer to an integer as its parameter. Currently it has some issues - it is your job to figure them out and fix the code.

Examples

dcc debug_increment.c -o debug_increment
./debug_increment
Please enter a number: 1
Before increment: 1
After increment: 2
./debug_increment
Please enter a number: -8
Before increment: -8
After increment: -7
./debug_increment
Please enter a number: 100
Before increment: 100
After increment: 101
New! You can run an automated code style checker using the following command:
1091 style debug_increment.c
    

When you think your program is working, you can use autotest to run some simple automated tests:

1091 autotest debug_increment

When you are finished working on this exercise, you must submit your work by running give:

give dp1091 lab09_debug_increment debug_increment.c
    

You must run give before Monday 28 October 09:00 to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Sample solution for debug_increment.c
// debug_pointers.c
// This program given a number, incraments it using pointers
// Written by Sofia De Bellis, z5418801 on July 2023

#include <stdio.h>

void increment(int *ptr) {
    (*ptr)++;
}

int main() {
    int num;
    printf("Please enter a number: ");
    scanf("%d", &num);
    int *ptr = &num;

    printf("Before increment: %d\n", *ptr);
    increment(ptr);
    printf("After increment: %d\n", *ptr);

    return 0;
}

Exercise
(●◌◌)
:

Calculate both the sum and product of the values in an array

Download array_sum_prod.c here, or copy it to your CSE account using the following command:

cp -n /import/reed/A/dp1091/public_html/24T3/activities/array_sum_prod/array_sum_prod.c .

The above file array_sum_prod.c contains a function array_sum_prod, which should find the sum and the product of the values stored in the array. It should write these values into the integers referenced by the pointers in the input to the function.

Unfortunately, the provided function doesn't actually work. For this lab exercise, your task is to complete this function.

The file also contains a main function which you can use to help test your array_sum_prod function. It has two simple test cases.

This main function will not be marked -- you must write all of your code in the array_sum_prod function.

You may modify the main function if you wish (e.g. to add further tests), but only the array_sum_prod function will be marked.

Examples

dcc -o array_sum_prod array_sum_prod.c 
./array_sum_prod 
Sum: 20, Product: 360
Sum: 10, Product: 24

Assumptions/Restrictions/Clarifications

  • You will not be given an empty array as input, you can assume that you have at least 1 value.
New! You can run an automated code style checker using the following command:
1091 style array_sum_prod.c
    

When you think your program is working, you can use autotest to run some simple automated tests:

1091 autotest array_sum_prod

When you are finished working on this exercise, you and your lab partner must both submit your work by running give:

give dp1091 lab09_array_sum_prod array_sum_prod.c
    

Note, even though this is a pair exercise, you both must run give from your own account before Monday 28 October 09:00 to obtain the marks for this lab exercise.

Sample solution for array_sum_prod.c
// COMP1511 Array Sum Product
// Calculate the sum and the product of the elements in an array
// and write the results into variables passed into the function
// by reference.

// Modified by Marc Chee, March 2020

#include <stdio.h>

void array_sum_prod(int length, int nums[length], int *sum, int *product);

// This is a simple main function that you can use to test your array_sum_prod
// function.
// It will not be marked - only your array_sum_prod function will be marked.
//
// Note: the autotest does not call this main function!
// It calls your array_sum_prod function directly.
// Any changes that you make to this main function will not affect the autotests.

int main(int argc, char *argv[]){
   int nums[] = {3,4,1,5,6,1};
   int prod;
   int sum;

   //Pass in the address of the sum and product variables
   array_sum_prod(6, nums, &sum, &prod);

   printf("The sum is %d and prod is %d\n",sum,prod);
   return 0;
}


// Calculates the sum and product of the array nums.
// Actually modifies the  variables that *sum and *product are pointing to
void array_sum_prod(int length, int nums[length], int *sum, int *product) {
    int i = 0;
    *sum = 0;
    *product = 1;
    while (i < length) {
        *sum = *sum + nums[i];
        *product = *product * nums[i];
        i++;
    }
}

Exercise
(●◌◌)
:

Using pointers and a function to swap number values

Download swap_pointers.c here, or copy it to your CSE account using the following command:

cp -n /import/reed/A/dp1091/public_html/24T3/activities/swap_pointers/swap_pointers.c .

swap_pointers should take two pointers to integers as input and swap the values stored in those two integers.

For example if the integers are:

int first = 1;
int second = 2;

After your function runs, first should be 2 and second should be 1.

Assumptions/Restrictions/Clarifications

  • swap_pointers is a void function. It cannot return any values.
  • swap_pointers should not call scanf (or getchar or fgets).
  • swap_pointers should not print anything. It should not call printf.
  • Your submitted file may contain a main function. It will not be tested or marked.
New! You can run an automated code style checker using the following command:
1091 style swap_pointers.c
    

When you think your program is working, you can use autotest to run some simple automated tests:

1091 autotest swap_pointers

When you are finished working on this exercise, you must submit your work by running give:

give dp1091 lab09_swap_pointers swap_pointers.c
    

You must run give before Monday 28 October 09:00 to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Sample solution for swap_pointers.c
#include <stdio.h>

// swap the values in two integers, given as pointers
void swap_pointers(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// This is a simple main function which could be used
// to test your swap_pointers function.
// It will not be marked.
// Only your swap_pointers function will be marked.

int main(void) {
    int first = 1;
    int second = 2;
    
    swap_pointers(&first, &second);
    
    printf("%d, %d\n", first, second);
    return 0;
}

Exercise
(●◌◌)
:

My Scanf

Download my_scanf.c here, or copy it to your CSE account using the following command:

cp -n /import/reed/A/dp1091/public_html/24T3/activities/my_scanf/my_scanf.c .

Ben Briant has decided to learn how scanf() works, and to help with his understanding, he has decided to write his own simple scanf functions!

They are much simpler than a regular scanf, as they only allow for scanning in a single integer or a single double (depending on if my_scanf_int() or my_scanf_double() is being called) at a time.

Both of these functions should:

  • take in a pointer to a variable that we want to scan our value into,
  • read a value from the user (using regular scanf), then
  • set the value of the input to be the value read from the user.

Unfortunately, Ben got overwhelmed with all the pointer syntax (* and &), so decided to just avoid writing any of it! Your job is to put all the * and & in the correct spots in the code.

You will have to edit both the main() function, my_scanf_int() and my_scanf_double(), But you can't change any part of the code aside from adding * or &.

Examples

dcc my_scanf.c -o my_scanf
./my_scanf 
Enter the amount of study you need to do this week (in decimal): 7.5
Enter the number of days you have free: 3
You have on average 2.50 hour(s) each free day to do homework.

Testing

When testing your program, we are checking more than that it simply produces the correct output. We are also testing that the functions work correctly individually (by replacing your main function with one of our own).

New! You can run an automated code style checker using the following command:
1091 style my_scanf.c
    

When you think your program is working, you can use autotest to run some simple automated tests:

1091 autotest my_scanf

When you are finished working on this exercise, you must submit your work by running give:

give dp1091 lab09_my_scanf my_scanf.c
    

You must run give before Monday 28 October 09:00 to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Sample solution for my_scanf.c
// A program that creates its own simple scanf functions.
// Activity written by Paula

// This program was written by Ben Briant
// This program was fixed by [student]

#include <stdio.h>

void my_scanf_double(double *d) {
    double input;
    scanf("%lf", &input);
    *d = input;
}

void my_scanf_int(int *i) {
    int input;
    scanf("%d", &input);
    *i = input;
}

int main(void) {

    printf("Enter the amount of study you need to do this week (in decimal): ");
    double total_time;
    my_scanf_double(&total_time);

    printf("Enter the number of days you have free: ");
    int days;
    my_scanf_int(&days);

    double time_per_day = total_time / days;
    printf("You have on average %.2lf hour(s) each free day to do homework.\n", time_per_day);

    return 0;
}

Exercise
(●●◌)
:

Summation

Write a C program summation.c that takes integers as command line arguments and calculates their sum.

Examples

dcc summation.c -o summation
./summation 1 2 3 4 5 6 7 8 9
Sum: 45
./summation -5 10 -15 20
Sum: 10
./summation 100
Sum: 100
./summation
Sum: 0

Assumptions/Restrictions/Clarifications

  • You may find the atoi() function in the C standard library (stdlib.h) useful.
  • You may assume that argv[0] will always be the program name and all subsequent elements will be integers.
New! You can run an automated code style checker using the following command:
1091 style summation.c
    

When you think your program is working, you can use autotest to run some simple automated tests:

1091 autotest summation

When you are finished working on this exercise, you must submit your work by running give:

give dp1091 lab09_summation summation.c
    

You must run give before Monday 28 October 09:00 to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Sample solution for summation.c
// summation.c
//
// This program calculates and outputs the sum of all the integers provided as
// command line arguments.
//
// Written by Sofia De Bellis, z5418801, July 2023

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

int main(int argc, char* argv[]) {
    int sum = 0;

    // Start from index 1 to skip the program name (argv[0])
    for (int i = 1; i < argc; i++) {
        // Convert each command line argument to an integer using atoi() and
        // add the current number to the sum
        sum += atoi(argv[i]);
    }

    printf("Sum: %d\n", sum);

    return 0;
}

Exercise
(●●●)
:

Stellar Information Capture

Download stellar_information.c here, or copy it to your CSE account using the following command:

cp -n /import/reed/A/dp1091/public_html/24T3/activities/stellar_information/stellar_information.c .

Write a C program stellar_information.c that simulates a star system in space. Each star in the system is represented by a structure containing its name, distance from Earth (in light-years), and spectral type. Your task is to initialize a pointer to a star structure, write a function to populate its fields, a function to calculate an estimate for the time it would take to travel from earth to the star and a function to print the star's information and the estimate for the time it would take to travel from earth to the star.

Task 1

Define a structure named star with the following fields:

  1. name: a string of size 50 to store the star's name.
  2. distance: a double to store the star's distance from Earth in light-years.
  3. spectral_type: a character to store the star's spectral type (e.g., O, B, A, F, G, K, M).

Task 2

Declare a pointer star_ptr to a star structure.

Task 3

Write the function called input_star_information() that prompts the user to enter the star's name, distance from Earth, and spectral type. Then store the input values in the respective fields of the structure pointed to by star_ptr.

Task 4

Write the function called time_travel() that, given a pointer to a star, calculates and returns the estimated travel time from Earth to the star based on star's distance. This calculation involves the following steps:

  1. Converting the stars distance from light-years to kilometers by multiplying the distance by the CONVERSION_CONSTANT that is defined at the top of your program.
  2. Dividing that previously calculated value by the LIGHT_SPEED constant which is defined at the top of your program.

Task 5

Write the function called print_star_information() that, given a pointer to a star, prints the star's information (name, distance, spectral type, and time travel).

Examples

dcc stellar_information.c -o stellar_information
./stellar_information
Enter the star's name: Sirius
Enter the star's distance from Earth (in light-years): 8.6
Enter the star's spectral type: A

Star's Information:
Name: Sirius
Distance: 8.600000 light-years
Spectral Type: A
Estimated travel time from Earth: 271403091.80 seconds
./stellar_information
Enter the star's name: Polaris
Enter the star's distance from Earth (in light-years): 323
Enter the star's spectral type: F

Star's Information:
Name: Polaris
Distance: 323.000000 light-years
Spectral Type: F
Estimated travel time from Earth: 10193395192.08 seconds
./stellar_information
Enter the star's name: Rigel
Enter the star's distance from Earth (in light-years): 864.3
Enter the star's spectral type: B

Star's Information:
Name: Rigel
Distance: 864.300000 light-years
Spectral Type: B
Estimated travel time from Earth: 27276010726.06 seconds

Assumptions/Restrictions/Clarifications

  • You may assume that valid input will always be given
  • You may find using %.2lf useful for printing the travel time value to two decimal places
New! You can run an automated code style checker using the following command:
1091 style stellar_information.c
    

When you think your program is working, you can use autotest to run some simple automated tests:

1091 autotest stellar_information

When you are finished working on this exercise, you must submit your work by running give:

give dp1091 lab09_stellar_information stellar_information.c
    

You must run give before Monday 28 October 09:00 to obtain the marks for this lab exercise. Note that this is an individual exercise, the work you submit with give must be entirely your own.

Sample solution for stellar_information.c
// stellar_information.c
// This program simulates a star system in space
// Written by Sofia De Bellis, z5418801, July 2023

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

#define CONVERSION_CONSTANT 9.461e12
#define LIGHT_SPEED 299792.458

struct star {
    char name[50];
    double distance;
    char spectral_type;
};

void print_star_information(struct star* star);
void input_star_information(struct star* star);
double time_travel(struct star* star);

int main(void) {
    struct star star;
    struct star *star_ptr = &star;
    input_star_information(star_ptr);
    print_star_information(star_ptr);
    return 0;
}

// Takes in the stars information
void input_star_information(struct star* star) {
    printf("Enter the star's name: ");
    fgets(star->name, 50, stdin);

    printf("Enter the star's distance from Earth (in light-years): ");
    scanf("%lf", &star->distance);

    printf("Enter the star's spectral type: ");
    scanf(" %c", &star->spectral_type);
}

// Prints the stars information
void print_star_information(struct star* star) {
    printf("\nStar's Information:\n");
    printf("Name: %s", star->name);
    printf("Distance: %lf light-years\n", star->distance);
    printf("Spectral Type: %c\n", star->spectral_type);
    printf("Estimated travel time from Earth: %.2lf seconds\n", time_travel(star));
}

// Estimate travel time from Earth to the star based on star's distance
double time_travel(struct star* star) {
    double distance_km = star->distance * CONVERSION_CONSTANT; 
    double travel_time = distance_km / LIGHT_SPEED; 
    return travel_time;
}

Exercise — individual:
(Not For Marks) Debugging - concatenate

Download debug_concatenate.c here, or copy it to your CSE account using the following command:

cp -n /import/reed/A/dp1091/public_html/24T3/activities/debug_concatenate/debug_concatenate.c .

Note that this exercise is not marked or worth marks!

Debugging Tips!

Some debugging tips for you:

  • dcc output - as you run into issues, dcc will point you to where the errors are. Remember that dcc gives you the line number the issue is on, and will give some sort of explanation. Make sure you read everything dcc gives you. Sometimes we get “errors carried forward”, so find your first error, fix that, then recompile.
  • print statements - sometimes it can be handy to see if the flow of your code puts you in the spot you expect it to be (ie. inside the right if statement, or going through a loop the correct amount of times). A quick way you can check this is by putting print statements in your code for testing purposes, like "the value of x is %d and y is %d". This lets you check that you got against what you expected.
  • DPST1091 debugging guide

The Task

This exercise concatenate the strings passed as command-line arguments excluding the filename. Currently it has some issues - it is your job to figure them out and fix the code. Additionally, think of ways you could refactor the starter code to produce a simpler solution.

Examples

dcc debug_concatenate.c -o debug_concatenate
./debug_concatenate A blue whales heartbeat can be heard over 2 miles away
Concatenated string: Abluewhalesheartbeatcanbeheardover2milesaway
./debug_concatenate The moon has moonquakes
Concatenated string: Themoonhasmoonquakes
./debug_concatenate Pigs cannot look up into the sky
Concatenated string: Pigscannotlookupintothesky
./debug_concatenate
Concatenated string: 
New! You can run an automated code style checker using the following command:
1091 style debug_concatenate.c
    

When you think your program is working, you can use autotest to run some simple automated tests:

1091 autotest debug_concatenate
Sample solution for debug_concatenate.c
// debug_concatenate.c
//
// This program given command line args produces a concatenated
// string of all command line args
//
// Written by Sofia De Bellis, z5418801 on July 2023

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


int main(int argc, char *argv[]) {
    
    int i;
    int total_length = 0;

    for (i = 1; i < argc; i++) {
        total_length += strlen(argv[i]);
    }

    char result[total_length];
    result[0] = '\0';

    for (i = 1; i < argc; i++) {
        strcat(result, argv[i]);
    }

    printf("Concatenated string: %s\n", result);

    
    return 0;
}

Submission

When you are finished each exercises make sure you submit your work by running give.

You only need to do this if the exercise specifies a give command, otherwise - the exercise is not worth marks.

You can run give multiple times. Only your last submission will be marked.

Don't submit any exercises you haven't attempted.

If you are working at home, you may find it more convenient to upload your work via give's web interface.

Remember you have until Week 10 Monday 9:00am to submit your work.

You cannot obtain marks by e-mailing your code to tutors or lecturers.

You check the files you have submitted here.

Automarking will be run by the lecturer several days after the submission deadline, using test cases different to those autotest runs for you. (Hint: do your own testing as well as running autotest.)

After automarking is run by the lecturer you can view your results here. The resulting mark will also be available via give's web interface.

Lab Marks

When all components of a lab are automarked you should be able to view the the marks via give's web interface or by running this command on a CSE machine:

1091 classrun -sturec

Generative AI Permission Level

In completing this assessment, you are permitted to use standard editing and referencing functions in the software you use to complete your assessment. These functions are described below. You must not use any functions that generate or paraphrase passages of text or other media, whether based on your own work or not.

If your Convenor has concerns that your submission contains passages of AI-generated text or media, you may be asked to account for your work. If you are unable to satisfactorily demonstrate your understanding of your submission, you may be referred to UNSW Conduct & Integrity Office for investigation for academic misconduct and possible penalties.

DPST1091/CPTG1391 Specific Information

You are permitted to use the tools dcc-help to help you understand the error messages you may get when compiling the code you have written.

You are permitted to use autotest-help to help you understand why your code may not be passing the automated tests.

You are not permitted to submit code generated by automatic AI tools such as Github Copilot, ChatGPT, Google Bard in DPST1091/CPTG1391/COMP1511 for assignments. Submitting code generated by Github Copilot, ChatGPT, Google Bard and similar tools will be treated as plagiarism.

Our reasoning behind our decisions:

Systems such as Github Copilot and ChatGPT based on large language models or other generative artificial intelligence techniques, look likely to become heavily used by programmers. However, you need a good understanding of the language you are coding in and the systems involved before you can effectively use these tools. Using these tools to generate code for DPST1091/CPTG1391/COMP1511 instead of writing the code yourself will hinder your learning.