CSE 333 Exercise 2
Due: Friday, October 9 by 11 AM
Rating: 2 (note)
Each exercise this quarter is rated on a integer scale of 1 – 5, inclusive, with 1 being the "least time-consuming" and 5 being the "most time-consuming".
This difficulty scale is meant as a rough guide for you in predicting the amount of time to set aside for each exercise as you balance the work required for 333 with your other obligations. However, it is necessarily imperfect as everyone's set of circumstances and experiences with the exercises differ. If your experience with an exercise does not align with its rating, that is not a reflection of you or your abilities.
Goals
- Write code that uses pointers and data representations.
- Examine the relationship between pointers and arrays.
- Use format specifiers to handle printing fixed-width integers.
Background
As discussed in lecture, arrays and pointers are closely related:
- When used in an expression, an array name evaluates to a pointer.
- Array subscripting notation is actually pointer manipulation:
ar[i]↔*(ar+i). - An array argument and a pointer argument are functionally equivalent in that the function receives a copy of the pointer.
In addition, recall the topic of endianness:
- Endianness determines the ordering of the bytes when multibyte
data is stored in memory — the least significant
byte is stored at the littlest or biggest address.
- This does not affect the address of the data, which is always that of the first/lowest byte.
Problem Description
Write a C program (ex2.c) that does the following:
-
Contains a function called
PrintByteswith prototypevoid PrintBytes(void* mem_addr, int num_bytes). Thevoidpointer can be thought of as a generalized form of an array of bytes andnum_bytescan be thought of as the length of the "array." This function should print out the length, the address passed in, and the bytes of memory as exactly two digits each in lowercase hexadecimal, e.g.,
The 4 bytes starting at 0x7fff1081856c are: ff 01 30 4e
- Recall that the address printed may vary from execution to execution due to security measures such as stack randomization.
- For the case of
num_bytes = 0, it's ok to have a space at the end of the output. - For the case of
num_bytes > 0, there should not be a space at the end of the output.
-
Contains a function called
CopyAndSortthat accepts, in order, two arrays ofuint8_t's (i.e., two arrays of bytes) and an array length as arguments; you should assume the length of the two arrays are the same. The function should (1) callPrintByteson the first array and itssizeofand (2) iterate through the entries of the first array and copy the entries into the second array in non-descending (i.e., ascending with duplicates allowed) sorted order.- You should not use any library functions that would perform
the sort for you (e.g.,
qsort()), however you may use any type of sort. We would recommend using insertion sort.
- You should not use any library functions that would perform
the sort for you (e.g.,
-
Completes the
mainfunction found below that sorts a local array {3, 2, 0, 8, 17, 6, 10, 7, 8, 1, 12} and dumps the bytes of the arrays along with some other variables using the two functions that you wrote. Your main should match the provided code exactly, with the exception of filling in the missing arguments:int main(int argc, char* argv[]) { int32_t int_val = 1; float float_val = 1.0f; uint8_t arr_unsorted[] = {3, 2, 0, 8, 17, 6, 10, 7, 8, 1, 12}; uint8_t arr_sorted[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; PrintBytes(&int_val, sizeof(int_val)); PrintBytes(&float_val, sizeof(float_val)); PrintBytes(arr_unsorted, _____); CopyAndSort(arr_unsorted, arr_sorted, _____); PrintBytes(arr_sorted, _____); return EXIT_SUCCESS; }
Implementation Notes
PrintBytes
- You will want to match the formatting shown in the example given above exactly, including spacing and capitalization.
- You will need to convince the compiler to let you access bytes
in memory starting from a
void*. - You will need to use format specifiers in
printfto print out a pointer value as well as auint8_tin lowercase hexadecimal. As a hint, take inspiration from the following code:uint8_t a_byte = 0xD1; printf("The byte is: %02" PRIx8 " -- enjoy!\n", a_byte);
CopyAndSort
- The array lengths and subscripts can be stored in variables of
type
int. -
Depending on your implementation, you may get a compiler warning
stating:
'sizeof' on array function parameter.... We encourage you to stop and think why gcc believes it is worth warning you about this. It is fine for your submission to generate this warning when compiled; however, you should fix any other compiler warnings you get in your code.
Test Suite
We have provided a test suite executable in your GitLab repo that can help you check just the output correctness of your code (i.e., it does not check style or memory). This test suite is purposely opaque and will not reveal what is failing. You should aim to see the following output:
$ ./test_ex2 Expected output purposely not shown. Output MATCHES expected (does not guarantee a full score; depends on your implementation)
Style Focus
General
For the sake of our autograder, make sure that your function names match the specifications exactly, including capitalization. You should write comments explaining the behavior and purpose of functions you define.
Program Layout
As with the previous exercise, make sure that you organize and comment your functions in such a way that follows the best C practices.
Format Specifiers
Utilize the correct format specifiers to avoid implicit casts and to increase the portability of your code.
Constants
Avoid "magic numbers" (i.e., unnamed numerical
constants) where possible.
Use predefined constants (e.g., EXIT_SUCCESS),
if available, or use #define to define/name any
integer constants that have a clear and specific use.
Use sizeof to increase the portability of your code.
Submission
Submit the following file(s) by creating
an ex2-submit tag in your repo before the
assignment deadline.
The file(s) should be located in the exact directory listed below
(i.e., there should be a directory ex2 with
the ex2.c file inside it),
including capitalization:
ex2/ex2.c
For full credit, your code must:
- Compile without errors or warnings on CSE Linux machines
(lab workstations,
attu, or CSE home VM). - Have no runtime errors, memory leaks, or memory errors
(
gccandvalgrind). - Be contained in the file listed above that compiles with the
command:
$ gcc -Wall -g -std=c17 -o ex2 ex2.c
- Have a comment at the top of your
.cfile with your name(s) and CSE or UW email address(es). - Be pretty: the formatting, modularization, variable and
function names, commenting, and so on should be consistent with
class style guidelines.
Additionally, the linter shouldn't have any complaints about your
code (
cpplint.py --clint). - Be robust: your code should deal with hard-to-handle/edge cases and bogus user input (if there are any) gracefully.