CSSE7231 – Semester 1, 2025 Assignment 1 (Version 1.1)

Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due

CSSE7231 – Semester 1, 2025
Assignment 1 (Version 1.1)
Marks: 75
Weighting: 15%
Due: 3:00pm Friday 28 March, 2025
This specification was created for the use of MarcusWANG(s4561296) only.
Do not share this document. Sharing this document may result in a misconduct penalty.
Specification changes since version 1.0 are shown in blue and are summarised at the end of the document.

Introduction

The goal of this assignment is to give you practice in C programming. You will build on this ability in theremainder of the course (and subsequent programming assignments will be more difficult than this one). You are to create a program called uqexpr (shorthand for “UQ Expression”) that will evaluate expressions and assignment operations entered on stdin or from a file. The assignment will also test your ability to code to a particular programming style guide and to use a revision control system appropriately.

Student Conduct

This is an individual assignment. You should feel free to discuss general aspects of C programming andthe assignment specification with fellow students, including on the discussion forum. In general, questions like“How should the program behave if h this happensi ?” would be safe, if they are seeking clarification on the specification.

You must not actively help (or seek help from) other students or other people with the actual design, structure and/or coding of your assignment solution. It is cheating to look at another person’s assignment code and it is cheating to allow your code to be seen or shared in printed or electronic form by others. All submitted code will be subject to automated checks for plagiarism and collusion. If we detect plagiarism or collusion, formal misconduct actions will be initiated against you, and those you cheated with. That’s right, if you share your code with a friend, even inadvertently, then both of you are in trouble. Do not post your code to a public place such as the course discussion forum or a public code repository. (Code in private posts to the discussion forum is permitted.) You must assume that some students in the course may have very long extensions so do not post your code to any public repository until at least three months after the result release date for the course (or check with the course coordinator if you wish to post it sooner). Do not allow others to access your computer – you must keep your code secure. Never leave your work unattended.

You must follow the following code usage and referencing rules for all code committed to your SVN repository (not just the version that you submit):

Code Origin
Usage/Referencing
Code provided by teaching staff this semester

Code provided to you in writing this semester by CSSE7231 teaching staff (e.g., code hosted on Blackboard, found in /local/courses/csse2310/resources on moss, posted on the discussion forum by teaching staff, provided in Ed Lessons, or shown in class).

Permitted

May be used freely without reference. (You must be able to point to the source if queried about it – so you may find it easier to reference the code.)

Code you wrote this semester for this course

Code you have personally written this semester for CSSE7231 (e.g. code written for A1 reused in A3) – pro vided you have not shared or published it.

Permitted
May be used freely without reference. (This assumes that no reference was required for the original use.)
Unpublished code you wrote earlier

Code you have personally written in a previous enrolment in this course or in another UQ course or for other reasonsand where that code has not been shared with any otherperson or published in any way.

Conditions apply, references required

May be used provided you understand the code AND the source of the code is referenced in a commentadjacent to that code (in the required format – see the style guide). If such code is used without appropriate referencing then this will be considered misconduct.

Code from man pages on moss

Code examples found in man pages on moss. (This does not apply to code from man pages found on other systems or websites unless that code is also in the moss man page.)

Code and learning from AI tools

Code written by, modified by, debugged by, explained by, obtained from, or based on the output of, an artificial intelligence tool or other code generation tool that youalone personally have interacted with, without the assistance of another person. This includes code you wroteyourself but then modified or debugged because of yourinteraction with such a tool. It also includes code youwrote where you learned about the concepts or libraryfunctions etc. because of your interaction with such atool. It also includes where comments are written by sucha tool – comments are part of your code.

Conditions apply, references & documentation req’d
May be used provided you understand the code AND the source of the code or learning is referenced in a com ment adjacent to that code (in the required format – see the style guide) AND an ASCII text file (named toolHistory.txt) is included in your repository and withyour submission that describes in detail how the tool wasused. (All of your interactions with the tool must be captured.) The file must be committed to the repository at the same time as any code derived from such a tool. If such code is used without appropriate referencing and without inclusion of the toolHistory.txt file then this will be considered misconduct. See the detailed AI tool use documentation requirements on Blackboard – this tells you what must be in the toolHistory.txt file.

Code copied from sources not mentioned above

