Lab materials
- Slides: Introduction
- Slides: Pointers
Reminder on style
- Coding style must be uniform throughout all the code files
- Your code should be easily readable and maintainable
- Prefer simple over bloated and overengineered code
- Divide your code into functions
- Functions should be simple, short, do only one thing and do it well
- Keep computational and input/output functions separate. If a function produces a result, it should avoid side effects if possible.
- Functions should be easily reusable. This will help you during the test and the exam.
- main function should be the first function in a file. All user-defined functions should be positioned after the main function.
- Use reasonably fast algorithms within the ones we’ve studies so far
- Avoid global variables in most situations, there are a few where it’s okay and those situations will be mentioned separately during the course.
Tasks
There are two lab tasks in this class. The first task focuses on passing data using pointers and the second task is about how arrays and pointers work together. Second task is divided into two parts and extended by an extra task.
Lab task 1 [W01-1]: Pointer to a variable
This is a classical swap the two values in a function task. Try to solve this task by instructions and slides alone, without using outside help or materials.
Download the starter code here: https://blue.pri.ee/ttu/files/iax0584/aluskoodid/t1_swap_template.c
Theory nugget 1: stderr standard stream
This semester we will start to separate error outputs from normal outputs. All error outputs will go to stderr standard error stream. This is common for most programming languages, including C. It allows to filter out errors from the normal output, look up “redirect stderr to file” for more information.
Old way: print all errors to stdout standard output stream: printf("Error! ....");
From now on: print all errors to stderr standard error stream: fprintf(stderr, "Error! ...");
Theory nugget: New macros introduced in the starter code
When reading through the starter code, you’ll notice a new element __FUNCTION__ – this is a string that prints the function name where it is used. It will be resolved when you compile the code – do not attempt to modify it. Starting from C99 standard, you can also use __func__ – both achieve the same thing.
In addition, there are two more macros that are often used for debugging code:
- __LINE__ prints the line number where the macro is used
- __FILE__ prints the name of the file where the macro is used
Using those, we could write something like
|
1 2 |
fprintf(stderr, "Error: Unexpected NULL-ptr in function %s at %s:%d\n", __func__, __FILE__, __LINE__); |
This makes it easier to observe in which file, in which function and on which line an error occurred.
Requirements
- Use the starter code provided
- All parts you need to complete are marked with TODO in the starter code
- Create two functions according to function comments in the starter code. One to read values, second to swap values. Call the functions.
- Print out the memory addresses where the data is stored in three different locations
- In the main() function, show where the variables are declared at in memory
- In the reading function, show the addresses where you are storing the values to
- In the swap function, show the location where the values are you are swapping
- Explain the significance of the address values when defending!
Testing
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
risto@risto-lt3:~/Nextcloud/work/ttu/teaching/_generic/prog2/lab/pointers$ ./t1_swap Addresses in function main x @ 0x7ffffd82f7d0 y @ 0x7ffffd82f7d4 Addresses in function ReadValues x @ 0x7ffffd82f7d0 y @ 0x7ffffd82f7d4 Enter value x: 19 Enter value y: 4 Original values in main x = 19 y = 4 Addresses in function SwapValues x @ 0x7ffffd82f7d0 y @ 0x7ffffd82f7d4 Updated values in main x = 4 y = 19 |
Lab task 2 part 1 [W01-2]: Pointer to an array
The purpose of the second task is to show how arrays and pointers are related to each other. In addition, we will explore pointer arithmetic and and do a reminder from last semester, where we learned about files and command line arguments.
The program needs a data file that contains integers. Create the data file yourself! Numbers can either be separated by spaces or newlines.
Requirements
Create a program that fulfills the following requirements
- Reads 10 integers from a file and stores them into an array
- The name of the file is read as a command line argument
- Show the array base address in the main function
- Print out the read integers and their memory addresses
- Find the minimum and maximum value from the array
Additional requirements that must be met
- During this task, you are not permitted to use square brackets [] for indexing the array (limitation does not apply to declaring an array). Use pointer arithmetic in all functions
- The program is halted if the file doesn’t exist or it was unable to read integers from the file – i.e. file contains something else
- You must complete the list of functions specified in the requirements
- All functions must be called from the main() function
- The minimum and maximum value must be printed in the main() function
- All error messages must be printed to the stderr standard stream.
Create the following functions
- Create a function, that reads 10 numbers from a file and stores them in an array.
- Optional: if you wish, you can print out the addresses during reading for self-checking and comparison against other functions
- Parameters: array, the array size (limit), name of input file
- Return: how many numbers were read
- You must avoid reading more numbers than can fit into the array
- You can use the following partial solution for the function and fill in the gaps highlighted by TODO. It should be relatively similar to week 8 in programming one, but with the addition of the file
12345678910111213141516171819202122232425262728int ReadValuesFromFile(int *arr, int arrayMaxSize, const char *fileName){// TODO: Open the file and check if it opened// Read a maximum of arrayMaxSize integersint i = 0;while (i < arrayMaxSize){// TODO: Read a number from file and store the return value for checkingint ret = fscanf();// Something happened - either file ended or input format was incorrectif (ret != 1){// Stop reading integers and return the number of members readbreak;}// Increment successfully read integer counti++;}// TODO: Close the input filefclose();// TODO: Return the number of integers readreturn ;} - Additional hint: For a readable solution of calling this function, you can store the command line argument in a pointer as follows:
12345// Grab the file namechar *inputFile = argv[1];// Read data from file,int numCnt = ReadValuesFromFile(nums, LEN, inputFile);
- Create a function that prints out all numbers and their memory addresses
- Parameters: name of the array, number of integers read from the file
- Create a function that find both the minimum and maximum number
- You can only call this function once – it must find both results in one go and store them
- Function can’t return anything, i.e. the function return type must be void .
- Assume that only one minimum and maximum exists
- Use the concept of pointers from task 1 to solve getting multiple values from a function.
- Do not use an array to store min/max values!
- Do not print the results in this function.
Testing
When testing the base task, test for four different results
- Command line arguments are missing, program prints an error and closes
- File does not open, program prints an error and closes
- There are no integers in the file, program prints an error and closes
- There are some integers in the file. At most 10 will be read and printed. Minimum and maximum value will be printed.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
risto@risto-lt:~/pr2/wk1_pointers$ ./task2 nums.txt Array address in main(): 0x7ffd30f10220 Printing data from file 0x7ffd30f10220: 5 0x7ffd30f10224: 9 0x7ffd30f1022c: 12 0x7ffd30f10234: 0 0x7ffd30f10238: 51 0x7ffd30f1023c: -22 0x7ffd30f10240: -1 0x7ffd30f10244: 7 Min: -22 Max: 51 |
Lab task 2 part 2 [W01-3]: Interpretation of array concept
The purpose of the second part of the task is to make sure you understood the concept that an array can be interpreted as the pointer to the first member.
Requirements
- Create (or reuse 😉 ) a function that is able to print n numbers and their memory addresses in the array.
- The function can only have two parameters.
- The function must be built in a way that it is able to print any arbitrary array
- To demonstrate that you wrote this function correctly (and understood the topic correctly), call the function 3 times, so that
- it will print out all members of the array
- it will print out elements 0 to 4
- it will print out elements 3 – 9
- NB! What happens if you got less numbers from the file?
Hint 1: Think before acting! This part of the task is about the concept of pointers and arrays rather than creating some very clever and devious solution! Do not attempt to over-engineer the solution!
Hint 2: The text preceding the printed array members should be printed in the main() function, before the function call.
Testing
Part two has two possible results
- Array is long enough, program will print the requested sequences
- Array does not contain enough members, program will print an error.
The example shows expected output if enough members were read.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
risto@risto-lt:~/pr2/wk1_pointers$ ./task2 nums.txt Array address in main(): 0x7ffd30f10220 Printing data from file 0x7ffd30f10220: 5 0x7ffd30f10224: 9 0x7ffd30f10228: 15 0x7ffd30f1022c: 12 0x7ffd30f10230: 8 0x7ffd30f10234: 0 0x7ffd30f10238: 51 0x7ffd30f1023c: -22 0x7ffd30f10240: -1 0x7ffd30f10244: 7 Min: -22 Max: 51 Array print from 0 to 9 0x7ffd30f10220: 5 0x7ffd30f10224: 9 0x7ffd30f10228: 15 0x7ffd30f1022c: 12 0x7ffd30f10230: 8 0x7ffd30f10234: 0 0x7ffd30f10238: 51 0x7ffd30f1023c: -22 0x7ffd30f10240: -1 0x7ffd30f10244: 7 Array print from 0 to 4 0x7ffd30f10220: 5 0x7ffd30f10224: 9 0x7ffd30f10228: 15 0x7ffd30f1022c: 12 0x7ffd30f10230: 8 Array print from 3 to 7 0x7ffd30f1022c: 12 0x7ffd30f10230: 8 0x7ffd30f10234: 0 0x7ffd30f10238: 51 0x7ffd30f1023c: -22 |
Extra task [W01-4]: MinMax task with addresses
In this task, we will recreate the minmax function from part 1 of task 2 . We add the ability to also print the memory addresses and indexes for the minimum and maximum value.
You are recommended to leave the original implementation in place and create a new function.
Requirements
- Create a new function to find the locations of the minimum and maximum elements in the array in one go.
- The return type of this function must be void .
- The function must have 4 parameters
- Array
- Length of the array
- 2 pointers or double pointers – figure out what to store in them!
- In the main function, print out the following results
- The min and max value
- The addresses of where the min and max are stored in the array
- The index of min and max value in the array.
- NB! You must calculate the results, not loop through the array
Testing
Expected output of extra task
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
risto@risto-lt:~/pr2/wk1_pointers$ ./task2 nums.txt Array address in main(): 0x7ffd30f10220 Printing data from file 0x7ffd30f10220: 5 0x7ffd30f10224: 9 0x7ffd30f10228: 15 0x7ffd30f1022c: 12 0x7ffd30f10230: 8 0x7ffd30f10234: 0 0x7ffd30f10238: 51 0x7ffd30f1023c: -22 0x7ffd30f10240: -1 0x7ffd30f10244: 7 Min: -22 Max: 51 Array print from 0 to 9 0x7ffd30f10220: 5 0x7ffd30f10224: 9 0x7ffd30f10228: 15 0x7ffd30f1022c: 12 0x7ffd30f10230: 8 0x7ffd30f10234: 0 0x7ffd30f10238: 51 0x7ffd30f1023c: -22 0x7ffd30f10240: -1 0x7ffd30f10244: 7 Array print from 0 to 4 0x7ffd30f10220: 5 0x7ffd30f10224: 9 0x7ffd30f10228: 15 0x7ffd30f1022c: 12 0x7ffd30f10230: 8 Array print from 3 to 7 0x7ffd30f1022c: 12 0x7ffd30f10230: 8 0x7ffd30f10234: 0 0x7ffd30f10238: 51 0x7ffd30f1023c: -22 Min -22; address 0x7ffd30f1023c; index 7 Max 51; address 0x7ffd30f10238; index 6 |
After the class, you should
- Understand the requirements for this subject, including how to get a grade
- Understand what a pointer is
- Understand the significance of memory addresses
- Understand virtual and physical addresses
- Know what affects the address length
- Know the extra memory requirements for explicit use of pointers
- Be able to declare pointers
- Know the coding style aspects of declaring and using pointers
- Know what’s the importance of pointer data types
- Know the significance and use for NULL pointers
- Know the two pointer operators and where to use them
- Have some understanding of possible use cases for pointers
- Know how to use pointer arithmetic
- Have a better understanding of the scanf arguments and how pointers come into play here
- Understand why we said that arrays were editable when passed to a function, but variables were not
- Be able to pass the addresses of variables to functions as pointers
- Be able to edit multiple variables in a function
- Understand the concept of double pointers
- Know how to use a ternary operator
- Know how to use GCC macros for listing the name of the file, function and line number
- Know how and when to use stderr standard stream
Additional content
- Predefined macros
https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html - Beej’s Guide to C Programming: Pointers—Cower In Fear!
https://beej.us/guide/bgc/html/split/pointers.html#pointers - Beej’s Guide to C Programming: Pointers II: Arithmetic
https://beej.us/guide/bgc/html/split/pointers2.html#pointers2 - C pointers
https://www.geeksforgeeks.org/c-pointers - Pointers – CS50 shorts
https://www.youtube.com/watch?v=XISnO2YhnsY