C Programming
Topics
Introduction, Fundamentals of C Programming
Introduction to components of a Computer System.
Introduction to structure programming approach,
Introduction to Algorithm and Flowchart
Keywords, Identifiers, Constants and Variables
Data types in C, Operators in C
Basic Input and Output Operations
Expressions and Precedence of Operators
In-built Functions, Pre-processor Directives,library, Header Files
Program Documentation
• Insert comments in the program to make it
easy to understand.
• Put a comment for each function.
• Put comments for the important variables.
• Do not give too many comments.
Program indentation
• Use proper indentation.
• C has standard indentation conventions.
– Followed by any book on C
– Followed in the class
Identifiers
• Identifiers
– Names given to various program elements
(variables, constants, functions, etc.)
– May consist of letters, digits and the underscore
(‘_’) character, with no space in between.
– First character must be a letter.
– An identifier can be arbitrary long.
• Some C compilers recognize only the first few
characters of the name (16 or 31).
– Case sensitive
• ‘area’, ‘AREA’ and ‘Area’ are all different
– Examples : number, simple_interest, List
– Non-examples :1stnum, simple interest,
no-of-students
Keywords
– Reserved words that have standard, predefined
meanings in C.
– Cannot be used as identifiers.
– OK within comments.
– Standard C keywords:
auto break case char const continue default do
double elseelse enum extern float for goto if
int long register return short signed sizeof static
struct switch typedef union unsigned void volatile while
Data Types in C
Data types refer to an extensive system used for declaring
variables or functions of different types before its use. The
type of a variable determines how much space it occupies in
storage and how the bit pattern stored is interpreted. The
value of a variable can be changed any time.
C has the following 4 types of data types
basic built-in data types: int, float, double, char
Enumeration data type: enum
Derived data type: pointer, array, structure, union
Void data type: void
Data Types in C
• int : signed integer, typically 2 / 4 bytes
int numberOfStudents ;
• char: character, typically 1 byte
char lock; char key = ‘Q’ ;
• float: floating point number (4 bytes)
float averageTemp ;
• double: double precision floating point (8 bytes)
double electrondPerSecond ;
Integer Data Type
The integer datatype in C is used to store the integer numbers (any number including
positive, negative and zero without decimal part). Octal values, hexadecimal values, and
decimal values can be stored in int data type in C.
Range: -2,147,483,648 to 2,147,483,647
Size: 4 bytes
Format Specifier: %d
Syntax of Integer
We use int keyword to declare the integer variable:
int var_name;
The integer data type can also be used as
unsigned int: Unsigned int data type in C is used to store the data values from zero to
positive numbers but it can’t store negative values like signed int.
short int: It is lesser in size than the int by 2 bytes so can only store values from -32,768 to
32,767.
long int: Larger version of the int datatype so can store values greater than int.
unsigned short int: Similar in relationship with short int as unsigned int with int.
The integer data type can also be used as
unsigned int: Unsigned int data type in C is used to store the data values from zero to positive numbers but
it can’t store negative values like signed int.
short int: It is lesser in size than the int by 2 bytes so can only store values from -32,768 to 32,767.
long int: Larger version of the int datatype so can store values greater than int.
unsigned short int: Similar in relationship with short int as unsigned int with int.
#include <stdio.h>
int main()
{
// Integer value with positive data.
int a = 9;
// integer value with negative data.
int b = -9;
// U or u is Used for Unsigned int in C.
int c = 89U;
// L or l is used for long int in C.
long int d = 99998L;
printf("Integer value with positive data: %d\n", a);
printf("Integer value with negative data: %d\n", b);
printf("Integer value with an unsigned int data: %u\n",c);
printf("Integer value with an long int data: %ld", d);
return 0;
}
Output
Integer value with positive data: 9
Integer value with negative data: -9
Integer value with an unsigned int data: 89
Integer value with an long int data: 99998
Character Data Type
Character data type allows its variable to store only a single character. The
size of the character is 1 byte. It is the most basic data type in C. It stores a
single character and requires a single byte of memory in almost all
compilers.
Range: (-128 to 127) or (0 to 255)
Size: 1 byte
Format Specifier: %c
Syntax of char
The char keyword is used to declare the variable of character type:
char var_name;
#include <stdio.h>
int main()
{
char a = 'a';
char c;
printf("Value of a: %c\n", a);
a++;
printf("Value of a after increment is: %c\n", a);
// c is assigned ASCII values
// which corresponds to the
// character 'c'
// a-->97 b-->98 c-->99
// here c will be printed
c = 99;
printf("Value of c: %c", c);
return 0;
}
Output
Value of a: a
Value of a after increment is: b
Value of c: c
Float Data Type
In C programming float data type is used to store floating-point values. Float in C
is used to store decimal and exponential values. It is used to store decimal numbers
(numbers with floating point values) with single precision.
Range: 1.2E-38 to 3.4E+38
Size: 4 bytes
Format Specifier: %f
Syntax of float
The float keyword is used to declare the variable as a floating point:
float var_name;
// C Program to demonstrate use
// of Floating types
#include <stdio.h>
int main()
{
float a = 9.0f;
float b = 2.5f;
// 2x10^-4
float c = 2E-4f;
printf("%f\n", a);
printf("%f\n", b);
printf("%f", c);
return 0;
}
Output
9.000000
2.500000
0.000200
Double Data Type
A Double data type in C is used to store decimal numbers (numbers with floating
point values) with double precision. It is used to define numeric values which hold
numbers with decimal values in C.
The double data type is basically a precision sort of data type that is capable of
holding 64 bits of decimal numbers or floating points. Since double has more
precision as compared to that float then it is much more obvious that it occupies
twice the memory occupied by the floating-point type. It can easily accommodate
about 16 to 17 digits after or before a decimal point.
Range: 1.7E-308 to 1.7E+308
Size: 8 bytes
Format Specifier: %lf
Syntax of Double
The variable can be declared as double precision floating point using the double
keyword:
double var_name;
/ C Program to demonstrate
// use of double data type
#include <stdio.h>
int main()
{
double a = 123123123.00;
double b = 12.293123;
double c = 2312312312.123123;
printf("%lf\n", a);
printf("%lf\n", b);
printf("%lf", c);
return 0;
}
Output
123123123.000000
12.293123
2312312312.123123
Void Data Type
The void data type in C is used to specify that no value is present. It does not provide a result value to its
caller. It has no values and no operations. It is used to represent nothing. Void is used in multiple ways as
function return type, function arguments as void, and pointers to void.
Syntax:
// function return type void
void exit(int check);
// Function without any parameter can accept void.
int print(void);
// memory allocation function which
// returns a pointer to void.
void *malloc (size_t size);
Example of Void
// C program to demonstrate
// use of void pointers
#include <stdio.h>
int main()
{
int val = 30;
void* ptr = &val;
printf("%d", *(int*)ptr);
return 0;
}
Output
30
Size (bytes) Range Format Specifier
Data Type
short int 2 -32,768 to 32,767 %hd
unsigned short int 2 0 to 65,535 %hu
unsigned int 4 0 to 4,294,967,295 %u
int 4 -2,147,483,648 to 2,147,483,647 %d
long int 4 -2,147,483,648 to 2,147,483,647 %ld
unsigned long int 4 0 to 4,294,967,295 %lu
long long int 8 -(2^63) to (2^63)-1 %lld
unsigned long long int 8 0 to 18,446,744,073,709,551,615 %llu
signed char 1 -128 to 127 %c
unsigned char 1 0 to 255 %c
float 4 1.2E-38 to 3.4E+38 %f
double 8 1.7E-308 to 1.7E+308 %lf
long double 16 3.4E-4932 to 1.1E+4932 %Lf
Operators
• Arithmetic Operators
– % is a modulus operator. x % y results in the remainder
when x is divided by y and is zero when x is divisible
by y.
– Cannot be applied to float or double variables.
– Example
if ( num % 2 == 0 )
printf(“%d is an even number\n”,
num)’;
else
printf(“%d is an odd number\n”,
num);
22
Type Conversions
– The operands of a binary operator must have a the same type and
the result is also of the same type.
– Integer division:
c = (9 / 5)*(f - 32)
The operands of the division are both int and hence the result also
would be int. For correct results, one may write
c = (9.0 / 5.0)*(f - 32)
– In case the two operands of a binary operator are different, but
compatible, then they are converted to the same type by the
compiler. The mechanism (set of rules) is called Automatic Type
Casting.
c = (9.0 / 5)*(f - 32)
– It is possible to force a conversion of an operand. This is called
Explicit Type casting.
c = ((float) 9 / 5)*(f - 32)
23
Automatic Type Casting
1. char and short operands are converted to int
Hierarchy
2. Lower data types are converted to the higher
Double
data types and result is of higher type.
float
3. The conversions between unsigned and long
signed types may not yield intuitive results.
Int
4. Example Short and
float f; double d; long l; char
int i; short s;
d + f f will be converted to double
i / s s will be converted to int
l / i i is converted to long; long
result
24
Explicit Type Casting
– The general form of a type casting operator is
– (type-name) expression
– It is generally a good practice to use explicit casts than to
rely on automatic type conversions.
– Example
C = (float)9 / 5 * ( f – 32 )
– float to int conversion causes truncation of fractional
part
– double to float conversion causes rounding of digits
– long int to int causes dropping of the higher order
bits.
25
Constants
• integer constants:
– 0, 1, 648, 9999
• floating point constants:
– 0.2, 12.3, 1.67E+8, 1.12E-12
• character constants:
– ‘C’, ‘x’, ‘ ‘,
• string constants:
– “Welcome aboard”, “Rs. 89.95”, “Bye \n”
Ascii value
Character
000 NUL
032 blank
036 $ Escape Sequences: Certain
038 &
non-
043 +
048 0 printing characters can be ex-
049 1 pressed in terms of escape
057 9 sequences:
065 A ‘\n’ : new line
066 B ‘\t’ : horizontal tab
090 Z ‘\v’ : vertical tab
097 a
‘\\’ : backslash
098 b
122 z
‘\”’ : double quote
‘\0’ : null
Variables
• It is an identifier
– used to represent a specified type of information
– within a designated portion of the program
• The data item must be assigned to the variable at some
point of the program
• It can be accessed later by referring to the variable name
• A given variable can be assigned different data items at
different places within the program.
int a, b, c ; a b c d
char d; ? ? ? ?
a = 3; 3 ? ? ?
b = 5; 3 5 ? ?
c = a+b; 3 5 8 ?
3 5 8 97
d = ‘a’ ;
a = 4; 4 5 8 97
b = 2; 4 2 8 97
c = a-b; 4 2 2 97
d = ‘D’ ; 4 2 2 68
Declaration of Variables
data-type variable-list ;
Declaration :
int a, b, c; 1. specifies the name of
float root1, root2; the variable
2. Specifies what type of
char flag, response; data the variable will
hold.
A First Look at Pointers
• A variable is assigned a specific memory location.
– For example, a variable speed is assigned memory location
1350.
– Also assume that the memory location contains the data value
100.
– When we use the name speed in an expression, it refers to the
value 100 stored in the memory location.
distance = speed * time;
• Thus every variable has an address (in memory), and its
contents.
Contd.
• In C terminology, in an expression
– speed refers to the contents of the memory location.
– &speed refers to the address of the memory location.
• Examples:
– printf (“%f %f %f”, speed, time, distance);
– scanf (“%f %f”, &speed, &time);
An Example
#include <stdio.h>
main()
{
float speed, time, distance;
scanf (“%f %f”, &speed, &time);
distance = speed * time;
printf (“\n The distance traversed is: \n”,distance);
}
Assignment Statement
• Used to assign values to variables, using the assignment
operator (=).
• General syntax:
variable_name = expression;
• Examples:
– velocity = 20;
– b = 15; temp = 12.5; /* Multiple assign on same line */
– A = A + 10;
– v = u + f * t;
– s = u * t + 0.5 * f * t * t;
Contd.
• A value can be assigned to a variable at the time
the variable is declared.
– int speed = 30;
– char flag = ‘y’;
• Several variables can be assigned the same value
using multiple assignment operators.
– a = b = c = 5;
– flag1 = flag2 = ‘y’;
– speed = flow = 0.0;
Assignment Statement
• Used to assign values to variables, using the assignment
operator (=).
• General syntax:
variable_name = expression;
• Examples:
– velocity = 20.5;
– b = 15; temp = 12; /* Multiple assign on same line*/
– A = A + 10;
– v = u + f * t;
– s = u * t + 0.5 * f * t * t;
Operators in Expressions
Operators
Arithmetic Relational Logical
Operators Operators Operators
Operator Precedence
• In decreasing order of priority
1. Parentheses :: ( )
2. Unary minus :: -5
3. Multiplication, Division, and Modulus
4. Addition and Subtraction
• For operators of the same priority, evaluation is
from left to right as they appear.
• Parenthesis may be used to change the
precedence of operator evaluation.
Examples: Arithmetic expressions
• a+b*c–d/e a + (b * c) – (d / e)
• a * -b + d % e – f a * (-b) + (d % e) – f
• a–b+c+d (((a – b) + c) + d)
• x*y*z ((x * y) * z)
• a+b+c*d*e (a + b) + ((c * d) * e)
Integer Arithmetic
• When the operands in an arithmetic
expression are integers, the expression is
called integer expression, and the operation
is called integer arithmetic.
• Integer arithmetic always yields integer
values.
Real Arithmetic
• Arithmetic operations involving only real or
floating-point operands.
• Since floating-point values are rounded to the
number of significant digits permissible, the final
value is an approximation of the final result.
– 1.0 / 3.0 * 3.0 will have the value 0.99999 and not
1.0
• The modulus operator cannot be used with real
operands.
Mixed-mode Arithmetic
• When one of the operands is integer and the other
is real, the expression is called a mixed-mode
arithmetic expression.
• If either operand is of the real type, then only real
arithmetic is performed, and the result is a real
number.
– 25 / 10 2
– 25 / 10.0 2.5
• Some more issues will be considered later.
Relational Operators
• Used to compare two quantities.
< is less than
> is greater than
<= is less than or equal to
>= is greater than or equal to
== is equal to
!= is not equal to
Examples
• 10 > 20 is false
• 25 < 35.5 is true
• 12 > (7 + 5) is false
• When arithmetic expressions are used on either
side of a relational operator, the arithmetic
expressions will be evaluated first and then the
results compared.
– a + b > c – d is the same as (a+b) > (c+d)
Logical Operators
• Logical operators act upon logical
expressions
– && : and (true if both operands are true)
– || : or (true if either or both operands true
– ! : negates the value of the logical expression
• Example
– (n >= lo_bound) && (n <= upper_bound)
– ! (num > 100)
Example: Logical Operators
int main () {
int i, j;
for (i=0; i<2; i++) {
for (j=0; j<2; j++)
printf (“%d AND %d = %d,
%d OR %d=%d\n”,
i,j,i&&j, i,j, i||j) ;
}
}
$ ./a.out
0 AND 0 = 0 0 OR 0 = 0
0 AND 1 = 0 0 OR 1 = 1
1 AND 0 = 0 1 OR 0 = 1
1 AND 1 = 1 1 OR 1 = 1
$
int main () {
int amount ; /* The no of bytes to be transferred */
int rate ; /* The average network transfer rate */
int time; /* The time, in seconds, for the transfer */
int hours, minutes, seconds; /* The no of hrs,mins,secs for the
transfer*/
printf (“How many bytes of data to be transferred ?\n”) ;
scanf (“%d”, &amount) ;
printf (“What is the average transfer rate in bytes/sec ?\n”) ;
scanf (“%d”, &rate) ;
time = amount / rate ;
hours = time / 3600 ;
minutes = (time % 3600) / 60 ;
seconds = ((time % 3600) % 60) /60 ;
printf (“The expected time is %dh %dm %ds\n”,
hours,minutes,seconds);
}
C’s special operators
• ++ and -- : a trademark of C programming
• ++ : increments a variable ;
• -- : decrements a variable
• x++
– In an expression, value of this expression is the
value of x prior to increment
• ++x
– In an expression, value of this expression is the
value of x after the increment.
x = 4; x = 4;
y = x++; y = ++x ;
y=4, x=5 after y=5, x=5 after evaluation
evaluation
x += 5 equivalent to x=x+5
h %= f equivalent to h = h%f
product *= num equivalent to product = product *
num
void main ()
{
int x = 10;
printf (“ x = %d\n”, ++x) ;
printf (“x = %d\n”, x++) ;
}
Question : What will get printed ?
Variables, Constants, Memory
Variables and constants
• All temporary variables are stored in
variables and constants.
– The value of a variable can be changed.
– The value of a constant does not change.
• Variables and constants are stored in main
memory.
Memory
• How does memory look like ?
– A list of storage locations, each having a unique
address
– Variables and constants are stored in these
storage locations.
– A variable is like a house. The name of the
variable is the address of the house.
Address and Values
Memory Map
0000
Every variable is 0001
mapped to a
particular 8000
memory address 8001
8002 32
C
Variables in Memory
Instruction executed Memory location allocated
to a variable X
X = 10
T
i X = 20 10
m
e X = X +1
X = X*5
Variables in Memory
Memory location allocated
Instruction executed to a variable X
X = 10
T
i X = 20 20
m
e X = X +1
X = X*5
Variables in Memory
Memory location allocated
Instruction executed to a variable X
X = 10
T
i X = 20 21
m
e X = X +1
X = X*5
Variables in Memory
Memory location allocated
Instruction executed to a variable X
X = 10
T
i X = 20 105
m
e X = X +1
X = X*5
Variables (contd.)
X = 20
20 X
Y=15
X = Y+3 ? Y
Y=x/6
Variables (contd.)
X = 20
20 X
Y=15
X = Y+3 15 Y
Y=x/6
Variables (contd.)
X = 20
18 X
Y=15
X = Y+3 15 Y
Y=x/6
Variables (contd.)
X = 20
18 X
Y=15
X = Y+3 3 Y
Y=X/6
The C Programming Language
Why learn C ?
• "Least common denominator" - good building
block for learning other languages
– Subset of C++
– Similar to JAVA
• Closeness to machine allows one to learn about
system-level details
• Portable - compilers available for most platforms
• Very fast
/* Program Name : countdown
Description : This program prompts the user to type
in a positive number and counts down from that
number to 0, displaying each number */
#include <stdio.h>
#define STOP 0
main ()
{
int counter ; /* Holds intermediate count value */
int startPoint ; /* Starting point for countdown */
/* Prompt the user for input */
printf ("Enter a positive number : ") ;
scanf ("%d", &startPoint) ;
for (counter=startPoint; counter
>=STOP;counter--)
printf ("%d\n", counter) ;
}
$ cc t1.c
$ ./a.out
Enter a positive number : 6
6
5
4
3
2
1
0
$
Sections of the C Program
There are 6 basic sections responsible for the proper execution of a program. Sections are mentioned
below:
Documentation
Preprocessor Section
Definition
Global Declaration
Main() Function
Sub Programs
1. Documentation
This section consists of the description of the program, the name of the program, and the creation date and
time of the program. It is specified at the start of the program in the form of comments. Documentation
can be represented as:
// description, name of the program, programmer name, date, time etc.
or
/*
description, name of the program, programmer name, date, time etc.
*/
2. Preprocessor Section
All the header files of the program will be declared in the preprocessor section of the
program. Header files help us to access other’s improved code into our code. A copy of these
multiple files is inserted into our program before the process of compilation.
Example:
#include<stdio.h>
#include<math.h>
3. Definition
Preprocessors are the programs that process our source code before the process of
compilation. There are multiple steps which are involved in the writing and execution of the
program. Preprocessor directives start with the ‘#’ symbol. The #define preprocessor is used
to create a constant throughout the program. Whenever this name is encountered by the
compiler, it is replaced by the actual piece of defined code.
Example:
#define long long ll
4. Global Declaration
The global declaration section contains global variables, function declaration, and static
variables. Variables and functions which are declared in this scope can be used anywhere in
the program.
Example:
int num = 18;
5. Main() Function
Every C program must have a main function. The main() function of the program is written
in this section. Operations like declaration and execution are performed inside the curly
braces of the main program. The return type of the main() function can be int as well as void
too. void() main tells the compiler that the program will not return any value. The int main()
tells the compiler that the program will return an integer value.
Example:
void main()
or
int main()
6. Sub Programs
User-defined functions are called in this section of the program. The control of the program
is shifted to the called function whenever they are called from the main or outside the main()
function. These are specified as per the requirements of the programmer.
Example:
int sum(int x, int y)
{
return x+y;
}
Example
// Documentation
/ * file: sum.c
* description: program to find sum.
*/
// Link
#include <stdio.h>
// Definition
#define X 20
// Global Declaration
int sum(int y);
// Main() Function
int main(void)
{
int y = 55;
printf("Sum: %d", sum(y));
return 0;
}
// Subprogram
int sum(int y)
{
return y + X;
}
The first C program
#include <stdio.h>
void main ()
{
printf ("Hello, World! \n") ;
}
All programs run from the main function
printf is a function in the library stdio.h
To include any library use #include
Second C program
#include <stdio.h>
void main()
{
int x = 1, y;
int sum;
y = 3;
sum = x + y; /* adds x to y, places
value in variable sum */
printf( “%d plus %d is %d\n”, x, y, sum );
}
Comments
• Any string of symbols placed between the
delimiters /* and */.
• Can span multiple lines
• Can’not be nested! Be careful.
• /* /* /* Hi */ is an example of a comment.
• /* Hi */ */ is going to generate a parse error
Keywords
• Reserved words that cannot be used as
variable names
• OK within comments . . .
• Examples: break, if, else, do, for, while, int,
void
• Exhaustive list in any C book
Identifiers
A token (word) composed of a sequence of letters,
digits, and underscore (_) character. (NO spaces.)
– First character cannot be a digit
– C is case sensitive, so beware (e.g. printf
≠Printf)
Identifiers such as printf normally would not be
redefined; be careful
Used to give names to variables, functions, etc.
Only the first 31 characters matter
Constants
0, 77, 3.14 examples.
• Strings: double quotes. “Hello”
• Characters: single quotes. ‘a’ , ‘z’
• Have types implicitly associated with them
• 1234567890999 too large for most machines
Input and Output
• printf : performs output to the standard output
device (typically defined to be the monitor)
– It requires a format string to which we can provide
• The text to print out
• Specifications on how to print the values
printf ("The number is %d.\n", num) ;
The format specification %d causes the value listed
after the format string to be embedded in the
output as a decimal number in place of %d.
Input
• scanf : performs input from the standard input
device, which is the keyboard by default.
– It requires a format string and a list of
variables into which the value received
from the input device will be stored.
•scanf ("%d", &size) ;
•scanf ("%c", &nextchar) ;
•scanf ("%f", &length) ;
Variables
• Variables hold the values upon which a program
acts. They are the symbolic reference to values.
• The following declares a variable that will contain
an integer value.
int num_of_students ;
The compiler reserves an integer's worth of memory for
num_of_students
In C, all variables must be declared before they can be
used.
• A variable declaration conveys three pieces
of information
– the variable's identifier
– its type
– its scope - the region of the program in which the
variable is accessible.
(implicitly specified by the place in the code
where the declaration occurs.)
C Program # 3
• #include <stdio.h>
main ()
{
int num_of_students ;
scanf ("%d", &num_of_students) ;
printf ("%d \n", num_of_students) ;
}
Declarations
• Declaring a Variable
– Each variable used must be declared.
– A form of a declaration statement is
data-type var1, var2,…;
– Declaration announces the data type of a variable and allocates
appropriate memory location. No initial value (like 0 for integers)
should be assumed.
– It is possible to assign an initial value to a variable in the
declaration itself.
data-type var = expression;
– Examples
int sum = 0;
char newLine = ‘\n’;
float epsilon = 1.0e-6;
85
Constants
• Numerical Constants
– Constants like 12, 253 are stored as int type. No
decimal point.
– 12L or 12l are stored as long int.
– 12U or 12u are stored as unsigned int.
– 12UL or 12ul are stored as unsigned long int.
– Numbers with a decimal point (12.34) are stored
as double.
– Numbers with exponent (12e-3 = 12 x 10-3 ) are
stored as double.
– 12.34f or 1.234e1f are stored as float.
– These are not valid constants:
25,000 7.1e 4 $200 2.3e-3.4 etc.
86
Constants
• Character and string constants
– ‘c’ , a single character in single quotes are stored as char.
Some special character are represented as two characters in single
quotes.
‘\n’ = newline, ‘\t’= tab, ‘\\’ = backlash, ‘\”’ = double
quotes.
Char constants also can be written in terms of their ASCII code.
‘\060’ = ‘0’ (Decimal code is 48).
– A sequence of characters enclosed in double quotes is called a
string constant or string literal. For example
“Charu”
“A”
“3/9”
“x = 5”
87
Variables
• Naming a Variable
– Must be a valid identifier.
– Must not be a keyword
– Names are case sensitive.
– Variables are identified by only first 32 characters.
– Library commonly uses names beginning with _.
– Naming Styles: Uppercase style and Underscore style
– lowerLimit lower_limit
– incomeTax income_tax
88
Declarations
• Declaring a Variable
– Each variable used must be declared.
– A form of a declaration statement is
data-type var1, var2,…;
– Declaration announces the data type of a variable and allocates
appropriate memory location. No initial value (like 0 for integers)
should be assumed.
– It is possible to assign an initial value to a variable in the
declaration itself.
data-type var = expression;
– Examples
int sum = 0;
char newLine = ‘\n’;
float epsilon = 1.0e-6;
89
Global and Local Variables /* Compute Area and Perimeter of
• Global a circle */
#include <stdio.h>
Variables float pi = 3.14159; /* Global */
– These variables are main() {
float rad; /* Local */
declared outside all
functions. printf( “Enter the radius “ );
– Life time of a global scanf(“%f” , &rad);
variable is the entire
execution period of the if ( rad > 0.0 ) {
program. float area = pi * rad * rad;
float peri = 2 * pi * rad;
– Can be accessed by any
function defined below printf( “Area = %f\n” , area
the declaration, in a );
file. printf( “Peri = %f\n” , peri
);
}
else
printf( “Negative radius\n”);
printf( “Area = %f\n” , area );
}
90
Global and Local Variables
/* Compute Area and Perimeter of
• Local Variables a circle */
– These variables are #include <stdio.h>
float pi = 3.14159; /* Global */
declared inside some
main() {
functions. float rad; /* Local */
– Life time of a local
variable is the entire printf( “Enter the radius “ );
execution period of the scanf(“%f” , &rad);
function in which it is
if ( rad > 0.0 ) {
defined.
float area = pi * rad * rad;
– Cannot be accessed by float peri = 2 * pi * rad;
any other function.
– In general variables printf( “Area = %f\n” , area
);
declared inside a block
printf( “Peri = %f\n” , peri
are accessible only in );
that block. }
else
printf( “Negative radius\n”);
printf( “Area = %f\n” , area );
}
91
Sample C program #4
#include <stdio.h>
#define PI 3.1415926
float myfunc (float r)
/* Compute the area of a circle */ {
main() float a;
{ a = PI * r * r;
float radius, area; /* return result */
float myfunc (float radius); return (a);
}
scanf (“%f”, &radius);
area = myfunc (radius);
printf (“\n Area is %f \n”,
area);
}
Operators and Expressions
Operators
• Operators are used to manipulate variables.
• They perform
– arithmetic
– logic functions
– comparisons between values
int x = 6 ;
int y = 9;
int z, w;
z=x+y; w=x*y;
Expressions and statements
• Expressions : combine constants and variables with
operators
– x*y
• Expressions can be grouped to form statements
– z=x*y;
Semicolons terminate statements
• One or more simple sentences can be grouped to
form a compound sentence or a block by enclosing
within { }
Assignment operator
int x = 4 ;
x=x+9;
1. The right hand side is evaluated.
2. The left hand side is set to the value of the right
hand side.
All expressions evaluate to a value of a particular
type.
x + 9 evaluates to the integer value of 13.
Arithmetic operators
+ : addition • distance = rate * time ;
• netIncome = income - tax ;
- : subtraction
• speed = distance / time ;
* : multiplication • area = PI * radius * radius
/ : division • y = a * x * x + b*x + c;
% : modulus • quotient = dividend/divisor;
operator • remainder=dividend %divisor;
Operators in C
1. Arithmetic operators
2. Relational operators
3. Logical operators
4. Assignment operators
5. Increment and decrement operators
6. Conditional operators
7. Bitwise operators
8. Special operators
Arithmetic operators
Operator example Meaning
+ a+b Addition –unary
- a–b Subtraction- unary
* a*b Multiplication
/ a/b Division
% a%b Modulo division- remainder
Relational Operators
Operator Meaning
< Is less than
<= Is less than or equal to
> Is greater than
>= Is greater than or equal to
== Equal to
!= Not equal to
Logical Operators
Operator Meaning
&& Logical AND
|| Logical OR
! Logical NOT
Logical expression or a compound relational
expression-
An expression that combines two or more relational
expressions
Ex: if (a==b && b==c)
Truth Table
Value of the expression
a b
a && b a || b
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1
(operand_1 || operand_2)
Types of Logical Operators
1. Logical AND ( && ) and Logical OR (||)Operator
Synt
ax
(operand _1&& operand_2) (operand_1 || operand_2)
C program for Logical AND and OR Operator
#include <stdio.h> #include <stdio.h>
// Driver code // Driver code
int main() int main()
{ {
int a = 10, b = 20; int a = -1, b = 20;
if (a > 0 && b > 0) { if (a > 0 || b > 0) {
printf("Both values are greater than 0\n"); printf("Any one of the given value is "
} "greater than 0\n");
else { }
printf("Both values are less than 0\n"); else {
} printf("Both values are less than 0\n");
return 0; }
} return 0;
}
Output
Both values are greater than 0 Output
Any one of the given value is greater than 0
3. Logical NOT Operator ( ! )
#include <stdio.h>
int main()
{
int a = 10, b = 20;
if (!(a > 0 && b > 0)) {
// condition returned true but
// logical NOT operator changed
!(operand_1 && // it to false
operand_2) printf("Both values are greater than 0\n");
}
else {
printf("Both values are less than 0\n");
}
return 0;
}
Assignment operators
Syntax:
v op = exp;
Where v = variable,
op = shorthand assignment operator
exp = expression
Ex: x=x+3
x+=3
Shorthand Assignment operators
Simple assignment
Shorthand operator
operator
a = a+1 a + =1
a = a-1 a - =1
a = a* (m+n) a * = m+n
a = a / (m+n) a / = m+n
a = a %b a %=b
Increment & Decrement Operators
C supports 2 useful operators namely
1. Increment ++
2. Decrement – operators
The ++ operator adds a value 1 to the operand
The – operator subtracts 1 from the operand
++a or a++
--a or a--
Rules for ++ & -- operators
1. These require variables as their operands
2. When postfix either ++ or – is used with the
variable in a given expression, the expression is
evaluated first and then it is incremented or
decremented by one
3. When prefix either ++ or – is used with the variable
in a given expression, it is incremented or
decremented by one first and then the expression is
evaluated with the new value
Examples for ++ & -- operators
Let the value of a =5 and b=++a then
a = b =6
Let the value of a = 5 and b=a++ then
a =5 but b=6
i.e.:
1. a prefix operator first adds 1 to the operand and
then the result is assigned to the variable on the
left
2. a postfix operator first assigns the value to the
variable on left and then increments the operand.
Conditional operators
Syntax:
exp1 ? exp2 : exp3
Where exp1,exp2 and exp3 are expressions
Working of the ? Operator:
Exp1 is evaluated first, if it is nonzero(1/true) then the expression2 is
evaluated and this becomes the value of the expression,
If exp1 is false(0/zero) exp3 is evaluated and its value becomes the value
of the expression
Ex: m=2;
n=3
r=(m>n) ? m : n;
Bitwise operators
These operators allow manipulation of data at the bit level
Operator Meaning
& Bitwise AND
| Bitwise OR
^ Bitwise exclusive OR
<< Shift left
>> Shift right
Special operators
1. Comma operator ( ,)
2. sizeof operator – sizeof( )
3. Pointer operators – ( & and *)
4. Member selection operators – ( . and ->)
Arithmetic Expressions
Algebraic expression C expression
axb-c a*b-c
(m+n)(x+y) (m+n)*(x+y)
a*b/c
3x2+2x+1 3*x*x+2*x+1
a/b
S=(a+b+c)/2
S=
Arithmetic Expressions
Algebraic expression C expression
area= area=sqrt(s*(s-a)*(s-b)*(s-c))
Sin sin(b/sqrt(a*a+b*b))
tow1=sqrt((rowx-rowy)/2+tow*x*y*y)
tow1=sqrt(pow((rowx-rowy)/2,2)+tow*x*y*y)
y=(alpha+beta)/sin(theta*3.1416/180)+abs(x)
Precedence of operators
BODMAS RULE-
Brackets of Division Multiplication Addition Subtraction
Brackets will have the highest precedence and have to be
evaluated first, then comes of , then comes
division, multiplication, addition and finally subtraction.
C language uses some rules in evaluating the expressions
and they r called as precedence rules or sometimes also
referred to as hierarchy of operations, with some operators
with highest precedence and some with least.
The 2 distinct priority levels of arithmetic operators in c are-
Highest priority : * / %
Lowest priority : + -
Rules for evaluation of expression
1. First parenthesized sub expression from left to right are evaluated.
2. If parentheses are nested, the evaluation begins with the innermost
sub expression
3. The precedence rule is applied in determining the order of
application of operators in evaluating sub expressions
4. The associatively rule is applied when 2 or more operators of the
same precedence level appear in a sub expression.
5. Arithmetic expressions are evaluated from left to right using the
rules of precedence
6. When parentheses are used, the expressions within parentheses
assume highest priority
Hierarchy of operators
Operator Description Associativity
( ), [ ] Function call, array Left to Right
element reference
+, -, ++, - Unary plus, minus,
-,!,~,*,& increment, decrement,
logical negation, 1’s Right to Left
complement, pointer
reference, address
*, / , % Multiplication, Left to Right
division, modulus
Example 1
Evaluate x1=(-b+ sqrt (b*b-4*a*c))/(2*a) @ a=1, b=-5, c=6
=(-(-5)+sqrt((-5)(-5)-4*1*6))/(2*1)
=(5 + sqrt((-5)(-5)-4*1*6))/(2*1)
=(5 + sqrt(25 -4*1*6))/(2*1)
=(5 + sqrt(25 -4*6))/(2*1)
=(5 + sqrt(25 -24))/(2*1)
=(5 + sqrt(1))/(2*1)
=(5 + 1.0)/(2*1)
=(6.0)/(2*1)
=6.0/2 = 3.0
Algorithm and
Flowchart
ALGORITHMS AND FLOWCHARTS
• A typical programming task can be divided into two
phases:
• Problem solving phase
– produce an ordered sequence of steps that describe solution
of problem
– this sequence of steps is called an algorithm
• Implementation phase
– implement the program in some programming language
Steps in Problem Solving
• First produce a general algorithm (one can use
pseudocode)
• Refine the algorithm successively to get step by
step detailed algorithm that is very close to a
computer language.
• Pseudocode is an artificial and informal language
that helps programmers develop algorithms.
Pseudocode is very similar to everyday English.
Algorithm
• Definition: An algorithm is a step-by-step procedure
or set of rules for solving a particular problem or
accomplishing a specific task. It is a finite sequence
of well-defined instructions that provides a clear,
unambiguous solution to a problem.
Need for Algorithms
1. Problem Solving: Algorithms provide a systematic approach to solving
problems, breaking down complex tasks into smaller, more manageable
steps.
2. Efficiency: Well-designed algorithms can significantly improve the
efficiency of programs, reducing time and resource requirements.
3. Reusability: Algorithms can be reused across different programs and
projects to solve similar problems, promoting code modularization and
maintainability.
4. Scalability: Algorithms help in designing scalable solutions that can
handle increasing data sizes and computational demands.
5. Correctness: Algorithms ensure the correctness of program behavior by
providing a precise sequence of steps to achieve the desired outcome
Properties of Algorithms
1. Finite: Algorithms must terminate after a finite number of steps. They cannot run
indefinitely.
2. Well-defined: Each step of the algorithm must be precisely and unambiguously
defined, with clear instructions on what actions to perform.
3. Input: An algorithm must have zero or more inputs, which are specified before the
algorithm begins execution.
4. Output: Every algorithm produces one or more outputs based on its inputs and the
steps performed during execution.
5. Deterministic: The behavior of an algorithm at any given step must be
deterministic, meaning it should produce the same result for the same inputs every
time it is executed.
6. Efficiency: Algorithms should be designed to be as efficient as possible,
considering factors such as time complexity, space complexity, and computational
resources required.
7. Feasibility: An algorithm must be feasible, meaning it should be possible to
execute it using the available resources, including memory, processing power, and
time.
8. Correctness: An algorithm must produce the correct output for all valid inputs,
meeting the specified requirements and solving the problem it was designed for.
Pseudocode & Algorithm
• Example 1: Write an algorithm to
determine a student’s final grade and
indicate whether it is passing or failing. The
final grade is calculated as the average of
four marks.
Pseudocode & Algorithm
Pseudocode:
• Input a set of 4 marks
• Calculate their average by summing and dividing
by 4
• if average is below 50
Print “FAIL”
else
Print “PASS”
Pseudocode & Algorithm
• Detailed Algorithm
• Step 1: Input M1,M2,M3,M4
Step 2: GRADE ← (M1+M2+M3+M4)/4
Step 3: if (GRADE < 50) then
Print “FAIL”
else
Print “PASS”
endif
The Flowchart
• A schematic representation of a sequence of operations, as
in a manufacturing process or computer program.
• (Technical) A graphical representation of the sequence of
operations in an information system or program.
The Flowchart
A Flowchart
– shows logic of an algorithm
– emphasizes individual steps and their
interconnections
– e.g. control flow from one action to the next
Example 2
• Write an algorithm and draw a flowchart to
convert the length in feet to centimeter.
Pseudocode:
• Input the length in feet (Lft)
• Calculate the length in cm (Lcm) by
multiplying LFT with 30
• Print length in cm (LCM)
Example 3
Write an algorithm and draw a flowchart that
will read the two sides of a rectangle and
calculate its area.
Pseudocode
• Input the width (W) and Length (L) of a rectangle
• Calculate the area (A) by multiplying L with W
• Print A
Flowcharts
• Flowcharts is a graph used to depict or show
a step by step solution using symbols which
represent a task.
• The symbols used consist of geometrical
shapes that are connected by flow lines.
• It is an alternative to pseudocoding; whereas
a pseudocode description is verbal, a
flowchart is graphical
Principles of 133
in nature.
Programming - NI
Flowchart Symbols
Terminal symbol - indicates the beginning
and
end pointssymbol
Process of an algorithm.
- shows an instruction
other than
input, output or
Input-output selection.
symbol - shows an input or an
output
operation.
Disk storage I/O symbol - indicates input
from or output to disk storage.
Printer output symbol - shows hardcopy
printer
output.
Principles of 134
Programming - NI
Flowchart Symbols cont…
Selection symbol - shows a selection
process
for two-way selection.
Off-page connector - provides
continuation of a logical path on another
page.
On-page connector - provides
continuation
of logical path at another point in the
same
Flow
page. lines - indicate the logical
sequence of
execution steps in the algorithm.
Principles of 135
Programming - NI
Flowchart – sequence control structure
Statement 1
Statement 2
Statement 3
136
Flowchart – selection control structure
No Yes
Conditi
on
else- then-
statemen statemen
t(s) t(s)
137
Flowchart – repetition control structure
yes Loop
Condition Statement(s)
no
138
Flowchart – example 1
Begin
Read birth date
Calculate
Age = current year – birth date
Display
age
End
139
Flowchart – example 5
Begin
sum = 0
current_number = 1
NO
current_number <= 10? print sum
YES
End
sum = sum + current_number
current_number = current_number + 1
140
Example 4
• Write an algorithm and draw a flowchart that will
calculate the roots of a quadratic equation
• Hint: d = sqrt ( ), and the roots are: x1 =
(–b + d)/2a and x2 = (–b – d)/2a
1.Draw a flowchart to input two numbers from the user and display the largest of two numbers.
2. Add two numbers entered by the user .
3. Find the largest among three different numbers entered by the user.
4. Find the Fibonacci series till term≤1000.
Swap two numbers
Exercises: Algorithm & Flowchart
1.) Create an algorithm and a flowchart that will compute the area
of a circle.
2.) Create an algorithm and a flowchart that will compute the sum
of two numbers. If the sum is below or equal to twenty, two
numbers will be entered again. If the sum is above 20, it will
display the sum.
Compound Statement
• Each compound statement is enclosed
within a pair of braces (‘{‘ and ‘}’).
– The braces may contain combinations of
elementary statements and other compound
statements.
• Comments may appear anywhere in a
program, enclosed within delimiters
• ‘/*’ and ‘*/’.
Compound Statement (or block)
{
definitions-and-declarations (optional)
statement-list
}
Used for grouping, as function body, and to
restrict identifier visibility
Desirable programming style
• Clarity
– The program should be clearly written.
– It should be easy to follow the program logic.
• Meaningful variable names
– Make variable/constant names meaningful to
enhance program clarity.
• ‘area’ instead of ‘a’
• ‘radius’ instead of ‘r’
C Preprocessor
1 Introduction
• The C preprocessor executes before a program is
compiled.
• Some actions it performs are the inclusion of
other files in the file being compiled, definition of
symbolic constants and macros, conditional
compilation of program code and conditional
execution of preprocessor directives.
• Preprocessor directives begin with # and only
whitespace characters and comments may
appear before a preprocessor directive on a line.
The C preprocessor is a macro processor that is used automatically by the C
compiler to transform your program before actual compilation. It is called a
macro processor because it allows you to define macros.
The C preprocessor provides following type:
• Inclusion of header files : These are files of declarations that can be substituted
into your program.
• Macro expansion: You can define macros, which are abbreviations for C code,
and then the C preprocessor will replace the macros with their definitions
throughout the program.
• Conditional compilation: Using special preprocessing directives, you can include
or exclude parts of the program according to various conditions.
•Preprocessing directives are lines in your program that start with `#'.
•The `#' is followed by an identifier that is the directive name.
For example, `#define' is the directive that defines a macro. Whitespace is also
allowed before and after the `#'.
2 #include Preprocessor Directive
• The #include preprocessor directive has been used
throughout this text.
• The #include directive causes a copy of a specified
file to be included in place of the directive.
• The two forms of the #include directive are:
• #include <filename>
#include "filename"
• The difference between these is the location the
preprocessor begins searches for the file to be
included.
• If the file name is enclosed in quotes, the
preprocessor starts searches in the same directory as
the file being compiled for the file to be included (and
may search other locations, too).
2 #include Preprocessor Directive (Cont.)
• This method is normally used to include
programmer-defined headers.
• If the file name is enclosed in angle
brackets (< and >)—used for standard
library headers—the search is performed
in an implementation-dependent manner,
normally through predesignated
compiler and system directories.
2 #include Preprocessor Directive (Cont.)
• The #include directive is used to include
standard library headers such as stdio.h
and stdlib.h (see Fig. 5.10) and with
programs consisting of multiple source files
that are to be compiled together.
• A header containing declarations common
to the separate program files is often
created and included in the file.
• Examples of such declarations are structure
and union declarations, enumerations and
function prototypes.
3 #define Preprocessor Directive: Symbolic
Constants
• The #define directive creates symbolic
constants—constants represented as
symbols—and macros—operations defined
as symbols.
• The #define directive format is
• #define identifier replacement-text
• When this line appears in a file, all
subsequent occurrences of identifier that do
not appear in string literals will be replaced
by replacement-text automatically before
the program is compiled.
3 #define Preprocessor Directive: Symbolic
Constants (Cont.)
• For example,
#define PI 3.14159
replaces all subsequent occurrences of the symbolic
constant PI with the numeric constant 3.14159.
• Symbolic constants enable you to create a name for a
constant and use the name throughout the program.
• If the constant needs to be modified throughout the
program, it can be modified once in the #define
directive.
• When the program is recompiled, all occurrences of
the constant in the program will be modified
accordingly.
3 #define Preprocessor Directive: Symbolic
Constants (Cont.)
• Everything to the right of the symbolic constant name
replaces the symbolic constant.] For example, #define
PI = 3.14159 causes the preprocessor to replace every
occurrence of the identifier PI with = 3.14159.
• This is the cause of many subtle logic and syntax errors.
• For this reason, you may prefer to use const variable
declarations, such as
– const double PI = 3.14159;
in preference to the preceding #define. Redefining a
symbolic constant with a new value is also an error.
4 #define Preprocessor Directive: Macros
• A macro is an identifier defined in a #define
preprocessor directive.
• As with symbolic constants, the macro-identifier is
replaced in the program with the replacement-text
before the program is compiled.
• Macros may be defined with or without arguments.
• A macro without arguments is processed like a
symbolic constant.
• In a macro with arguments, the arguments are
substituted in the replacement text, then the macro is
expanded—i.e., the replacement-text replaces the
identifier and argument list in the program.
4 #define Preprocessor Directive: Macros
(Cont.)
• [Note: A symbolic constant is a type of
macro.]
• Consider the following macro definition with
one argument for the area of a circle:
#define CIRCLE_AREA(x) ((PI) * (x) * (x))
• Wherever CIRCLE_AREA(y) appears in the
file, the value of y is substituted for x in the
replacement-text, the symbolic constant PI
is replaced by its value (defined previously)
and the macro is expanded in the program.
4 #define Preprocessor Directive: Macros
(Cont.)
• For example, the statement
• area = CIRCLE_AREA(4);
is expanded to
• area = ((3.14159) * (4) * (4));
then, at compile time, the value of the expression
is evaluated and assigned to variable area.
• The parentheses around each x in the
replacement text force the proper order of
evaluation when the macro argument is an
expression.
4 #define Preprocessor Directive: Macros
(Cont.)
• For example, the statement
• area = CIRCLE_AREA(c + 2);
is expanded to
• area = ((3.14159) * (c + 2) * (c + 2));
which evaluates correctly because the
parentheses force the proper order of
evaluation.
4 #define Preprocessor Directive: Macros
(Cont.)
• If the parentheses in the macro definition
are omitted, the macro expansion is
• area = 3.14159 * c + 2 * c + 2;
which evaluates incorrectly as
• area = (3.14159 * c) + (2 * c) + 2;
because of the rules of operator
precedence.
4 #define Preprocessor Directive: Macros
(Cont.)
• Macro CIRCLE_AREA could be defined more
safely as a function.
• Function circleArea
• double circleArea(double x)
{
return 3.14159 * x * x;
}
performs the same calculation as macro
CIRCLE_AREA, but the function’s argument
is evaluated only once when the function is
called.
4 #define Preprocessor Directive: Macros
(Cont.)
• The following is a macro definition with two
arguments for the area of a rectangle:
• #define RECTANGLE_AREA(x, y) ((x) * (y))
• Wherever RECTANGLE_AREA(x, y) appears in
the program, the values of x and y are
substituted in the macro replacement text and
the macro is expanded in place of the macro
name.
• For example, the statement
• rectArea = RECTANGLE_AREA(a + 4, b + 7);
• is expanded to
• rectArea = ((a + 4) * (b + 7));
4 #define Preprocessor Directive: Macros
(Cont.)
• The value of the expression is evaluated at
runtime and assigned to variable rectArea.
• The replacement text for a macro or symbolic
constant is normally any text on the line after the
identifier in the #define directive.
• If the replacement text for a macro or symbolic
constant is longer than the remainder of the line,
a backslash (\) must be placed at the end of the
line, indicating that the replacement text
continues on the next line.
4 #define Preprocessor Directive: Macros
(Cont.)
• Symbolic constants and macros can be discarded
by using the #undef preprocessor directive.
• Directive #undef “undefines” a symbolic constant
or macro name.
• The scope of a symbolic constant or macro is
from its definition until it’s undefined with
#undef, or until the end of the file.
• Once undefined, a name can be redefined with
#define.
• Functions in the standard library sometimes are
defined as macros based on other library
functions.
4 #define Preprocessor Directive: Macros
(Cont.)
• A macro commonly defined in the <stdio.h> header is
• #define getchar() getc(stdin)
• The macro definition of getchar uses function getc to
get one character from the standard input stream.
• Function putchar of the <stdio.h> header and the
character handling functions of the <ctype.h> header
often are implemented as macros as well.
• Expressions with side effects (i.e., variable values are
modified) should not be passed to a macro because
macro arguments may be evaluated more than once.
5 Conditional Compilation
• Conditional compilation enables you to control
the execution of preprocessor directives and the
compilation of program code.
• Each conditional preprocessor directive
evaluates a constant integer expression.
• Cast expressions, sizeof expressions and
enumeration constants cannot be evaluated in
preprocessor directives.
• The conditional preprocessor construct is much
like the if selection statement.
5 Conditional Compilation (Cont.)
• Consider the following preprocessor code:
• #if !defined(MY_CONSTANT)
#define MY_CONSTANT 0
#endif
Which determines whether MY_CONSTANT is
defined—that is, whether MY_CONSTANT has already
appeared in an earlier #define directive.
• The expression defined(MY_CONSTANT) evaluates to 1 if
MY_CONSTANT is defined and 0 otherwise.
• If the result is 0, !defined(MY_CONSTANT) evaluates to 1
and MY_CONSTANT is defined.
• Otherwise, the #define directive is skipped.
5 Conditional Compilation (Cont.)
• Every #if construct ends with #endif.
• Directives #ifdef and #ifndef are shorthand for #if
defined(name) and #if !defined(name).
• A multiple-part conditional preprocessor construct may
be tested by using the #elif (the equivalent of else if in
an if statement) and the #else (the equivalent of else
in an if statement) directives.
• These directives are frequently used to prevent header
files from being included multiple times in the same source
file.
• We use this technique extensively in the C++ part of this
book.
5 Conditional Compilation (Cont.)
• During program development, it’s often helpful
to “comment out” portions of code to prevent
them from being compiled.
• If the code contains multiline comments, /* and
*/ cannot be used to accomplish this task,
because such comments cannot be nested.
• Instead, you can use the following preprocessor
construct:
• #if 0
code prevented from compiling
#endif
• To enable the code to be compiled, replace the 0
in the preceding construct with 1.
5 Conditional Compilation (Cont.)
• Conditional compilation is commonly used as a
debugging aid.
• Many C implementations include debuggers, which
provide much more powerful features than
conditional compilation.
• If a debugger is not available, printf statements are
often used to print variable values and to confirm the
flow of control.
• These printf statements can be enclosed in
conditional preprocessor directives so the
statements are compiled only while the debugging
process is not completed.
5 Conditional Compilation (Cont.)
• For example,
• #ifdef DEBUG
printf("Variable x = %d\n", x);
#endif
causes a printf statement to be
compiled in the program if the symbolic
constant DEBUG has been defined
(#define DEBUG) before directive
#ifdef DEBUG.
5 Conditional Compilation (Cont.)
• When debugging is completed, the #define directive
is removed from the source file (or commented out)
and the printf statements inserted for debugging
purposes are ignored during compilation.
• In larger programs, it may be desirable to define
several different symbolic constants that control the
conditional compilation in separate sections of the
source file.
• Many compilers allow you to define and undefine
symbolic constants with a compiler flag so that you
do not need to change the code.
6 #error and #pragma Preprocessor Directives
• The #error directive
• #error tokens
prints an implementation-dependent message
including the tokens specified in the directive.
• The tokens are sequences of characters separated by
spaces.
• For example,
• #error 1 - Out of range error
contains 6 tokens.
• When a #error directive is processed on some
systems, the tokens in the directive are displayed as
an error message, preprocessing stops and the
program does not compile.
6 #error and #pragma Preprocessor Directives
(Cont.)
• The #pragma directive
• #pragma tokens
causes an implementation-defined action.
• A pragma not recognized by the
implementation is ignored.
© 2016 Pearson Education, Ltd. All rights reserved.
7 # and ## Operators
• The # and ## preprocessor operators are available in
Standard C.
• The # operator causes a replacement text token to be
converted to a string surrounded by quotes.
• Consider the following macro definition:
• #define HELLO(x) printf("Hello, " #x "\n");
• When HELLO(John) appears in a program file, it’s
expanded to
• printf("Hello, " "John" "\n");
• The string "John" replaces #x in the replacement
text.
7 # and ## Operators (Cont.)
• Strings separated by white space are
concatenated during preprocessing, so
the preceding statement is equivalent to
• printf("Hello, John\n");
• The # operator must be used in a macro
with arguments because the operand of #
refers to an argument of the macro.
• The ## operator concatenates two
tokens.
7 # and ## Operators (Cont.)
• Consider the following macro definition:
• #define TOKENCONCAT(x, y) x ## y
• When TOKENCONCAT appears in the
program, its arguments are concatenated
and used to replace the macro.
• For example, TOKENCONCAT(O, K) is
replaced by OK in the program.
• The ## operator must have two
operands.
8 Line Numbers
• The #line preprocessor directive causes
the subsequent source code lines to be
renumbered starting with the specified
constant integer value.
• The directive
• #line 100
starts line numbering from 100 beginning
with the next source code line.
• A filename can be included in the #line
directive.
8 Line Numbers (Cont.)
• The directive
• #line 100 "file1.c"
indicates that lines are numbered from 100
beginning with the next source code line and
that the name of the file for the purpose of
any compiler messages is "file1.c".
• The directive normally is used to help make
the messages produced by syntax errors and
compiler warnings more meaningful.
• The line numbers do not appear in the
source file.
9 Predefined Symbolic Constants
• Standard C provides predefined symbolic
constants, several of which are shown in
Fig. 13.1——the rest are in Section 6.10.8 of
the C standard document.
• The identifiers for each of the predefined
symbolic constants begin and end with two
underscores.
• These identifiers and the defined identifier
(used in Section 13.5) cannot be used in
#define or #undef directives.
10 Assertions
• The assert macro—defined in the <assert.h>
header—tests the value of an expression at
execution time.
• If the value of the expression is false (0), assert
prints an error message and calls function abort
(of the general utilities library—<stdlib.h>) to
terminate program execution.
• This is a useful debugging tool for testing whether a
variable has a correct value.
• For example, suppose variable x should never be
larger than 10 in a program.
10 Assertions (Cont.)
• An assertion may be used to test the value of
x and print an error message if the value of
x is incorrect.
• The statement would be
• assert(x <= 10);
• If x is greater than 10 when the preceding
statement is encountered in a program, an
error message containing the line number
and filename is printed and the program
terminates.
10 Assertions (Cont.)
• You may then concentrate on this area of the
code to find the error.
• If the symbolic constant NDEBUG is defined,
subsequent assertions will be ignored.
• Thus, when assertions are no longer needed,
the line
• #define NDEBUG
is inserted in the program file rather than
each assertion being deleted manually.
10 Assertions (Cont.)
• [Note: The new C standard includes a
capability called _Static_assert, which is
essentially a compile-time version of
assert that produces a compilation error
if the assertion fails. We discuss
_Static_assert in Appendix F.]
Exercise
• Suppose your program contains two integer variables,
x and y which have values 3 and 4 respectively, Write
C statements that will exchange the values in x and y
such that after the statements are executed, x is equal
to 4 and y is equal to 3.
– First, write this routine using a temporary variable
for storage.
– Now re-write this routine without using a temporary
variable for storage.