Code, in any programming language:


  • copied from any website or forum (including StackOverflow and CSDN);
  • copied from any public or private repositories;
  • copied from textbooks, publications, videos, apps;
  • copied from code provided by teaching staff only in a previous offering of this course (e.g. previous assignment one solution);
  • written by or partially written by someone else or written with the assistance of someone else (other than a teaching staff member);
  • written by an AI tool that you did not personally and solely interact with;
  • written by you and available to other students; or
  • from any other source besides those mentioned in earlier table rows above.
Prohibited
May not be used. If the source of the code is referenced adjacent to the code then this will be considered code without academic merit (not misconduct) and will be re moved from your assignment prior to marking (which may cause compilation to fail and zero marks to be awarded). Copied code without adjacent referencing will be consid ered misconduct and action will be taken.

This prohibition includes code written in other program ming languages that has been converted to C.

Code that you have learned from
Examples, websites, discussions, videos, code (in any pro gramming language), etc. that you have learned from or that you have taken inspiration from or based any part of your code on but have not copied or just converted from another programming language. This includes learningabout the existence of and behaviour of library functions and system calls that are not covered in class.
Conditions apply, references required

May be used provided you do not directly copy code ANDyou understand the code AND the source of the code or inspiration or learning is referenced in a comment adjacent to that code (in the required format – see the style guide). If such code is used without appropriate referencing then this will be considered misconduct.

You must not share this assignment specification with any person (other than course staff), organisation, website, etc. Uploading or otherwise providing the assignment specification or part of it to a thirdparty including online tutorial and contract cheating websites is considered misconduct. The university is awareof many of these sites and many cooperate with us in misconduct investigations. You are permitted to postsmall extracts of this document to the course Ed Discussion forum for the purposes of seeking or providingclarification on this specification.

In short – Don’t risk it! If you’re having trouble, seek help early from a member of the teaching staff.Don’t be tempted to copy another student’s code or to use an online cheating service. Don’t help another relationship. You should read and understand the statements on student misconduct in the course profile and on the school website: https://eecs.uq.edu.au/current-students/guidelines-and-policies-students/ student-conduct.

Specification

The uqexpr program evaluates expressions and assignment operations entered on stdin or from a file.

Expressions
An expression is a combination of variables, numbers and operators that are evaluated to a single number. For example, sin(3.14/variable) is an expression that equals approximately 0 if variable = 1, and 1 if variable = 2.

Assignment Operations

Assignment operations have a single equals sign (=) and a single variable on the left-hand side (LHS) of the equals sign and an expression on the right-hand side (RHS) of the equals sign. The expression is evaluated and the variable is assigned the result. For example, E = m*c∧2 is an assignment operation. If m = 2 and c = 3*10∧8, then E is assigned the value 18*10∧16.

Command Line Arguments

Your uqexpr program is to accept command line arguments as follows:
./uqexpr [--def string ] [--significantfigures num ] [--loopable string ] [filename]

The square brackets ([]) indicate optional arguments. The italics indicate placeholders for user-supplied value arguments. uqexpr expects zero or more option arguments beginning with “--” to follow the command name (with an associated value argument after --def, --loopable and --significantfigures). Option arguments can be in any order. A single optional filename for the input file to be read will follow this – if it is absent then expressions and assignment operations will be read from stdin. It is acceptable to run uqexprwith no command line arguments. It is also possible to provide filename as an  argument without any option arguments.

