0% found this document useful (0 votes)
2 views93 pages

Chapter5 - Program Design and Efficiency - Tobeupdated

Uploaded by

chimcucto51
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views93 pages

Chapter5 - Program Design and Efficiency - Tobeupdated

Uploaded by

chimcucto51
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 93

EE3491 - Kỹ thuật lập trình

EE3490E – Programming Techniques


Chapter 5: Program Design &
Efficiency
Lecturer: Dr. Hoang Duc Chinh (Hoàng Đức Chính)
Department of Automation Engineering
School of Electrical and Electronic Engineering
Email: [email protected]

© HĐC 2024.1
Program design and efficiency
“Designing object-oriented software is hard, and designing
reusable object-oriented software is even harder...It takes a
long time for novices to learn what object-oriented design is
all about. Experienced designers evidently know something
inexperienced ones don't...
One thing expert designers know not to do is solve every
problem from first principles. Rather, they reuse solutions
that have worked for them in the past. When they find a
good solution, they use it again and again. Such experience
is part of what makes them experts. Consequently, you'll
find recurring patterns of classes and communicating
objects in many object-oriented systems. These patterns
solve specific design problems and make object-oriented
design more flexible, elegant, and ultimately reusable...”
Erich Gamma et. al.: Design Patterns: Elements of Reusable
Object-Oriented Software, Addison-Wesley, 1995.

© HDC 2024.1 Chapter 5: Program design & efficiency 2


Content

5.1. Program design process revision


5.2. Code optimization
5.3. Good habits in programming
5.4. Event-driven programming

© HDC 2024.1 Chapter 5: Program design & efficiency 3


5.1. Program design process

Analysis  Design  Programming


Analyse the problem
Propose a big-picture/generic solution
 Functions are divided together with a diagram illustrating
function call diagram
Design each specific function
 These functions depends only existing low level (basic)
functions if applicable
Finally, it’s the coding task

© HDC 2024.1 Chapter 5: Program design & efficiency 4


Design steps

Requirements and technical specifications


Data flow of the program
Data structure
Top-down or bottom-up approaches
Write the source code
Debug and test

 Design is not a sequential process but performed with


complete steps one by one

© HDC 2024.1 Chapter 5: Program design & efficiency 5


Requirements and technical specifications

Requirements:
 what are the main objectives of the program
 requirements must be clear but do not need to be detailed
Technical specifications: describe specifications of the
program in details
 E.g.: format, response of the program, memory constraint
Technical specifications can be extended subsequently as
the program is developed

© HDC 2024.1 Chapter 5: Program design & efficiency 6


Define function features

Find common aspects


Parameterize distinguish features
Specify which functions are called by the one being
designed
 Draw a diagram to illustrate the relationship between the
functions

© HDC 2024.1 Chapter 5: Program design & efficiency 7


Data flow

Draw a diagram of the main features


 Sequence of the functions, loops, …
Two main diagrams: design and state-transition diagrams
Goals: clear vision of
 Main components and operations of the software
 How the transition among these components happens
 Relationship amongst program components

© HDC 2024.1 Chapter 5: Program design & efficiency 8


Example: flowchart diagram

START

statements
statements

conditional
FALSE

TRUE

statements

END

© HDC 2024.1 Chapter 5: Program design & efficiency 9


Data structure

Decide which type of data structure to be used mainly in


the program and exchanged amongst program
components
The data structure would be identified in the design
diagram of the software

© HDC 2024.1 Chapter 5: Program design & efficiency 10


Format design

Two approaches (revised): top-down and bottom-up


Propose a set of function but not the detailed
implementation
Describe the program in written language or pseudo-
code
loop number of times
prompt user and get integer value
calculate factorial
print factorial
Then replace each component by the respective C
function

© HDC 2024.1 Chapter 5: Program design & efficiency 11


Example: Game of Tic-Tac-Toe

Requirements:
 Enable user to play tic-tac-toe game with computer (placing X
and O)
 Allow user to choose if they want to play first or computer
starts first
 Ask if user wants to play again once the game finishes

© HDC 2024.1 Chapter 5: Program design & efficiency 12


Description

Welcome message:
Welcome to TIC-TAC-TOE.
-----------------------

The object of this game is to get a line of X's


before the computer gets a line of O's. A line may
be across, down, or diagonal.

Play area is illustrated with 1 – 9 as the followings:

1|2|3
-----
4|5|6
-----
7|8|9

© HDC 2024.1 Chapter 5: Program design & efficiency 13


Description

The user plays first:


Do you wish to go first (1-Yes, 0-No) ?
The user select position by choosing the number:
Your turn (1 - 9):
Display the game layout after each step
X| |
-----
X|O|
-----
|X|O

© HDC 2024.1 Chapter 5: Program design & efficiency 14


Description

Print out the final result:


You win. Congratulations!!
You lose. Better luck next time.
Its a draw. How dull.

Ask if the user want to continue?


Do you wish to play again (1-Yes, 0-No) ?

© HDC 2024.1 Chapter 5: Program design & efficiency 15


5.2 Code optimization

Efficient Programs
Selecting the algorithm
 Developer should use the best applicable algorithm
 Then considering the efficiency of the code
 E.g.: Calculating the summation of n continuous integer
starting at m
void main() { void main()
long n,m,i , sum ; {
cout << ‘ Enter n ‘ ; cin << n; long n,m , sum ;
cout << ‘ Enter m ‘ ; cin << m; cout << ‘ Enter n ‘ ; cin << n;
sum =0; cout << ‘ Enter m ‘ ; cin << m;
for(i = m ; i < = m+n; i++) sum =(m + m+ n) * n / 2;
sum += i; cout << ‘ Sum = ‘ <<sum;
cout << ‘ Sum = ‘ <<sum; }
}

© HDC 2024.1 Chapter 5: Program design & efficiency 16


Utilizing the compiler flags

Some compilers play a very important role in optimizing


the program
 They analyse the source code deeply and perform all the
possible tasks “machinely”
 E.g.: GNU g++ compiler in Linux/Cygwin used for a C
program
g++ –O5 –o myprog myprog.c
The above compiler command can improve the efficiency by
10% to 300%

© HDC 2024.1 Chapter 5: Program design & efficiency 17


But …

There may be still room improvement which cannot be


done by the compiler
Inappropriate parts of the code should be removed
Increase the efficiency as high as possible
Need to relook at the program when it runs slowly
How to achieve fast and best enhancement?

© HDC 2024.1 Chapter 5: Program design & efficiency 18


Writing Efficient Code

Identify the cause of inefficiency


Redundant computation, especially
 In procedures
 Loops

© HDC 2024.1 Chapter 5: Program design & efficiency 19


Initialize once, use multiple times

Before
float f()
{ double value = sin(0.25);
//
…..
}

After
double defaultValue = sin(0.25);

float f()
{ double value =
defaultValue;
//
…..
}

© HDC 2024.1 Chapter 5: Program design & efficiency 20


Remove ordinary expressions

Do not perform an expression multiple times!


Some compilers can recognize and process

for (i = 1; i<=10;i++)
x += strlen(str);
Y = 15 + strlen(str);

len = strlen(str);
for (i = 1;i<=10;i++)
x += len;
Y = 15 + len;

© HDC 2024.1 Chapter 5: Program design & efficiency 21


Move constant expressions out of the loops

Do not repeat unnecessary expressions


Some Compilers can process automatically!

for (i =0; i<100;i++)


plot(i, i*sin(d));

M = sin(d);
for (i =0; i<100;i++)
plot(i, i*M);

© HDC 2024.1 Chapter 5: Program design & efficiency 22


Reduce computation time

In Neural Network simulation, a function named


sigmoid is often used
If x is a large positive number 1
sigmoid ( x) 
sigmoid(x)  1 1  e kx
If x is a large negative number
sigmoid (x)  0

© HDC 2024.1 Chapter 5: Program design & efficiency 23


sigmoid function

float sigmoid (float x )


{
return 1.0 / (1.0 + exp(-x))
};

© HDC 2024.1 Chapter 5: Program design & efficiency 24


sigmoid function

 Calculation of exp(-x) is very time-consuming!


 It is usually computed approximately by using series expansion
 Taylor/Maclaurin formula
 Calculate the sum of ((-x)n / n!)
 Each of this expression requires to work with floating point numbers
 In many cases, neural network simulation call the function
hundred millions times for each run
 Thus, the time taken to compute sigmoid(x) is very large (70-
80% of total running duration)

© HDC 2024.1 Chapter 5: Program design & efficiency 25


sigmoid function – a solution

Instead of calling the function all the time


 Calculating with N points and save to an array x0 sigmoid(x0)
 In each call of sigmoid: x1 sigmoid(x1)
o Find the nearest value of x and its respected result x2 sigmoid(x2)
o Perform linear interpolation to find the final result
x3 sigmoid(x3)
x4 sigmoid(x4)
x5 sigmoid(x5)
x6 sigmoid(x6)
.
.
.

