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.
This exercise includes a short, graded and required warm-up in
questions.txt (in the starter). It has three steps:
DumpBytes works, add the
suggested code to check your predictions, then remove that temporary
code so your program still prints only the required output.
Do Step 1 first, before writing any code. Submit your completed
questions.txt along with your code.
In this exercise you will write a small C program (ex2.c)
that lets you see how data is actually stored in memory,
one byte at a time. Additionally, you will write a function that sorts an array of bytes.
The goal is to get comfortable with the close relationship between arrays, pointers,
and the raw bytes.
You will not start from a blank file. The provided starter
ex2.c (in your exercise repo) already contains:
main that calls your functions.
Your job is to (1) write the bodies of the two functions
described below, and (2) replace the three
TODO_REPLACE_THIS placeholders in main with
the correct length arguments. You should not need to change anything
else in main.
DumpBytesvoid DumpBytes(void* data_ptr, int32_t data_len);
DumpBytes prints the raw bytes of any piece of
data. Because the first parameter is a void*, the caller
can hand it the address of an int, a float,
an array, or anything else. DumpBytes simply treats
that address as the start of a sequence of data_len
individual bytes.
It should print one line containing, in this order:
data_len, in decimal;data_ptr, in
hexadecimal; anddata_len bytes, in lowercase
hexadecimal.The exact text, spacing, and formatting are important and are spelled out in the Output Format section below.
CopyAndSortvoid CopyAndSort(uint8_t src[], uint8_t dst[], int array_len);
CopyAndSort receives two arrays of bytes (a source
array src and a destination array dst),
along with array_len, the number of elements. You may
assume both arrays have exactly array_len elements. The
function does two things, in order:
DumpBytes on src, passing
sizeof(src) as the length. Look closely at what this
line prints when you run your program, and compare it against what
you expected to see.
src into dst,
but rearranged into non-descending order. The
original src array is left unchanged.
For example, if src holds
{3, 2, 0, 8, 2}, then after the call
dst should hold
{0, 2, 2, 3, 8}.
main
The provided main declares a few local variables and then
calls your functions on them. In three of those calls the length
argument is left as the placeholder TODO_REPLACE_THIS;
you must replace each one with the correct value. Think carefully
about what each call needs, since the right answer is not the
same in every case.
While testing, compile your program into an executable called
ex2:
$ gcc -Wall -g -std=c17 -o ex2 ex2.c
'sizeof' on array function parameter .... This warning is
expected for this assignment and is not counted against you.
Our autograder compiles with -Wno-sizeof-array-argument.
You must fix all other warnings.
Every call to DumpBytes prints exactly one line in this
format (your output must match exactly, including the capital
The, spacing, and lowercase hex):
The 4 bytes starting at 0x7fff1081856c are: ff 01 30 4e
data_len > 0, there must be no trailing
space. When data_len == 0, a trailing space is
fine.This exercise builds on the close relationship between arrays and pointers discussed in lecture:
ar[i] ↔
*(ar + i).CopyAndSort.A few specific things to keep in mind as you implement:
void* in DumpBytes
before you can read individual bytes through it.<inttypes.h>
(already included) to print a uint8_t and a pointer in
lowercase hex, e.g.:
uint8_t a_byte = 0xD1;
printf("The byte is: %02" PRIx8 " -- enjoy!\n", a_byte);
qsort); we
recommend insertion sort. Remember to handle the degenerate
zero-length array gracefully.Function names must match the spec exactly, including capitalization, since our autograder depends on it. Write a short comment above each function describing its behavior and purpose.
Use the correct format specifiers to avoid implicit casts and keep
your code portable. Avoid magic numbers: prefer predefined constants
(e.g., EXIT_SUCCESS), #defined names, and
sizeof over unnamed literals.
Run the linter and valgrind periodically and resolve all issues before submitting:
$ ./cpplint.py --clint ex2.c Done processing ex2.c $ valgrind ./ex2 ... ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Begin from the provided starter files (ex2.c and
questions.txt) in your
exercise repo.
Submit ex2/ex2.c and ex2/questions.txt by
creating an
ex2-submit
tag before the deadline.
$ gcc -Wall -g -std=c17 -o ex2 ex2.c
valgrind clean).ex2.c with
your name(s) and CSE/UW email(s).cpplint.py --clint runs clean.