Understanding Structured Programming and C Structures
Structured Programming Principles
1. State two reasons why structured programming insists on one entry point and one exit point to any construct in a program such as for-next, while, a function, etc… (Week 3 – Computations: Logic)
Answer:
- Aim for one entry point and one exit point. You do all initialization at one spot – the entry point, and all code cleanup at one spot – the exit point.
- Breaks and continues are discouraged in loops. Returns in the middle of a function are discouraged.
Functions and Variable Manipulation
2. What are two ways a function can change and return a variable?
Answer:
- The function can return a value which is assigned to a variable in the calling code.
- A function can take the address of a variable and change this variable within itself.
Pass by Value vs. Pass by Address
3. When passing parameters to functions, what is pass by value and pass by address? When would you use pass by value and when would you use pass by address? (Week 6 – Modularity: Pointers)
Answer:
- Use pass by value when you do not want to change the values of the variables in the calling function.
- Use pass by address when you do want to change the values of the variables in the calling functions.
Factorial Calculation Example
4. What is printed out in the following example if the user enters ‘3’?
What might the return value of factorial() represent?
#define_CRT_SECURE_NO_WARNINGS
#include
int factorial(int, double *);
main() {
int num;
double res;
printf("Enter a number : ");
scanf("%d", &num);
int retVal = factorial(num, &res);
if(retVal == 0) {
printf("The factorial of %d is %.2lf\n", num, res);
}
return 0;
}
int factorial(int number, double *result) {
*result = 1;
for (int i = 1; i <= number; ++i) {
*result = *result * (double)i;
}
return 0;
}
i | *result |
1 | 1*1 = 1 |
2 | 2*1 = 2 |
3 | 3*2 = 6 |
Answer: The program will print:”The factorial of 3 is 6.0″. The return value of factorial() (which is 0 in this case) could represent whether the calculation was successful or not.
Car Value Depreciation Example
What does the following program print out:
#define_CRT_SECURE_NO_WARNINGS
#define CURRENT_YEAR 2019
#define NUM 3
#include
struct Car {
char brand[31];
int year;
double purchasePrice;
double currentValue;
};
int GetValue(struct Car *);
int main() {
struct Car car[NUM] = {"Toyota Corolla", 2008, 21000.00, 21000.00,
"Mazda 3", 2013, 24000.00, 24000.00,
"Honda Accord", 2016, 30000.00, 30000.00 };
for (int i = 0; i < NUM; ++i) {
int err = GetValue(&car[i]);
if (err == 0) {
printf("The %d %s was bought for %.2lf but is now worth %.2lf\n",
car[i].year, car[i].brand,
car[i].purchasePrice, car[i].currentValue);
}
else {
printf("Your %d %s is worthless!\n", car[i].year, car[i].brand);
}
}
return 0;
}
int GetValue(struct Car *car) {
int retVal=0;
double depreciation = 3000.00 * (CURRENT_YEAR - car->year); //Loses $3000.00/year
car->currentValue = car->purchasePrice - depreciation;
if (car->currentValue <= 0) {
car->currentValue = 0;
retVal = -1;
}
return retVal;
}
Output:
Your 2008 Toyota Corolla is worthless!
The 2013 Mazda 3 was bought for 24000.00 but it is now worth 6000.00
The 2016 Honda Accord was bought for 30000.00 but is now worth 21000.00
Curve Marks Function
Write a function called CurveMarks that takes the array of students and multiplies each mark by CURVE_RATIO. If a mark is over 100, set the mark to 100.
int main(void) {
struct Student student[NUM] = { "Bill", 45, 57, 78, 62, 56, 10000,
"Tomasz", 66,67,78,44,59, 10001,
"Anusha", 72, 76, 74, 81, 69, 10002,
"Peng", 61, 62, 47, 56, 59, 10003,
"Erika", 77, 72, 42, 66, 79, 10004 };
CurveMarks(student);
for (int i = 0; i < NUM; ++i) {
printf("%s's marks are now", student[i].name);
for (int j = 0; j < NUM_MARKS; ++j) printf(" %d", student[i].marks[j]);
printf("\n");
}
return 0;
}
void CurveMarks(struct Student st[]) {
for (int i = 0; i < NUM; ++i) {
for (int j = 0; j < NUM_MARKS; ++j) {
int newMark = st[i].marks[j] * CURVE_RATIO;
if (newMark > 100) newMark = 100;
st[i].marks[j] = newMark;
}
}
}
Error Finding Exercise
5. There are five errors in the following code. Can you find them?
#define_CRT_SECURE_NO_WARNINGS
#include
int ReturnGrade(const double mark);
int main(void) {
double markInPercent;
do {
printf("Enter your mark in percent (enter -1 to quit): ");
scanf("%lf", markInPercent);
if (markInPercent >= '0') {
char grade[] = ReturnGrade(markInPercent);
switch (grade) {
case 'A':
printf("You got an A. You win a scholarship of $5000\n");
case 'B':
printf("You got a B. You win a scholarship of $1000\n");
case 'C':
case 'D'://fall-through
printf("You got a %c. You passed\n", grade);
break;
case 'F':
printf("You have failed.\n");
}
printf("\n");
}
} while (markInPercent >= 0);
}
char ReturnGrade(const double mark) {
char grade;
mark += 2; //One lab was not fair, add 2 percent to each mark
if (mark >= 80) grade = 'A';
elseif (mark >= 70) grade = 'B';
elseif (mark >= 60) grade = 'C';
elseif (mark >= 50) grade = 'D';
else grade = 'F';
return grade;
}
Corrected Code:
#define_CRT_SECURE_NO_WARNINGS
#include
//int ReturnGrade(const double mark);
char ReturnGrade(double mark); //Return char, Remove the const
int main(void) {
double markInPercent;
do {
printf("Enter your mark in percent (enter -1 to quit): ");
// scanf("%lf", markInPercent);
scanf("%lf", &markInPercent); //pass address of markInPercent
// if (markInPercent >= '0') {
if (markInPercent >= 0) { //Compare again a number and not a character
//char grade[] = ReturnGrade(markInPercent);
char grade = ReturnGrade(markInPercent); //ReturnGrade returns a char
// so get rid of the array
switch (grade) {
case 'A':
printf("You got an A. You win a scholarship of $5000\n");
break; //Add a break here
case 'B':
printf("You got a B. You win a scholarship of $1000\n");
break; //Add a break here
case 'C'://No break is required because a fallthrough is intended
case 'D'://fall-through
printf("You got a %c. You passed\n", grade);
break;
case 'F':
printf("You have failed.\n");
}
printf("\n");
}
} while (markInPercent >= 0);
}
//char ReturnGrade(const double mark) {
char ReturnGrade(double mark) { //Remove the const
char grade;
mark += 2; //One lab was not fair, add 2 percent to each mark
if (mark >= 80) grade = 'A';
else if (mark >= 70) grade = 'B'; //Corrected elseif to else if
else if (mark >= 60) grade = 'C'; //Corrected elseif to else if
else if (mark >= 50) grade = 'D'; //Corrected elseif to else if
else grade = 'F';
return grade;
}
Geological Data Program
Write a program that stores geological data for an earthquake. Create a structure called GeoData which stores the following elements:
- Name of the city [30 characters]
- Latitude of the city [double float]
- Longitude of the city [double float]
- Wave amplitude of the tremors [double float]
- Richter Scale of the earthquake [double float]
The main program will store geological data for three cities of type GeoData. The main program will prompt the user to enter the following for each of the three cities:
- The city name
- The latitude and longitude separated by a space on the same line
- The amplitude of the wave in millimeters
The main program will calculate the Richter scale for each entry by calling a function CalculateRichterScale which will return an integer and will accept a pointer to a GeoData structure.
The main function will determine which city has the greatest tremor. The main function will then print out which city has the greatest tremor, its latitude and longitude, the amplitude of the shock waves, and the Richter scale of the earthquake.
The function CalculateRichterScale returns an integer (0: no error, -1: error). It takes the wave amplitude of the tremor and calculates the Richter scale according to the following formula:
richterScale = sqrt(amplitude);
To use the sqrt() function, you will have to include the math library in math.h.
#define_CRT_SECURE_NO_WARNINGS
#define NUM 3
#include "math.h"
#include
struct GeoData {
char name[31];
double latitude;
double longitude;
double waveAmplitude;
double richterScale;
};
int CalculateRichterScale(struct GeoData *geo);
int main(void) {
struct GeoData city[NUM];
double largestAmplitude = 0;
int index = -1;
for (int i = 0; i < NUM; ++i) {
printf("Enter the city name: ");
scanf("%s", city[i].name);
printf("Enter the latitude and longitude separated by a space: ");
scanf("%lf %lf", &city[i].latitude, &city[i].longitude);
printf("Enter the wave Amplitude in millimeters: ");
scanf("%lf", &city[i].waveAmplitude);
int err = CalculateRichterScale(&city[i]);
if (err == 0 && city[i].waveAmplitude > largestAmplitude) {
largestAmplitude = city[i].waveAmplitude;
index = i;
}
}
printf("The city with the largest tremor is %s at latitude %.2lf and longitude %.2lf\n",
city[index].name, city[index].latitude, city[index].longitude);
printf("The tremor measured %.2lfmm which is %.2lf on the Richter scale\n",
city[index].waveAmplitude, city[index].richterScale);
}
int CalculateRichterScale(struct GeoData *geo) {
int retVal = 0;
if (geo->waveAmplitude < 0) {
geo->richterScale = 0;
retVal = -1;
}
else {
geo->richterScale = sqrt(geo->waveAmplitude);
}
return retVal;
}