x99 sigmoid(x99)

© HDC 2024.1 Chapter 5: Program design & efficiency 26


sigmoid function – a solution

Choose the number of points (N = 1000, 10000, etc.)


depending on the desired accuracy
Memory resource required for each point is 2 float or
double, i.e. 8 – 16 bytes/point
Initialize values for the array at the beginning of the
procedure

© HDC 2024.1 Chapter 5: Program design & efficiency 27


sigmoid function – a solution

X0 is known
 Compute Delta = X1-X0
 Comput Xmax = X0 + N * Delta;
With a given X
 Compute i = (X – X0)/Delta;
o Which needs a substation of two real numbers and a division of real
numbers
 Compute sigmoid(x)
o Which needs a multiplication of floats and a addition of floats

© HDC 2024.1 Chapter 5: Program design & efficiency 28


Result

If using exp(x) :


 Each call takes 300 nanoseconds on a computer equipped with
a Pentium 4, 2 Ghz CPU.
If using array searching and linear interpolation:
 Each call takes 30 nanoseconds
The speed increase 10 times
 The tradeoff is the increment of required memory space from
64KBytes to 640 KBytes

© HDC 2024.1 Chapter 5: Program design & efficiency 29


Stack, heap revisions

 Data segment of a program contains 3 parts:


 static, stack, and heap data.
 Static: global or static variables
 Faster to access
 Stack data:
 Local variables of a function, e.g. double_array in the previous example
 Faster access compared to Heap
 Heap data:
 Memory of the data is allocated dynamically, e.g. pchar in the previous
example
 The data is presented until it is freed or the program ends

 Developers need to decide the most appropriate type of variables


to achieve high efficiency
© HDC 2024.1 Chapter 5: Program design & efficiency 30
Static variables revision

 Type of data refers to global or 'static' variables, memory is


allocated during compile-time
int int_array[100];
int main() {
static float float_array[100];
double double_array[100];
char *pchar;
pchar = (char *)malloc(100);
/* .... */
return (0);
}

© HDC 2024.1 Chapter 5: Program design & efficiency 31


Static variables revision
 Variables declared in functions are allocated memory when the functions are
called, they will be deleted (memory is freed) when the functions complete
 They are reallocated memory and re-initialized when the functions are called
again
 If it is required to reserve a value until the program finishes, the local variable
should be declared as static one and initialized with a value
 The initialization is done once when the function is called and the value changed is stored for
subsequent calls
 Using this method, the function can “memorize” a few pieces of information after each call
 Using Static variable instead of Global one:
 The advantage of a static variable is that it is the local one in a function,
thus side effects can be avoided

© HDC 2024.1 Chapter 5: Program design & efficiency 32


Macros revisions
#define max(a,b) (a>b?a:b)
Inline are the same as macros as they are performed at
compile-time
 Macros are carried out by preprocessors, and inline functions
are inserted by compiler
However, there are some differences:
 Inline functions follows the procedures as a normal function
 Inline functions use the same syntax as a normal function,
except the keyword inline in the declaration
 Operations passed as arguments in inline functions are used
once. In some cases, operations passed as arguments in macros
can be used more than once.
 It is impossible to debug macros, but it can be done for inline
functions

© HDC 2024.1 Chapter 5: Program design & efficiency 33


Basis rules

Code Simplification
 Most of the programs which can run fast are simple. Thus,
developer should simplify the source code to make it run fast.
Problem Simplification
 To improve the program efficiency, the developer should
simplify the problem to solve
Relentless Suspicion
 One should question the necessary of each code block and each
field/property in data structure
Early Binding
 Carry out the task immediately to avoid redoing multiple times
later

© HDC 2024.1 Chapter 5: Program design & efficiency 34


Loop Rules

Hot spots in most of the programs are caused by loops


Move the code out of the loop
 Instead of performing computation in each iteration of the loop,
it should happen once outside the loop if applicable
Loop fusion:
 If two loops perform a similar task on the same set of elements,
they should be integrated into one loop

© HDC 2024.1 Chapter 5: Program design & efficiency 35


Optimize the following code