Some examples of how the program might be run include the following1 :
./uqexpr
./uqexpr ./input_file.txt
./uqexpr --significantfigures 5 toEvaluate.txt
./uqexpr --def ThisIsAVariable=3.14 --loopable ThisIsALoopVariable,5,-1,-5
./uqexpr --significantfigures 7 --loopable x,0,1,5 --def a=-1 --loopable \
loop,10,-1,-1 --def b=3.14 expr.txt
The meaning of the arguments is as follows. More details on the expected behaviour of the program are provided later in this document.
  • --def – this argument specifies the initial value for a given variable. If this argument is present then it must be followed by a string containing a variable name and value pair. A variable name should have an equals sign (=) after it, followed by a number to initially set the variable to. For example, to initialise the variable hello to the value 1, then the string that follows --def should be hello=1. The --def argument can be specified multiple times on the command line to define multiple variables.
  • --loopable – this argument specifies that the following variable can be looped through in expressions and assignment operations. Loop variables should have a name and range (i.e. start, increment and end values) separated by commas (,). For example, to set the variable x to loop from 10 to 5 in increments of -0.25, then the string that follows --loopable should be x,10,-0.25,5. The @loop command can be used to execute loops. The initial value of a newly defined loop variable should be its start value. The --loopable argument can be specified multiple times on the command line to define multiple loop variables. Refer to the Range Command and Advanced Functionality sections for more details about the use of loop variables.
  • --significantfigures – this single digit argument specifies the maximum number of significant figures of numerical values printed to stdout. For example, if --significantfigures 5 is specified, then printed numbers will have at most five significant figures. If --significantfigures is not specified, then the default maximum number of significant figures (4) will be used. --significantfigures can only be specified once on the command line. You can print out a floating point number to a specified maximum number of significant figures using the printf() or fprintf() format specifier %.*g. The first argument is the maximum number of significant figures and the second argument is the value to print.
  • filename – a filename specified at the end of the command line is the name of an input file containing expressions and assignment operations to be evaluated. If present, it is always specified last. If a filename is not specified, then expressions and assignment operations will be read from stdin. The filename string cannot begin with “--”. If the user wants to specify a file whose name does start with “--” then they should prefix the name with “./”.

Before doing anything else, your program must check the command line arguments for validity. If the program receives an invalid command line then it must print the following message:

Usage: ./uqexpr [--def string] [--significantfigures 2..8] [--loopable string] [filename]

to standard error (with a following newline), and exit with an exit status of 10.

Refer to the Command Line and Variable Checking section for information on how to determine the other rules of command line checking.

Checking whether an input file exists or can be opened is not part of the usage checking (other than checking that filename is not an empty string). Checking the contents/format of the strings following --loopable and/or --def is not part of the usage checking (other than checking that the strings are not empty). These are checked after command line validity as described below.

File Checking

If an input filename is provided on the command line, your program must check that it can be opened for reading. If it cannot be opened for reading, then your program must print the message:

uqexpr: unable to open input file "filename " for reading

to standard error (with a following newline) where filename is replaced by the name of the file from the command line. The double quotes must be present. Your program must then exit with an exit status of 14.

Variable Checking

If the usage check and input file check (if required) described above are successful, then your program must check the value of arguments that follow --def and/or --loopable
. The requirements for valid variables are:
  • A string after --def must be in the form name=value, i.e. variable names and values should be separated by an equals sign (=). The value is treated as a double precision floating point number.
  • A string after --loopable must be in the form name,start,increment,end, i.e. the start value, increment value and end value are specified after the loop variable name and are comma (,) separated. These values should be treated as numbers of type double. Refer to the Hints section for a function that can be used to convert a string to double. The increment value is used in each loop iteration to update the loop variable and therefore cannot be 0. The increment value should be positive if the start value is less than the end value. The increment value should be negative if the start value is greater than the end value. It is permissible for the start value to equal the end value, in which case the increment value can be any number other than 0.
  • Variable names must contain only letters (a to z, A to Z) and must have a length between 1 and 25 letters inclusive.
  • See the Command Line and Variable Checking section below for more information.

If any of the above requirements are found to be violated whilst checking variables, then your program must print the message:

uqexpr: invalid variable(s) were detected

to standard error (with a following newline). Your program must then exit with an exit status of 11.

After confirming the validity of all variables, if it is discovered that any variables have the same name, then your program must print the message:
uqexpr: duplicate variables were found
to standard error (with a following newline). Your program must then exit with an exit status of 1.

Command Line and Variable Checking

We have deliberately omitted some requirements for checking the arguments and variables specified on the command line. Please run the demo program (demo-uqexpr) and observe the behaviour of the program to answer the following questions.
  • Are variable names case sensitive?
  • What range of values is permitted to follow the --significantfigures option on the command line? (Hint: see the usage error message above.)
  • What happens if the filename string begins with “--”?
  • What happens if an empty string is given as a command line argument (in any position)?
  • What happens if the --significantfigures argument is given more than once on the command line?
  • What happens if an argument is given after any filename ?
  • What happens if an option argument (--def, --loopable or --significantfigures) is not followed by an option value argument?
  • What happens if an unexpected argument appears on the command line?

Program Behaviour

Program Startup

