C Programming Unit I Notes
C Programming Unit I Notes
UNIT – I
The example discussed above illustrates how a simple C program looks like and how
the program segment works. A C program may contain one or more sections which are
figured above.
The Documentation section usually contains the collection of comment lines giving the
name of the program, author’s or programmer’s name and few other details. The
second part is the link-section which gives instruction to the compiler to connect to the
various functions from the system library. The Definition section describes all the
symbolic-constants. The global declaration section is used to define those variables that
are used globally within the entire program and is used in more than one function. This
section also declares all the user-defined functions. Then comes the main(). All C
programs must have a main() which contains two parts:
Declaration part
Execution part
The declaration part is used to declare all variables that will be used within the
program. There needs to be at least one statement in the executable part and these two
parts are declared within the opening and closing curly braces of the main(). The
execution of program begins at the opening brace ‘{‘ and ends with the closing brace ‘}’.
Also it has to be noted that all the statements of these two parts needs to be terminated
with semi-colon.
The sub-program section deals with all user defined functions that are called from the
main(). These user defined functions are declared and defined usually after the main()
function.
1.3 Data Types
Each variable in C has an associated data type. Each data type requires different
amounts of memory and has some specific operations which can be performed over it.
Let us briefly describe them one by one:
Following are the examples of some very common data types used in C:
char: The most basic data type in C. It stores a single character and requires a single
byte of memory in almost all compilers.
int: As the name suggests, an int variable is used to store an integer.
float: It is used to store decimal numbers (numbers with floating point value) with
single precision.
double: It is used to store decimal numbers (numbers with floating point value) with
double precision.
Different data types also have different ranges upto which they can store numbers.
These ranges may vary from compiler to compiler. Below is list of ranges along with the
memory requirement and format specifiers on 32 bit gcc compiler.
Data Type Memory (bytes) Range Format Specifier
short int 2 -32,768 to 32,767 %hd
unsigned short int 2 0 to 65,535 %hu
unsigned int 4 0 to 4,294,967,295 %u
int 4 -2,147,483,648 to 2,147,483,647 %d
long int 4 -2,147,483,648 to 2,147,483,647 %ld
unsigned long int 4 0 to 4,294,967,295 %lu
return 0;
}
Output:
Hello World!
Hello! I am a character. My value is G and my size is 1 byte.
Hello! I am an integer. My value is 1 and my size is 4 bytes.
Hello! I am a double floating point variable. My value is 3.140000 and my size i
s 8 bytes.
Bye! See you soon. :)
#include <stdio.h>
/* function declaration */
void func(void);
main() {
while(count--) {
func();
}
/* function definition */
void func( void ) {
int count ;
extern void write_extern();
main() {
count = 5;
write_extern();
}
Second File: support.c
#include <stdio.h>
void write_extern(void) {
printf("count is %d\n", count);
}
1.5 Constants
Constants refer to fixed values that the program may not alter during its execution.
These fixed values are also called literals.
Constants can be of any of the basic data types like an integer constant, a floating
constant, a character constant, or a string literal. There are enumeration constants as well.
Constants are treated just like regular variables except that their values cannot be
modified after their definition.
Integer Literals
An integer literal can be a decimal, octal, or hexadecimal constant. A prefix specifies
the base or radix: 0x or 0X for hexadecimal, 0 for octal, and nothing for decimal.
An integer literal can also have a suffix that is a combination of U and L, for unsigned
and long, respectively. The suffix can be uppercase or lowercase and can be in any
order.
Here are some examples of integer literals −
212 /* Legal */
215u /* Legal */
0xFeeL /* Legal */
078 /* Illegal: 8 is not an octal digit */
032UU /* Illegal: cannot repeat a suffix */
Following are other examples of various types of integer literals −
85 /* decimal */
0213 /* octal */
0x4b /* hexadecimal */
30 /* int */
30u /* unsigned int */
30l /* long */
30ul /* unsigned long */
Floating-point Literals
A floating-point literal has an integer part, a decimal point, a fractional part, and an
exponent part. You can represent floating point literals either in decimal form or
exponential form.
While representing decimal form, you must include the decimal point, the exponent, or
both; and while representing exponential form, you must include the integer part, the
fractional part, or both. The signed exponent is introduced by e or E.
Here are some examples of floating-point literals −
3.14159 /* Legal */
314159E-5L /* Legal */
510E /* Illegal: incomplete exponent */
int main() {
printf("Hello\tWorld\n\n");
return 0;
}
When the above code is compiled and executed, it produces the following result −
Hello World
String Literals
String literals or constants are enclosed in double quotes "". A string contains
characters that are similar to character literals: plain characters, escape sequences, and
universal characters.
You can break a long line into multiple lines using string literals and separating them
using white spaces.
Here are some examples of string literals. All the three forms are identical strings.
"hello, dear"
"hello, \
dear"
#define LENGTH 10
int main() {
int area;
return 0;
}
When the above code is compiled and executed, it produces the following result −
value of area : 50
The const Keyword
You can use const prefix to declare constants with a specific type as follows −
const type variable = value;
The following example explains it in detail −
#include <stdio.h>
int main() {
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE = '\n';
int area;
return 0;
}
When the above code is compiled and executed, it produces the following result −
value of area : 50
Note that it is a good programming practice to define constants in CAPITALS.
1.6 Enumeration Constants
Enumeration (or enum) is a user defined data type in C. It is mainly used to assign
names to integral constants, the names make a program easy to read and maintain.
enum State {Working = 1, Failed = 0};
The keyword ‘enum’ is used to declare new enumeration types in C and C++.
Following is an example of enum declaration.
// The name of enumeration is "flag" and the constant
// are the values of the flag. By default, the values
// Or
int main()
{
enum week day;
day = Wed;
printf("%d",day);
return 0;
}
Output:
2
In the above example, we declared “day” as the variable and the value of “Wed” is
allocated to day, which is 2. So as a result, 2 is printed.
Another example of enumeration is:
// Another example program to demonstrate working
// of enum in C
#include<stdio.h>
int main()
{
int i;
for (i=Jan; i<=Dec; i++)
printf("%d ", i);
int main()
{
printf("%d, %d, %d", Working, Failed, Freezed);
return 0;
}
Output:
1, 0, 0
2. If we do not explicitly assign values to enum names, the compiler by default assigns
values starting from 0. For example, in the following C program, sunday gets value 0,
monday gets 1, and so on.
#include <stdio.h>
enum day {sunday, monday, tuesday, wednesday, thursday, friday,
saturday};
int main()
{
enum day d = thursday;
printf("The day number stored in d is %d", d);
return 0;
}
Output:
The day number stored in d is 4
3. We can assign values to some name in any order. All unassigned names get value as
value of previous name plus one.
#include <stdio.h>
enum day {sunday = 1, monday, tuesday = 5,
wednesday, thursday = 10, friday, saturday};
4. The value assigned to enum names must be some integeral constant, i.e., the value
must be in range from minimum possible integer value to maximum possible integer
value.
5. All enum constants must be unique in their scope. For example, the following
program fails in compilation.
enum state {working, failed};
enum result {failed, passed};
1.7 Keywords
Keywords in C Programming Language :
1. Keywords are those words whose meaning is already defined by Compiler
2. Cannot be used as Variable Name
3. There are 32 Keywords in C
4. C Keywords are also called as Reserved words .
32 Keywords in C Programming Language
auto double int struct
do if static while
1.8 Operator
An operator is a symbol that tells the compiler to perform specific mathematical or
logical functions. C language is rich in built-in operators and provides the following
types of operators −
Arithmetic Operators
Relational Operators
Logical Operators
Bitwise Operators
Assignment Operators
Misc Operators
We will, in this chapter, look into the way each operator works.
Arithmetic Operators
The following table shows all the arithmetic operators supported by the C language.
Assume variable A holds 10 and variable Bholds 20 then −
Show Examples
Operator Description Example
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
~ (~A ) = -61,
i.e,. 1100
Binary Ones Complement Operator is
0011 in 2's
unary and has the effect of 'flipping' bits.
complement
form.
?: If Condition is true
Conditional Expression. ? then value X :
otherwise value Y
1.8.1 Operators Precedence
Operator precedence determines the grouping of terms in an expression and decides
how an expression is evaluated. Certain operators have higher precedence than others;
for example, the multiplication operator has a higher precedence than the addition
operator.
For example, x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has a higher
precedence than +, so it first gets multiplied with 3*2 and then adds into 7.
Here, operators with the highest precedence appear at the top of the table, those with
the lowest appear at the bottom. Within an expression, higher precedence operators
will be evaluated first.
1 == 2 != 3
Here, operators == and != have same precedence. The associativity of both == and != is
left to right, i.e, the expression on the left is executed first and moves towards the right.
Thus, the expression above is equivalent to :
((1 == 2) != 3)
i.e, (1 == 2) executes first resulting into 0 (false)
then, (0 != 3) executes resulting into 1 (true)
Output
The table below shows all the operators in C with precedence and associativity.
Note: Precedence of operators decreases from top to bottom in the given table.
() Functional call
[] Array element reference
Left to right
-> Indirect member selection
. Direct member selection
* Multiply
/ Divide Left to right
% Remainder
+ Binary plus(Addition)
Left to right
- Binary minus(subtraction)
== Equal to
Left to right
!= Not equal to
= Simple assignment
Right to left
*= Assign product
/= Assign quotient
%= Assign remainder
-= Assign sum
&= Assign difference
^= Assign bitwise AND
|= Assign bitwise XOR
<<= Assign bitwise OR
>>= Assign left shift
Assign right shift
1.9 Expression
1. In programming, an expression is any legal combination of symbols that
represents a value.
2. C Programming Provides its own rules of Expression, whether it is legal
expression or illegal expression. For example, in the C language x+5 is a legal
expression.
3. Every expression consists of at least one operand and can have one or more
operators.
4. Operands are values and Operators are symbols that represent particular actions.
Valid C Programming Expression :
C Programming code gets compiled firstly before execution. In the different phases of
compiler, c programming expression is checked for its validity.
Expressions Validity
When we say Input, it means to feed some data into a program. An input can be given
in the form of a file or from the command line. C programming provides a set of built-
in functions to read the given input and feed it to the program as per requirement.
When we say Output, it means to display some data on screen, printer, or in any file. C
programming provides a set of built-in functions to output the data on the computer
screen as well as to save it in text or binary files.
The Standard Files
C programming treats all the devices as files. So devices such as the display are
addressed in the same way as files and the following three files are automatically
opened when a program executes to provide access to the keyboard and screen.
Standard File File Pointer Device
int c;
return 0;
}
When the above code is compiled and executed, it waits for you to input some text.
When you enter a text and press enter, then the program proceeds and reads only a
single character and displays it as follows −
$./a.out
Enter a value : this is test
You entered: t
The gets() and puts() Functions
The char *gets(char *s) function reads a line from stdin into the buffer pointed to
by s until either a terminating newline or EOF (End of File).
The int puts(const char *s) function writes the string 's' and 'a' trailing newline
to stdout.
#include <stdio.h>
int main( ) {
char str[100];
return 0;
}
char str[100];
int i;
return 0;
}
When the above code is compiled and executed, it waits for you to input some text.
When you enter a text and press enter, then program proceeds and reads the input and
displays it as follows −
$./a.out
Enter a value : seven 7
You entered: seven 7
Here, it should be noted that scanf() expects input in the same format as you provided
%s and %d, which means you have to provide valid inputs like "string integer". If you
provide "string string" or "integer integer", then it will be assumed as wrong input.
Secondly, while reading a string, scanf() stops reading as soon as it encounters a space,
so "this is test" are three strings for scanf().
x = 5;
The value of a variable may be changed. For example, if x has the value 5, then the
assignment statement
x = x + 1;
variable = expression;
where:
Examples:
int i = 0;
myDog.name = "Fido";
Intermediate:
i = j = k = 0;
Simple if statement
The general form of a simple if statement is,
if(expression)
{
statement inside;
}
statement outside;
If the expression returns true, then the statement-inside will be executed,
otherwise statement-inside is skipped and only the statement-outside is executed.
Example:
#include <stdio.h>
void main( )
{
int x, y;
x = 15;
y = 13;
if (x > y )
{
printf("x is greater than y");
}
}
x is greater than y
if...else statement
The general form of a simple if...else statement is,
if(expression)
{
statement block1;
}
else
{
statement block2;
}
If the expression is true, the statement-block1 is executed, else statement-block1 is
skipped and statement-block2 is executed.
Example:
void main( )
{
int x, y;
x = 15;
y = 18;
if (x > y )
{
printf("x is greater than y");
}
else
{
printf("y is greater than x");
}
}
y is greater than x
void main( )
{
int a, b, c;
printf("Enter 3 numbers...");
scanf("%d%d%d",&a, &b, &c);
else if ladder
The general form of else-if ladder is,
if(expression1)
{
statement block1;
}
else if(expression2)
{
statement block2;
}
else if(expression3 )
{
statement block3;
}
else
default statement;
The expression is tested from the top(of the ladder) downwards. As soon as
a true condition is found, the statement associated with it is executed.
Example :
#include <stdio.h>
void main( )
{
Points to Remember
1. In if statement, a single statement can be included without enclosing it into curly
braces { ... }
int a = 5;
if(a > 4)
printf("success");
No curly braces are required in the above case, but if we have more than one
statement inside ifcondition, then we must enclose them inside curly braces.
2. == must be used for comparison in the expression of if condition, if you use = the
expression will always return true, because it performs assignment not comparison.
3. Other than 0(zero), all other values are considered as true.
if(27)
printf("hello");
In above example, hello will be printed.
1.13 Switch Statement
Switch case statements are a substitute for long if statements that compare a variable to
several integral values
The switch statement is a multiway branch statement. It provides an easy way to
dispatch execution to different parts of code based on the value of the expression.
Switch is a control statement that allows a value to change control of execution.
Syntax:
switch (n)
{
case 1: // code to be executed if n = 1;
break;
case 2: // code to be executed if n = 2;
break;
default: // code to be executed if n doesn't match any cases
}
Important Points about Switch Case Statements:
1. The expression provided in the switch should result in a constant value otherwise
it would not be valid.
Valid expressions for switch:
// Constant expressions allowed
switch(1+2+23)
switch(1*2+3%4)
Invalid switch expressions for switch:
// Variable expression not allowed
switch(ab+cd)
switch(a+b+c)
2. Duplicate case values are not allowed.
3. The default statement is optional.Even if the switch case statement do not have a
default statement,
it would run without any problem.
4. The break statement is used inside the switch to terminate a statement sequence.
When a break statement is reached, the switch terminates, and the flow of control
jumps to the next line following the switch statement.
5. The break statement is optional. If omitted, execution will continue on into the
next case. The flow of control will fall through to subsequent cases until a break is
reached.
6. Nesting of switch statements are allowed, which means you can have switch
statements inside another switch. However nested switch statements should be
avoided as it makes program more complex and less readable.
Example:
// Following is a simple program to demonstrate
// syntax of switch.
#include <stdio.h>
int main()
{
int x = 2;
switch (x)
{
case 1: printf("Choice is 1");
break;
case 2: printf("Choice is 2");
break;
case 3: printf("Choice is 3");
break;
default: printf("Choice other than 1, 2 and 3");
break;
}
return 0;
}
Output:
Choice is 2
Types of Loops.
There are three type of Loops available in 'C' programming language.
while loop
for loop
do..while
Difference between conditional and looping statement
Conditional statement executes only once in the program where as looping
statements executes repeatedly several number of time.
While loop
In while loop First check the condition if condition is true then control goes inside
the loop body other wise goes outside the body. while loop will be repeats in clock
wise direction.
Syntax
Assignment;
while(condition)
{
Statements;
......
Increment/decrements (++ or --);
}
Note: If while loop condition never false then loop become infinite loop.
Example of while loop
#include<stdio.h>
#include<conio.h>
void main()
{
int i;
clrscr();
i=1;
while(i<5)
{
printf("\n%d",i);
i++;
}
getch();
}
Output
1
2
3
4
For loop
for loop is a statement which allows code to be repeatedly executed. For loop
contains 3 parts Initialization, Condition and Increment or Decrements.
#include<stdio.h>
#include<conio.h>
void main()
{
int i;
clrscr();
for(i=1;i<5;i++)
{
printf("\n%d",i);
}
getch();
}
Output
2
3
4
do-while
A do-while loop is similar to a while loop, except that a do-while loop is execute at
least one time.
A do while loop is a control flow statement that executes a block of code at least
once, and then repeatedly executes the block, or not, depending on a given condition
at the end of the block (in while).
Syntax
do
{
Statements;
........
Increment/decrement (++ or --)
} while();
#include<stdio.h>
#include<conio.h>
void main()
{
int i;
clrscr();
i=1;
do
{
printf("\n%d",i);
i++;
}
while(i<5);
getch();
}
Output
1
2
3
4
Nested loop
In Nested loop one loop is place within another loop body.
When we need to repeated loop body itself n number of times use nested loops.
Nested loops can be design upto 255 blocks.
1.15 Pre-processor directives
The C Preprocessor is not a part of the compiler, but is a separate step in the
compilation process. In simple terms, a C Preprocessor is just a text substitution tool
and it instructs the compiler to do required pre-processing before the actual
compilation. We'll refer to the C Preprocessor as CPP.
All preprocessor commands begin with a hash symbol (#). It must be the first nonblank
character, and for readability, a preprocessor directive should begin in the first column.
The following section lists down all the important preprocessor directives −
Sr.No. Directive & Description
1 #define
Substitutes a preprocessor macro.
2 #include
Inserts a particular header from another file.
3 #undef
Undefines a preprocessor macro.
4 #ifdef
Returns true if this macro is defined.
5 #ifndef
Returns true if this macro is not defined.
6 #if
Tests if a compile time condition is true.
7 #else
The alternative for #if.
9 #endif
Ends preprocessor conditional.
10 #error
Prints error message on stderr.
11 #pragma
Issues special commands to the compiler, using a
standardized method.
Preprocessors Examples
Analyze the following examples to understand various directives.
#define MAX_ARRAY_LENGTH 20
This directive tells the CPP to replace instances of MAX_ARRAY_LENGTH with 20.
Use #define for constants to increase readability.
#include <stdio.h>
#include "myheader.h"
These directives tell the CPP to get stdio.h from System Libraries and add the text to
the current source file. The next line tells CPP to get myheader.h from the local
directory and add the content to the current source file.
#undef FILE_SIZE
#define FILE_SIZE 42
It tells the CPP to undefine existing FILE_SIZE and define it as 42.
#ifndef MESSAGE
#define MESSAGE "You wish!"
#endif
It tells the CPP to define MESSAGE only if MESSAGE isn't already defined.
#ifdef DEBUG
/* Your debugging statements here */
#endif
It tells the CPP to process the statements enclosed if DEBUG is defined. This is useful if
you pass the -DDEBUG flag to the gcc compiler at the time of compilation. This will
define DEBUG, so you can turn debugging on and off on the fly during compilation.
Predefined Macros
ANSI C defines a number of macros. Although each one is available for use in
programming, the predefined macros should not be directly modified.
Sr.No. Macro & Description
1 __DATE__
The current date as a character literal in "MMM DD
YYYY" format.
3 __FILE__
This contains the current filename as a string literal.
4 __LINE__
This contains the current line number as a decimal
constant.
5 __STDC__
Defined as 1 when the compiler complies with the ANSI
standard.
Let's try the following example −
#include <stdio.h>
main() {
}
When the above code in a file test.c is compiled and executed, it produces the
following result −
File :test.c
Date :Jun 2 2012
Time :03:36:24
Line :8
ANSI :1
Preprocessor Operators
The C preprocessor offers the following operators to help create macros −
The Macro Continuation (\) Operator
A macro is normally confined to a single line. The macro continuation operator (\) is
used to continue a macro that is too long for a single line. For example −
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
The Stringize (#) Operator
The stringize or number-sign operator ( '#' ), when used within a macro definition,
converts a macro parameter into a string constant. This operator may be used only in a
macro having a specified argument or parameter list. For example −
#include <stdio.h>
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
int main(void) {
message_for(Carole, Debra);
return 0;
}
When the above code is compiled and executed, it produces the following result −
Carole and Debra: We love you!
The Token Pasting (##) Operator
The token-pasting operator (##) within a macro definition combines two arguments. It
permits two separate tokens in the macro definition to be joined into a single token. For
example −
#include <stdio.h>
int main(void) {
int token34 = 40;
tokenpaster(34);
return 0;
}
When the above code is compiled and executed, it produces the following result −
token34 = 40
It happened so because this example results in the following actual output from the
preprocessor −
printf ("token34 = %d", token34);
This example shows the concatenation of token##n into token34 and here we have
used both stringize and token-pasting.
The Defined() Operator
The preprocessor defined operator is used in constant expressions to determine if an
identifier is defined using #define. If the specified identifier is defined, the value is true
(non-zero). If the symbol is not defined, the value is false (zero). The defined operator
is specified as follows −
#include <stdio.h>
int main(void) {
printf("Here is the message: %s\n", MESSAGE);
return 0;
int main(void) {
printf("Max between 20 and 10 is %d\n", MAX(10, 20));
return 0;
}
When the above code is compiled and executed, it produces the following result −
Max between 20 and 10 is 20
In the above output, source file is filled with lots and lots of info, but at the end our
code is preserved.
Analysis:
printf contains now a + b rather than add(a, b) that’s because macros have
expanded.
Comments are stripped off.
#include<stdio.h> is missing instead we see lots of code. So header files has been
expanded and included in our source file.
Compiling
The next step is to compile filename.i and produce an; intermediate compiled output
file filename.s. This file is in assembly level instructions. Let’s see through this file
using $vi filename.s
The snapshot shows that it is in assembly language, which assembler can understand.
Assembly
In this phase the filename.s is taken as input and turned into filename.o by assembler.
This file contain machine level instructions. At this phase, only existing code is
converted into machine language, the function calls like printf() are not resolved. Let’s
view this file using $vi filename.o
Linking
This is the final phase in which all the linking of function calls with their definitions are
done. Linker knows where all these functions are implemented. Linker does some extra
work also, it adds some extra code to our program which is required when the program
starts and ends. For example, there is a code which is required for setting up the
environment like passing command line arguments. This task can be easily verified by
using $size filename.o and $size filename. Through these commands, we know that
how output file increases from an object file to an executable file. This is because of the
extra code that linker adds with our program.
Note that GCC by default does dynamic linking, so printf() is dynamically linked in
above program. Refer this, this and this for more details on static and dynamic linkings.