You are on page 1of 37

Fundamentals of C  The first line of the program 

#include Make sure the gcc compiler is in your path and


Provided by Firecodes <stdio.h> is a preprocessor command, that you are running it in the directory
which tells a C compiler to include containing the source file hello.c.
stdio.h file before going to actual
C Programs compilation.
A C program can vary from 3 lines to millions of  The next line int main() is the main
lines and it should be written into one or more function where the program execution You have seen the basic structure of a C
text files with extension ".c"; for begins. program, so it will be easy to understand other
example, hello.c. You can use "vi", "vim" or  The next line /*...*/ will be ignored by basic building blocks of the C programming
any other text editor to write your C program the compiler and it has been put to add language.
into a file.This tutorial assumes that you know additional comments in the program.
So such lines are called comments in Tokens in C
how to edit a text file and how to write source
code inside a program file. the program. A C program consists of various tokens and a
Before we study the basic building blocks of the  The next line printf(...) is another token is either a keyword, an identifier, a
C programming language, let us look at a bare function available in C which causes constant, a string literal, or a symbol. For
minimum C program structure so that we can the message "Hello, World!" to be example, the following C statement consists of
take it as a reference in the upcoming chapters. displayed on the screen. five tokens −
 The next line return 0; terminates the
Hello World Example main() function and returns the value 0. printf("Hello, World! \n");
A C program basically consists of the following Compile and Execute C Program The individual tokens are −
parts −
Let us see how to save the source code in a
printf
 Preprocessor Commands file, and how to compile and run it. Following
(
are the simple steps −
 Functions "Hello, World! \n"
 Open a text editor and add the above-
 Variables )
mentioned code. ;
 Statements & Expressions
 Save the file as hello.c
 Comments Semicolons
 Open a command prompt and go to the
Let us look at a simple code that would print the directory where you have saved the In a C program, the semicolon is a statement
words "Hello World" − file. terminator. That is, each individual statement
 Type gcc hello.c and press enter to must be ended with a semicolon. It indicates
compile your code. the end of one logical entity.
 If there are no errors in your code, the
#include <stdio.h> Given below are two different statements −
command prompt will take you to the
next line and would
int main() { printf("Hello, World! \n");
generate a.out executable file.
/* my first program in C */ return 0;
printf("Hello, World! \n");  Now, type a.out to execute your
program. Comments
return 0;  You will see the output "Hello
Comments are like helping text in your C
} World" printed on the screen.
program and they are ignored by the compiler.
$ gcc hello.c They start with /* and terminate with the
Let us take a look at the various parts of the $ ./a.out characters */ as shown below −
above program − Hello, World!
/* my first program in C */
You cannot have comments within comments different types. The type of a variable
and they do not occur within a string or continue goto sizeof volatile determines how much space it occupies in
character literals. storage and how the bit pattern stored is
interpreted.
Identifiers default if static while
The types in C can be classified as follows −
A C identifier is a name used to identify a
variable, function, or any other user-defined
item. An identifier starts with a letter A to Z, a to Sr.No Types & Description
do int struct _Packed
z, or an underscore '_' followed by zero or more .
letters, underscores, and digits (0 to 9).
C does not allow punctuation characters such double
1
as @, $, and % within identifiers. C is a case- Basic Types
sensitive programming language.
Thus, Manpower and manpower are two They are arithmetic types and
Whitespace in C
different identifiers in C. Here are some are further classified into: (a)
examples of acceptable identifiers − A line containing only whitespace, possibly with integer types and (b) floating-
a comment, is known as a blank line, and a C point types.
mohd zara abc move_name compiler totally ignores it.
a_123
myname50 _temp j a23b9 Whitespace is the term used in C to describe 2
Enumerated types
retVal blanks, tabs, newline characters and
Keywords comments. Whitespace separates one part of a They are again arithmetic types
statement from another and enables the and they are used to define
The following list shows the reserved words in compiler to identify where one element in a variables that can only assign
C. These reserved words may not be used as statement, such as int, ends and the next certain discrete integer values
constants or variables or any other identifier element begins. Therefore, in the following throughout the program.
names. statement −

