Procedural/Structured Programming

Learn about procedural programming and its implementation.

Introduction

In this lesson, we’ll explore the principles and techniques of procedural programming by utilizing functions as our primary tool. This programming paradigm is based on dividing complex problems into smaller, more manageable tasks and solving each task step-by-step. Procedural programming enables us to write concise, easy-to-understand, and reusable code.

Let’s explore the core principles of procedural programming:

  1. Defining memory requirements: In procedural programming, we define the memory requirements by declaring variables that store data. Each variable has a specific data type and occupies a certain amount of memory. By understanding our program’s data needs, we can efficiently allocate memory to store and manipulate data.

  2. Defining the flow of the program into concrete steps: Procedural programming involves defining a sequence of concrete steps or operations that guide the flow of our program’s execution. These steps are executed in the order they are defined, ensuring the desired outcome. By structuring the program flow, we can control the execution path and ensure tasks are performed in the intended order.

  3. Using functions for subdividing and reusability: Functions are a fundamental part of procedural programming. They enable code subdivision, allowing us to break down our program into smaller, reusable units. By defining functions, we can encapsulate specific tasks, enhance code organization, and promote reusability. Functions also provide a centralized location for managing code related to a particular task, improving code maintainability. The most important advantage of forming functions is that they are compact and bounded in scope.

The languages BASIC, Fortran, and COBOL used to be procedural languages. These languages used mainly goto statement for the flow of the program.

Structured programming is a programming paradigm that emphasizes the use of structured control flow constructs such as loops (for and while), conditionals (if else), and functions (procedures and methods). The main goal of structured programming is to promote clear and understandable code by avoiding unstructured control flow, such as the infamous goto statement. This paradigm encourages breaking down complex problems into smaller, manageable pieces using functions or procedures. The prime example of a structured programming language is C.

Note: Procedural programming is a subset of structured programming that emphasizes the organization of code into procedures or functions. Structured programming encompasses all the elements of procedural programming, with the distinction that it advocates against the use of the goto statement.

Example: Data analysis

We’re given an array of integers, and our task is to perform various analyses of the data. We need to find the largest and smallest values in the array and calculate the average, the median, the mode, and the variance.

Our goal is to develop a program in C++ that can handle these analyses efficiently. The program should follow the principles of procedural and structured programming, including defining memory requirements, defining the flow of the program into concrete steps, and utilizing functions for code subdivision and reusability.

Our program should read the size of the data followed by the data; then, it should perform the required analyses by calling the appropriate functions and displaying the results to the user.

By developing this program using procedural programming techniques, we’ll create a modular, reusable, and organized solution for analyzing arrays of data.

Implementation

Let’s solve the above problem by following the three-step approach.

Step 1: Defining the memory requirements

  • Define the array to store the integers.

  • Determine the length of the array.

  • Declare variables for storing the largest, smallest, average, median, mode, and variance values.

const int CAPACITY = 100;
int numbers[CAPACITY];
int length ; // will be decided later after loading the data
// Find the largest, smallest, average, median, mode, and variance values
int largest, smallest, average, median, mode, variance ;

Step 2: Defining the flow of the program into concrete steps

  • Read/initialize the data from the user/file, store it in the array, and set the size of the array.

  • Call the appropriate functions to find the largest number, smallest number, average, median, mode, and variance values by passing the array and its length as arguments.

  • Store the returned values in their respective variables.

  • Display the variables.

initialize(numbers, length); // length should be passed by reference
largest = findLargest(numbers, length);
smallest = findSmallest(numbers, length);
average = calculateAverage(numbers, length);
median = findMedian(numbers, length);
mode = findMode(numbers, length);
variance = calculateVariance(numbers, length);
// Displaying the data measures, along with data
displayDataAndMeasures(numbers, length, largest, smallest, average, median, mode, variance);

Step 3: Using functions for subdividing and reusability

  • Implement the functions for finding the largest number, smallest number, average, median, mode, and variance based on the given problem requirements.

  • Each function should perform a specific task, such as finding the largest number or calculating the average, making the code more modular and reusable.

  • Ensure that the functions take the array and its length as parameters to operate on the given data.

Let’s write the complete code and see how every module is written to complete the flow defined in Step 2.

