EC-101A Computer Systems and Programming

Manish Shrikhande Department of Earthquake Engineering Indian Institute of Technology Roorkee Roorkee-247667. INDIA

Computer Organization - 1 ●

Information processing machines – – –



Effect transformation of data from one form to another Requires a set of data to be manipulated, and a set of instructions (program) to carry out the desired manipulation.

Data and instructions need to be stored (different from electronic calculators!) –

A common storage may be used to store data as well as instructions ●

von Neumann architecture is used in all computers.

Computer Organization - 2 ●

Basic ingredients of a von Neumann computer: – –

Processor, the 'Brain' Storage ●

– ●

Different hierarchy of devices based on speed and cost.

Input/Output devices

All communications take place through a common channel, called a bus.

Memory and Cache ●



Information stored and fetched from the memory sub-system Random Access Memory maps addresses to memory locations – – –

Memory made of addressable “cells” Current standard size is 8-bits Memory address is an unsigned binary number (N-bit) ●



Address space is 2^N

Cache memory keeps memory currently in use in faster memory to speed access time

Structure of RAM

The von Neumann Architecture

Instruction Execution ●





● ●

Fetch instruction from Main Memory/Storage Decode (interpret) instruction Fetch operands from Registers Carry out operations Store result in Registers

Binary Coding ●







Instruction set: a set of basic operations that a computer is capable of performing Program: a set of instructions arranged in a certain sequence for a computational task Data: numbers and characters used as operands by instructions Binary encoding: both programs and data are encoded in binary form for digital computer to understand –

Possible to design more reliable and compact hardware by using base 2 representation

Number Representation on a Computer ●

Integers –

Non-negative integers encoded as binary numbers ●





N-bits can be used to represent numbers in the range 0 ~ 2^{N-1} A finite set! Overflow errors possible in arithmetic!

How to represent negative integers as well? ●

Sign and magnitude form – –



MSB is considered as the sign bit and rest are interpreted as unsigned integers: (-1)^{MSB} * Magnitude Two possible representations for 0: +/- 0

Biased representation – – –

Shift of origin Interpret the number as unsigned integer and then subtract a constant offset (bias = 2^{N-1} – 1) Inconvenient in implementing arithmetic

2's Complement Representation ●

2's complement of a binary number is the value obtained by subtracting the number from a large power of 2 – –

Specifically, from 2^N for N-bit 2's complement Used to represent the signed integers on digital computers ●



Subtraction can be performed as addition of two numbers thereby obviating the need for additional circuitry

In an N-bit binary number the MSB is the 2^{N-1} place. In 2's complement its place value is negated, it becomes -2^{N-1} and is called the sign bit.

More on 2's Complement ●

A quick way to determine 2's complement of a number is: –