int age; 3
auto else long switch The type void
there must be at least one whitespace
The type specifier void indicates
character (usually a space) between int and
that no value is available.
break enum register typedef age for the compiler to be able to distinguish
them. On the other hand, in the following
statement − 4
Derived types
case extern return union fruit = apples + oranges; // get
the total fruit They include (a) Pointer types,
(b) Array types, (c) Structure
no whitespace characters are necessary types, (d) Union types and (e)
char float short unsigned
between fruit and =, or between = and apples, Function types.
although you are free to include some if you
wish to increase readability.
const for signed void The array types and structure types are
referred collectively as the aggregate types.
The type of a function specifies the type of the
Data types in c refer to an extensive system function's return value. We will see the basic
used for declaring variables or functions of
types in the following section, where as other printf("SHRT_MIN : %d\n",
types will be covered in the upcoming chapters. to
SHRT_MIN);
9223372036854775807
printf("UCHAR_MAX : %d\n",
Integer Types
UCHAR_MAX);
The following table provides the details of printf("UINT_MAX : %u\n",
standard integer types with their storage sizes unsigne 8 bytes 0 to (unsigned int) UINT_MAX);
and value ranges − d long 1844674407370955161 printf("ULONG_MAX : %lu\n",
5 (unsigned long) ULONG_MAX);
Type Storag Value range printf("USHRT_MAX : %d\n",
(unsigned short) USHRT_MAX);
e size
To get the exact size of a type or a variable on return 0;
a particular platform, you can use }
char 1 byte -128 to 127 or 0 to 255 the sizeof operator. The
expressions sizeof(type) yields the storage size When you compile and execute the above
of the object or type in bytes. Given below is an program, it produces the following result on
example to get the size of various type on a Linux −
unsigne 1 byte 0 to 255 machine using different constant defined in
d char limits.h header file − CHAR_BIT : 8
CHAR_MAX : 127
#include <stdio.h> CHAR_MIN : -128
#include <stdlib.h> INT_MAX : 2147483647
signed 1 byte -128 to 127
#include <limits.h> INT_MIN : -2147483648
char LONG_MAX : 9223372036854775807
#include <float.h>
LONG_MIN : -9223372036854775808
int main(int argc, char** argv) { SCHAR_MAX : 127
-32,768 to 32,767 or SCHAR_MIN : -128
2 or 4 SHRT_MAX : 32767
int -2,147,483,648 to printf("CHAR_BIT : %d\n",
bytes CHAR_BIT); SHRT_MIN : -32768
2,147,483,647
printf("CHAR_MAX : %d\n", UCHAR_MAX : 255
CHAR_MAX); UINT_MAX : 4294967295
printf("CHAR_MIN : %d\n", ULONG_MAX : 18446744073709551615
unsigne 2 or 4 0 to 65,535 or 0 to CHAR_MIN); USHRT_MAX : 65535
d int bytes 4,294,967,295 printf("INT_MAX : %d\n", Floating-Point Types
INT_MAX);
printf("INT_MIN : %d\n", The following table provide the details of
short 2 bytes -32,768 to 32,767 INT_MIN); standard floating-point types with storage sizes
printf("LONG_MAX : %ld\n", and value ranges and their precision −
(long) LONG_MAX);
printf("LONG_MIN : %ld\n", Type Storage Value range Precision
unsigne 2 bytes 0 to 65,535 (long) LONG_MIN); size
d short printf("SCHAR_MAX : %d\n",
SCHAR_MAX);
printf("SCHAR_MIN : %d\n",
SCHAR_MIN); float 4 byte 1.2E-38 to 6 decimal
long 8 bytes -
printf("SHRT_MAX : %d\n", 3.4E+38 places
9223372036854775808
SHRT_MAX);
When you compile and execute the above
double 8 byte 2.3E-308 to 15 decimal program, it produces the following result on A pointer of type void *
1.7E+308 places Linux − represents the address of an
Storage size for float : 4 object, but not its type. For
FLT_MAX : 3.40282e+38 example, a memory allocation
long 10 byte 3.4E-4932 to 19 decimal FLT_MIN function void *malloc( size_t
: 1.17549e-38
double 1.1E+4932 places -FLT_MAX : -3.40282e+38 size ); returns a pointer to
-FLT_MIN : -1.17549e-38 void which can be casted to
DBL_MAX : 1.79769e+308 any data type.
The header file float.h defines macros that DBL_MIN : 2.22507e-308
allow you to use these values and other details -DBL_MAX : -1.79769e+308 A variable is nothing but a name given to a
about the binary representation of real numbers Precision value: 6 storage area that our programs can manipulate.
in your programs. The following example prints The void Type Each variable in C has a specific type, which
the storage space taken by a float type and its determines the size and layout of the variable's
range values − The void type specifies that no value is
memory; the range of values that can be stored
available. It is used in three kinds of situations
within that memory; and the set of operations

that can be applied to the variable.
#include <stdio.h> Sr.No Types & Description The name of a variable can be composed of
#include <stdlib.h> . letters, digits, and the underscore character. It
#include <limits.h> must begin with either a letter or an
#include <float.h> underscore. Upper and lowercase letters are
distinct because C is case-sensitive. Based on
int main(int argc, char** argv) { 1
Function returns as void the basic types explained in the previous
chapter, there will be the following basic
printf("Storage size for float : There are various functions in variable types −
%d \n", sizeof(float)); C which do not return any
printf("FLT_MAX : %g\n", value or you can say they
Sr.No Type & Description
(float) FLT_MAX); return void. A function with no
printf("FLT_MIN : %g\n", return value has the return .
(float) FLT_MIN); type as void. For
printf("-FLT_MAX : %g\n", example, void exit (int
(float) -FLT_MAX); status); 1
printf("-FLT_MIN : %g\n", char
(float) -FLT_MIN); Typically a single octet(one byte).
printf("DBL_MAX : %g\n", 2
Function arguments as void It is an integer type.
(double) DBL_MAX);
printf("DBL_MIN : %g\n", There are various functions in
(double) DBL_MIN); C which do not accept any 2
int
printf("-DBL_MAX : %g\n", parameter. A function with no
(double) -DBL_MAX); parameter can accept a void. The most natural size of integer for
printf("Precision value: %d\n", For example, int rand(void); the machine.
FLT_DIG );

return 0; 3 3
Pointers to void float
}
consists of an equal sign followed by a constant
A single-precision floating point expression as follows −
value. type variable_name = value; #include <stdio.h>

Some examples are − // Variable declaration:


4 extern int a, b;
double extern int d = 3, f = 5; // extern int c;
A double-precision floating point declaration of d and f. extern float f;
value. int d = 3, f = 5; //
definition and initializing d and f. int main () {
byte z = 22; //
5 definition and initializes z. /* variable definition: */
void char x = 'x'; // the int a, b;
Represents the absence of type. variable x has the value 'x'. int c;
For definition without an initializer: variables float f;
C programming language also allows to define with static storage duration are implicitly
initialized with NULL (all bytes have the value /* actual initialization */
various other types of variables, which we will a = 10;
cover in subsequent chapters like Enumeration, 0); the initial value of all other variables are
undefined. b = 20;
Pointer, Array, Structure, Union, etc. For this
chapter, let us study only basic variable types. Variable Declaration in C c = a + b;
Variable Definition in C printf("value of c : %d \n", c);
A variable declaration provides assurance to
A variable definition tells the compiler where the compiler that there exists a variable with the f = 70.0/3.0;
and how much storage to create for the given type and name so that the compiler can printf("value of f : %f \n", f);
variable. A variable definition specifies a data proceed for further compilation without
type and contains a list of one or more requiring the complete detail about the variable. return 0;
variables of that type as follows − A variable definition has its meaning at the time }
of compilation only, the compiler needs actual
type variable_list; variable definition at the time of linking the When the above code is compiled and
program. executed, it produces the following result −
Here, type must be a valid C data type
including char, w_char, int, float, double, bool, A variable declaration is useful when you are value of c : 30
or any user-defined object; using multiple files and you define your variable value of f : 23.333334
and variable_list may consist of one or more in one of the files which will be available at the
identifier names separated by commas. Some time of linking of the program. You will use the The same concept applies on function
valid declarations are shown here − keyword extern to declare a variable at any declaration where you provide a function name
place. Though you can declare a variable at the time of its declaration and its actual
int i, j, k; definition can be given anywhere else. For
multiple times in your C program, it can be
char c, ch; example −
defined only once in a file, a function, or a block
float f, salary;
of code.
double d; // function declaration
Example int func();
The line int i, j, k; declares and defines the
variables i, j, and k; which instruct the compiler Try the following example, where variables int main() {
to create variables named i, j and k of type int. have been declared at the top, but they have
been defined and initialized inside the main // function call
Variables can be initialized (assigned an initial
function −
value) in their declaration. The initializer
int i = func(); Constants are treated just like regular variables Here are some examples of floating-point
} except that their values cannot be modified literals −
after their definition.
3.14159 /* Legal */
// function definition 314159E-5L /* Legal */
Integer Literals
int func() { 510E /* Illegal: incomplete
return 0; An integer literal can be a decimal, octal, or exponent */
} hexadecimal constant. A prefix specifies the 210f /* Illegal: no decimal
Lvalues and Rvalues in C base or radix: 0x or 0X for hexadecimal, 0 for or exponent */
octal, and nothing for decimal. .e55 /* Illegal: missing
There are two kinds of expressions in C − integer or fraction */
An integer literal can also have a suffix that is a
 lvalue − Expressions that refer to a combination of U and L, for unsigned and long, Character Constants
memory location are called "lvalue" respectively. The suffix can be uppercase or
Character literals are enclosed in single quotes,
expressions. An lvalue may appear as lowercase and can be in any order.
e.g., 'x' can be stored in a simple variable
either the left-hand or right-hand side of
Here are some examples of integer literals − of char type.
an assignment.
212 /* Legal */ A character literal can be a plain character
 rvalue − The term rvalue refers to a
215u /* Legal */ (e.g., 'x'), an escape sequence (e.g., '\t'), or a
data value that is stored at some
0xFeeL /* Legal */ universal character (e.g., '\u02C0').
address in memory. An rvalue is an
078 /* Illegal: 8 is not an
expression that cannot have a value There are certain characters in C that represent
octal digit */
assigned to it which means an rvalue special meaning when preceded by a
032UU /* Illegal: cannot
may appear on the right-hand side but backslash for example, newline (\n) or tab (\t).
repeat a suffix */
not on the left-hand side of an
assignment. Following are other examples of various types Following is the example to show a few escape
of integer literals − sequence characters −
Variables are lvalues and so they may appear
on the left-hand side of an assignment. 85 /* decimal */
Numeric literals are rvalues and so they may 0213 /* octal */
not be assigned and cannot appear on the left- 0x4b /* hexadecimal */ #include <stdio.h>
hand side. Take a look at the following valid 30 /* int */
and invalid statements − 30u /* unsigned int */ int main() {
30l /* long */ printf("Hello\tWorld\n\n");
int g = 20; // valid statement 30ul /* unsigned long */
Floating-point Literals return 0;
10 = 20; // invalid statement; would }
generate compile-time error A floating-point literal has an integer part, a
decimal point, a fractional part, and an When the above code is compiled and
exponent part. You can represent floating point executed, it produces the following result −
Constants refer to fixed values that the program
literals either in decimal form or exponential Hello World
may not alter during its execution. These fixed
form.
values are also called literals. String Literals
While representing decimal form, you must
Constants can be of any of the basic data types String literals or constants are enclosed in
include the decimal point, the exponent, or
like an integer constant, a floating constant, a double quotes "". A string contains characters
both; and while representing exponential form,
character constant, or a string literal. There are that are similar to character literals: plain
you must include the integer part, the fractional
enumeration constants as well. characters, escape sequences, and universal
part, or both. The signed exponent is
introduced by e or E. characters.
You can break a long line into multiple lines When the above code is compiled and  extern
using string literals and separating them using executed, it produces the following result − The auto Storage Class
white spaces.
value of area : 50
The auto storage class is the default storage
Here are some examples of string literals. All The const Keyword class for all local variables.
the three forms are identical strings.
You can use const prefix to declare constants {
"hello, dear" with a specific type as follows − int mount;
"hello, \ const type variable = value; auto int month;
}
The following example explains it in detail −
dear"
The example above defines two variables with
in the same storage class. 'auto' can only be
"hello, " "d" "ear"
used within functions, i.e., local variables.
Defining Constants #include <stdio.h>
The register Storage Class
There are two simple ways in C to define int main() {
constants − const int LENGTH = 10; The register storage class is used to define
const int WIDTH = 5; local variables that should be stored in a
 Using #define preprocessor. register instead of RAM. This means that the
const char NEWLINE = '\n';
 Using const keyword. int area; variable has a maximum size equal to the
register size (usually one word) and can't have
The #define Preprocessor area = LENGTH * WIDTH; the unary '&' operator applied to it (as it does
printf("value of area : %d", not have a memory location).
Given below is the form to use #define
preprocessor to define a constant − area);
{
printf("%c", NEWLINE);
#define identifier value register int miles;
}
return 0;
The following example explains it in detail −
} The register should only be used for variables
that require quick access such as counters. It
When the above code is compiled and
should also be noted that defining 'register'
#include <stdio.h> executed, it produces the following result −
does not mean that the variable will be stored
value of area : 50 in a register. It means that it MIGHT be stored
#define LENGTH 10 in a register depending on hardware and
#define WIDTH 5 Note that it is a good programming practice to implementation restrictions.
#define NEWLINE '\n' define constants in CAPITALS.
The static Storage Class
A storage class defines the scope (visibility)
int main() { The static storage class instructs the compiler
and life-time of variables and/or functions within
int area; to keep a local variable in existence during the
a C Program. They precede the type that they
modify. We have four different storage classes life-time of the program instead of creating and
area = LENGTH * WIDTH; destroying it each time it comes into and goes
in a C program −
printf("value of area : %d", out of scope. Therefore, making local variables
area);
 auto static allows them to maintain their values
printf("%c", NEWLINE);
between function calls.
 register
return 0; The static modifier may also be applied to
}  static
global variables. When this is done, it causes
that variable's scope to be restricted to the file The extern Storage Class $gcc main.c support.c
in which it is declared.
The extern storage class is used to give a It will produce the executable program a.out.
In C programming, when static is used on a reference of a global variable that is visible to When this program is executed, it produces the
global variable, it causes only one copy of that ALL the program files. When you use 'extern', following result −
member to be shared by all the objects of its the variable cannot be initialized however, it
count is 5
class. points the variable name at a storage location
that has been previously defined.
When you have multiple files and you define a An operator is a symbol that tells the compiler
global variable or function, which will also be to perform specific mathematical or logical
#include <stdio.h>
used in other files, then extern will be used in functions. C language is rich in built-in
another file to provide the reference of defined operators and provides the following types of
/* function declaration */
variable or function. Just for operators −
void func(void);
understanding, extern is used to declare a
static int count = 5; /* global global variable or function in another file.  Arithmetic Operators
variable */  Relational Operators
The extern modifier is most commonly used
main() { when there are two or more files sharing the  Logical Operators
same global variables or functions as explained
 Bitwise Operators
while(count--) { below.
 Assignment Operators
func(); First File: main.c
}  Misc Operators
#include <stdio.h> We will, in this chapter, look into the way each
return 0;
operator works.
} int count ;
extern void write_extern(); Arithmetic Operators
/* function definition */
void func( void ) { main() { The following table shows all the arithmetic
count = 5; operators supported by the C language.
static int i = 5; /* local static write_extern(); Assume variable A holds 10 and
variable */ } variable B holds 20 then −
i++; Show Examples
Second File: support.c
printf("i is %d and count is
%d\n", i, count); #include <stdio.h> Operato Description Example
} r
extern int count;
When the above code is compiled and
executed, it produces the following result − void write_extern(void) {
+ Adds two operands. A + B = 30
printf("count is %d\n", count);
i is 6 and count is 4 }
i is 7 and count is 3
i is 8 and count is 2 Here, extern is being used to declare count in − Subtracts second A − B = -10
i is 9 and count is 1 the second file, where as it has its definition in operand from the
i is 10 and count is 0 the first file, main.c. Now, compile these two first.
files as follows −
* Multiplies both A * B = 200 becomes true. true. condition becomes
operands. true.

!= Checks if the values of (A != B)


/ Divides numerator B/A=2 two operands are is true. Logical Operators
by de-numerator. equal or not. If the Following table shows all the logical operators
values are not equal, supported by C language. Assume
then the condition variable A holds 1 and variable B holds 0, then
% Modulus Operator B%A=0 becomes true. −
and remainder of Show Examples
after an integer
division. > Checks if the value of (A > B) Operato De
left operand is greater is not r
than the value of right true.
++ Increment operator A++ = 11 operand. If yes, then
increases the the condition becomes
&& Called Logical AND operator. If both the ope
integer value by true.
true.
one.

< Checks if the value of (A < B)


|| Called Logical OR Operator. If any of the tw
-- Decrement A-- = 9 left operand is less is true.
becomes true.
operator decreases than the value of right
the integer value by operand. If yes, then
one. the condition becomes
true. ! Called Logical NOT Operator. It is used to re
condition is true, then Logical NOT operator
Relational Operators
The following table shows all the relational >= Checks if the value of (A >= B)
operators supported by C. Assume left operand is greater is not Bitwise Operators
variable A holds 10 and variable B holds 20 than or equal to the true.
then − value of right operand. Bitwise operator works on bits and perform bit-
If yes, then the by-bit operation. The truth tables for &, |, and ^
Show Examples condition becomes is as follows −
true.
Operato Description Example p q
r
<= Checks if the value of (A <= B)
left operand is less is true. 0 0
== Checks if the values of (A == B) than or equal to the
two operands are is not value of right operand.
equal or not. If yes, If yes, then the 0 1
then the condition
| Binary OR Operator copies a bit if it exists in =either operand.
Simple assignment operator. Assigns values

1 1

1 0 ^ Binary XOR Operator copies the bit if it is set in one operand but not both.
+= Add AND assignment operator. It adds the r
result to the left operand.
Assume A = 60 and B = 13 in binary format,
they will be as follows −
A = 0011 1100 ~
B = 0000 1101 -= Subtract AND assignment operator. It subtra
Binary One's Complement Operator is unary and has the assigns
effect ofthe
'flipping'
result bits.
to the left operand.
-----------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001 << Binary Left Shift Operator. The left operands *=
value is moved
Multiply
left by
AND
the assignment
number of bits
operator. It multip
specified by the right operand. assigns the result to the left operand.
~A = 1100 0011
The following table lists the bitwise operators
supported by C. Assume variable 'A' holds 60
and variable 'B' holds 13, then −
Show Examples >> Binary Right Shift Operator. The left operands/=value is moved
Divide
right
AND byassignment
the numberoperator.
of bits It divides
specified by the right operand. assigns the result to the left operand.
Operato
r

Assignment Operators %= Modulus AND assignment operator. It takes


& Binary AND Operator copies a bit to the result if it exists in both operands.
The following table lists the assignment result to the left operand.
operators supported by the C language −
Show Examples

Operato
<<= Left shift AND assignment operator.
r
* Pointer to a variable.

>>= Right shift AND assignment operator. ?: Conditional Expression. Relational <<

Operators Precedence in C
Equality
Operator precedence determines the grouping
of terms in an expression and decides how an
&= Bitwise AND assignment operator. expression is evaluated. Certain operators Bitwise AND
have higher precedence than others; for
example, the multiplication operator has a
higher precedence than the addition operator.
Bitwise XOR
For example, x = 7 + 3 * 2; here, x is assigned
^= Bitwise exclusive OR and assignment operator.
13, not 20 because operator * has a higher
precedence than +, so it first gets multiplied
Bitwise OR
with 3*2 and then adds into 7.
Here, operators with the highest precedence
appear at the top of the table, those with the Logical AND
|= Bitwise inclusive OR and assignment operator.
lowest appear at the bottom. Within an
expression, higher precedence operators will
be evaluated first.
Logical OR
Show Examples
Misc Operators ↦ sizeof & ternary
Category Conditional
Besides the operators discussed above, there
are a few other important operators
including sizeof and ? : supported by the C
Postfix Assignment = += -= *= /= %
Language.
Show Examples
Unary + - ! ~ ++ - - (type)* &Comma
sizeof
Operato Description
r
Multiplicative

sizeof() Returns the size of a variable. Decision making structures require that the
programmer specifies one or more conditions
Additive to be evaluated or tested by the program, along
with a statement or statements to be executed
& Returns the address of a variable. if the condition is determined to be true, and
Shift optionally, other statements to be executed if
the condition is determined to be false.
Show below is the general form of a typical You may encounter situations, when a block of
decision making structure found in most of the code needs to be executed several number of
An if statement can be followed by an optional
programming languages − expression is false. times. In general, statements are executed
sequentially: The first statement in a function is
executed first, followed by the second, and so
3 nested if statements on.
You can use one if or else if statement inside Programming
another languages provide various
control structures that allow for more
complicated execution paths.
4 switch statement
A loop statement allows us to execute a
A switch statement allows a variable to be tested for equality
statement or against a liststatements
group of of values. multiple
times. Given below is the general form of a loop
statement in most of the programming
5 nested switch statements languages −
You can use one switch statement inside another

The ? : Operator
We have covered conditional operator ? : in
the previous chapter which can be used to
replace if...else statements. It has the following
general form −
Exp1 ? Exp2 : Exp3;
Where Exp1, Exp2, and Exp3 are expressions.
C programming language assumes any non- Notice the use and placement of the colon.
zero and non-null values as true, and if it is
either zero or null, then it is assumed The value of a ? expression is determined like
as false value. this −

C programming language provides the 


Exp1 is evaluated. If it is true, then
following types of decision making statements. Exp2 is evaluated and becomes the
value of the entire ? expression.
Sr.No Statement
 &IfDescription
Exp1 is false, then Exp3 is evaluated
. and its value becomes the value of the
expression.
C programming language provides the
1 if statement following types of loops to handle looping
Loops
requirements.
An if statement consists of a boolean expression followed by one or more statements.
Sr.No Loop
.
2 if...else statement
A function declaration tells the compiler about
1 while loop a function's name, return type, and parameters.
Transfers control to the labeled statement.
A function definition provides the actual body
Repeats a statement or group of statements while a given condition is true. It tests the condition before
of the function.
The Infinite Loop
executing the loop body.
The C standard library provides numerous built-
A loop becomes an infinite loop if a condition
in functions that your program can call. For
never becomes false. The for loop is
2 for loop example, strcat() to concatenate two
traditionally used for this purpose. Since none
strings, memcpy() to copy one memory
Executes a sequence of statements multipleof times
the three
andexpressions
abbreviatesthat
theform thethat
code 'for'manages
loop the location
loop to another location, and many more
variable. are required, you can make an endless loop by
functions.
leaving the conditional expression empty.
A function can also be referred as a method or
3 do...while loop #include <stdio.h> a sub-routine or a procedure, etc.

It is more like a while statement, except that it int


tests main () { at the end of the loop body.
the condition Defining a Function

for( ; ; ) { The general form of a function definition in C


4 nested loops printf("This loop will run programming language is as follows −
forever.\n");
You can use one or more loops inside any other while, for, or do..while loop. return_type function_name( parameter
}
list ) {
body of the function
Loop Control Statements return 0;
}
}
Loop control statements change execution from
A function definition in C programming consists
its normal sequence. When execution leaves a When the conditional expression is absent, it is
of a function header and a function body. Here
scope, all automatic objects that were created assumed to be true. You may have an
are all the parts of a function −
in that scope are destroyed. initialization and increment expression, but C
programmers more commonly use the for(;;)  Return Type − A function may return a
C supports the following control statements.
construct to signify an infinite loop. value. The return_type is the data type
of the value the function returns. Some
Sr.No NOTE − You
Control Statement can terminate an infinite loop by
& Description functions perform the desired
. pressing Ctrl + C keys.
operations without returning a value. In
A function is a group of statements that this case, the return_type is the
together perform a task. Every C program has keyword void.
1 break statement at least one function, which is main(), and all
 Function Name − This is the actual
the most trivial programs can define additional
name of the function. The function
Terminates the loop or switch statement and functions.
transfers execution to the statement immediately following the name and the parameter list together
loop or switch. You can divide up your code into separate constitute the function signature.
functions. How you divide up your code among
 Parameters − A parameter is like a
different functions is up to you, but logically the
2 continue statement placeholder. When a function is
division is such that each function performs a
invoked, you pass a value to the
specific
Causes the loop to skip the remainder of its body task.
and immediately retest its condition prior to reiterating. parameter. This value is referred to as
actual parameter or argument. The
parameter list refers to the type, order,
3 goto statement
and number of the parameters of a
function. Parameters are optional; that
is, a function may contain no Function declaration is required when you return 0;
parameters. define a function in one source file and you call }
that function in another file. In such case, you
 Function Body − The function body should declare the function at the top of the file /* function returning the max
contains a collection of statements that calling the function. between two numbers */
define what the function does.
int max(int num1, int num2) {
Calling a Function
Example
While creating a C function, you give a /* local variable declaration */
Given below is the source code for a function definition of what the function has to do. To use int result;
called max(). This function takes two a function, you will have to call that function to
parameters num1 and num2 and returns the perform the defined task. if (num1 > num2)
maximum value between the two − result = num1;
When a program calls a function, the program else
/* function returning the max control is transferred to the called function. A result = num2;
between two numbers */ called function performs a defined task and
int max(int num1, int num2) { when its return statement is executed or when return result;
its function-ending closing brace is reached, it }
/* local variable declaration */ returns the program control back to the main
int result; program. We have kept max() along with main() and
compiled the source code. While running the
if (num1 > num2) To call a function, you simply need to pass the final executable, it would produce the following
result = num1; required parameters along with the function result −
else name, and if the function returns a value, then
result = num2; you can store the returned value. For example Max value is : 200
− Function Arguments
return result;
} If a function is to use arguments, it must
declare variables that accept the values of the
Function Declarations #include <stdio.h> arguments. These variables are called
A function declaration tells the compiler about the formal parameters of the function.
a function name and how to call the function. /* function declaration */
int max(int num1, int num2); Formal parameters behave like other local
The actual body of the function can be defined variables inside the function and are created
separately. upon entry into the function and destroyed
int main () {
A function declaration has the following parts − upon exit.
/* local variable definition */ While calling a function, there are two ways in
return_type function_name( parameter int a = 100; which arguments can be passed to a function −
list ); int b = 200;
For the above defined function max(), the int ret;
Sr.No Call
function declaration is as follows −
/* calling a function to get max .
int max(int num1, int num2); value */
Parameter names are not important in function ret = max(a, b);
declaration only their type is required, so the
following is also a valid declaration − printf( "Max value is : %d\n",
ret );
int max(int, int);
a = 10;
1 Call by value
b = 20;
#include <stdio.h> g = a + b;
This method copies the actual value of an argument into the formal parameter of the function. In this case,
changes made to the parameter inside the function have no
int main ()effect
{ on the argument. printf ("value of a = %d, b = %d
and g = %d\n", a, b, g);
/* local variable declaration */
2 Call by reference int a, b; return 0;
int c; }
This method copies the address of an argument into the formal parameter. Inside the function, the address
is used to access the actual argument used in the call. This means that changes made to the parameter
A program can have same name for local and
/* actual initialization */
affect the argument. global variables but the value of local variable
a = 10;
b = 20; inside a function will take preference. Here is
By default, C uses call by value to pass c = a + b; an example −
arguments. In general, it means the code within
a function cannot alter the arguments used to printf ("value of a = %d, b = %d
call the function. and c = %d\n", a, b, c);
#include <stdio.h>
A scope in any programming is a region of the return 0;
program where a defined variable can have its } /* global variable declaration */
existence and beyond that variable it cannot be int g = 20;
Global Variables
accessed. There are three places where
variables can be declared in C programming Global variables are defined outside a function, int main () {
language − usually on top of the program. Global variables
/* local variable declaration */
hold their values throughout the lifetime of your
 Inside a function or a block which is int g = 10;
program and they can be accessed inside any
called local variables.
of the functions defined for the program.
printf ("value of g = %d\n", g);
 Outside of all functions which is
A global variable can be accessed by any
called global variables. return 0;
function. That is, a global variable is available
 In the definition of function parameters for use throughout your entire program after its }
which are called formal parameters. declaration. The following program show how
global variables are used in a program. When the above code is compiled and
Let us understand what executed, it produces the following result −
are local and global variables,
value of g = 10
and formal parameters.
#include <stdio.h> Formal Parameters
Local Variables
Formal parameters, are treated as local
Variables that are declared inside a function or /* global variable declaration */ variables with-in a function and they take
block are called local variables. They can be int g; precedence over global variables. Following is
used only by statements that are inside that an example −
function or block of code. Local variables are int main () {
not known to functions outside their own. The
following example shows how local variables /* local variable declaration */
are used. Here all the variables a, b, and c are int a, b; #include <stdio.h>
local to main() function.
/* actual initialization */ /* global variable declaration */
int a = 20;

int main () {

/* local variable declaration in Int


main function */ Declaring Arrays
int a = 10;
int b = 20; To declare an array in C, a programmer
char specifies the type of the elements and the
int c = 0;
number of elements required by an array as
printf ("value of a in main() = follows −
%d\n", a); float
type arrayName [ arraySize ];
c = sum( a, b);
printf ("value of c in main() = This is called a single-dimensional array.
%d\n", c); The arraySize must be an integer constant
double
greater than zero and type can be any valid C
return 0; data type. For example, to declare a 10-
} element array called balance of type double,
pointer use this statement −
/* function to add two integers */
int sum(int a, int b) { double balance[10];
It is a good programming practice to initialize Here balance is a variable array which is
printf ("value of a in sum() = variables properly, otherwise your program may sufficient to hold up to 10 double numbers.
%d\n", a); produce unexpected results, because
printf ("value of b in sum() = Initializing Arrays
uninitialized variables will take some garbage
%d\n", b); value already available at their memory You can initialize an array in C either one by
location. one or using a single statement as follows −
return a + b;
} Arrays a kind of data structure that can store a double balance[5] = {1000.0, 2.0,
fixed-size sequential collection of elements of 3.4, 7.0, 50.0};
When the above code is compiled and the same type. An array is used to store a
executed, it produces the following result − collection of data, but it is often more useful to The number of values between braces { }
think of an array as a collection of variables of cannot be larger than the number of elements
value of a in main() = 10 that we declare for the array between square
value of a in sum() = 10 the same type.
brackets [ ].
value of b in sum() = 20 Instead of declaring individual variables, such
value of c in main() = 30 as number0, number1, ..., and number99, you If you omit the size of the array, an array just
Initializing Local and Global Variables declare one array variable such as numbers big enough to hold the initialization is created.
and use numbers[0], numbers[1], and ..., Therefore, if you write −
When a local variable is defined, it is not
numbers[99] to represent individual variables. A double balance[] = {1000.0, 2.0,
initialized by the system, you must initialize it
specific element in an array is accessed by an 3.4, 7.0, 50.0};
yourself. Global variables are initialized
index.
automatically by the system when you define You will create exactly the same array as you
them as follows − All arrays consist of contiguous memory did in the previous example. Following is an
locations. The lowest address corresponds to example to assign a single element of the array
Data Type the first element and the highest address to the −
last element.
balance[4] = 50.0; for (j = 0; j < 10; j++ ) {
4 Pointer to an array
th
The above statement assigns the 5  element in printf("Element[%d] = %d\n",
the array with a value of 50.0. All arrays have 0 j, n[j] ); You can generate a pointer to the first elemen
as the index of their first element which is also } index.
called the base index and the last index of an
array will be total size of the array minus 1. return 0;
}
Shown below is the pictorial representation of
the array we discussed above − When the above code is compiled and
Pointers in C are easy and fun to learn. Some
executed, it produces the following result −
C programming tasks are performed more
Element[0] = 100 easily with pointers, and other tasks, such as
Element[1] = 101 dynamic memory allocation, cannot be
Accessing Array Elements Element[2] = 102 performed without using pointers. So it
Element[3] = 103 becomes necessary to learn pointers to
An element is accessed by indexing the array Element[4] = 104 become a perfect C programmer. Let's start
name. This is done by placing the index of the Element[5] = 105 learning them in simple and easy steps.
element within square brackets after the name Element[6] = 106
of the array. For example − Element[7] = 107 As you know, every variable is a memory
Element[8] = 108 location and every memory location has its
double salary = balance[9]; address defined which can be accessed using
Element[9] = 109
The above statement will take the 10 th element ampersand (&) operator, which denotes an
Arrays in Detail
from the array and assign the value to salary address in memory. Consider the following
variable. The following example Shows how to Arrays are important to C and should need a lot example, which prints the address of the
use all the three above mentioned concepts viz. more attention. The following important variables defined −
declaration, assignment, and accessing arrays concepts related to array should be clear to a C
− programmer −
#include <stdio.h>
Sr.No
. int main () {
#include <stdio.h>

int main () { int var1;


1 Multi-dimensional arrays char var2[10];
int n[ 10 ]; /* n is an array of
10 integers */ printf("Address of var1 variable:
C supports multidimensional arrays. The simplest
%x\n",form &var1
of the multidimensional
); array is the two-dimens
int i,j; array. printf("Address of var2 variable:
/* initialize elements of array n %x\n", &var2 );
to 0 */ 2 Passing arrays to functions
for ( i = 0; i < 10; i++ ) { return 0;
n[ i ] = i + 100; /* set } by specifying the array's name without an index.
You can pass to the function a pointer to an array
element at location i to i + 100 */
When the above code is compiled and
}
3 Return array from a function executed, it produces the following result −
/* output each array element's C allows a function to return an array. Address of var1 variable: bff5a400
value */ Address of var2 variable: bff5a3f6
What are Pointers? specified by its operand. The following example The NULL pointer is a constant with a value of
makes use of these operations − zero defined in several standard libraries.
A pointer is a variable whose value is the Consider the following program −
address of another variable, i.e., direct address
of the memory location. Like any variable or
constant, you must declare a pointer before #include <stdio.h>
using it to store any variable address. The #include <stdio.h>
general form of a pointer variable declaration is int main () {
− int main () {
int var = 20; /* actual
type *var-name;
variable declaration */ int *ptr = NULL;
Here, type is the pointer's base type; it must be int *ip; /* pointer
a valid C data type and var-name is the name variable declaration */ printf("The value of ptr is :
of the pointer variable. The asterisk * used to %x\n", ptr );
declare a pointer is the same asterisk used for ip = &var; /* store address of
multiplication. However, in this statement the var in pointer variable*/ return 0;
asterisk is being used to designate a variable }
as a pointer. Take a look at some of the valid printf("Address of var variable:
pointer declarations − %x\n", &var ); When the above code is compiled and
executed, it produces the following result −
int *ip; /* pointer to an /* address stored in pointer
integer */ The value of ptr is 0
variable */
double *dp; /* pointer to a printf("Address stored in ip In most of the operating systems, programs are
double */ variable: %x\n", ip ); not permitted to access memory at address 0
float *fp; /* pointer to a float because that memory is reserved by the
*/ /* access the value using the operating system. However, the memory
char *ch /* pointer to a pointer */ address 0 has special significance; it signals
character */ printf("Value of *ip variable: that the pointer is not intended to point to an
The actual data type of the value of all pointers, %d\n", *ip ); accessible memory location. But by convention,
whether integer, float, character, or otherwise, if a pointer contains the null (zero) value, it is
is the same, a long hexadecimal number that return 0; assumed to point to nothing.
represents a memory address. The only }
To check for a null pointer, you can use an 'if'
difference between pointers of different data statement as follows −
When the above code is compiled and
types is the data type of the variable or
executed, it produces the following result −
constant that the pointer points to. if(ptr) /* succeeds if p is not
Address of var variable: bffd8b3c null */
How to Use Pointers? Address stored in ip variable: if(!ptr) /* succeeds if p is null
There are a few important operations, which we bffd8b3c */
will do with the help of pointers very Value of *ip variable: 20 Pointers in Detail
frequently. (a) We define a pointer NULL Pointers
Pointers have many but easy concepts and
variable, (b) assign the address of a variable to
It is always a good practice to assign a NULL they are very important to C programming. The
a pointer and (c) finally access the value at the
value to a pointer variable in case you do not following important pointer concepts should be
address available in the pointer variable. This is
have an exact address to be assigned. This is clear to any C programmer −
done by using unary operator * that returns the
value of the variable located at the address done at the time of variable declaration. A
pointer that is assigned NULL is called Sr.No Con
a null pointer.
char greeting[] = "Hello";
.
Following is the memory presentation of the
above defined string in C/C++ − Concatenates string s2 onto the end of strin
1 Pointer arithmetic
3
There are four arithmetic operators that can be used in pointers: ++, --, +, - strlen(s1);
Returns the length of string s1.
2 Array of pointers
4
You can define arrays to hold a number of pointers.
Actually, you do not place the null character at strcmp(s1, s2);
the end of a string constant. The C compiler
automatically places the '\0' at the end of the Returns 0 if s1 and s2 are the same; less th
3 Pointer to pointer string when it initializes the array. Let us try to
print the above mentioned string − 5
C allows you to have pointer on a pointer and so on. strchr(s1, ch);
Returns a pointer to the first occurrence of c
4 Passing pointers to functions in C #include <stdio.h>

int enable
Passing an argument by reference or by address main the
() passed
{ argument to be changed in the calling
6
function by the called function. strstr(s1, s2);
char greeting[6] = {'H', 'e',
Returns a pointer to the first occurrence of s
'l', 'l', 'o', '\0'};
5 Return pointer from functions in C printf("Greeting message: %s\n",
greeting ); The following example uses some of the
C allows a function to return a pointer to the local
returnvariable,
0; static variable, and dynamically allocated
memory as well. above-mentioned functions −
}

When the above code is compiled and #include <stdio.h>


Strings are actually one-dimensional array of executed, it produces the following result −
characters terminated by a null character '\0'. #include <string.h>
Thus a null-terminated string contains the Greeting message: Hello
characters that comprise the string followed by int main () {
C supports a wide range of functions that
a null.
manipulate null-terminated strings − char str1[12] = "Hello";
The following declaration and initialization char str2[12] = "World";
create a string consisting of the word "Hello". Sr.No. char str3[12];
To hold the null character at the end of the int len ;
array, the size of the character array containing
the string is one more than the number of /* copy str1 into str3 */
1
characters in the word "Hello." strcpy(s1, s2); strcpy(str3, str1);
printf("strcpy( str3, str1) :
char greeting[6] = {'H', 'e', 'l', Copies string s2 into string s1. %s\n", str3 );
'l', 'o', '\0'};
If you follow the rule of array initialization then /* concatenates str1 and str2 */
2
you can write the above statement as follows − strcat(s1, s2); strcat( str1, str2);
printf("strcat( str1, str2): member definition; struct Books Book1; /*
%s\n", str1 ); ... Declare Book1 of type Book */
member definition; struct Books Book2; /*
/* total lenghth of str1 after } [one or more structure variables]; Declare Book2 of type Book */
concatenation */
len = strlen(str1); The structure tag is optional and each /* book 1 specification */
printf("strlen(str1) : %d\n", member definition is a normal variable strcpy( Book1.title, "C
len ); definition, such as int i; or float f; or any other Programming");
valid variable definition. At the end of the strcpy( Book1.author, "Nuha
return 0; structure's definition, before the final semicolon, Ali");
} you can specify one or more structure variables strcpy( Book1.subject, "C
but it is optional. Here is the way you would Programming Tutorial");
When the above code is compiled and declare the Book structure − Book1.book_id = 6495407;
executed, it produces the following result −
struct Books { /* book 2 specification */
strcpy( str3, str1) : Hello char title[50];
strcat( str1, str2): HelloWorld strcpy( Book2.title, "Telecom
char author[50]; Billing");
strlen(str1) : 10 char subject[100]; strcpy( Book2.author, "Zara
int book_id; Ali");
} book; strcpy( Book2.subject, "Telecom
Arrays allow to define type of variables that can
hold several data items of the same kind. Accessing Structure Members Billing Tutorial");
Similarly structure is another user defined data Book2.book_id = 6495700;
To access any member of a structure, we use
type available in C that allows to combine data
the member access operator (.). The member /* print Book1 info */
items of different kinds.
access operator is coded as a period between printf( "Book 1 title : %s\n",
Structures are used to represent a record. the structure variable name and the structure Book1.title);
Suppose you want to keep track of your books member that we wish to access. You would use printf( "Book 1 author : %s\n",
in a library. You might want to track the the keyword struct to define variables of Book1.author);
following attributes about each book − structure type. The following example shows printf( "Book 1 subject : %s\n",
how to use a structure in a program − Book1.subject);
 Title printf( "Book 1 book_id : %d\n",
Book1.book_id);
 Author
 Subject #include <stdio.h> /* print Book2 info */
#include <string.h> printf( "Book 2 title : %s\n",
 Book ID Book2.title);
Defining a Structure struct Books { printf( "Book 2 author : %s\n",
char title[50]; Book2.author);
To define a structure, you must use char author[50]; printf( "Book 2 subject : %s\n",
the struct statement. The struct statement char subject[100]; Book2.subject);
defines a new data type, with more than one int book_id; printf( "Book 2 book_id : %d\n",
member. The format of the struct statement is }; Book2.book_id);
as follows −
int main( ) { return 0;
struct [structure tag] {
}
member definition;
When the above code is compiled and strcpy( Book1.subject, "C Book book_id : 6495700
executed, it produces the following result − Programming Tutorial"); Pointers to Structures
Book 1 title : C Programming Book1.book_id = 6495407;
You can define pointers to structures in the
Book 1 author : Nuha Ali same way as you define pointer to any other
Book 1 subject : C Programming /* book 2 specification */
strcpy( Book2.title, "Telecom variable −
Tutorial
Book 1 book_id : 6495407 Billing"); struct Books *struct_pointer;
Book 2 title : Telecom Billing strcpy( Book2.author, "Zara
Ali"); Now, you can store the address of a structure
Book 2 author : Zara Ali
strcpy( Book2.subject, "Telecom variable in the above defined pointer variable.
Book 2 subject : Telecom Billing
Billing Tutorial"); To find the address of a structure variable,
Tutorial
Book2.book_id = 6495700; place the '&'; operator before the structure's
Book 2 book_id : 6495700
name as follows −
Structures as Function Arguments /* print Book1 info */
printBook( Book1 ); struct_pointer = &Book1;
You can pass a structure as a function
argument in the same way as you pass any To access the members of a structure using a
other variable or pointer. /* Print Book2 info */
printBook( Book2 ); pointer to that structure, you must use the →
operator as follows −
return 0; struct_pointer->title;
#include <stdio.h> }
#include <string.h> Let us re-write the above example using
void printBook( struct Books book ) structure pointer.
struct Books { {
char title[50];
char author[50]; printf( "Book title : %s\n",
char subject[100]; book.title); #include <stdio.h>
int book_id; printf( "Book author : %s\n", #include <string.h>
}; book.author);
printf( "Book subject : %s\n", struct Books {
/* function declaration */ book.subject); char title[50];
void printBook( struct Books book ); printf( "Book book_id : %d\n", char author[50];
book.book_id); char subject[100];
int main( ) { } int book_id;
};
struct Books Book1; /* When the above code is compiled and
Declare Book1 of type Book */ executed, it produces the following result − /* function declaration */
struct Books Book2; /* Book title : C Programming void printBook( struct Books *book
Declare Book2 of type Book */ Book author : Nuha Ali );
Book subject : C Programming int main( ) {
/* book 1 specification */ Tutorial
strcpy( Book1.title, "C Book book_id : 6495407 struct Books Book1; /*
Programming"); Book title : Telecom Billing Declare Book1 of type Book */
strcpy( Book1.author, "Nuha Book author : Zara Ali struct Books Book2; /*
Ali"); Book subject : Telecom Billing Declare Book2 of type Book */
Tutorial
/* book 1 specification */ Book subject : C Programming A union is a special data type available in C
strcpy( Book1.title, "C Tutorial that allows to store different data types in the
Programming"); Book book_id : 6495407 same memory location. You can define a union
strcpy( Book1.author, "Nuha Book title : Telecom Billing with many members, but only one member can
Ali"); Book author : Zara Ali contain a value at any given time. Unions
strcpy( Book1.subject, "C Book subject : Telecom Billing provide an efficient way of using the same
Programming Tutorial"); Tutorial memory location for multiple-purpose.
Book1.book_id = 6495407; Book book_id : 6495700
Defining a Union
Bit Fields
/* book 2 specification */ To define a union, you must use
strcpy( Book2.title, "Telecom Bit Fields allow the packing of data in a
the union statement in the same way as you
Billing"); structure. This is especially useful when
did while defining a structure. The union
strcpy( Book2.author, "Zara memory or data storage is at a premium.
statement defines a new data type with more
Ali"); Typical examples include −
than one member for your program. The format
strcpy( Book2.subject, "Telecom  Packing several objects into a machine of the union statement is as follows −
Billing Tutorial"); word. e.g. 1 bit flags can be
Book2.book_id = 6495700; compacted. union [union tag] {
member definition;
/* print Book1 info by passing  Reading external file formats -- non- member definition;
address of Book1 */ standard file formats could be read in, ...
printBook( &Book1 ); e.g., 9-bit integers. member definition;
} [one or more union variables];
/* print Book2 info by passing C allows us to do this in a structure definition by
address of Book2 */ putting :bit length after the variable. For The union tag is optional and each member
printBook( &Book2 ); example − definition is a normal variable definition, such
as int i; or float f; or any other valid variable
struct packed_struct { definition. At the end of the union's definition,
return 0;
unsigned int f1:1;
} before the final semicolon, you can specify one
unsigned int f2:1;
or more union variables but it is optional. Here
unsigned int f3:1;
void printBook( struct Books *book ) is the way you would define a union type
unsigned int f4:1;
{ named Data having three members i, f, and str
unsigned int type:4;

unsigned int my_int:9;
printf( "Book title : %s\n",
} pack; union Data {
book->title);
printf( "Book author : %s\n", int i;
Here, the packed_struct contains 6 members: float f;
book->author); Four 1 bit flags f1..f3, a 4-bit type and a 9-bit
printf( "Book subject : %s\n", char str[20];
my_int. } data;
book->subject);
printf( "Book book_id : %d\n", C automatically packs the above bit fields as
book->book_id); compactly as possible, provided that the Now, a variable of Data type can store an
} maximum length of the field is less than or integer, a floating-point number, or a string of
equal to the integer word length of the characters. It means a single variable, i.e.,
When the above code is compiled and computer. If this is not the case, then some same memory location, can be used to store
executed, it produces the following result − compilers may allow memory overlap for the multiple types of data. You can use any built-in
fields while others would store the next field in or user defined data types inside a union based
Book title : C Programming on your requirement.
Book author : Nuha Ali the next word.
The memory occupied by a union will be large #include <string.h> #include <string.h>
enough to hold the largest member of the
union. For example, in the above example, union Data { union Data {
Data type will occupy 20 bytes of memory int i; int i;
space because this is the maximum space float f; float f;
which can be occupied by a character string. char str[20]; char str[20];
The following example displays the total }; };
memory size occupied by the above union −
int main( ) { int main( ) {

union Data data; union Data data;


#include <stdio.h>
#include <string.h> data.i = 10; data.i = 10;
data.f = 220.5; printf( "data.i : %d\n", data.i);
union Data { strcpy( data.str, "C
int i; Programming"); data.f = 220.5;
float f; printf( "data.f : %f\n", data.f);
char str[20]; printf( "data.i : %d\n", data.i);
}; printf( "data.f : %f\n", data.f); strcpy( data.str, "C
printf( "data.str : %s\n", Programming");
int main( ) { data.str); printf( "data.str : %s\n",
data.str);
union Data data; return 0;
} return 0;
printf( "Memory size occupied by }
data : %d\n", sizeof(data)); When the above code is compiled and
executed, it produces the following result − When the above code is compiled and
return 0; executed, it produces the following result −
} data.i : 1917853763
data.f : data.i : 10
When the above code is compiled and 4122360580327794860452759994368.0000 data.f : 220.500000
executed, it produces the following result − 00 data.str : C Programming
data.str : C Programming
Memory size occupied by data : 20 Here, all the members are getting printed very
Accessing Union Members Here, we can see that the values well because one member is being used at a
of i and f members of union got corrupted time.
To access any member of a union, we use because the final value assigned to the variable
the member access operator (.). The member has occupied the memory location and this is Suppose your C program contains a number of
access operator is coded as a period between the reason that the value of str member is TRUE/FALSE variables grouped in a structure
the union variable name and the union member getting printed very well. called status, as follows −
that we wish to access. You would use the
Now let's look into the same example once struct {
keyword union to define variables of union
again where we will use one variable at a time unsigned int widthValidated;
type. The following example shows how to use unsigned int heightValidated;
unions in a program − which is the main purpose of having unions −
} status;

This structure requires 8 bytes of memory


#include <stdio.h> space but in actual, we are going to store either
#include <stdio.h>
0 or 1 in each of the variables. The C printf( "Memory size occupied by variable to store a value from 0 to 7, then you
programming language offers a better way to status1 : %d\n", sizeof(status1)); can define a bit field with a width of 3 bits as
utilize the memory space in such situations. printf( "Memory size occupied by follows −
status2 : %d\n", sizeof(status2));
If you are using such variables inside a struct {
return 0;
structure then you can define the width of a unsigned int age : 3;
}
variable which tells the C compiler that you are } Age;
going to use only those number of bytes. For When the above code is compiled and
example, the above structure can be re-written executed, it produces the following result − The above structure definition instructs the C
as follows − compiler that the age variable is going to use
Memory size occupied by status1 : 8 only 3 bits to store the value. If you try to use
struct { Memory size occupied by status2 : 4 more than 3 bits, then it will not allow you to do
unsigned int widthValidated : 1; Bit Field Declaration so. Let us try the following example −
unsigned int heightValidated : 1;
} status; The declaration of a bit-field has the following
form inside a structure −
The above structure requires 4 bytes of #include <stdio.h>
memory space for status variable, but only 2 struct { #include <string.h>
bits will be used to store the values. type [member_name] : width ;
}; struct {
If you will use up to 32 variables each one with
unsigned int age : 3;
a width of 1 bit, then also the status structure The following table describes the variable } Age;
will use 4 bytes. However as soon as you have elements of a bit field −
33 variables, it will allocate the next slot of the int main( ) {
memory and it will start using 8 bytes. Let us Sr.No
check the following example to understand the . Age.age = 4;
concept − printf( "Sizeof( Age ) : %d\n",
sizeof(Age) );
1 printf( "Age.age : %d\n", Age.age
type );
#include <stdio.h>
#include <string.h> An integer type that determines how a bit-field's Age.age
value is interpreted. The type may be int, signed in
= 7;
unsigned int. printf( "Age.age : %d\n", Age.age
/* define simple structure */
struct { );
unsigned int widthValidated; 2
member_name Age.age = 8;
unsigned int heightValidated;
} status1; printf( "Age.age : %d\n", Age.age
The name of the bit-field. );
/* define a structure with bit
fields */ 3 return 0;
width }
struct {
unsigned int widthValidated : 1; The number of bits in the bit-field. The width must be less
When the than or equal
above codeto isthecompiled
bit width ofit the
willspecified t
unsigned int heightValidated : 1;
compile with a warning and when executed, it
} status2;
The variables defined with a predefined width produces the following result −
int main( ) { are called bit fields. A bit field can hold more Sizeof( Age ) : 4
than a single bit; for example, if you need a Age.age : 4
Age.age : 7 strcpy( book.author, "Nuha Ali");
Age.age : 0 strcpy( book.subject, "C #define TRUE 1
Programming Tutorial"); #define FALSE 0
book.book_id = 6495407;
The C programming language provides a int main( ) {
keyword called typedef, which you can use to printf( "Book title : %s\n", printf( "Value of TRUE : %d\n",
give a type a new name. Following is an book.title); TRUE);
example to define a term BYTE for one-byte printf( "Book author : %s\n", printf( "Value of FALSE : %d\n",
numbers − book.author); FALSE);
typedef unsigned char BYTE; printf( "Book subject : %s\n",
book.subject); return 0;
After this type definition, the identifier BYTE printf( "Book book_id : %d\n", }
can be used as an abbreviation for the book.book_id);
type unsigned char, for example.. When the above code is compiled and
return 0; executed, it produces the following result −
BYTE b1, b2;
} Value of TRUE : 1
By convention, uppercase letters are used for Value of FALSE : 0
these definitions to remind the user that the When the above code is compiled and
type name is really a symbolic abbreviation, but executed, it produces the following result −
you can use lowercase, as follows − Book title : C Programming When we say Input, it means to feed some
typedef unsigned char byte; Book author : Nuha Ali data into a program. An input can be given in
Book subject : C Programming the form of a file or from the command line. C
You can use typedef to give a name to your Tutorial programming provides a set of built-in functions
user defined data types as well. For example, Book book_id : 6495407 to read the given input and feed it to the
you can use typedef with structure to define a typedef vs #define program as per requirement.
new data type and then use that data type to
define structure variables directly as follows − #define is a C-directive which is also used to When we say Output, it means to display some
define the aliases for various data types similar data on screen, printer, or in any file. C
to typedef but with the following differences − programming provides a set of built-in functions
to output the data on the computer screen as
#include <stdio.h>  typedef is limited to giving symbolic well as to save it in text or binary files.
#include <string.h> names to types only where
as #define can be used to define alias The Standard Files
typedef struct Books { for values as well, q., you can define 1 C programming treats all the devices as files.
char title[50]; as ONE etc. So devices such as the display are addressed
char author[50]; in the same way as files and the following three
char subject[100];  typedef interpretation is performed by
the compiler files are automatically opened when a program
int book_id; executes to provide access to the keyboard
} Book; whereas #define statements are
processed by the pre-processor. and screen.
int main( ) { The following example shows how to use Standard File File Poi
#define in a program −
Book book;

strcpy( book.title, "C Standard input stdin


Programming"); #include <stdio.h>
the program proceeds and reads only a single The int printf(const char *format, ...) function
Standard output stdoutcharacter and displays it as follows − writes the output to the standard output
stream stdout and produces the output
$./a.out
according to the format provided.
Enter a value : this is test
Standard error stderr
You entered: t The format can be a simple constant string, but
The gets() and puts() Functions you can specify %s, %d, %c, %f, etc., to print
or read strings, integer, character or float
The file pointers are the means to access the The char *gets(char *s) function reads a line respectively. There are many other formatting
file for reading and writing purpose. This from stdin into the buffer pointed to by s until options available which can be used based on
section explains how to read values from the either a terminating newline or EOF (End of requirements. Let us now proceed with a
screen and how to print the result on the File). simple example to understand the concepts
screen. better −
The int puts(const char *s) function writes the
The getchar() and putchar() Functions string 's' and 'a' trailing newline to stdout. #include <stdio.h>
The int getchar(void) function reads the next NOTE: Though it has been deprecated to use int main( ) {
available character from the screen and returns gets() function, Instead of using gets, you want
it as an integer. This function reads only single to use fgets(). char str[100];
character at a time. You can use this method in int i;
the loop in case you want to read more than #include <stdio.h>
one character from the screen. int main( ) { printf( "Enter a value :");
scanf("%s %d", str, &i);
The int putchar(int c) function puts the passed char str[100];
character on the screen and returns the same printf( "\nYou entered: %s %d ",
character. This function puts only single printf( "Enter a value :"); str, i);
character at a time. You can use this method in gets( str );
the loop in case you want to display more than return 0;
one character on the screen. Check the printf( "\nYou entered: "); }
following example − puts( str );
When the above code is compiled and
#include <stdio.h> return 0; executed, it waits for you to input some text.
int main( ) { } When you enter a text and press enter, then
program proceeds and reads the input and
int c; When the above code is compiled and displays it as follows −
executed, it waits for you to input some text.
printf( "Enter a value :"); $./a.out
When you enter a text and press enter, then
c = getchar( ); Enter a value : seven 7
the program proceeds and reads the complete
You entered: seven 7
line till end, and displays it as follows −
printf( "\nYou entered: "); Here, it should be noted that scanf() expects
putchar( c ); $./a.out
Enter a value : this is test input in the same format as you provided %s
You entered: this is test and %d, which means you have to provide valid
return 0; inputs like "string integer". If you provide "string
} The scanf() and printf() Functions string" or "integer integer", then it will be
The int scanf(const char *format, ...) function assumed as wrong input. Secondly, while
When the above code is compiled and
reads the input from the standard input reading a string, scanf() stops reading as soon
executed, it waits for you to input some text.
stream stdin and scans that input according to as it encounters a space, so "this is test" are
When you enter a text and press enter, then
the format provided. three strings for scanf().
The last chapter explained the standard input Writing a File
and output devices handled by C programming Opens a text file for writing in appending mode. If it does not exist, then a new file is created. Here
language. This chapter cover how C Following is the simplest function to write
program will start appending content in the existing file content.
programmers can create, open, close text or individual characters to a stream −
binary files for their data storage. int fputc( int c, FILE *fp );
4
A file represents a sequence of bytes, r+ The function fputc() writes the character value
regardless of it being a text file or a binary file. Opens a text file for both reading and writing. of the argument c to the output stream
C programming language provides access on referenced by fp. It returns the written character
high level functions as well as low level (OS written on success otherwise EOF if there is an
level) calls to handle file on your storage 5 error. You can use the following functions to
devices. This chapter will take you through the w+
write a null-terminated string to a stream −
important calls for file management. Opens a text file for both reading and writing.intIt first truncates the file to zero
fputs( const char *s, length
FILE if it exists, othe
Opening Files creates a file if it does not exist. *fp );
You can use the fopen( ) function to create a The function fputs() writes the string s to the
new file or to open an existing file. This call will 6 output stream referenced by fp. It returns a
a+
initialize an object of the type FILE, which non-negative value on success,
contains all the information necessary to control Opens a text file for both reading and writing. Itotherwise EOF is
creates the file if returned
it does not
in exist.
case ofThe reading
any error. will start
the stream. The prototype of this function call is the beginning but writing can only be appended. You can use int fprintf(FILE *fp,const char
as follows − *format, ...) function as well to write a string
into a file. Try the following example.
FILE *fopen( const char * filename, If you are going to handle binary files, then you
const char * mode ); will use following access modes instead of the Make sure you have /tmp directory available. If
above mentioned ones − it is not, then before proceeding, you must
Here, filename is a string literal, which you will
create this directory on your machine.
use to name your file, and access mode can "rb", "wb", "ab", "rb+", "r+b",
have one of the following values − "wb+", "w+b", "ab+", "a+b" #include <stdio.h>
Closing a File
Sr.No main() {
. To close a file, use the fclose( ) function. The FILE *fp;
prototype of this function is −
int fclose( FILE *fp ); fp = fopen("/tmp/test.txt",
"w+");
1 The fclose(-) function returns zero on success,
r fprintf(fp, "This is testing for
or EOF if there is an error in closing the file. fprintf...\n");
Opens an existing text file for reading purpose.This function actually flushes any data still fputs("This is testing for
pending in the buffer to the file, closes the file, fputs...\n", fp);
and releases any memory used for the file. The fclose(fp);
2
w EOF is a constant defined in the header }
file stdio.h.
Opens a text file for writing. If it does not exist, then a new file is created. Here your program will start writing
When the above code is compiled and
content from the beginning of the file. There are various functions provided by C executed, it creates a new file test.txt in /tmp
standard library to read and write a file, directory and writes two lines using two
character by character, or in the form of a fixed different functions. Let us read this file in the
3 length string.
a next section.
Reading a File directive should begin in the first column. The
} following section lists down all the important
Given below is the simplest function to read a preprocessor directives −
single character from a file − When the above code is compiled and
int fgetc( FILE * fp ); executed, it reads the file created in the Sr.No. Di
previous section and produces the following
The fgetc() function reads a character from the result −
input file referenced by fp. The return value is
the character read, or in case of any error, it 1 : This 1
2: is testing for fprintf... #define
returns EOF. The following function allows to
read a string from a stream − Substitutes a preprocessor macro.
3: This is testing for fputs...
char *fgets( char *buf, int n, FILE
*fp ); Let's see a little more in detail about what
2
happened here. First, fscanf() read #include
The functions fgets() reads up to n-1 just This because after that, it encountered a
characters from the input stream referenced by space, second call is for fgets() which reads Inserts a particular header from another fil
fp. It copies the read string into the buffer buf, the remaining line till it encountered end of line.
appending a null character to terminate the Finally, the last call fgets() reads the second 3
string. line completely. #undef
If this function encounters a newline character Binary I/O Functions Undefines a preprocessor macro.
'\n' or the end of the file EOF before they have
read the maximum number of characters, then There are two functions, that can be used for
it returns only the characters read up to that binary input and output − 4
#ifdef
point including the new line character. You can
also use int fscanf(FILE *fp, const char size_t fread(void *ptr, size_t Returns true if this macro is defined.
*format, ...) function to read strings from a file, size_of_elements, size_t
number_of_elements, FILE *a_file);
but it stops reading after encountering the first
space character. 5
size_t fwrite(const void *ptr, #ifndef
#include <stdio.h> size_t size_of_elements, size_t Returns true if this macro is not defined.
number_of_elements, FILE *a_file);
main() {
Both of these functions should be used to read 6
or write blocks of memories - usually arrays or #if
FILE *fp;
char buff[255]; structures. Tests if a compile time condition is true.
The C Preprocessor is not a part of the
fp = fopen("/tmp/test.txt", "r"); compiler, but is a separate step in the
fscanf(fp, "%s", buff); 7
compilation process. In simple terms, a C #else
printf("1 : %s\n", buff ); Preprocessor is just a text substitution tool and
it instructs the compiler to do required pre- The alternative for #if.
fgets(buff, 255, (FILE*)fp); processing before the actual compilation. We'll
printf("2: %s\n", buff ); refer to the C Preprocessor as CPP. 8
#elif
fgets(buff, 255, (FILE*)fp); All preprocessor commands begin with a hash
printf("3: %s\n", buff ); symbol (#). It must be the first nonblank #else and #if in one statement.
fclose(fp); character, and for readability, a preprocessor
#ifdef DEBUG Let's try the following example −
9
#endif /* Your debugging statements here
*/
Ends preprocessor conditional. #endif
#include <stdio.h>
It tells the CPP to process the statements
10 int main() {
#error enclosed if DEBUG is defined. This is useful if
you pass the -DDEBUG flag to the gcc compiler
Prints error message on stderr. at the time of compilation. This will define printf("File :%s\n", __FILE__ );
DEBUG, so you can turn debugging on and off printf("Date :%s\n", __DATE__ );
on the fly during compilation. printf("Time :%s\n", __TIME__ );
11 printf("Line :%d\n", __LINE__ );
#pragma
Predefined Macros printf("ANSI :%d\n", __STDC__ );
Issues special commands to the compiler, using a standardized method.
ANSI C defines a number of macros. Although }
each one is available for use in programming,
Preprocessors Examples the predefined macros should not be directly When the above code in a file test.c is
Analyze the following examples to understand modified. compiled and executed, it produces the
various directives. following result −
Sr.No.
#define MAX_ARRAY_LENGTH 20 File :test.c
Date :Jun 2 2012
This directive tells the CPP to replace instances Time :03:36:24
of MAX_ARRAY_LENGTH with 20. 1 Line :8
Use #define for constants to increase __DATE__
ANSI :1
readability. The current date as a character literal in "MMM DD YYYY" format.
Preprocessor Operators
#include <stdio.h> The C preprocessor offers the following
#include "myheader.h" 2 operators to help create macros −
__TIME__
These directives tell the CPP to get stdio.h The Macro Continuation (\) Operator
from System Libraries and add the text to the The current time as a character literal in "HH:MM:SS" format.
current source file. The next line tells CPP to A macro is normally confined to a single line.
get myheader.h from the local directory and The macro continuation operator (\) is used to
3
add the content to the current source file. __FILE__ continue a macro that is too long for a single
line. For example −
#undef FILE_SIZE This contains the current filename as a string literal.
#define FILE_SIZE 42 #define message_for(a, b) \
printf(#a " and " #b ": We love
It tells the CPP to undefine existing FILE_SIZE 4 you!\n")
__LINE__
and define it as 42.
This contains the current line number as The Stringize
a decimal (#) Operator
constant.
#ifndef MESSAGE The stringize or number-sign operator ( '#' ),
#define MESSAGE "You wish!" when used within a macro definition, converts a
#endif 5
__STDC__ macro parameter into a string constant. This
operator may be used only in a macro having a
It tells the CPP to define MESSAGE only if Defined as 1 when the compiler complies specified
with the ANSI standard.
argument or parameter list. For
MESSAGE isn't already defined. example −
This example shows the concatenation of Macros with arguments must be defined using
token##n into token34 and here we have used the #define directive before they can be used.
#include <stdio.h> both stringize and token-pasting. The argument list is enclosed in parentheses
and must immediately follow the macro name.
The Defined() Operator Spaces are not allowed between the macro
#define message_for(a, b) \
printf(#a " and " #b ": We love The preprocessor defined operator is used in name and open parenthesis. For example −
you!\n") constant expressions to determine if an
identifier is defined using #define. If the
int main(void) { specified identifier is defined, the value is true
message_for(Carole, Debra); #include <stdio.h>
(non-zero). If the symbol is not defined, the
return 0; value is false (zero). The defined operator is
} #define MAX(x,y) ((x) > (y) ? (x) :
specified as follows −
(y))
When the above code is compiled and
executed, it produces the following result − int main(void) {
#include <stdio.h> printf("Max between 20 and 10 is
Carole and Debra: We love you! %d\n", MAX(10, 20));
The Token Pasting (##) Operator #if !defined (MESSAGE) return 0;
#define MESSAGE "You wish!" }
The token-pasting operator (##) within a macro
definition combines two arguments. It permits #endif
When the above code is compiled and
two separate tokens in the macro definition to executed, it produces the following result −
be joined into a single token. For example − int main(void) {
printf("Here is the message: Max between 20 and 10 is 20
%s\n", MESSAGE);
return 0;
#include <stdio.h> } A header file is a file with extension .h which
contains C function declarations and macro
#define tokenpaster(n) printf When the above code is compiled and definitions to be shared between several
("token" #n " = %d", token##n) executed, it produces the following result − source files. There are two types of header
Here is the message: You wish! files: the files that the programmer writes and
int main(void) { the files that comes with your compiler.
int token34 = 40; Parameterized Macros
tokenpaster(34); You request to use a header file in your
One of the powerful functions of the CPP is the program by including it with the C
return 0; ability to simulate functions using
} preprocessing directive #include, like you have
parameterized macros. For example, we might seen inclusion of stdio.h header file, which
have some code to square a number as follows comes along with your compiler.
When the above code is compiled and −
executed, it produces the following result − Including a header file is equal to copying the
token34 = 40 int square(int x) { content of the header file but we do not do it
return x * x; because it will be error-prone and it is not a
It happened so because this example results in } good idea to copy the content of a header file in
the following actual output from the the source files, especially if we have multiple
preprocessor − We can rewrite above the code using a macro source files in a program.
as follows −
printf ("token34 = %d", token34); A simple practice in C or C++ programs is that
#define square(x) ((x) * (x)) we keep all the constants, macros, system wide
global variables, and function prototypes in the
header files and include that header file the compiler will see the same token stream as But as it grows, it becomes tedious, instead the
wherever it is required. it would if program.c read. preprocessor offers the ability to use a macro
for the header name. This is called
Include Syntax int x; a computed include. Instead of writing a
char *test (void); header name as the direct argument
Both the user and the system header files are
included using the preprocessing of #include, you simply put a macro name
int main (void) { there −
directive #include. It has the following two
puts (test ());
forms − #define SYSTEM_H "system_1.h"
}
#include <file> ...
Once-Only Headers #include SYSTEM_H
This form is used for system header files. It If a header file happens to be included twice, SYSTEM_H will be expanded, and the
searches for a file named 'file' in a standard list the compiler will process its contents twice and preprocessor will look for system_1.h as if
of system directories. You can prepend it will result in an error. The standard way to the #include had been written that way
directories to this list with the -I option while prevent this is to enclose the entire real originally. SYSTEM_H could be defined by your
compiling your source code. contents of the file in a conditional, like this − Makefile with a -D option.
#include "file"
#ifndef HEADER_FILE Converting one datatype into another is known
This form is used for header files of your own #define HEADER_FILE as type casting or, type-conversion. For
program. It searches for a file named 'file' in the example, if you want to store a 'long' value into
directory containing the current file. You can the entire header file file a simple integer then you can type cast 'long' to
prepend directories to this list with the -I option 'int'. You can convert the values from one type
while compiling your source code. #endif to another explicitly using the cast operator as
Include Operation follows −
This construct is commonly known as a
wrapper #ifndef. When the header is included (type_name) expression
The #include directive works by directing the C
preprocessor to scan the specified file as input again, the conditional will be false, because
Consider the following example where the cast
before continuing with the rest of the current HEADER_FILE is defined. The preprocessor
operator causes the division of one integer
source file. The output from the preprocessor will skip over the entire contents of the file, and
variable by another to be performed as a
contains the output already generated, followed the compiler will not see it twice.
floating-point operation −
by the output resulting from the included file, Computed Includes
followed by the output that comes from the text
after the #include directive. For example, if you Sometimes it is necessary to select one of the
have a header file header.h as follows − several different header files to be included into #include <stdio.h>
your program. For instance, they might specify
char *test (void); configuration parameters to be used on main() {
and a main program called program.c that uses different sorts of operating systems. You could
the header file, like this − do this with a series of conditionals as follows − int sum = 17, count = 5;
double mean;
int x; #if SYSTEM_1
#include "header.h" # include "system_1.h" mean = (double) sum / count;
#elif SYSTEM_2 printf("Value of mean : %f\n",
int main (void) { # include "system_2.h" mean );
puts (test ()); #elif SYSTEM_3 }
} ...
#endif When the above code is compiled and
executed, it produces the following result −
Value of mean : 3.400000 Usual Arithmetic Conversion
It should be noted here that the cast operator The usual arithmetic conversions are
has precedence over division, so the value #include <stdio.h>
implicitly performed to cast their values to a
of sum is first converted to type double and common type. The compiler first
main() {
finally it gets divided by count yielding a double performs integer promotion; if the operands still
value. have different types, then they are converted to
int i = 17;
the type that appears highest in the following
Type conversions can be implicit which is char c = 'c'; /* ascii value is
hierarchy − 99 */
performed by the compiler automatically, or it
can be specified explicitly through the use of float sum;
the cast operator. It is considered good
programming practice to use the cast operator sum = i + c;
whenever type conversions are necessary. printf("Value of sum : %f\n", sum
);
Integer Promotion }
Integer promotion is the process by which When the above code is compiled and
values of integer type "smaller" executed, it produces the following result −
than int or unsigned int are converted either
to int or unsigned int. Consider an example of Value of sum : 116.000000
adding a character with an integer −
Here, it is simple to understand that first c gets
converted to integer, but as the final value is
double, usual arithmetic conversion applies and
#include <stdio.h> the compiler converts i and c into 'float' and
adds them yielding a 'float' result.
main() {
As such, C programming does not provide
direct support for error handling but being a
int i = 17;
system programming language, it provides you
char c = 'c'; /* ascii value is
access at lower level in the form of return
99 */
values. Most of the C or even Unix function
int sum;
calls return -1 or NULL in case of any error and
sum = i + c; set an error code errno. It is set as a global
printf("Value of sum : %d\n", sum variable and indicates an error occurred during
); any function call. You can find various error
} codes defined in <error.h> header file.
So a C programmer can check the returned
When the above code is compiled and values and can take appropriate action
executed, it produces the following result − depending on the return value. It is a good
Value of sum : 116 practice, to set errno to 0 at the time of
initializing a program. A value of 0 indicates
Here, the value of sum is 116 because the that there is no error in the program.
compiler is doing integer promotion and The usual arithmetic conversions are not
converting the value of 'c' to ASCII before performed for the assignment operators, nor for errno, perror(). and strerror()
performing the actual addition operation. the logical operators && and ||. Let us take the The C programming language
following example to understand the concept − provides perror() and strerror() functions
which can be used to display the text message } Program Exit Status
associated with errno.
When the above code is compiled and It is a common practice to exit with a value of
 The perror() function displays the string executed, it produces the following result − EXIT_SUCCESS in case of program coming
you pass to it, followed by a colon, a out after a successful operation. Here,
space, and then the textual Value of errno: 2 EXIT_SUCCESS is a macro and it is defined as
representation of the current errno Error printed by perror: No such 0.
value. file or directory
Error opening file: No such file or If you have an error condition in your program
 The strerror() function, which returns a directory and you are coming out then you should exit
pointer to the textual representation of with a status EXIT_FAILURE which is defined
Divide by Zero Errors
the current errno value. as -1. So let's write above program as follows −
It is a common problem that at the time of
Let's try to simulate an error condition and try to dividing any number, programmers do not
open a file which does not exist. Here I'm using check if a divisor is zero and finally it creates a
both the functions to show the usage, but you runtime error. #include <stdio.h>
can use one or more ways of printing your #include <stdlib.h>
errors. Second important point to note is that The code below fixes this by checking if the
you should use stderr file stream to output all divisor is zero before dividing − main() {
the errors.
int dividend = 20;
#include <stdio.h> int divisor = 5;
#include <errno.h> #include <stdio.h> int quotient;
#include <string.h> #include <stdlib.h>
if( divisor == 0) {
extern int errno ; main() { fprintf(stderr, "Division by
zero! Exiting...\n");
int main () { int dividend = 20; exit(EXIT_FAILURE);
int divisor = 0; }
FILE * pf; int quotient;
int errnum; quotient = dividend / divisor;
pf = fopen ("unexist.txt", "rb"); if( divisor == 0){ fprintf(stderr, "Value of
fprintf(stderr, "Division by quotient : %d\n", quotient );
if (pf == NULL) { zero! Exiting...\n");
exit(-1); exit(EXIT_SUCCESS);
errnum = errno; }
fprintf(stderr, "Value of }Recursion is the process of repeating items in
errno: %d\n", errno); quotient = dividend / divisor; a self-similar way. In programming languages,
perror("Error printed by fprintf(stderr, "Value of if a program allows you to call a function inside
perror"); quotient : %d\n", quotient ); the same function, then it is called a recursive
fprintf(stderr, "Error opening call of the function.
file: %s\n", strerror( errnum )); exit(0);
} else { } void recursion() {
recursion(); /* function calls
fclose (pf); When the above code is compiled and itself */
} executed, it produces the following result − }
Division by zero! Exiting...
return 0; int main() {
recursion();
}
#include <stdio.h> Sometimes, you may come across a situation,
The C programming language supports when you want to have a function, which can
recursion, i.e., a function to call itself. But while int fibonacci(int i) { take variable number of arguments, i.e.,
using recursion, programmers need to be parameters, instead of predefined number of
careful to define an exit condition from the if(i == 0) { parameters. The C programming language
function, otherwise it will go into an infinite loop. return 0; provides a solution for this situation and you
} are allowed to define a function which can
Recursive functions are very useful to solve accept variable number of parameters based
many mathematical problems, such as if(i == 1) { on your requirement. The following example
calculating the factorial of a number, generating return 1; shows the definition of such a function.
Fibonacci series, etc. }
return fibonacci(i-1) + int func(int, ... ) {
Number Factorial .
fibonacci(i-2);
The following example calculates the factorial } .
of a given number using a recursive function − .
int main() { }

int i; int main() {


#include <stdio.h> func(1, 2, 3);
for (i = 0; i < 10; i++) { func(1, 2, 3, 4);
unsigned long long int }
printf("%d\t\n",
factorial(unsigned int i) { fibonacci(i)); It should be noted that the function func() has
}
if(i <= 1) { its last argument as ellipses, i.e. three dotes
return 1; (...) and the one just before the ellipses is
return 0;
} always an int which will represent the total
}
return i * factorial(i - 1); number variable arguments passed. To use
} When the above code is compiled and such functionality, you need to make use
executed, it produces the following result − of stdarg.h header file which provides the
int main() { functions and macros to implement the
int i = 12; 0 functionality of variable arguments and follow
printf("Factorial of %d is %d\n", 1 the given steps −
i, factorial(i)); 1
return 0; 2  Define a function with its last parameter
} 3 as ellipses and the one just before the
5 ellipses is always an int which will
When the above code is compiled and 8 represent the number of arguments.
executed, it produces the following result − 13
21  Create a va_list type variable in the
Factorial of 12 is 479001600 34 function definition. This type is defined
Fibonacci Series in stdarg.h header file.

The following example generates the Fibonacci  Use int parameter and va_start macro


When the above code is compiled and to initialize the va_list variable to an
series for a given number using a recursive
executed, it produces the following result − argument list. The macro va_start is
function −
Value of quotient : 4 defined in stdarg.h header file.
 Use va_arg macro and va_list variable function average() has been called twice and char name[100];
to access each item in argument list. each time the first argument represents the
But now let us consider a situation where you
total number of variable arguments being
 Use a macro va_end to clean up the have no idea about the length of the text you
passed. Only ellipses will be used to pass
memory assigned to va_list variable. need to store, for example, you want to store a
variable number of arguments.
detailed description about a topic. Here we
Now let us follow the above steps and write Average of 2, 3, 4, 5 = 3.500000 need to define a pointer to character without
down a simple function which can take the Average of 5, 10, 15 = 10.000000 defining how much memory is required and
variable number of parameters and return their later, based on requirement, we can allocate
average − memory as shown in the below example −
This chapter explains dynamic memory
management in C. The C programming
#include <stdio.h> language provides several functions for
#include <stdarg.h> memory allocation and management. These #include <stdio.h>
functions can be found in #include <stdlib.h>
double average(int num,...) { the <stdlib.h> header file. #include <string.h>

va_list valist; Sr.No. int main() {


double sum = 0.0;
int i; char name[100];
char *description;
/* initialize valist for num 1
void *calloc(int num, int size);
number of arguments */ strcpy(name, "Zara Ali");
va_start(valist, num); This function allocates an array of num elements each of which size in bytes will be
/* allocate memory dynamically */
/* access all the arguments description = malloc( 200 *
assigned to valist */ 2 sizeof(char) );
void free(void *address);
for (i = 0; i < num; i++) {
sum += va_arg(valist, int); This function releases a block of memory block specified by address. == NULL ) {
if( description
} fprintf(stderr, "Error -
unable to allocate required
3 memory\n");
/* clean memory reserved for void *malloc(int num);
valist */ } else {
va_end(valist); This function allocates an array of num bytes and leave them uninitialized.
strcpy( description, "Zara ali
a DPS student in class 10th");
return sum/num; }
4
} void *realloc(void *address, int newsize);
printf("Name = %s\n", name );
int main() { This function re-allocates memory extending it upto
printf("Description: %s\n",
printf("Average of 2, 3, 4, 5 = description );
%f\n", average(4, 2,3,4,5)); Allocating Memory Dynamically }
printf("Average of 5, 10, 15 =
%f\n", average(3, 5,10,15)); While programming, if you are aware of the When the above code is compiled and
} size of an array, then it is easy and you can executed, it produces the following result.
define it as an array. For example, to store a
Name = Zara Ali
When the above code is compiled and name of any person, it can go up to a maximum
Description: Zara ali a DPS student
executed, it produces the following result. It of 100 characters, so you can define something
in class 10th
should be noted that the as follows −
Same program can be written strcpy( description, "Zara ali The command line arguments are handled
using calloc(); only thing is you need to a DPS student."); using main() function arguments
replace malloc with calloc as follows − } where argc refers to the number of arguments
passed, and argv[] is a pointer array which
calloc(200, sizeof(char)); /* suppose you want to store points to each argument passed to the
bigger description */ program. Following is a simple example which
So you have complete control and you can checks if there is any argument supplied from
description =
pass any size value while allocating memory, the command line and take action accordingly
realloc( description, 100 *
unlike arrays where once the size defined, you sizeof(char) ); −
cannot change it.
if( description == NULL ) { #include <stdio.h>
Resizing and Releasing Memory
fprintf(stderr, "Error -
When your program comes out, operating unable to allocate required int main( int argc, char *argv[] )
system automatically release all the memory memory\n"); {
allocated by your program but as a good } else {
practice when you are not in need of memory strcat( description, "She is if( argc == 2 ) {
anymore then you should release that memory in class 10th"); printf("The argument supplied
by calling the function free(). } is %s\n", argv[1]);
}
Alternatively, you can increase or decrease the else if( argc > 2 ) {
printf("Name = %s\n", name );
size of an allocated memory block by calling printf("Description: %s\n", printf("Too many arguments
the function realloc(). Let us check the above description ); supplied.\n");
program once again and make use of realloc() }
and free() functions − /* release memory using free() else {
function */ printf("One argument
free(description); expected.\n");
} }
#include <stdio.h> }
#include <stdlib.h>
When the above code is compiled and
#include <string.h> When the above code is compiled and
executed, it produces the following result.
executed with single argument, it produces the
int main() { Name = Zara Ali following result.
Description: Zara ali a DPS
char name[100]; student.She is in class 10th $./a.out testing
char *description; The argument supplied is testing
You can try the above example without re-
strcpy(name, "Zara Ali"); allocating extra memory, and strcat() function When the above code is compiled and
will give an error due to lack of available executed with a two arguments, it produces the
/* allocate memory dynamically */ memory in description. following result.
description = malloc( 30 * It is possible to pass some values from the
sizeof(char) ); $./a.out testing1 testing2
command line to your C programs when they Too many arguments supplied.
are executed. These values are
if( description == NULL ) { called command line arguments and many
fprintf(stderr, "Error - When the above code is compiled and
times they are important for your program executed without passing any argument, it
unable to allocate required especially when you want to control your
memory\n"); produces the following result.
program from outside instead of hard coding
} else { those values inside the code. $./a.out
One argument expected Progranm name ./a.out
The argument supplied is testing1
It should be noted that argv[0] holds the name testing2
of the program itself and argv[1] is a pointer to
the first command line argument supplied, and
*argv[n] is the last argument. If no arguments
are supplied, argc will be one, and if you pass
one argument then argc is set at 2.
You pass all the command line arguments
separated by a space, but if argument itself has
a space then you can pass such arguments by
putting them inside double quotes "" or single
quotes ''. Let us re-write above example once
again where we will print program name and
we also pass a command line argument by
putting inside double quotes −

#include <stdio.h>

int main( int argc, char *argv[] )


{

printf("Program name %s\n",


argv[0]);

if( argc == 2 ) {
printf("The argument supplied
is %s\n", argv[1]);
}
else if( argc > 2 ) {
printf("Too many arguments
supplied.\n");
}
else {
printf("One argument
expected.\n");
}
}

When the above code is compiled and


executed with a single argument separated by
space but inside double quotes, it produces the
following result.
$./a.out "testing1 testing2"

You might also like