Press + to interact
main.cpp
numbers.txt
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
using namespace std;
void initialize(int numbers[], int &length)
{
ifstream rdr("numbers.txt");
rdr>>length;
for(int i=0; i<length; i++)
rdr>>numbers[i];
}
// Function to find the largest element in the array
int findLargest(int numbers[], int length)
{
int largest = numbers[0];
for (int i = 1; i < length; i++)
{
if (numbers[i] > largest)
{
largest = numbers[i];
}
}
return largest;
}
// Function to find the smallest element in the array
int findSmallest(int numbers[], int length) {
int smallest = numbers[0];
for (int i = 1; i < length; i++) {
if (numbers[i] < smallest) {
smallest = numbers[i];
}
}
return smallest;
}
// Function to calculate the average of the array elements
float calculateAverage(int numbers[], int length)
{
int sum = 0;
for (int i = 0; i < length; i++)
{
sum += numbers[i];
}
return static_cast<float>(sum) / length;
}
// Function to find the median of the array
float findMedian(int numbers[], int length)
{
sort(numbers, numbers + length);
if (length % 2 == 0)
return static_cast<float>(numbers[length / 2 - 1] + numbers[length / 2]) / 2.0;
else
return static_cast<float>(numbers[length / 2]);
}
// Function to find the mode of the array
int findMode(int numbers[], int length)
{
int mode = numbers[0];
int maxCount = 0;
for (int i = 0; i < length; i++)
{
int count = 0;
for (int j = 0; j < length; j++)
{
if (numbers[j] == numbers[i])
{
count++;
}
}
if (count > maxCount)
{
maxCount = count;
mode = numbers[i];
}
}
return mode;
}
// Function to calculate the variance of the array data
float calculateVariance(int numbers[], int length)
{
float mean = calculateAverage(numbers, length);
float variance = 0.0;
for (int i = 0; i < length; i++)
{
variance += pow(numbers[i] - mean, 2);
}
return variance / length;
}
void displayDataAndMeasures(int numbers[], int length, int largest, int smallest,
float average,float median, float mode, float variance)
{
cout << "Data["<<length<<"] = { ";
for(int i=0; i<length; i++)
cout << numbers[i] << " ";
cout << "}" << endl;;
cout << "The largest number is: " << largest << endl;
cout << "The smallest number is: " << smallest << endl;
cout << "The average is: " << average << endl;
cout << "The median is: " << median << endl;
cout << "The mode is: " << mode << endl;
}
int main()
{
// Define the array and its length
const int CAPACITY = 100;
int numbers[CAPACITY];
int length;
// Find the largest, smallest, average, median, mode, and variance
int largest, smallest, mode;
float average, median, variance ;
initialize(numbers, length); // length should be passed by reference
largest = findLargest(numbers, length);
smallest = findSmallest(numbers, length);
average = calculateAverage(numbers, length);
median = findMedian(numbers, length);
mode = findMode(numbers, length);
variance = calculateVariance(numbers, length);
// Displaying the data measures, along with data
displayDataAndMeasures(numbers, length, largest, smallest, average, median, mode, variance);
// Display the results
return 0;
}

The provided code aims to analyze a set of numbers stored in an array by calculating various measures, such as the largest number, smallest number, average, median, mode, and variance. Let’s break it down into key components:

  • Memory requirements:

    • The initialize() function reads the numbers from a file and initializes the numbers array and its length.

    • This ensures that the memory requirements for storing the array and its length are defined.

  • The flow of the program:

    • The main() function serves as the entry point.

    • It declares the numbers array, length, and variables to be measured, such as the largest number, smallest number, mode, average, median, and variance.

    • It calls the initialize() function to read the numbers from the file and populate the array.

    • It then calls specific functions to calculate the analytic measures:

      • findLargest() and findSmallest() find the largest and smallest numbers in the array, respectively.

      • calculateAverage() calculates the average of the numbers.

      • findMedian() determines the median value using the sort() function from the <algorithm> library.

      • findMode() finds the mode (the number that occurs most frequently in the array).

      • calculateVariance() calculates the variance by utilizing the calculateAverage() function.

    • The displayDataAndMeasures() function is called to display the array data and the calculated measures.

  • The divide and conquer rule and code reusability:

    • The divide and conquer rule is demonstrated through the use of functions, where each function is defined separately (dividing the program into smaller problems and solving each of them exclusively).

    • Each function focuses on a specific task and can be reused in different parts of the code or in other programs:

      • For example, calculateVariance() leverages the calculateAverage() function to calculate the mean value, avoiding code duplication.

      • The findMedian() function uses the sort() function from the <algorithm> library, demonstrating the reusability of the existing code.

    • Functions promote modularity and maintainability by dividing the code into manageable units, making it easier to understand, test, and modify.

By applying procedural and structured programming principles and utilizing reusable functions, the code becomes more organized, modular, and maintainable. It efficiently analyzes the array of numbers, calculating various measures and displaying the results to the user.