If the above checks are successful, your program must print the following message to standard output (stdout), with a newline at the end of each line:

Welcome to uqexpr!
This program was written by s4561296.

Your program must then print the initialised variables that were identified and their value, each separated by a newline. The value should be formatted using the maximum number of significant figures specified by the --significantfigures option argument. If --significantfigures was not specified on the command line, then the default value (4) should be used. For example, if --def hello=1 --def world=2 is specified on the command line, this message must be printed:

Variables:

hello = 1

world = 2

If no initialised variables were specified, then this message must be printed instead:

No variables were specified.

Your program must then print the loop variables that were identified, each separated by a newline. The current value, start, increment and end values should be formatted using the maximum number of significant figures specified by the --significantfigures option argument. If --significantfigures was not specified on the command line, then the default value (4) should be used. For example, if --loopable x,0,1,10 --loopable y,10,-0.123456789,5 --significantfigures 5 is specified on the command line, this message must be printed:

Loop variables:
x = 0 (0, 1, 10)
y = 10 (10, -0.12346, 5)

If no loop variables were specified, then this message must be printed instead:

No loop variables were identified.

After variables are reported, the following message must be printed if no input file was specified on the command line, i.e. lines are to be read from stdin:

Enter your expressions and assignment operations to be evaluated.

Expression and Assignment Operation Validation and Evaluation