For example: 0101 5 in decimal 1010 Flip the bits +0001 Add 1 to Flip all bits – change 0 the LSB to 1 and 1 to 0 (One's 1011 complement) (-1*2^3 + 1*2 + 1*2^0) Add 1 to the LSB to get = - 5 in decimal the 2's complement

Even More on 2's Complement Subtraction in 2's comp: 5 – 5 = 0 (in decimal) 0101 + 1011 = 5 + ( - 5) [1]0000 = 0 (Discarding the overflowing carry bit [1])

Multiplication by Booth's Algorithm If x is the count of bits of the multiplicand and y is the count of bits of the multiplier: ●



Draw a grid of three rows, each with columns for x+y+1 bits. Label the lines respectively A (add), S (subtract), and P (product). In 2's complement notation fill first x bits of each line with: – – –

A: the multiplicand S: the negative of the multiplicand P: zeroes

Booth's Algorithm (contd.) ●

Fill the next y bits of each line with: – – –





Do both of these steps y times –

A: zeroes S: zeroes P: the multiplier

If the last two bits in the product are: ● ●

Fill the last bit of each line with a zero



– ●

00 or 11: Do nothing 01: P = P + A . Ignore any overflow 10: P = P + S. Ignore any overflow

Arithmetically shift the product right one position

Drop the last bit from the product for final result.

Booth's Algorithm (Example) ●

Multiply 3 and - 4 in 2's complement rep: – – –









A = 0011 0000 0 S = 1101 0000 0 P = 0000 1100 0





Last 2 bits are 00: do nothing Impose one arithmetic right shift ●



P = 0000 0110 0

Last 2 bits are 00: do nothing



P = 1110 1001 1

Last 2 bits are 11: do nothing Arithmetic right shift ●



P = 1101 0011 0 (P = P + S)

Arithmetic right shift ●



P = 0000 0011 0

Last 2 bits are 10: ●

Perform the loop four times –

Arithmetic right shift

P = 1111 0100 1

Product is 1111 0100, which is -12

Floating Point Representation ●

Computer is a finite machine – finite in size and speed –



Inherently incapable of representing the infinite numbers on real number line and therefore only a finite set of discrete numbers can be exactly represented Scientific computations require very large as well as very small numbers ● ●



Integers do not serve the purpose of scientific computing A proper representation of fractions is needed

Floating point representation: 2.35329 E +09, 23.53290 E +08, 0.23533 E +10 all represent the same number. Magnitude is governed by the exponent. Arbitrarily large and small representations are possible.

IEEE Floating Point Representation ●



The normalized floating point numbers are ∓ m₀ . m₁ m₂ ... × βᴱ where, β is the base of number system, E is the exponent, and the whole part of the significand is restricted to the range 0 < m₀ < β. For binary system, the normalization condition implies that the whole part of the significand will always be 1. – Concept of hidden bit to achieve more precision by storing only fractional field and assuming that whole part is always 1.

IEEE Standard 754 ●

Single precision floating point numbers are represented as 32 bits (4 bytes) long pattern – – –



MSB is the sign bit (s) Next 8 bits represent the exponent field (E) Subsequent 23 bits contain the fractional part of the significand ([1].f) providing 24 bits of effective precision (p)

Double precision floating point numbers are represented as 64 bits (8 bytes) long pattern – – –

MSB is the sign bit (s) Next 11 bits are interpreted as exponent (E) Subsequent 52 bits denote the fractional part of the significand ([1].f) with 53 bits of effective precision (p)

Floating Point Numbers (contd.) ●





The normalized floating point numbers are represented as (-1)^s х [1].f х 2^e The exponent, e, is a signed integer represented using biased notation with a bias of 2^{N-1} – 1 with N being the number of bits for exponent field The clever trick of using the hidden bit to attain an extra bit of precision has an unwanted side effect: – –

The number 0 can not be represented!! Necessitates special provision to include a representation of 0 in the set of machine numbers

IEEE 754 Format Parameters

IEEE 754 Special Representations ●

The pattern with all 0's and all 1's in the exponent field interpreted differently –

– –

Extend the range of non-zero numbers by admitting the representation of denormalized (or, subnormal) numbers, a formal representation of (signed) 0, signed infinity, and signal for invalid operation Subnormal numbers reduce underflow errors +/- Inf provides a consistent handling of overflow

Floating Point Exceptions

Limitations of IEEE Floating Point Representation ●



Only a finite set of discrete numbers can be represented exactly on the computer The available machine numbers are not spaced uniformly over the whole range – –

The difference between two consecutive machine numbers increases with the magnitude of numbers Greater round off errors in computing with large magnitude numbers ●



Scaling of numbers is often necessary to operate in the small magnitude range, where the population density of machine numbers is higher, to minimize round off errors.

Normal laws of arithmetic (such as associative rule) may not hold in IEEE 754 floating point arithmetic!

Programming: Taming the Beast ●

What is a computer program? – –



A collection of instructions that describe a task, or a set of tasks to be performed by a computer. May refer to the source code written in a programming language, or to the executable form of this code.

What are the ingredients of a computer program? –

Algorithms ● ● ●



Need an order/sequence for carrying out instructions Need to facilitate repetition Need to facilitate decision making

Data ● ●

Need to provide for different data types Need to provide for an organized representation

Programming with C++ ●

A high-level general purpose programming language –

Efficient and portable ●



Supports multiple programming styles ● ● ● ●



Procedural programming Data abstraction Object-oriented programming Generic programming

Gives the programmer a lot of freedom ●



System-dependent features are moved to “header files”

Freedom comes with responsibility!

Good quality compiler tools are readily available

Sample Program: Hello World! #include // This is a line comment. // Include iostream header file to facilitate basic input/output #include // Include C Standard library using namespace std; /* This is a block comment. Declare default namespace to be used as the std. */ int main (){ cout << “Hello world!” << endl; system (“pause”); return 0; }

Structure of a C++ Program-1 ●



● ●

All lines beginning with two slashes (//) are considered as comment. Everything within the pair /* and */ is also considered as comment. # indicator for a pre-processor directive Header files - an important feature of C/C++ – –



Enhances portability by confining system specific features to appropriate header files. Separates interface from the implementation.

Namespace - allows a group of one or more identifiers to exist.

Structure of a C++ Program-2 ●

iostream.h: the standard header file providing the basic input/output functionality. – – –

System header files included within < and > User defined header files included within '' and '' C++ standard allows omission of the file extension in include directive ●





A way to allow the use of modern template-based specifications (invoked without the extension) Use older (C style) non template-based specifications – if invoked with ''.h'' extension

All libraries of C are available with the traditional ''.h'' extension ●

Modern C++ implementation available with prefixing a ''c'' before the name and dropping the ''.h'' extension

Structure of a C++ Program-3 ●







● ●

Every program must have a master function called as main () The program execution always starts from this master function. The function main ()should be of integer return type for the OS to receive exit signals. The body of the program must be enclosed within a pair of braces - { and }. Each statement should terminate with a semi-colon Compound statement: valid statements within matching pairs of { and }

Variables and Data Types-1 ●

Variables – a portion of memory to store data – –

Need identifiers to distinguish one variable from other A valid identifier is a sequence of alphabets, numerals, or underscore character ( _ ) ●

Should always begin with an alphabet, or the underline –

● ●



Identifiers beginning with '_' are usually used for system specific keywords, or external identifiers

In no case identifiers can begin with a digit. Identifiers have to be different from the set of reserved keywords of the programming language.

C/C++ is a case sensitive language ●

BLACK, Black, and black are three different valid identifiers

Variables and Data Types-2 ● ●

Variables are stored in computer storage space Computer needs to be told about the type of data stored in a variable – –

Different types of data require different amount of storage Fundamental data types in C++ ● ● ● ● ● ● ●

char – character, or small integer – 1 byte long short int – short integer – 2 bytes long int – integer/long integer – 4 bytes long bool – Boolean value (True/False) – 1 byte long float – Floating point number – 4 bytes long double – Double precision floating point number – 8 bytes wchar_t – Wide character – 2 byles long

Declaration of Identifiers ●

Every identifier needs to be declared before it can be used in a program The syntax to declare a variable is to specify the type of data and the name of the identifier: signed int i; unsigned int j; float x, y; – Optionally, the identifiers can be initialized at the time of declaration: signed short i = -7; unsigned long j(0); float x = -2.3, y (4.5); –

● ●

C-style initialization by using assignment operator C++ constructor style initialization by using parentheses

Scope Rules for Identifiers ●

An identifier's life span in a program is decided by the scope of its declaration –

Declaration can be either in global scope, or in local scope. ●



Global identifiers can be accessed from anywhere in the code. Local identifiers are accessible only within the block in which they have been declared.

#include using namespace std; int Integer=0; // Global variable char Character='c'; // Global var float Score(0.0);// Global var int main(){ /* Local variables visible within function main () */ float x1(0.0); bool test = true; if (test) { /* Local variables accessible only within this block of {... } */ int i(0); float y1(0.0; } cout <<“i, y1 are inaccessible”; return 0; }

Naming Conventions and Programming Style ● ●





ALL_CAPITALS are recommended for constants First_capital is recommended for Global variables all_lowercase is recommended for local variables Indent in code is strongly recommended to make the structure obvious –

3 spaces is recommended as indent length

Expressions and Operators-1 ●



Expression is a combination of operators, literal data values and identifiers that can be evaluated. Operator is a mechanism that takes data value(s) and transforms them into a new data value. –

Examples: Negation (unary operator), Multiplication (*), Real Division (/), Integer Division (/), Remainder (%), Addition (+), Subtraction (-), etc. ●



The division operator (/) is overloaded !! The behaviour is determined by the data type of its operands.

Operators have a default precedence order and expressions are evaluated from left to right. –

Use parentheses to override default precedences.

Expressions and Operators-2 ●

The expression 2 + 3 / 5 is evaluated as 2 + (3 / 5) which evaluates to 2 – –





To alter the default sequence of operations, write the expression as (2 +3)/5 which evaluates to 1 (<<) is a stream insertion operator and (>>) is a stream extraction operator –



Division has higher precedence than summation. Integer division truncates the fractional part.

Overloaded! Behaviour depends on the data type of the operands.

Assignment operator (=) is used to assign values to identifiers as in float std_dev = 0.0;

Expressions and Operators-3 ●

● ●

Example of a valid arithmetic expression from the code grading.cpp: cut_off_aplus = ave + 2.0 * \ std_dev; (\) is a line continuation operator All identifiers should be declared first before they can be used in expressions – strict type checking! –

Identifiers can be declared anywhere in the code as long as it is done before their use in expressions ●

Great flexibility but can also be a source of errors: multiple declarations of an identifier at different places –

Possible conflicts resolved by the scope of identifiers

Decision Making: Equality and Relational Operators ●

Equality Operators (x == y) x is equal to y – (x != y) x is not equal to y Relational Operators – (x > y) x is greater than y – (x < y) x is less than y – (x >= y) x is greater than, or equal to y – (x <= y) x is less than, or equal to y Logical Operators – '&&' is the logical AND operator – '||' is the logical OR operator – '!' is the logical NOT operator –





Operators (Contd.) ●

Arithmetic Assignment Operators x += dx; is same as x = x + dx; x -= dx; is same as x = x - dx; x *= y; is same as x = x * y; x /= y; is same as x = x / y; x %= y; is same as x = x % y; ++ is increment operator (add 1) ++x is pre-increment x++ is post-increment -- is decrement operator (subtract 1) --x is pre-decrement x-- is post-decrement

Control Structures ●

Only three control structures needed to write a computer program: –

Sequence structure ●



Usually built into the programming language

Selection structure ●

Three types available in C++ –



Repetition structure ●

Three types available in C++ –



if, if/else and switch

while, for and do/while

Strategy to develop a program –

Write pseudocode ● ●

Helps to think out the algorithm and fine tune it Comprises of only execution/action statements

Pseudocode An outline of the sequence of steps in solution. A possible psuedocode for the students' grading: Read in total number of students ● Read and store individual scores ● Compute class average ● Compute standard deviation ● Compute grade thresholds ● Go over all students' scores again ➢ Compare with thresholds ✔ Award grade ●

Decision Control Structures if (condition) { statement1; statement2; }

switch (expression){ case constant1: statement1; break; case constant2: statement2; break; default: statement3; break; }

if (condition){ statement1; statement2; } else { statement3; statement4; } Conditional operator: y =(expression) ? result1: result2;

Repetition Control Structures while (expression) { statement1; statement2; }

for (initialization;condition;increment){ statement1; statement2; }

do { statement1; statement2; } while (expression);

Interrupting Control Flow ●

It is possible to terminate a repetition control structure prematurely if required. C++ standard provides two different ways to achieve this: –

break statement ●



continue statement ●





Terminates the repetition loop completely and the program control moves to the next statement. Skips the rest of the loop in current cycle and the control returns to the beginning of next cycle of the repetition loop.

Control can also be transferred with the much maligned goto statement. exit function defined in cstdlib library can be used to terminate the program.

Matters of Formatting ●

iomanip library facilitates manipulation of input/output –





setw(int const) sets the field width for the following stream object setprecision (int const)sets number of digits of precision fixed used to enforce fixed form for floating point numbers

#include #include #include using namespace std; int main (){ int iseed = 0, irand = 0; for (int i = 0; i <=10; i++){ cout << left << setw(10); cout << “i = “ << i \ << endl; } system (“pause”); cout<<”Enter a non-negative” \ << “ integer: “; cin >> iseed; srand (iseed); while (irand < 100){ cout << setprecision (3); cout << ((float) rand()) \ /((float) RAND_MAX); irand += 1; } system (“pause”); return 0; }

File I/O ●

#include needed to facilitate reading from and writing to files. – –

ifstream denotes the input file stream type ofstream denotes the output file stream type ●



Used to create file handles which can be associated with any specified file with the help of open() member function File association terminated with close() member function

#include #include #include using namespace std; int main(){ string name1; ifstream fin; ofstream fout; cout << ”Input file? ”; getline(cin,name1); fin.open(name1.c_str()); fout.open(”output.dat”); float x(0.0), y(0.0); fin >> x >> y; x += y; fout << x; fin.close(); fout.close(); cin.get(); return 0; }

File Opening Modes ●

While opening the file to read, or write special attributes can be specified as in fstream fout (“output.dat”, ios::out|ios::app);



Different file opening modes can be combined with bitwise OR ( | ) operator.

Mode ios::in ios::out ios::app ios::ate

Purpose Open file to read Open for writing Append to file Current file marker placed at the end Overwrites the ios::trunc file ios::nocreate Do not create a new file if the named file does not exist

File Positioning Functions ●

C++ imposes no structure on the file – –



All files are created for sequential access Random access files can be simulated by using data structures of uniform sizes A “get pointer” (seekg(long)) indicates the position in the file from which the next input is to occur







A “put pointer” (seekp(long)) indicates the position in the file at which next output is to be placed The file position pointer is an integer value that specifies the location in the file as a number of bytes from the file's starting location tellg() and tellp() return the current locations

The Preprocessor-1 ●

A collection of special statements called directives – – –

● ●

Used for macro substitution, conditional compilation, and inclusion of named files Identified by hash (#) as the first non-white character Not program statements but are digested by the preprocessor before compiler generates executable

#include includes a copy of specified file #define PI 3.14159 – –

Defines a symbolic constant PI which remains defined till the end of file or until #undef PI is encountered Macro definition ● ●

#define MAX((x),(y)) ((x)>(y)?(x):(y)) Inline functions better than macros

The Preprocessor-2 ●

Conditional compilation of the code is possible with the use of –



#define, #ifdef, #ifndef, #if, #elif, #else, #endif

#error directive prints specified tokens and aborts preprocessing and compilation

#if TABLE_SIZE>200 #undef TABLE_SIZE #define TABLE_SIZE 200 #elif TABLE_SIZE<50 #undef TABLE_SIZE #define TABLE_SIZE 50 #else #undef TABLE_SIZE #define TABLE_SIZE 100 #endif int table[TABLE_SIZE]; #ifndef __cplusplus #error A C++ compiler is required! #endif

Principles of Structured Programming ●

At all times and under all circumstances, the programmer must keep the program within his/her intellectual grasp. –

Top-down design and construction ● ●



Limited control structures ● ●



Divide problem into smaller problems Single entry and exit points for a code block solving a small sub-problem Stacked up Nested

Limited scope of data structures ●

Prevent unintentional alternation of data by different program segments

Functional Decomposition-1 ●

Enforce logical structure in program – –

The problem is divided into smaller parts A function is used to solve a sub-part ●



Structure and logic of the program is clearly visible

Function declaration and definition ●

Value returning and void type

#include #include using namespace std; int add (int x, int y){ int r = 0; r = x + y; return r; } int main (){ int i = 0, j = 0; cout << “Enter two “; cout << “integers\n”; cin >> i >> j; cout << “Sum = “; cout << add(i, j); return 0; }

Functional Decomposition-2 ●



Functions should be declared first (prototype) if the definition comes after the calling function. Data type of the return value from a function should be explicitly indicated. –



Passing arguments to functions: – –



If a function is not required to return anything to the calling function then use void type. By value (a copy of the value is passed) By reference (address is passed, contents altered)

Functions can be overloaded. –

Correct function definition is picked by comparing type, number, and order of arguments in function call with prototype declarations.

Function Definition-1 ●



All variables defined in function are local variables – Include the function arguments Attributes of an identifier – Storage class: determine the longevity of identifier ● auto, register, extern, mutable, and static – Scope: where the identifier can be referenced in a program – Linkage: facilitates recognition of identifiers in multiple source files of a program

Function Definition-2 ●



Parameter passed by reference can be prefixed with const keyword to prevent the contents of the identifier from being modified. Default arguments – – –

Values assigned to arguments in function prototype Rightmost in the function's parameter list Can be omitted in a function call ●



The compiler rewrites the function call and automatically inserts the default values of arguments

Qualifier inline before a function's return type in definition (should precede function call) –

Generate a copy of the code in place to avoid an explicit function call

Function Recursion ●

Functions can call themselves – recursion –

In each call the problem is divided into a simpler problem ●



To the point where no further simplification is possible – base case If the function is called with a base case, the function simply returns a result.

#include using namespace std; long factorial (int = 0); // Default value of argument int main(){ int i(0); extern float Global_X; cout << ”Enter integer for computing factorial: ”; cin >> i; if (i < 0 ){ cout << ”Factorial of neg. int not defined!”; exit 1;} Global_X = i*i; cout << ”Factorial ” << i << ” = ” << factorial(i); cout << ”Square of ” << i << ” = ” << Global_X; cin.ignore(); cin.get(); return 0; } long factorial (int x){ static int fact = 1; if (x > 1) fact = x * factorial(x-1); return fact; } float Global_X(0.0);

Function Overloading ●

Several function definitions with same name can co-exist as long as those have different sets of parameters –

The standard math library provides float, double and long double versions of mathematical functions.

#include using namespace std; inline int add(int x=0, int y=0){ cout << “Inside int add!” << endl; return (x+y); } inline float add(float x=0, float y=0){ cout << “Inside float add!” << endl; return (x+y); } int main(){ int i(0), j(0); float x(0.0), y(0.0); cout << ”Enter 2 ints and 2 floats: ”; cin >> i >> j >> x >> y; cout << “Sum on ints = “ << add(i,j); cout << “Sum of floats = “ << add(x,y); cin.ignore(); cin.get(); return 0; }

Arrays ●

A series of elements of the same type stored in contiguous memory locations –

Individual elements are accessible via a common identifier with an index, e.g., type name[SIZE] ●





type is a valid data type, name is the identifier, SIZE is the number of elements that the array may contain. The size of the array (SIZE in the above example) should be a constant integer because the size of the array is determined at compile time for non-dynamic memory blocks

Initialization: – –

Global and static arrays are automatically initialized to default values, i.e., pattern of 0's in all bits. Arrays declared in local scope are not automatically initialized

Arrays: Initializaton ●

Initialization is possible at the time of declaration as: int idata[5]={1, -1, 4, 2, -3}; – –

The number of initialization data within { } should not be greater than the declared size of array. The dimension of the array can be omitted from declaration if it is possible to get this information from the initialiazation as: int jdat[]={1, -1, 4}; will define an array of integers of size 3 and is equivalent to: int jdat[3]={1, -1, 4}; ●

It is permitted to have fewer initialization values than the size of array. The specified values are used to initialize the array elements from beginning. The remaining elements are initialized to 0.

Array Elements ●



The name of the array is synonymous with the address of the memory block containing the first element. The individual elements are accessed by “offset with respect to the first element” mechanism. –





The first element of array f[10] is accessed as f[0] while the 10th element is accessed as f[9]

Name of array can be passed as an argument to a function to simulate call by reference. C++ standard does not forbid access of memory locations outside the declared dimensions of arrays

Multidimensional Arrays ●

Arrays can be arranged to have multiple dimensions, e.g., two dimensional arrays can be declared as: type name [RSIZE][CSIZE] – –



RSIZE and CSIZE are constant integers defining the row and column dimensions of array Arrays of more than two dimensions can be declared similarly but their use is extremely rare.

Arrays are stored in row-major format – –

Important issue in implementing matrix manipulation algorithms Initialization is also done row-wise.

Arrays: Function Arguments-1 ●

Array name is a constant pointer to the address of the first element –

Name of the array can be passed as a function argument ●



Simulated pass by reference. Avoids large scale movement of data required by pass by value for large size arrays Possible to prevent modification of the array contents by the called function by using const prefix before array type in function prototype and definition –



The principle of least privilege – grant only as much access as required for the task, not more.

For one-dimensional arrays, the dimension can be omitted in function prototype.

Arrays: Function Arguments-2 ●

It is necessary to explicitly specify the array dimensions other than the first in function prototype and definition. –



Needed for function to know the position of memory block to wrap around to next row. 1-D arrays can be used without specifying dimensions.

#include #define NSUB 6 using namespace std; void average (const float score [][NSUB], float mean [], \ int nrows, int ncols){ for (int j=0; j(nrows);} return; } int main(){ const int NSIZE = 100; int nrows = 0; // Actual number of rows of data to be processed int ncols = 0; // Actual number of columns to be processed float score [NSIZE][NSUB] = {0}; float mean [NSUB] = {0}; cout << “Enter number of rows and columns of data: “; cin >> nrows >> ncols; cout << “Enter data row-wise\n”; for (int i=0; i> score[i][j]; // Read the data } /* Call function to process the data */ average (score, mean, nrows, ncols); return 0;}

Strings: Array of Characters-1 ●

In classic C-style, strings are considered as array of char type terminated by a “null” character ('\0') –



{'M','a','n','i','s','h'} is not a string but {'M','a','n','i','s','h','\0'} is treated as a string.

Stream insertion and extraction operators are overloaded to display the contents of char arrays –

cout << Name; displays the contents of the char array Name[] instead of the address of the first element.

Strings: Array of Characters-2 ●

char arrays can also be initialized as: char Name[50] = “Some String”; – The terminating null character is automatically supplied. ● The array should be long enough to accommodate char data and a terminating '\0' – Stream insertion continues till the null character – Stream extraction begins at the first non-white character and continues till the first whitespace character.

Strings: Array of Characters-3 ●

For reading in strings with one or more whitespace characters: –

– –



Use cin.getline(Name); to read upto and including the newline character and add a terminating null character Use cin.get(Name); to read upto the newline character and add a terminating null character Use cin.get(Name,NCHAR); read NCHAR characters into char array Name and add a terminating '\0'

Several functions for manipulating strings can be accessed by #include

The String Class ●



C++ provides another mechanism for handling strings – through the string class. It enables treatment of string data in the same way as fundamental built-in data types –

– –

Requires inclusion of system header file string, and Requires specification of namespace as std

#include #include using namespace std; int main(){ string mystring(“Test string”); mystring += “, another string”; string second = “Overwrite”; mystring = second; string fname; cout << “Enter filename? “; getline(cin, fname); ifstream fin; // Open input file to read data fin.open(fname.c_str()); }

return 0;

Pointers: what are those? Computer memory is arranged as a sequence of bytes grouped into words ● Each byte has a unique address or index in this sequence ● The size of a word determines the size of addressable memory in a machine ● A pointer is a variable which contains the memory address of another variable ● A pointer has the type of the value pointed to and is declared as such by using asterisk: char * pc; float * px; int ** ppi; ●



ppi points to a location which in turn points to an int data

Pointer Manipulation ●





The value pointed to by a pointer can be retrieved, or dereferenced, by using the unary operator * The dereferenced value of a pointer can be used in normal operations Arrays use consecutive blocks of memory to store data –

Name of the array (without any index) is the address of the beginning of the block

int k = 9,* pk = NULL, j = 3; //Assign address of k to pointer pk = &k; // Modify contents via pointer *pk = 10; /* Dereferenced pointer values can be used in expressions */ (*pk) -= j;

float score[100]; /* Name of the array is an address */ float * pscore = score; /* Array elements can be accessed via pointer */ *(pscore + 5) = 78.5; // 78.5 stored in score[5]

Pointer Arithmetic ●

Pointers should preferably initialized to NULL – – –



Pointer arithmetic can be used to adjust where a pointer points – –



NULL is a constant defined in cstdlib Will cause an error if it is used in any operation Important because an inadvertent wrong use of pointer can be potentially disastrous

pscore points to the first element of array score (pscore + 5) then points to the sixth element score[5]

Increment/decrement of a pointer advances/ retracts the position by sizeof(type) where type is the type of data to which it points.

Pointers and the Data Pointed to - 1 ●

The pointers can be combined with const qualifier in four different ways –

Nonconstant pointer to nonconstant data ●



Highest access is granted: the data can be modified through the dereferenced pointer and the pointer can be modified to point to other data, e.g., float *fPtr = NULL;

Nonconstant pointer to constant data ●

Pointer can be modified to point to any data but the data pointed to cannot be modified as it is treated as a constant object, e.g., const float *fPtr = NULL;

Pointers and the Data Pointed to - 2 –

Constant pointer to nonconstant data ●



A constant pointer points to the same memory location, the data at that location can be modified through the pointer, e.g., float * const fPtr = &z;

Constant pointer to constant data ●

Least access is granted. Neither pointer nor the data it points to can be modified, e.g., const float * const fPtr = &z;

Pointers: Example Codes // Nonconstant pointer to nonconstant data float light_speed = 0.0; /* declare a float and initialize it to 0 */ float * lsPtr = NULL; /* Pointer to float initialized to NULL */ lsPtr = & light_speed; /* assign address of the float to the pointer */ *lsPtr = 3.0e10; /* Assign value to float via pointer */

//Constant pointer to nonconstant data float A[100] = {0.0}; /* declare a float array and initialize to 0 */ float * const Aptr = A; /* Assign the address of beginning of array to a constant pointer */

// Nonconstant pointer to constant data float compute_int(float *fPtr, float principal, float duration); const float savings_rate(0.05); const float current_rate(0.02); float * ratePtr = NULL; ratePtr = &savings_rate; cout << compute_int(ratePtr,x,t); ratePtr = ¤t_rate; // Constant pointer to constant data const float CON(0.03); const float * const ratePtr=&CON;

Function Pointers ●

Every function has its dedicated working area –

A pointer can be defined to point to the beginning of this block ●



Allows to pass functions as arguments to other functions! In the example, minus is a pointer to a function that takes two int arguments and is immediately assigned to point to function subtraction

#include using namespace std; int addition (int x, int y) { return (x + y); } int subtraction (int x, int y) { return (x – y); } int operation (int x, int y, int (*functocall)(int, int)){ int g; g = (*functocall)(x, y); return (g); } int main(){ int x(0), y(0); int (*minus)(int, int) = subtraction; x = operation (10, 5, addition); y = operation (9, x, minus); cout << y << endl; return 0; }

Dynamic Memory Allocation - 1 ●

Facilitate allocation of memory at run-time according to the needs of the problem Operators new and new[] allocate requisite amount of memory according to the data type requested and return a pointer to the beginning of the allocated memory pointer1 = new type; pointer2 = new type [Num_Of_Elem]; – Dynamically allocated memory can be freed (released to the Operating System) by operators delete and delete[] delete pointer1; delete[] pointer2; –

Dynamic Memory Allocation - 2 ●



Two dimensional arrays can be created “on the fly” by using dynamic allocation using an array of pointers to pointer of the required data type NULL pointer is returned if allocation fails and exceptions are not thrown

float ** ppf == NULL; ppf = new (nothrow) float * [row]; if (ppf == NULL) { cout << “Allocation failed!”; exit 1; } for (int i = 0; i
Aggregate Data Types - 1 ●

C++ allows the users to combine standard built-in data types to create new userdefined data types also known as aggregate data types, or ADTs – –

The ADTs may also contain other ADTs Primary mechanism of creating ADTs is through struct

int nstud(0); const int NLEN(100); struct student_data{ unsigned long enrol; char Name[NLEN]; float score; }; // End struct student_data student_data * ec101a = NULL; cout << “Enter number of students in ec101a: ”; cin >> nstud; ec101a = new student_data [nstud]; // Create an array of structs to store data for (int i = 0; i> ec101a[i].enrol; cin.getline(ec101a[i].Name,\ NLEN,':'); cin >> ec101a[i].score; }

Aggregate Data Types - 2 ●

Keyword struct introduces the structure definition –





The identifier student_data is the structure tag that is used as the name of user defined data type The names declared in the braces of structure definition are members Each structure definition must end with a semicolon



Structure members are accessed by member access operators –





(.) dot operator access members by name of object, or by dereferenced object pointer (->) arrow operator access members via object pointers Structures can have a pointer to an object of the same type as a member but not object

Other Data Types ●





C++ allows users to define synonyms for existing data types by using typedef, e.g., typedef unsigned long WORD; The new typename WORD can be used subsequently to declare new identifiers Enumerations (enum) create a new data type not based on any of the base types enum months_t{january=1, february, march, april, may, june, july, august, september, october, november, december} month_of_year;

Data Structures in C++ ●

The amount of data to be processed may shrink or expand –



Arrays are not very efficient at managing this aspect of data management (resizing arrays requires mass movement of data) Special data structures needed for the purpose ●

Use self referential structures for – – –

● ●

Linear lists (singly linked and doubly linked) Trees (nodes with branches) Hash tables (a versatile data structure combining arrays and lists)

Storage allocated at the runtime The allocated storage need not be a contiguous stretch! –

A great advantage over arrays.

Linked Lists-1 ●

● ● ●



A singly linked list is a set of items, each with data and a pointer to the next item The head of the list is a pointer to the first item End of list is marked by a NULL pointer Lists can be easily rearranged by exchanging a few pointers Fundamental list operations: – – – –

Add a new item to the front, or back Find a specific item Add a new item before a specific item Delete a specific item

Linked Lists-2 ●

A doubly linked list element has two pointers –



Head pointer points to the previous object in the link Tail pointer points to the next object

Trees ●



Tree is a hierarchical data structure that stores a set of items in which each item has a value, may point to zero, or more others, and is pointed to by exactly one other. The root of the tree is the sole exception – no item points to it.

Hash Tables NULL

● ●



A hash table is an array of lists A “hash value” is used to index a table where the information is stored Each list corresponds to a chain of items sharing a hash value

Object Oriented Programming ●

Classes as generalization of structures – – – – –

Provide a method of logical grouping Groupings are of both data and functionality Data members are objects (variables, literal data values, etc.) Member functions provide the methods (actions, or operations) for manipulating data Details can be hidden from the programmer – information hiding! ●



Facilitates easy maintenance of program modules

Objects are instances of classes ●

Basic building blocks of a complete solution

Classes-1 ●

Classes are declared using the keyword class and has the following generic form: class Class_name { access_specifier01: member01; member02; access_specifier02: member03; member04; } obj01, obj02;

Classes-2 ●

The declaration is very similar to that for a structure except –

– ●

members can be data as well as functions operating on member data (actually in C++ structures can also have member functions) the access_specifiers can be either of public, private, and protected

These specifiers modify the member access rights – – –

private members are accessible only from within other members of the same class, or from friends protected members are accessible from within other members of the same class, friends, and derived classes public members are freely accessible

Classes-3 ●

When an object of a class is created, C++ calls the constructor for that class –



If no constructor is defined, C++ invokes a default constructor, which allocates memory for the object, but doesn't initialize it. Defining constructors is good programming practice ● ●



Uninitialized member fields have garbage value in them A possible source of illegal statements and bugs

A constructor is similar to a function but with following differences: ● ● ●

Has the same name as that of the class No return type No return statement

Class Constructors-1 ●

The constructor is responsible for turning the raw memory allotted to an object into a usable object. –

Default constructor is a constructor that takes no arguments ●





A constructor that takes all default arguments is also a default constructor as it can be called without any parameter Data members should be initialized using initializer rather than by assignment to reduce overheads

Copy constructor is a special constructor that can be called to copy an object, e.g., for class X X::X(const X&) ●

The copy constructor is called more often behind the scenes whenever the compiler needs a copy of an object, e.g., during a function call, so that the semantics of pass-by-value can be preserved.

Class Constructors-2 ●

Providing a copy constructor in a class definition is important if the class data contains pointers –





Default copy constructor generated by C++ compiler generates a copy of the object by member-wise assignment, known as shallow copying. User defined copy constructors facilitate deep copying which copy the contents pointed to by the pointer variables instead of just copying the address pointed to. Eliminates the possibility of two pointer data members of two different objects pointing to same memory address. ● ●

Important issue if one of the two objects is destroyed earlier! Fail-safe handling of dynamic memory allocation.

const Member Functions ●









Member functions should be declared with the const keyword after them if they are to operate on a const (this) object. If the function is not declared const, it cannot be applied to a const object A const function can be applied to non-const objects A function can only be declared const if it doesn't modify any of its fields. The const keyword is placed after the function header before the left brace in both the prototype and the definition.

The this Pointer ●





Every object has access to its own address through a pointer called this Objects use this pointer implicitly, or explicitly to reference their data members and member functions The type of this pointer depends on the type of the object and whether the member function in which this is used is declared const –

For example, in a nonconstant member function of class Complex, the this pointer has type Complex * const. In a constant member function it is of type const Complex * const

The Complex Class ●



Data members of the object can be assigned values by using member functions Or the arguments specified at the time of declaring objects can be used to initialize data members by using initializer syntax

class Complex{ public: Complex(float=0.0,float=0.0); ~Complex(); void printVal(); const Complex operator+(const Complex & op); friend istream & operator>> (istream & input, Complex & op); private: float re; float im; }; // End of class definition Complex::Complex(float x, float y) : re(x), im(y) {// Empty body of constructor } void Complex::printVal(){ std::cout<< “Real part = “ << re; std::cout<< “Imag part = “ << im; return; }

Operator Overloading-1 ●



Defining an overloaded operator is like defining a function, but the name of that function is operator@, where @ represents the operator that is being overloaded The number of arguments in the overloaded operator's argument list depends on two factors: – –



Whether it is a unary operator (one argument), or a binary operator (two arguments) Whether the operator is defined as a global friend function (one argument for unary, two for binary) or a member function (zero arguments for unary, one for binary – the object becomes the left-hand argument). Ternary operator can not be overloaded.

Operator Overloading-2 ●





Overloading should not change the natural meaning of operators being overloaded. The evaluation precedence of the operators can not be changed by overloading In the following example, the return type of the function is declared to be const Complex to ensure that returned value is accessed only by const member functions

Overloading + Operator ●



In the example code, we have made operator+ a member function of Complex class An expression of the form c = a + b; is replaced by a method call as

c=a.operator+(b);

const Complex Complex::operator+(\ const Complex & op) { float real= this->re + op.re; float imag= this->im + op.im; return (Complex(real,imag)); } const Complex Complex::operator*(\ const Complex & op) { float x=(abs(re)>abs(im))?re:im; float y=(abs(op.re)>abs(op.im))? op.re:op.im; float z = (abs(x) > abs(y))?x:y; float real = z*((re/z)*op.re – (im/z)*op.im); float imag = z*(re*(op.im/z) + im*(op.re/z)); return (Complex(real,imag)); }

Overloading Assignment Operator ●





The const return avoids (c1 = c2) = c3; The overloaded assignment operator should always guard against the possibility of self-assignment Returning object reference through this pointer enables c1 = c2 = c3;

const Complex & Complex::operator= (const Complex & right){ if (this == &right){ std::cout<< “Error! Object cannot be copied onto itself”; exit 1; } re = right.re; im = right.im; return (*this); } // Overloaded friend function for // stream insertion istream & operator>> (istream & input, Complex & op){ input >> op.re >> op.im; return input; // enables input >> z1 >> z2; }

Friend Functions and Classes ●

Friend functions are those declared with a friend prefix in class definition These are not member functions of the class but still have the privilege of accessing data in private, or protected section – Defined outside the class scope – To declare all functions of ClassTwo as friends of ClassOne, the appropriate declaration of the type friend class ClassTwo in the definition of class ClassOne –



Friendship between classes is not transitive – it should be explicitly granted

Static Class Members ●



Sometimes, it is required to have a copy of a variable shared by all objects of a class A static class variable is used for this purpose –



Represents class-wide information and is declared with the keyword static

The static data members have class scope –



Each static data member must be initialized once (and only once) at the file scope and is accessed by the variable name prefixed by scope resolution operator and class name as Complex::count = 0; The static public member functions are provided in class definition to access static data even if no objects of that class exist

Composition and Inheritance ●





New classes can be created from existing classes by adding more data and functionality Basic idea of object oriented programming – code reuse! Two ways of using and extending existing classes – –

Composition: New class is defined which contains objects of existing class as data member Inheritance: New class (known as the derived class) is derived from existing class such that the new class inherits all data and methods of the existing class (known as the base class)

Inheritance-1 ●

When a new class is derived from a base class, all member data and functions of the base class are inherited by the derived class except the following – – –



Constructor(s) and destructor are not inherited The assignment operator is not inherited Friend functions and friend classes of the base class are not inherited

In order to derive a class from another, we use a colon (:) in the declaration of the derived class using the following format: class NewClass : public BaseClass { ... };

Inheritance-2 ●

Public and protected members of base class are accessible by the methods of derived class –



Private members of the base class can be accessed by member functions of the base class only

Pointers to the objects of derived class are type compatible with the pointer to objects of base class –



This concept can be utilized to enhance the functionality of the derived class without affecting the base class The concept of polymorphism!

Polymorphism and Virtual Functions ●

A member of a class that can be redefined in its derived classes is known as a virtual member – –



In order to declare a member of a class as virtual, we must precede its declaration with the keyword virtual The virtual keyword allows a member of a derived class with the same name as one in the base class to be appropriately called from a pointer, and more precisely when the type of the pointer is a pointer to the base class but is pointing to an object of the derived class

A class that declares or inherits a virtual function is called a polymorphic class.

Principles of OOP-1 ●

Liskov Substitution Principle –



Open Closed Principle –



An instance of a derived class should be able to replace any instance of its superclass. A reusable class should be open for extension, but closed for modification.

Dependency Inversion Principle –

The module that implements a high level policy should not depend on the modules that implement the low level policies, but rather, they should depend on some well-defined interfaces.

Principles of OOP-2 ●

Interface Segregation Principle –



Reuse Release Equivalence Principle –



The granule of reuse is the granule of release.

Common Closer Principle –



The dependency of one class to another one should depend on the smallest possible interface.

The classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all classes in that package.

Common Reuse Principle –

The classes in a package are reused together

Principles of OOP-3 ●

Acyclic Dependencies Principle –



Stable Dependencies Principle –



Architectures must be crafted using a set of stable dependencies.

Stable Abstractions Principle –



The dependency structure between packages must not contain cyclic dependencies.

An architecture should contain as many stable abstractions as possible, and these abstractions should be isolated from the ones that are more likely to change

Information Hiding Principle –

If code chunk A doesn't need to know how code chunk B (which it calls) does its job, don't make it know it.

EC-101A Computer Systems and Programming

A finite set! Overflow errors possible in arithmetic! – How to represent negative integers as well? ○ Sign and magnitude form. – MSB is considered as the sign bit and rest are interpreted as unsigned integers: (-1)^{MSB} * Magnitude. – Two possible representations for 0: +/- 0. ○ Biased representation. – Shift of origin.

481KB Sizes 4 Downloads 87 Views

Recommend Documents

systems programming and operating systems
Think os a brief. introduction to operating systems free. ... Browser homepage be,mca notes question papers resus online fm. ... programming course by anthony joseph. ... Types of computer programmers codestart blog. ... dhamdhere pdf free.

EC101A Principles of Macroeconomics
... Registration office prior to the withdrawal deadline date. .... Faculty members are encouraged to make this definition clear to their students. ... academic dishonesty is considered to be an equivalent breach of academic integrity and is treated.

COMPUTER PROGRAMMING AND PROBLEM SOLVING.pdf
COMPUTER PROGRAMMING AND PROBLEM SOLVING.pdf. COMPUTER PROGRAMMING AND PROBLEM SOLVING.pdf. Open. Extract. Open with. Sign In.

Concepts, Techniques, and Models of Computer Programming
Jun 5, 2003 - 2.1 Defining practical programming languages . . . . . . . . . . . . . 33 .... 3 Declarative Programming Techniques. 113 ... 3.7.3 A word frequency application . ...... an Apple Macintosh PowerBook G4 with Mac OS X and X11. The first ..

Concepts, Techniques, and Models of Computer Programming
Jun 5, 2003 - One approach to study computer programming is to study .... based on Java, but the problem exists in all existing languages to some degree.

fundamentals of computer programming and information technology ...
fundamentals of computer programming and information technology pdf. fundamentals of computer programming and information technology pdf. Open. Extract.

111208-110003-Computer Programming and Utilization.pdf ...
Page 1 of 2. Stand 02/ 2000 MULTITESTER I Seite 1. RANGE MAX/MIN VoltSensor HOLD. MM 1-3. V. V. OFF. Hz A. A. °C. °F. Hz. A. MAX. 10A. FUSED. AUTO HOLD. MAX. MIN. nmF. D Bedienungsanleitung. Operating manual. F Notice d'emploi. E Instrucciones de s

Computer Programming and Problem Solving.pdf
Whoops! There was a problem loading this page. Computer Programming and Problem Solving.pdf. Computer Programming and Problem Solving.pdf. Open.

COMPUtER PROGRAMMiNG
Good salaries. Good growth. If there is an app for something, there is computer programmer behind it.. Modern life is sup- ported by computer programs.. In 2009 the median salary was. $90,000 a year. Current growth is projected at over 30% per year t

CS162 Operating Systems and Systems Programming Lecture 1 What ...
Jan 21, 2015 - Networking, distributed systems ... Systems, services, protocols, … ..... http://asuc.org/honorcode/resources/HC%20Guide%20for%20Syllabi.pdf.

Return-Oriented Programming: Systems, Languages, and Applications
systems, has negative implications for an entire class of security mechanisms: those that seek to prevent malicious ... understood that W⊕X is not foolproof [Solar Designer 1997; Krahmer 2005; McDonald. 1999], it was thought to be a ..... The remai

Expert-Systems-Principles-And-Programming-Fourth-Edition.pdf ...
Our web service was launched using a wish to function as a. comprehensive online digital collection which offers entry to many PDF file e-book assortment. You may find many kinds of. e-publication and also other literatures from our files data base.