Learning Goals
You will learn how to:
- Create a type for functions that have the same types of arguments and return value
- Make a structure with an attribute as a function pointer
- Write a function that takes a pointer to this structure (modified from HW2)
- Write a function that integrates multiple functions
- Read data from a file and write output to another file
- Detect errors and return proper code (
true,false,EXIT_SUCCESS, orEXIT_FAILURE) - Write Makefile to test
Please be aware that this you need to write a lot more for this assignment. Please start early. You are encouraged to study HW0 – HW2 thoroughly before starting this assignment. This assignment is designed with the assumption that you are familiar with the details in HW0 – HW2.
Background
1. Function pointer
In HW2 you have seen how to use a pointer to store the address of a structure object. Here in this assignment, you will learn to use a pointer to store the address of a function.
Every function in a C program refers to a specific address. It is possible to create pointers to store functions’ starting addresses, and then call functions by using those addresses, instead of the function name directly.
In C, a function pointer is declared by this syntax:
typedef type (* typename) (arguments)
For example:
typedef int (* funcptr)(int, int);
creates a type for pointers to functions that take two integers as input arguments and return one integer.
Here is an example of creating and using function pointers:
//create a function pointer type called "funcptr"
//funcptr functions take one int as an argument and return an int
typedef int (* funcptr)(int, int);
funcptr f = foo; //f now refers to the function foo
int x = f(3, 4); //equivalent to: int x = foo(3, 4);
In this assignment, you need to create a type called funcptr (you must use this name) for the functions you want to integrate. A function of type funcptr should take as argument one double, and return one double.
With this type, it is possible to create an array funcptr funcs[5] containing five functions called func1, func2, …, func5. The program can go through these five functions in the same way as going through normal array elements. For example, funcs[0] refers to the first element in this function array, that is func1.
2. Function pointer as attribute/field
An important concept in developing high-quality software is making a function’s behavior controlled by the argument(s) and nothing else. In HW2, the function to be integrated was not in the argument — we assumed it was a function called func. This can easily create confusion. Similarly, global variables and static variables can create confusion because they can make functions behave in ways that are not completely controlled by the input arguments. Thus, you should avoid using global and static variables.
After creating the type for function pointers, it is possible to make a function pointer an attribute of a structure. Now, everything needed to run the integration function is passed into the integration function as the argument.
3. Reading and writing files
This assignment asks you to read and write data from files. The key to working with files is to understand the basic file manipulation API (an “Application Program Interface” — the functions that provide certain behavior):
FILE *: All files are manipulated through pointers to FILE structures. We will call the pointer to a FILE structure a file “handle”.
In the following we use FILE * fp; to declares a file handle called fp as an example.
FILE * fopen(const char * path, const char * mode): Open a file whose file name is stored in the character arraypath. The character arraymodeindicates how you want to access the file. Themodeinfopen()has several possible values as follows:
"r": open the file for reading, starting at the beginning of the file."r+": open the file for reading and writing, starting at the beginning of the file."w": open the file for writing, starting at the beginning of the file. This deletes any content already in the file."w+": open the file for reading and writing, starting at the beginning of the file. This deletes any content already in the file. The file is created if it does not exist."a": open the file for appending, starting at the end of the current contents of the file. The file is created if it does not exist."a+": open the file for reading and appending: reads start at the beginning of the file, writes append to the end of the file. The file is created if it does not exist.
You can find out more by typing man fopen on the ecegrid machines.
int fscanf(FILE * file, const char * format, ...): This works just likescanf, but reads from the file pointer file.
- For example,
fscanf(fp, "%lfn", &d)reads a double (%lf) from the input filefpand stores the result ind. You can find out more by typingman fscanfon the ecegrid machines. You can find out more by typingman fscanfon the ecegrid machines.
int fprintf(FILE * file, const char * format, ...): This works just likeprintf, but writes to the file pointer file. Note that for fprintf to work, the file you pass should have been opened in a mode that allows writing.
- For example,
fprintf(fp, "%d", 2021);writes a integer (%d) 2021 to the filefp. You can find out more by typingman fprintfon the ecegrid machines.
int feof(FILE * file): checks the end-of-file indicator for the given file. This function returns a non-zero value when End-of-File indicator is detected, else returns zero.int fclose(FILE * file):Close the file. You should always close files when you are done using the


0 comments