C exercises: pointers, character arrays, I/O, and functions
These exercises are from exercise 10.3 on p. 424 and exercise 8.1 on p.
354, with minor modifications, of C How to Program (2nd ed.) by Dietel,
H.M. & Dietel, P.J. (1988). Englewood Cliffs, NJ: Prentice Hall.
- Write a single statement or set of statements
to accomplish each of the following:
- Define a
part containing an
partName whose values
may be as long as 25 characters.
Part to be a synonym for the type
Part to declare variable
a to be of type
b to be of type
struct part, and variable
ptr to be of type pointer to
- Read a part number and a part name from the keyboard into the
individual members of variable
- Assign the member values of variable
to element 3 of array
- Assign the address of array
b to the pointer variable
- Print the members values of element 3 of array
b to the
display using the variable
and the structure pointer operator to refer to the members.
Assume the following variables have been declared as shown.
double number1 = 7.3, number2;
char s1, s2;
- Declare the variable
dPtr to be a pointer to a variable
- Assign the address of variable
number1 to pointer variable
- Print the value of the variable pointed to by
dPtr to the
- Assign the value of the variable pointed to by
- Print the value of
number2 to the display.
- Print the address of
number1 to the display.
- Print the address stored in
dPtr to the display.
- Is the value printed the equal to the address of
- Copy the string stored in character array
s1 into character array
- Compare the string stored in character array
the string in character array
s2, and print the result to the display.
- Append the string in character array
to the string in character array
Will this cause a run-time error?
- Determine the length of the string stored in character array
and print the result to the display.
These exercises are intended to test your use of structs, pointers, dynamic memory allocation and deallocation, functions and function pointers (as well as basic program I/O) to implement, use, and test basic data structures.
Implement and demonstrate memory-safe use of a singly linked list as follows:
Write code to demonstrate various techniques for function invocation and use, as follows:
- Declare a struct that has two elements: an integer and a pointer to the same struct type.
malloc to dynamically allocate four instances of that struct type and update their pointers to form a chain where each instance except for the last one points to the next one, and the last one points to nothing.
- Fill in the integer fields of those instances with four different values and then print out the instances integer values in order, from the beginning to the end of the list.
- Remove the second instance from the list, keeping the list intact (with the first element in the list now pointing to what used to be the third element in the list) and using
free to dynamically deallocate the memory for the instance that you removed from the list, and then again print out the instances integer values in order, from the beginning to the end of the list, to confirm that the correct element was removed from the list.
- Declare and define a function that takes an unsigned integer as its only input and returns a pointer to a dynamically allocated linked list (using the techniques from the exercises above) of all of the prime factors of that unsigned integer (for example: if the function was given 15 then the list should have two elements, a five and a three; if the function was given 12 then the list should have three elements, two twos and a three; if the function was given 0 or 1 then the list should be empty).
- Declare and define a function that takes a pointer to a dynamically allocated linked list (of the same type that the function from the previous exercise produces), prints out the integers in that list to the standard output stream, and then iterates through the list using
free to dynamically deallocate the memory for each instance in the list.
- Write a program that takes a single command line argument, converts it into its equivalent unsigned integer representation (for example the string "11" should become the unsigned integer 11, the string "0" should become the unsigned integer 0, etc.), passes it into a call to the first function you implemented above, and then passes the pointer that was returned by that function into a call to the second function you implemented above - compile and run your program with different input values to confirm it can handle various cases correctly without crashing (e.g., due to problems with pointer initialization, memory management, etc.) and that it returns the correct values in each case.
- Declare function pointers of the appropriate types for each of the two functions your program uses, and reimplement your program using those pointers to invoke the functions instead of calling them directly - again compile and test your program to make sure it performs correctly (and produces the same outputs) as the original program did for each of your test cases.