Your program must then repeatedly read lines from the input file (or stdin if no input file was specified). Each line is terminated by a newline character or pending EOF. Lines beginning with a hash symbol (#) are considered comments and ignored. The line (excluding any terminating newline) will then be evaluated for its validity. If the line entered is not a valid expression or assignment operation, your program must print the following message (terminated by a newline) to stderr and attempt to read another line from the input file or stdin :

Error in command, expression or assignment operation detected

The rules for valid expressions are:

  • No equals sign (=) present in the line read.
  • Able to be compiled by the tinyexpr library without error. See the Provided Libraries section below for more details about the tinyexpr library. The expression should be compiled using all validated loop and non-loop variables.
The rules for valid assignment operations are:


  • One equals sign (=) present in the line read.
  • he RHS of the assignment operation (i.e. the part after the equals sign) must be able to be compiled by the tinyexpr library without error.
  • The LHS of the assignment operation should contain a single variable name and no other variable names, numbers or operators. Whitespace characters are permissible before and after the variable name. If a variable name is valid and is not an existing variable, then it is to be defined as a new non-loop variableand its value is to be set to the result after the RHS is evaluated by the tinyexpr library.  Refer to the Hints section for more details.


If an expression or assignment operation is found to be valid, it should then be evaluated by the tinyexpr library. For expressions, your program must print the following message:
Result = value

to standard output (stdout) with a following newline, where value is replaced by the result after evaluating the expression and is formatted according to the --significantfigures option argument.

For assignment operations, your program must evaluate the expression on the RHS of the assignment oper ation and then store the result in the memory location of the variable on the LHS. Your program must print the following message:
var = value

to standard output (stdout) with a following newline, where var is replaced by the variable name and value is replaced by the result after evaluating the expression and is formatted according to the --significantfigures option argument. Assignment operations entered by the user can assign values to variables that are dependent on the values of other variables, e.g. y = 2 + x and x = 2 * x are valid assignment operations.

Your program must then attempt to read another expression or assignment operation from the file or stdinand repeat the above process.

Exiting the Program

If end-of-file (EOF2 ) is detected on stdin when your program goes to read a line, your program must print the following message to stdout
(with a terminating newline):
Thanks for using uqexpr.
and exit with exit status 0.

Print Command

The @print command can be used to print the name of all non-loop variables and their current values and then all loop variables with their current values and range to stdout. There should be no leading or trailing characters (including whitespace) before or after the command, respectively. For example, suppose the user enters the following command:

./uqexpr --significantfigures 2 --loopable y,0,1,10 --loopable x,10,-0.25,5 \

--def hello=5 --def HeLLo=3.14

If the @print command is specified by the user via stdin or the input file, the following lines should be printed to stdout :

Variables:
hello = 5
HeLLo = 3.1
Loop variables:
y = 0 (0, 1, 10)
x = 10 (10, -0.25, 5)

Note that “No variables were specified.” and “No loop variables were identified.” lines should be printed instead of “Variables:” and “Loop variables:” if no non-loop or loop variables have been defined, respectively.

Range Command

The @range var command allows the user to define additional loop variables or redefine the range of existing loop variables. There should be no leading or trailing characters (including whitespace) before or after the command, respectively. There should be a single space between @range and var . var is replaced by a string that follows the same format as the string that follows --loopable on the command line and should be subject to the same checks, e.g. variable names must be letters only. For example, to set the variable y to loop from 10 to 5 in increments of -0.25, then the command entered via stdin or within the input file should be:

@range y,10,-0.25,5

Assuming that --significantfigures 2 was specified on the command line, the following line should be printed to stdout, containing the name and range of y :

y = 10 (10, -0.25, 5)

Note that since the range of existing loop variables can be redefined, it is permissible for existing loop variable names to be specified in a @range var command. It is also valid to convert an existing non-loop variable to a loop variable3 . No loop variables are (re)defined if any errors are found in the vars argument. If the commandis valid, the value of the variable is set to be the start value of the range.  If the command entered is invalid, your program must print the following message (terminated by a newline) to stderr and attempt to read another line from the input file or stdin :

Error in command, expression or assignment operation detected

Advanced Functionality

This section describes more advanced functionality which involves implementing loop variable looping. It is recommended that you not implement this until other functionality is working. Loop variables can be looped through using the command @loop var expression , where var is replaced by the name of a loop variable and expression is replaced by an expression or assignment operation. There should be no leading characters (including whitespace) before the command. There should be a single space between @loop, var and expression . There should be a single space between @loop and var and at least one space after var .
The expression or assignment operation can contain any number of spaces. The specified loop variable must be looped through based on its start, increment and end values and the specified expression or assignment operation must be evaluated for each loop iteration. At the start of a loop, the loop variable is initialised tothe start value. expression is evaluated and the loop value is incremented. This  process repeats until the loop variable reaches its final value, which should be ≤ the end value if the increment is positive or ≥ the end value if the increment is negative. For example, if the string that follows --loopable on the command line is y,10,-2.2,5, then all expressions/assignment operations specified in the expression section of the @loop y expression command must be evaluated when y = 10.0, y = 7.8 and y = 5.6. It is recommended that you run the demo program (demo-uqexpr) to see how looping through a loop variable should work.

For assignment operations specified in the @loop command, your program must evaluate the expression on the RHS of the assignment operation and then store the result in the memory location of the variable on the LHS. For both expressions and assignment operations specified in the @loop command, your program must print their respective evaluation messages described previously with the following string appended to the end of each message before the newline:

when var = value

where var is replaced by the loop variable name and value is replaced by its respective value for that iteration and is formatted according to the --significantfigures option argument.

If any errors are detected while evaluating the @loop command (e.g. non-existent loop variable or invalid expression or assignment operation), then the loop should not be executed and var must maintain the value it had before the @loop command was issued. Your program must print the following message (terminated by a newline) to stderr and attempt to read another line from the input file or stdin:

Error in command, expression or assignment operation detected

Other Requirements

Your program must free all allocated memory before exiting, including if it exits due to a usage, file or variable error.

(Your program does not have to free memory if it exits due to a signal, e.g. the interrupt signal generated by pressing Ctrl-C.)

For any aspects of behaviour not described in this specification, your program must behave in the same manner as demo-uqexpr. If you’re unsure about some aspect, then you can run the demo program to check theexpected behaviour.

We will not test for unexpected system call or library failures in an otherwise correctly implemented program (e.g. if malloc() fails due to insufficient available resources). We will not test your program by defining variables that have the same name as tinyexpr functions or constants, e.g. sin, cos, tan, sqrt, e and pi. Your program can behave however it likes in these cases, including crashing.

Example Sessions

Some example interactions with uqexpr are shown below. Lines typed by the user (i.e. the command and text entered on standard input) are shown in bold green for clarity. Lines printed to standard error are shown in bold red. Other lines are printed to standard output. Note that the $ character is the shell prompt – it is not entered by the user nor output by uqexpr.

Example 1: Example uqexpr session with only --significantfigures specified on the command line and demonstrating the use of the @print command. Note that the user presses Ctrl-D (to terminate input – detectedby the program as EOF) just before the line “Thanks for using uqexpr.” is printed.

$ ./uqexpr --significantfigures
Welcome to uqexpr!
This program was written by s4561296.
No variables were specified.
No loop variables were identified.
Enter your expressions and assignment operations to be evaluated.
hello
Error in command, expression or assignment operation detected
z = 1
z = 1
# comments like this are ignored and whitespace is ignored in the expression below
23 + 10
Result = 33
e
Result = 2.72
# Euler’s Number approximation
eApprox = 1 + 1/1 + 1/(1*2) + 1/(1*2*3) + 1/(1*2*3*4) + 1/(1*2*3*4*5) + 1/(1*2*3*4*5*6)
Result = 2.72 eApprox = 2.72
pi
Result = 3.14
VarOne = sin(pi)
VarOne = 1.22e-16
VarTwo = sin(pi/2)
VarTwo = 1
@print
Variables:
z = 1
eApprox = 2.72
VarOne = 1.22e-16
VarTwo = 1
No loop variables were identified.
Thanks for using uqexpr.
$ echo $
?
0
$
Example 2: Example uqexpr session with --significantfigures, initialised variables and an input file. Notice that the variables a, b, c, V and apparentTemperature are set dynamically within the input file. The variables ambientTemperature, humidity and windSpeed are set on the command line, so a different apparent Temperature is calculated when their specified values change.
$ cat
inputFile
# comment to be ignored
this is an invalid expression
# set these variables
a = 1
b = 2
c = 3
# volume of an ellipsoid
V = (4/3) * pi * a * b * c
# calculate apparent temperature
apparentTemperature = ambientTemperature + 0.0201465 * humidity * exp(17.27 *
ambientTemperature / (237.7 + ambientTemperature)) - (0.7 * windSpeed) - 4
$ ./uqexpr --significantfigures 5 --def ambientTemperature=29.0
\
--def humidity=49.5 --def windSpeed=0.1 inputFile
Welcome to uqexpr!
This program was written by s4561296.
Variables:
ambientTemperature = 29
humidity = 49.5
windSpeed = 0.1
No loop variables were identified.
Error in command, expression or assignment operation detected
a = 1
b = 2
c = 3
V = 25.133
apparentTemperature = 31.452
Thanks for using uqexpr.
$ ./uqexpr --significantfigures 5 --def ambientTemperature=-1.6
\
--def humidity=66 --def windSpeed=5 inputFile
Welcome to uqexpr!
This program was written by s4561296.
Variables:
ambientTemperature = -1.6
humidity = 66
windSpeed = 5
No loop variables were identified.
Error in command, expression or assignment operation detected
a = 1
b = 2
c = 3
V = 25.133
apparentTemperature = -7.9172
Thanks for using uqexpr.

Example 3: Example uqexpr session with --loopable, --def and --significantfigures arguments specified on the command line and the use of @range, @print and @loop commands. A loop variable is used to perform integration. The factorial of n can be calculated using R 0 1 (− ln x) n dx. This integral will be evaluated to find the factorial of 5, which we expect to be 120. Note that x is set to 1 initially and the @range command changes its value to 0.000001 (1e-06). After the loop, the value of x is 0.999999 instead of 1 due to a floating point rounding issue. During the loop, each iteration uses and updates the current value of sum.

$ ./uqexpr --loopable x,1,1,3 --def sum=0 --def n=5 --significantfigures
7
Welcome to uqexpr!
This program was written by s4561296.
Variables:
sum = 0
n = 5
Loop variables:
x = 1 (1, 1, 3)
Enter your expressions and assignment operations to be evaluated.
@range y,0.25,0.25,1
y = 0.25 (0.25, 0.25, 1)
@range x,0.000001,0.000001,1
x = 1e-06 (1e-06, 1e-06, 1)
@loop x sum = sum + ((-ln(x)) n) * 0.000001
sum = 0.503309 when x = 1e-06
sum = 0.8924082 when x = 2e-06
sum = 1.224996 when x = 3e-06
sum = 1.521628 when x = 4e-06
sum = 1.792572 when x = 5e-06
sum = 2.043877 when x = 6e-06
sum = 2.279479 when x = 7e-06
sum = 2.502125 when x = 8e-06
sum = 2.713819 when x = 9e-06
sum = 2.916088 when x = 1e-05
[Output is hidden for brevity]
sum = 119.5148 when x = 0.99999
sum = 119.5148 when x = 0.999991
sum = 119.5148 when x = 0.999992
sum = 119.5148 when x = 0.999993
sum = 119.5148 when x = 0.999994
sum = 119.5148 when x = 0.999995
sum = 119.5148 when x = 0.999996
sum = 119.5148 when x = 0.999997
sum = 119.5148 when x = 0.999998
sum = 119.5148 when x = 0.999999
@print
Variables:
sum = 119.5148
n = 5
Loop variables:
x = 0.999999 (1e-06, 1e-06, 1)
y = 0.25 (0.25, 0.25, 1)

Provided Libraries

libtinyexpr

The tinyexpr library has been pre-compiled into a shared library for you, providing all of the functions and data types required.

These functions are declared in /local/courses/csse2310/include/tinyexpr.h on moss. To use them, you will need to add #include to your code and use the compiler flag

-I/local/courses/csse2310/include when compiling your code so that the compiler can find the include file.

You will also need to link with the library containing these functions. To do this, use the compiler arguments

-L/local/courses/csse2310/lib -ltinyexpr
Note that the tinyexpr library uses the C math library, so you will also need to link your programs with
the -lm option.
Important note: You must use the version of tinyexpr.h and the pre-compiled library provided for you on moss – do not download and use the tinyexpr.c and tinyexpr.h from GitHub. The original version will generate style warnings that will cost you marks, and we will instrument libtinyexpr to support the marking process. Failure to use the provided version will cause your marking tests to fail.

Using the tinyexpr library

tinyexpr is a small C library for parsing and evaluating mathematical expressions. For example, you can use tinyexpr to evaluate the function “sqrt(sin(x+y+z)+1)” using C calls. This will give your programs the ability to work with arbitrary mathematical functions. There a few steps to using tinyexpr, as illustrated below.

Example 4: tinyexpr usage example using argv to dynamically define arbitrary variables and evaluate an arbitrary expression.

#include
>
#include
>
int main(int argc,
char* argv[])
{
argc−−;
argv++;
if (argc < 1)
{
fprintf(stderr, "Usage: ./tinyexprtest expression [variables]\n"
);
return
1;
}
// Create arrays of type te variable and double
te variable teVars[argc − 1];
double
values[argc − 1];
// Loop through each variable and initialise
it
for (int i = 1; i < argc; i++)
{
values[i − 1] = i;
te variable var = {.name = argv[i], .address = &(values[i − 1]), .type = TE VARIABLE,
.context = NULL}
;
teVars[i − 1] = var;
printf("Created new var \"%s\" with value %.3g\n"
, argv[i], values[i − 1]);
}
int
errPos;
// Parse and compile the expression, passing the vars, var count and ptr to an error
return
te expr* expr = te compile(argv[0], teVars, argc − 1, &errPos);
// expr is not NULL if compilation
succeeded
if (expr)
{
// Evaluate the
expression
printf("%s = %.3g\n"
, argv[0], te eval(expr));
// Free the memory associated with the
expression
te free(expr);
} else
{
printf("Error parsing expression \"%s\" at character %d\n"
, argv[0], errPos);
return
2;
}
return
0;
}
Let’s compile the program and then run:
./tinyexprtest "sqrt(sin(x+y+z)+1)" x y z
This will produce the following output:
Created new var "x" with value 1
Created new var "y" with value 2
Created new var "z" with value 3
sqrt(sin(x+y+z)+1) = 0.849
A few things to note from the above example:
  • te_variable variables must be bound to a memory location that can hold a double precision floating point number.
  • After variable binding, te_compile is used to compile the expression string for later evaluation.
  • If compilation fails, te_compile will return NULL and the errPos variable will be updated to the character number in the string where the parse error occurred.
  • After parsing and compilation, updates to the original variables (x, y and z in this example) will be reflected on each call to te_eval().
  • After you are finished with an expression, release the memory by calling te_free().
This little introduction should be enough for the use of tinyexpr required in this assignment, however, you may also refer to the source code and more complex examples at the project GitHub repository if you wish: https://github.com/codeplea/tinyexpr

Style

Your program must follow version 3 of the CSSE2310/CSSE7231 C programming style guide available on the course Blackboard site. Your submission must also comply with the Documentation required for the use of AI tools (if applicable).



发表评论

电子邮件地址不会被公开。 必填项已用*标注