Exercise Solutions
Concepts Questions
1. Pointer Declaration and Interpretation
int* ptrA;- ptrA is a pointer to an integer; it can hold the address of an int variablechar* ptrB;- ptrB is a pointer to a character; it can hold the address of a char variablestruct Student* ptrC;- ptrC is a pointer to a Student struct; it can hold the address of a Student struct variable
2. Address-of Operator
&age represents the memory address of the variable age. The address-of operator is needed because a pointer variable must be initialized with an address, not a regular value. &age retrieves the address so it can be stored in the pointer variable ptrAge.
3. Pass by Value vs. Pass by Address
- Pass by Value: A copy of the value is made and passed to the function. Changes to the parameter do not affect the original variable.
- Pass by Address: The address of the variable is passed. The function can access and modify the original variable.
- For Structs: Pass by address is preferred because structs can be large and contain many data members. Copying the entire struct (pass by value) is inefficient. Passing only the address (pass by address) is much more efficient and still allows the function to access all struct data members.
4. Arrow Operator
struct Book
{
char title[100];
char author[50];
int pages;
float rating;
};
...
struct Book mybook = {"Guards! Guards!","Terry Pratchett", 432, 4.7}; //a)
void printBook(struct Book* book){
printf("%s - %s - %d: %.1f\n", book->author, book->title, book->pages, book->rating);
}
5. Dereference Operator
The dereference operator (*) accesses the value stored at the address a pointer holds. It "follows" the pointer to get the actual value.
Example:
int x = 10;
int* ptr = &x;
*ptr = 20; // Changes x to 20 through the pointer
printf("%d\n", *ptr); // Prints 20
printf("%d\n", x); // Prints 20
6. Multiple Return Values
Functions in C have only one return value. When a function needs to produce multiple results, pointers can be used as parameters to allow the function to modify multiple variables in the calling function. For example, a function that converts seconds into minutes and seconds needs to find two values; pointers allow this.
7. const with Pointers
const struct Student* student means the function receives a pointer to a Student struct, but the function cannot modify the struct's data members. The const modifier signals that the function will only read the struct data, not change it. This protects the original struct from accidental modification and makes the function's intentions clear
Walkthrough
Exact Output:
Initial: daisy=15, rose=0
Final: daisy=30, rose=3
Debugging
1. Logical Error:
The swap function uses pass by value. The parameters a and b are copies of x and y. Swapping a and b does not affect the original variables x and y in main().
2. Why It Doesn't Work:
When swap(x, y) is called, copies of x and y are made and assigned to parameters a and b. The function swaps these copies, but the original variables in main() remain unchanged.
3. Corrected Program:
#include <stdio.h>
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main(void)
{
int x = 10;
int y = 20;
printf("Before swap: x = %d, y = %d\n", x, y);
swap(&x, &y);
printf("After swap: x = %d, y = %d\n", x, y);
return 0;
}
The key changes:
- Parameters are now pointers:
int* aandint* b - Function call passes addresses:
swap(&x, &y) - Dereference operators access the original variables:
*aand*b
Programming
Problem 1: Working with Structs
struct Rectangle
{
float width;
float height;
};
float area(const struct Rectangle* rect)
{
return rect->width * rect->height;
}
void scale(struct Rectangle* rect, float widthScale,
float heightScale)
{
rect->width = rect->width * widthScale;
rect->height = rect->height * heightScale;
}
Problem 2: Height Converter
void convertHeight(float height, int* foot, int* inches)
{
int totalInches = height / 2.54; // this will round down the calculating by truncating
//decimals
*foot = totalInches / 12;
*inches = totalInches%12;
}