found = FALSE;
for(i=0;i<10000;i++) {
if( list[i] == -99 ) {
found = TRUE;
}
}
if( found ) printf("Yes, there is a -
99. !\n");

© HDC 2024.1 Chapter 5: Program design & efficiency 36


5.3. Good habits in programming

“It is not enough for code to


work.”
… Robert C. Martin, Clean Code: A Handbook of Agile
Software Craftsmanship

© HDC 2024.1 Chapter 5: Program design & efficiency 37


5.3.1 Good programming style

1. Write clearly / don't be too clever


2. Say what you mean, simply and directly
3. Use library functions whenever feasible
4. Avoid too many temporary variables
5. Write clearly / don't sacrifice clarity for efficiency

© HDC 2024.1 Chapter 5: Program design & efficiency 38


Good programming style

6. Let the machine do the dirty work


7. Replace repetitive expressions by calls to common
functions
8. Parenthesize to avoid ambiguity
9. Choose variable names that won't be confused
10. Avoid unnecessary branches
11. If a logical expression is hard to understand, try
transforming it
12. Choose a data representation that makes the
program simple

© HDC 2024.1 Chapter 5: Program design & efficiency 39


Good programming style

13. Write first in easy-to-understand pseudo


language; then translate into whatever language
you have to use
14. Modularize. Use procedures and functions
15. Avoid gotos completely if you can keep the
program readable
16. Don't patch bad code / rewrite it
17. Write and test a big program in small pieces

© HDC 2024.1 Chapter 5: Program design & efficiency 40


Good programming style

18. Use recursive procedures for recursively-defined


data structures
19. Test input for plausibility and validity
20. Make sure input doesn't violate the limits of the
program
21. Terminate input by end-of-file marker, not by
count
22. Identify bad input; recover if possible
23. Make input easy to prepare and output self-
explanatory

© HDC 2024.1 Chapter 5: Program design & efficiency 41


Good programming style

24. Use uniform input formats


25. Make sure all variable are initialized before use
26. Test programs at their boundary values
26. Check some answers by hand
27. 10.0 times 0.1 is hardly ever 1.0
28. 7/8 is zero while 7.0/8.0 is not zero
29. Make it right before you make it faster

© HDC 2024.1 Chapter 5: Program design & efficiency 42


Good programming style

30. Make it clear before you make it faster


31. Let your compiler do the simple optimizations
32. Don't strain to re-use code; reorganize instead
33. Make sure special cases are truly special
34. Keep it simple to make it faster
35. Make sure comments and code agree
36. Don't comment bad code | rewrite it
37. Use variable names that mean something
38. Format a program to help the reader understand
it
39. Don't over-comment

© HDC 2024.1 Chapter 5: Program design & efficiency 43


5.3.2 Program Style

Why is the program style important?


 Errors are usually due to developers’ mistakes
o What is the use of a variable?
o How is a function called?
 Good code = code which is easy to read
How to make the code easy to read?
 Program structure must be neat and easy to understand
 Use popular terms
 Select suitable and self-described names
 Write clear and comprehensive comments
 Use module

© HDC 2024.1 Chapter 5: Program design & efficiency 44


Structure: “Paragraphs”

Use blank line to differentiate blocks/paragraphs


#include <stdio.h>
#include <stdlib.h>

int main(void)

/* Read a circle's radius from stdin, and compute and write its
diameter and circumference to stdout. Return 0 if successful. */

{
const double PI = 3.14159;
int radius;
int diam;
double circum;

printf("Enter the circle's radius:\n");


if (scanf("%d", &radius) != 1)
{
fprintf(stderr, "Error: Not a number\n");
exit(EXIT_FAILURE); /* or: return EXIT_FAILURE; */
}

© HDC 2024.1 Chapter 5: Program design & efficiency 45


Structure: Expressions

Write expression in original format


E.g.: Verify if n satisfies that j < n < k
 Bad code
if (!(n >= k) && !(n <= j))
 Good code
if ((j < n) && (n < k))
Conditional expressions should be written in such a way
that you can read normally
Do not write the conditional expressions in a form that you
never use

© HDC 2024.1 Chapter 5: Program design & efficiency 46


Structure: Expressions (cont.)

Use () to avoid confusion


E.g.: Verify if n satisfies that j < n < k
 Moderately bad code
if (j < n && n < k)
 Moderately better code
if ((j < n) && (n < k))
Groups should be classified clearly
 Relation operators (e.g.: “>”) has the higher priority than logic
operators (e.g.: “&&”), but who can remember that?

© HDC 2024.1 Chapter 5: Program design & efficiency 47


Structure: Expressions (cont.)

Use () to avoid confusion


E.g.: reand and print the characters till the end of file
 Wrong code (what is going on???)
while (c = getchar() != EOF)
putchar(c);
 Right code
while ((c = getchar()) != EOF)
putchar(c);

Groups should be classified clearly:explicit


 Logic operator (“!=”) has the higher priority than assignment
operator (“=”)

© HDC 2024.1 Chapter 5: Program design & efficiency 48


Structure: Expressions (cont.)

Simplify complicated expressions


E.g.: Identify the characters with respect to the months in
a year
 Bad code
if ((c == 'J') || (c == 'F') || (c ==
'M') || (c == 'A') || (c == 'S') || (c
== 'O') || (c == 'N') || (c == 'D'))
 Good code
if ((c == 'J') || (c == 'F') ||
(c == 'M') || (c == 'A') ||
(c == 'S') || (c == 'O') ||
(c == 'N') || (c == 'D'))

Should organize parallel expressions!

© HDC 2024.1 Chapter 5: Program design & efficiency 49


Spaces

Should use blank line to separate the main code block


Align vertically
x = 5;
y_prime = 7;
z_axis = 4.3;
Leave spaces around the operators
No: y=slope*x+intercept;
Yes: y = slope * x + intercept;
Use () to emphasize
Yes: y = (slope * x) + intercept;
Justify minor parts of the code

© HDC 2024.1 Chapter 5: Program design & efficiency 50


Naming (revised)

Name
 Letters, digits and underscore (_)
 Cannot start with a digit
 Cannot be C/C++ keywords such as double, return
Differentiate UPPERCASE and lowercase text
 VAR, Var, var, vAr are treated differently
It is valid to use all uppercase letters
 However, all uppercase text are used in #define statement (will
be discussed) conventionally

© HDC 2024.1 Chapter 5: Program design & efficiency 51


Naming (revised)

Precious material
Microsoft Excel has more than 65.000 variables
How long should the name be?
m
mph
miles_per_hour
average_miles_per_hour_that_the_car_went

Avoid similar names, e.g.: mph vs. Mph vs. mqh

© HDC 2024.1 Chapter 5: Program design & efficiency 52


Naming (revised)

OK Invalid Valid, but …


rectangleWidth 10TimesLength a1
rectangle_Width My Variable l
rectangle_width int O
length_10_Rectangle rectangleWidth and
rectanglewidth or
rectangle_Width

© HDC 2024.1 Chapter 5: Program design & efficiency 53


Purity

Use familiar methods for familiar problems


No: x = (y = x) + 1;

Yes: y = x;
x = x + 1;

It is note required to be concise or complicated without


proper reasons. If it is, specific explanation should be
provided

© HDC 2024.1 Chapter 5: Program design & efficiency 54


#define
NO = sign NO ;
Naming the constant:
#define PI 3.14159265
#define AVOGADRO 6.02e23
#define LINE_WIDTH 80
#define FIELD_WIDTH 10
#define FIELDS_PER_LINE (LINE_WIDTH / FIELD_WIDTH)
...
area = PI * radius * radius;
lines = fields / FIELDS_PER_LINE;

Attention!
yes UPPER CASE
yes ( )

© HDC 2024.1 Chapter 5: Program design & efficiency 55


Why to use #define?

Convenient to modify and maintain


No strange numbers (without explanation)
 Use names with emotion
Avoid typos
Avoid assignment to constants
double pi; vs.
pi = 3.14; #define PI 3.14
... ...
pi = 17.2; PI = 17.2; syntax error

© HDC 2024.1 Chapter 5: Program design & efficiency 56


Function Comments

Describe necessary information to call a function


precisely
Describe what a function does, not how it does
The code itself must be clear, easy to understand how it
operates…
If not, write the comments inside function definition
Describe inputs: input arguments, files to read, global
variables to use
Describe outputs: returning value, output arguments,
files to write, global variables affected

© HDC 2024.1 Chapter 5: Program design & efficiency 57


/* Comments */

/*************************************************
Explanation at
* Program: Mi_To_Km
the beginning
* Purpose: Miles to kilometers conversion
of the code
* Author: A. Hacker, 1/18/00 Section AF (Turing)
*************************************************/

Explanation of /* Calculate volume of cylinder and ...


the main code * Inputs : radius, height, ...
block * Output : volume, ...
* Assumes : radius, height nonnegative */
.
Sparsely .
individual .
explanation /* Tell user it’s negative. */

© HDC 2024.1 Chapter 5: Program design & efficiency 58


/* Comments */

Tell the cause, not description


 Should not:
/* subtract one from sheep */
sheep = sheep - 1;
 Should:
/* account for the sheep that
the big bad wolf just ate */
sheep = sheep - 1;

© HDC 2024.1 Chapter 5: Program design & efficiency 59


/* Comments */ for documentation
/**
* A brief history of JavaDoc-style (C-style) comments.
*
* This is the typical JavaDoc-style C-style comment. It starts with two
* asterisks.
*
* @param theory Even if there is only one possible unified theory. it is just a
* set of rules and equations.
*/
void cstyle( int theory );

© HDC 2024.1 Chapter 5: Program design & efficiency 60


/* Comments */ for documentation
/*******************************************************************************
* A brief history of JavaDoc-style (C-style) banner comments.
*
* This is the typical JavaDoc-style C-style "banner" comment. It starts with
* a forward slash followed by some number, n, of asterisks, where n > 2. It's
* written this way to be more "visible" to developers who are reading the
* source code.
*
* Often, developers are unaware that this is not (by default) a valid Doxygen
* comment block!
*
* However, as long as JAVADOC_BLOCK = YES is added to the Doxyfile, it will
* work as expected.
*
* This style of commenting behaves well with clang-format.
*
* @param theory Even if there is only one possible unified theory. it is just a
* set of rules and equations.
******************************************************************************/
void javadocBanner( int theory );

© HDC 2024.1 Chapter 5: Program design & efficiency 61


/* Comments */ for documentation
/***************************************************************************/
/**
* A brief history of Doxygen-style banner comments.
*
* This is a Doxygen-style C-style "banner" comment. It starts with a "normal"
* comment and is then converted to a "special" comment block near the end of
* the first line. It is written this way to be more "visible" to developers
* who are reading the source code.
* This style of commenting behaves poorly with clang-format.
*
* @param theory Even if there is only one possible unified theory. it is just a
* set of rules and equations.
******************************************************************************/
void doxygenBanner( int theory );

© HDC 2024.1 Chapter 5: Program design & efficiency 62


Programming style

A program is a document:
 Computer read it partially
 Human read it completely
 Donald Knuth: “literate programming”
Programming style is a term useful to developers and
related to:
 Comments, spaces, indentation, name
 Understandable, straightforward, elegant code
 Code quality

Usually present a good design

© HDC 2024.1 Chapter 5: Program design & efficiency 63


Example
/* Convert miles per hour to feet per second
* Author:...
* Date: ...
*/

#include <stdio.h>

/* conversion constants. */
#define FEET_PER_MILE 5280.0
#define SECONDS_PER_HOUR (60.0 * 60.0)

int main(void)
{
double miles_per_hour; /* input mph */
double feet_per_second; /* corresponding feet/sec */
double feet_per_hour; /* corresponding feet/hr */

/* prompt user for input */


printf(“Enter a number of miles per hour: ”);
scanf(“%lf”, &miles_per_hour);

/* convert from miles per hour to feet per second */


feet_per_hour = miles_per_hour * FEET_PER_MILE;

feet_per_second = feet_per_hour / SECONDS_PER_HOUR;

/* format and print results */


printf(“%f miles per hour is equal to %f feet per ”
“second.\n”, miles_per_hour, feet_per_second);

return(0);
}

© HDC 2024.1 Chapter 5: Program design & efficiency 64


Small things big impact

#include<stdio.h>
int main(void){double v1,v2,v3,v4,v5;pr\
intf(“Enter a number of miles per hour:\
”);scanf(“%lf”,&v1);v5=v1*14.6666667;pr\
intf(“%f miles per hour is equal to %f \
feet per second.\n”,v1,v5);return(0);}

© HDC 2024.1 Chapter 5: Program design & efficiency 65


5.3.3 Error handling – Error code

 Developers often need a mechanism to indicate that the


function can't accomplish its work because of some kind of
error.
 It might be invalid, an unexpected result being received from a
peripheral device, or a resource allocation issue.
 One of the most traditional and widespread ways to report an
error condition is through error codes.
 This is an efficient and ubiquitous mechanism that does not depend
on the programming language or the operating system.
 Due to its efficiency, versatility, and ability to cross various platform
boundaries, it is highly used in embedded software development.
 Designing a function interface that returns either a value or
an error code may be tricky, especially if the value and the
error code have different types.

© HDC 2024.1 Chapter 5: Program design & efficiency 66


fprintf revise

Prototype:
int fprintf ( FILE * stream,
const char * format, ... );
Return Value:
 On success, the total number of characters written is returned.
 If a writing error occurs, the error indicator (ferror) is set
and a negative number is returned.
 If a multibyte character encoding error occurs while writing
wide characters, errno is set to EILSEQ and a negative
number is returned.
errno is a macro of type int indicating “Last error
number”

© HDC 2024.1 Chapter 5: Program design & efficiency 67


fprintf revise
#include <stdio.h>
#include <errno.h>
#include <string.h>

extern int errno ;

int main () {
FILE * pf;
int errnum;
pf = fopen ("unexist.txt", "rb");

if (pf == NULL) {
errnum = errno;
fprintf(stderr, "Value of errno: %d\n", errno);
perror("Error printed by perror");
fprintf(stderr, "Error opening file: %s\n", strerror( errnum ));
} else {
fclose (pf);
}

return 0;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 68


Error code examples

// first implementation
#include <iostream>
int Receive(int input, std::string& output) {
if (input < 0) {
return -1;
}
output = "Hello";
return 0;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 69


Error code examples

// second implementation
#include <iostream>
std::string Receive(int input, int& error) {
if (input < 0) {
error = -1;
return "";
}
error = 0;
return "Hello";
}

© HDC 2024.1 Chapter 5: Program design & efficiency 70


Error code examples

// third second implementation


std::pair<int, std::string> Receive(int
input){
std::pair<int, std::string> result;
if (input < 0) {
result.first = -1;
} else {
result.second = "Hello";
}
return result;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 71


Error code examples
void Display(const char* prefix, int err, const std::string& result) {
if (err < 0) {
std::cout << prefix << " error: " << err << std::endl;
} else {
std::cout << prefix << " result: " << result << std::endl;
}
}

void Test(int input) {


std::string outputResult;
int err = Receive(input, outputResult);
Display(" Receive 1", err, outputResult);

int outputErr = -1;


std::string result = Receive(input, outputErr);
Display(" Receive 2", outputErr, result);

std::pair<int, std::string> ret = Receive(input);


Display(" Receive 3", ret.first, ret.second);
}

© HDC 2024.1 Chapter 5: Program design & efficiency 72


Error code examples

int main() {
std::cout << "Input: -1" <<
std::endl;
Test(-1);
std::cout << "Input: 1" << std::endl;
Test(1);
return 0;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 73


5.3.4 Exception handling

 C++ offers another mechanism for error handling, called


exceptions.
 Exceptions aim to simplify error handling and make it more
reliable. It help to avoid lots of if-else constructs when using
error code which makes the function logic more obscure.
 When using exceptions, developers do not need to check for
errors after every function invocation. Exceptions propagate
through the call stack automatically, until they reach the code
that can handle it properly by logging, retrying, or
terminating the application.
 While exceptions are the default error handling mechanism
of the C++ standard library, communicating with peripheral
devices or the underlying operating system layer still
involves error codes.

© HDC 2024.1 Chapter 5: Program design & efficiency 74


Exception handling statements

try {
// Block of code to try
throw exception; // Throw an
exception when a problem arise
}
catch () {
// Block of code to handle errors
}

© HDC 2024.1 Chapter 5: Program design & efficiency 75


Exception handling example 1
try {
int age = 15;
if (age > 18) {
cout << "Access granted - you are old enough.";
} else {
throw (age);
}
}
catch (int myNum) {
cout << "Access denied - You must be at least 18 years old.\n";
cout << "Age is: " << myNum;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 76


Exception handling example 1

try {
int age = 15;
if (age > 18) {
cout << "Access granted - you are old enough.";
} else {
throw 505;
}
}
catch (int myNum) {
cout << "Access denied - You must be at least 18 years old.\n";
cout << "Error number: " << myNum;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 77


Exception handling example 1
try {
int age = 15;
if (age > 18) {
cout << "Access granted - you are old enough.";
} else {
throw 505;
}
}
catch (. . .) {
cout << "Access denied - You must be at least 18 years old.\n";
cout << "Error number: " << myNum;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 78


Exception handling example 2
#include <iostream>
#include <system_error>
#include <fcntl.h>
#include <unistd.h>

class Device
{
int fd;
public:
Device(const std::string &deviceName) {
fd = open(deviceName.c_str(), O_RDWR);
if (fd < 0) {
throw std::system_error(errno, std::system_category(),
"Failed to open device file");
}
}
~Device() {
close(fd);
}
// continue in next slide …

© HDC 2024.1 Chapter 5: Program design & efficiency 79


Exception handling example 2
// continue from previous slides
void Send(const std::string &data) {
size_t offset = 0;
size_t len = data.size();
while (offset < data.size() - 1) {
int sent = write(fd, data.data() + offset, data.size() -
offset);
if (sent < 0) {
throw std::system_error(errno,
std::system_category(),
"Failed to send data");
}
offset += sent;
}
}
};

© HDC 2024.1 Chapter 5: Program design & efficiency 80


Exception handling example 2
int main() {
try {
Device serial("/dev/ttyUSB0");
// change to “COMx”, e.g. “COM2” in Windows
serial.Send("Hello");
}
catch (std::system_error &e) {
std::cout << "Error: " << e.what() << std::endl;
std::cout << "Code: " << e.code() << " means \"“
<< e.code().message()
<< "\"" << std::endl;
}
return 0;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 81


5.4 Event-driven programming

Event-driven programming is a programming paradigm


in which the flow of the program is determined by
events such as
 Starting the program, initializing variables
 Stepping in a loop, waiting for a command or an event
occurring such as mouse clicks, key presses, sensor outputs, or
messages from other programs or threads, timer stop
 Event handling subroutines/functions
 Getting back to the loop and wait for subsequent
events/commands
Embedded software also follows this paradigm

© HDC 2024.1 Chapter 5: Program design & efficiency 82


Example

Read “command” from keyboard and perform


corresponding tasks
Inputs: character from keyboard
 a: execute “command A” via function A_handler()
 b: execute “command B” via function B_handler()
 q: exit the software
Pseudo code of the main loop
Wait for the next command
If a, execute command A
If b, execute command B
If q, exit

© HDC 2024.1 Chapter 5: Program design & efficiency 83


Loop control scheme

Repeat until stopping condition matches


Use variable done to verify stopping condition

set done to false


while not done
body statements
if quit command, set done to true

© HDC 2024.1 Chapter 5: Program design & efficiency 84


Source code
#define FALSE 0
#define TRUE 1
int main(void) {
char command;
int done;
done = FALSE;
while (!done) {
command = ReadCommand( );
/* Input command from user */
switch (command) {
case ‘a’: A_handler(); /* Execute command A */
break;
case ‘b’: B_handler(); /* Execute command B */
break;
case ‘q’: done = TRUE; /* quit */
break;
default: printf(“Unrecognized command\n”);
}
}
return 0;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 85


Multithreading

Multithreading is a specialized form of multitasking


which allows the computer to run two or more tasks
concurrently
Two types of multitasking:
 Process-based multitasking handles the concurrent execution of
programs.
 Thread-based multitasking deals with the concurrent execution
of pieces of the same program.
A multithreaded program contains two or more parts that
can run concurrently. Each part of such a program is
called a thread, and each thread defines a separate path
of execution.

© HDC 2024.1 Chapter 5: Program design & efficiency 86


Multithreading

Image courtesy: https://en.wikipedia.org/wiki/Thread_(computing)#/media/File:Multithreaded_process.svg

© HDC 2024.1 Chapter 5: Program design & efficiency 87


Multithreading

© HDC 2024.1 Chapter 5: Program design & efficiency 88


Function call within a thread

1. Using The Function Object


// Define the class for function object
class functionObject_class {
// Overload () operator
void operator()(params)
{
// code to be executed
}
};
// Cr

© HDC 2024.1 Chapter 5: Program design & efficiency 89


Function call within a thread

2. Using Function Pointer


void funct_call(params){
//code to be executed
}
std::thread thread_obj(funct_call, params);

© HDC 2024.1 Chapter 5: Program design & efficiency 90


Function call within a thread

3. Using A Lambda Expression


// Define a lambda expression
auto f = [](params) {
// code for execution
};
std::thread thread_object(f, params);

© HDC 2024.1 Chapter 5: Program design & efficiency 91


Example
#include <iostream> int main() {
#include <thread> // Define a Lambda Expression
auto f = [](int n) {
using namespace std;
for (int i = 0; i < n; i++)
// function to be used in callable cout << "Thread 3 :: callable => lambda
void func_dummy(int N) { expression\n";
for (int i = 0; i < N; i++) { };
cout << "Thread 1 :: callable => //launch thread using function pointer as
callable
function pointer\n";
thread th1(func_dummy, 2);
} // launch thread using function object as
} callable
// A callable object thread th2(thread_obj(), 2);
class thread_obj { //launch thread using lambda expression as
callable
public:
thread th3(f, 2);
void operator()(int n) { // Wait for thread t1 to finish
for (int i = 0; i < n; i++) th1.join();
cout << "Thread 2 :: callable => // Wait for thread t2 to finish
function object\n"; th2.join();
// Wait for thread t3 to finish
}
th3.join();
}; return 0;
}

© HDC 2024.1 Chapter 5: Program design & efficiency 92


END OF CHAPTER 5

You might also like