0% found this document useful (0 votes)
15 views

Chapter5 - Program Design and Efficiency

Kỹ thuật lập trình BKHN

Uploaded by

Minh Huệ Tô
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

Chapter5 - Program Design and Efficiency

Kỹ thuật lập trình BKHN

Uploaded by

Minh Huệ Tô
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 93

EE3491/EE3490E –

Kỹ thuật lập trình /


Programming Techniques
Chapter 5: Program
design & efficiency
Lecturer: Dr. Hoang Duc Chinh (Hoàng Đức Chính)
Department of Industrial Automation
School of Electrical Engineering
Email: [email protected] © DIA 2022.2
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.
Chapter 5: Program design & efficiency © DIA 2022.2 2
Content
5.1. Program design process revision
5.2. Code optimization
5.3. Good habits in programming
5.4. Event-driven programming

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 4


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

Chapter 5: Program design & efficiency © DIA 2022.2 5


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
Chapter 5: Program design & efficiency © DIA 2022.2 6
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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 8


Example: flowchart diagram

START

statements
statements

conditional
FALSE

TRUE

statements

END

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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
Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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) ?

Chapter 5: Program design & efficiency © DIA 2022.2 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; }
}

Chapter 5: Program design & efficiency © DIA 2022.2 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%

Chapter 5: Program design & efficiency © DIA 2022.2 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?

Chapter 5: Program design & efficiency © DIA 2022.2 18


Writing Efficient Code
 Identify the cause of inefficiency
 Redundant computation, especially
 In procedures
 Loops

Chapter 5: Program design & efficiency © DIA 2022.2 19


Initialize once, use multiple times
 Before float f()
{ double value = sin(0.25);
//
…..
}

double defaultValue = sin(0.25);


 After
float f()
{ double value =
defaultValue;
//
…..
}
Chapter 5: Program design & efficiency © DIA 2022.2 20
Static Variables
 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);
}

Chapter 5: Program design & efficiency © DIA 2022.2 21


Static Variables
 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

Chapter 5: Program design & efficiency © DIA 2022.2 22


Stack, heap revisions
 Data segment of a program contains 3 parts:
 static, stack, and heap data.
 Static: global or static variables
 Stack data:
 Local variables of a function, e.g. double_array in the previous
example
 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

Chapter 5: Program design & efficiency © DIA 2022.2 23


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

Chapter 5: Program design & efficiency © DIA 2022.2 24


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;

Chapter 5: Program design & efficiency © DIA 2022.2 25


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);

Chapter 5: Program design & efficiency © DIA 2022.2 26


Reduce computation time
 In Neural Network simulation, a
function named sigmoid is often 1
sigmoid ( x) 
used 1  e kx
 If x is a large positive number
sigmoid(x)  1
 If x is a large negative number
sigmoid (x)  0

Chapter 5: Program design & efficiency © DIA 2022.2 27


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

Chapter 5: Program design & efficiency © DIA 2022.2 28


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)

Chapter 5: Program design & efficiency © DIA 2022.2 29


sigmoid function – a solution
 Instead of calling the function all the time x0 sigmoid(x0)
 Calculating with N points and save to an array x1 sigmoid(x1)
x2 sigmoid(x2)
 In each call of sigmoid:
x3 sigmoid(x3)
• Find the nearest value of x and its respected result
x4 sigmoid(x4)
• Perform linear interpolation to find the final result
x5 sigmoid(x5)
x6 sigmoid(x6)
.
.
.

x99 sigmoid(x99)

Chapter 5: Program design & efficiency © DIA 2022.2 30


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

Chapter 5: Program design & efficiency © DIA 2022.2 31


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;
• Which needs a substation of two real numbers and a division of real
numbers
 Comput sigmoid(x)
• Which needs a multiplication of floats and a addition of floats

Chapter 5: Program design & efficiency © DIA 2022.2 32


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

Chapter 5: Program design & efficiency © DIA 2022.2 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
Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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");

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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
Chapter 5: Program design & efficiency © DIA 2022.2 43
5.3.2 Program Style
 Why is the program style important?
 Errors are usually due to developers’ mistakes
• What is the use of a variable?
• 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
Chapter 5: Program design & efficiency © DIA 2022.2 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; */
}

Chapter 5: Program design & efficiency © DIA 2022.2 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
Chapter 5: Program design & efficiency © DIA 2022.2 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?

Chapter 5: Program design & efficiency © DIA 2022.2 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 (“=”)
Chapter 5: Program design & efficiency © DIA 2022.2 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!
Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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 ( )

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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
Chapter 5: Program design & efficiency © DIA 2022.2 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)
*************************************************/

/* Calculate volume of cylinder and ...


Explanation of
* Inputs: radius, height, ...
the main code
* Output: volume, ...
block
* Assumes: radius, height nonnegative */
.
.
Sparsely
.
individual
/* Tell user it’s negative. */
explanation
Chapter 5: Program design & efficiency © DIA 2022.2 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;

Chapter 5: Program design & efficiency © DIA 2022.2 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 );

Chapter 5: Program design & efficiency © DIA 2022.2 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 );

Chapter 5: Program design & efficiency © DIA 2022.2 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 );

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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);
}

Chapter 5: Program design & efficiency © DIA 2022.2 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);}

Chapter 5: Program design & efficiency © DIA 2022.2 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.

Chapter 5: Program design & efficiency © DIA 2022.2 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”

Chapter 5: Program design & efficiency © DIA 2022.2 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;
}

Chapter 5: Program design & efficiency © DIA 2022.2 68


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

Chapter 5: Program design & efficiency © DIA 2022.2 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";
}

Chapter 5: Program design & efficiency © DIA 2022.2 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;
}

Chapter 5: Program design & efficiency © DIA 2022.2 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);
}

Chapter 5: Program design & efficiency © DIA 2022.2 72


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

Chapter 5: Program design & efficiency © DIA 2022.2 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.

Chapter 5: Program design & efficiency © DIA 2022.2 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
}

Chapter 5: Program design & efficiency © DIA 2022.2 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;
}

Chapter 5: Program design & efficiency © DIA 2022.2 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;
}

Chapter 5: Program design & efficiency © DIA 2022.2 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;
}

Chapter 5: Program design & efficiency © DIA 2022.2 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 …

Chapter 5: Program design & efficiency © DIA 2022.2 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;
}
}
};

Chapter 5: Program design & efficiency © DIA 2022.2 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;
}

Chapter 5: Program design & efficiency © DIA 2022.2 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
Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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

Chapter 5: Program design & efficiency © DIA 2022.2 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;
}

Chapter 5: Program design & efficiency © DIA 2022.2 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.
Chapter 5: Program design & efficiency © DIA 2022.2 86
Multithreading

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

Chapter 5: Program design & efficiency © DIA 2022.2 87


Multithreading

Chapter 5: Program design & efficiency © DIA 2022.2 88


Function call within a thread
1. Using The Function Object
/</em>/ Define the class for function object
class functionObject_class {
// Overload () operator
void operator()(params)
{
// code to be executed
}
};
// Cr
Chapter 5: Program design & efficiency © DIA 2022.2 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);

Chapter 5: Program design & efficiency © DIA 2022.2 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);

Chapter 5: Program design & efficiency © DIA 2022.2 91


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

Chapter 5: Program design & efficiency © DIA 2022.2 92


END OF CHAPTER 5

Chapter 5: Program design & efficiency © DIA 2022.2 93

You might also like