0% found this document useful (0 votes)
17 views516 pages

Essential C Programming Guide

C programming is a general-purpose language developed in 1972, primarily for system development and is widely used due to its efficiency and structured nature. It is essential for software engineers, providing a foundation for learning other programming languages and allowing direct hardware interaction. The language has various applications, including operating systems, compilers, and embedded systems, and features such as portability, extensibility, and a rich set of built-in operators.

Uploaded by

mwendwafreddie
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views516 pages

Essential C Programming Guide

C programming is a general-purpose language developed in 1972, primarily for system development and is widely used due to its efficiency and structured nature. It is essential for software engineers, providing a foundation for learning other programming languages and allowing direct hardware interaction. The language has various applications, including operating systems, compilers, and embedded systems, and features such as portability, extensibility, and a rich set of built-in operators.

Uploaded by

mwendwafreddie
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

C PROGRAMMING NOTES

C programming is a general-purpose, procedural, imperative computer programming language


developed in 1972 by Dennis M. Ritchie at the Bell Telephone Laboratories to develop the
UNIX operating system. C is the most widely used computer language. It keeps fluctuating at
number one scale of popularity along with Java programming language, which is also equally
popular and most widely used among modern software programmers.

Why to Learn C Programming?

C programming language is a MUST for students and working professionals to become a great
Software Engineer especially when they are working in Software Development Domain. Here
are some of the important reasons why you should learn C Programming −

 It is a structured programming language and you can use the skills learned in C to master
other programming languages.
 You can use C program to write efficient codes and develop robust projects.
 C is a low-level language and you can use it to interact more directly with the computer's
hardware and memory.

Facts about C

C is the most widely used and popular System Programming Language. Most of the state-of-the-
art software have been implemented using C. Here are some facts about the C language:

 C was invented to write an operating system called UNIX. The UNIX OS was totally
written in C.
 C is a successor of B language which was introduced around the early 1970s.
 The language was formalized in 1988 by the American National Standard Institute (ANSI).

Hello World using C Programming

Just to give you a little excitement about C programming, I'm going to give you a small
conventional C Programming Hello World program. You can run it here using the "Edit and
Run" button.

#include <stdio.h>

int main() {
/* my first program in C */
printf("Hello, World! \n");

return 0;
}

Softwares developed using C Programming language

C was initially used for system development work, particularly the programs that make-up the
operating system. C was adopted as a system development language because it produces code
that runs nearly as fast as the code written in assembly language. Some examples of the use of C
are -

 Operating Systems
 Language Compilers
 Assemblers
 Text Editors
 Print Spoolers
 Network Drivers
 Modern Programs
 Databases
 Language Interpreters
 Utilities

Introduction

C is a general−purpose, high−level language that was originally developed by Dennis M. Ritchie


to develop the UNIX operating system at Bell Labs. C was originally first implemented on the
DEC PDP-11 computer in 1972.

In 1978, Brian Kernighan and Dennis Ritchie produced the first publicly available description of
C, now known as the K&R standard.

The UNIX operating system, the C compiler, and essentially all UNIX application programs
have been written in C. C has now become a widely used professional language for various
reasons −

 Easy to learn
 Structured language
 It produces efficient programs
 It can handle low−level activities
 It can be compiled on a variety of computer platforms

Facts about C

 C was invented to write an operating system called UNIX.


 C is a successor of B language which was introduced around the early 1970s.
 The language was formalized in 1988 by the American National Standard Institute (ANSI).
 The UNIX OS was totally written in C.
 Today C is the most widely used and popular System Programming Language.
 Most of the state-of-the-art software have been implemented using C.
 Today's most popular Linux OS and RDBMS MySQL have been written in C.

Why Use C Language?

C was initially used for system development work, particularly the programs that make-up the
operating system. C was adopted as a system development language because it produces code
that runs nearly as fast as the code written in assembly language.

Some examples of the use of C might be −

 Operating Systems
 Language Compilers
 Assemblers
 Text Editors
 Print Spoolers
 Network Drivers
 Modern Programs
 Databases
 Language Interpreters
 Utilities

C covers all the basic concepts of programming. It's a base or mother programming language to
learn object−oriented programming like C++, Java, .Net, etc. Many modern programming
languages such as C++, Java, and Python have borrowed syntax and concepts from C.

Advantages of C Language

The following are the advantages of C language −

 Efficiency and speed − C is known for being high−performing and efficient. It can let you
work with memory at a low level, as well as allow direct access to hardware, making it
ideal for applications requiring speed and economical resource use.
 Portable − C programs can be compiled and executed on different platforms with minimal
or no modifications. This portability is due to the fact that the language has been
standardized and compilers are available for use on various operating systems globally.
 Close to Hardware − C allows direct manipulation of hardware through the use
of pointers and low−level operations. This makes it suitable for system programming and
developing applications that require fine-grained control over hardware resources.
 Standard Libraries − For common tasks such as input/output
operations, string manipulation, and mathematical computations, C comes with a large
standard library which helps developers write code more efficiently by leveraging
pre−built functions.
 Structured Programming − C helps to organize code into modular and
easy−to−understand structures. With functions, loops, and conditionals, developers can
produce clear code that is easy to maintain.
 Procedural Language − C follows a procedural paradigm that is often simpler and more
straightforward for some types of programming tasks.
 Versatility − C language is a versatile programming language and it can be used for
various types of software such as system applications, compilers, firmware, application
software, etc.

Drawbacks of C Language

The following are the disadvantages/drawbacks of C language −

 Manual Memory Management − C languages need manual memory management, where


a developer has to take care of allocating and deallocating memory explicitly.
 No Object−Oriented Feature − Nowadays, most of the programming languages support
the OOPs features. But C language does not support it.
 No Garbage Collection − C language does not support the concept of Garbage collection.
A developer needs to allocate and deallocate memory manually and this can be error-prone
and lead to memory leaks or inefficient memory usage.
 No Exception Handling − C language does not provide any library for handling
exceptions. A developer needs to write code to handle all types of expectations.

Applications of C Language

The following are the applications of C language −

 System Programming − C language is used to develop system software which are close
to hardware such as operating systems, firmware, language translators, etc.
 Embedded Systems − C language is used in embedded system programming for a wide
range of devices such as microcontrollers, industrial controllers, etc.
 Compiler and Interpreters − C language is very common to develop language compilers
and interpreters.
 Database Systems − Since C language is efficient and fast for low-level memory
manipulation. It is used for developing DBMS and RDBMS engines.
 Networking Software − C language is used to develop networking software such as
protocols, routers, and network utilities.
 Game Development − C language is widely used for developing games, gaming
applications, and game engines.
 Scientific and Mathematical Applications − C language is efficient in developing
applications where scientific computing is required. Applications such as simulations,
numerical analysis, and other scientific computations are usually developed in C language.
 Text Editor and IDEs − C language is used for developing text editors and integrated
development environments such as Vim and Emacs.

Getting Started with C Programming

To learn C effectively, we need to understand its structure first. Every programming language
has its programming structure. A typical structure of a C program includes several parts. The
following steps show the C structure of a regular C program−

Include Header Files

Include necessary header files that contain declarations of functions, constants, and macros that
can be used in one or more source code files. Some popular header files are as −

stdio.h − Provides input and output functions like printf and scanf.

#include <stdio.h>

stdlib.h − Contains functions involving memory allocation, rand function, and other utility
functions.

#include <stdlib.h>

math.h − Includes mathematical functions like sqrt, sin, cos, etc.

#include <math.h>

string.h − Includes functions for manipulating strings, such as strcpy, strlen, etc.

#include <string.h>

ctype.h − Functions for testing and mapping characters, like isalpha, isdigit, etc.

#include <ctype.h>

stdbool.h − Defines the boolean data type and values true and false.
#include <stdbool.h>

time.h − Contains functions for working with date and time.

#include <time.h>

limits.h − Defines various implementation-specific limits on integer types.

#include <limits.h>

Macros and Constants

Define any macros or constants that will be used throughout the program. Macros and constants
are optional.

Example

#include <stdio.h>
#define PI 3.14159
int main() {
float radius = 5.0;
float area = PI * radius * radius;

printf("Area of the circle: %f\n", area);


return 0;
}

Output

Area of the circle: 78.539749

Global Declarations in C

Global declarations are optional:

int globalVariable;
void sampleFunction();

Declare global variables and functions that will be used across different parts of the program.
Take a look at the following example −
#include <stdio.h>

// Global variable declaration


int globalVariable;

int main()
{
// Rest of the program
return 0;
}

Main Function

Every C program must have a main function. It is the entry point of the program. Take a look at
the following example −

int main() {
float radius = 5.0;
float area = PI * radius * radius;

printf("Area of the circle: %f\n", area);


return 0;
}

Functions in C

Define other functions as needed. The main function may call these functions. Take a look at the
following example:

#include <stdio.h>

// Global function declaration


void samplefunction();

int main() {
// Programming statements
return 0;
}
// Global function definition
void samplefunction () {
// Function programming statements implementation
}

A C program can vary from 3 lines to millions of lines and it should be written into one or more
text files with extension ".c"; for example, hello.c. You can use "vi", "vim" or any other text
editor to write your C program into a file.

This tutorial assumes that you know how to edit a text file and how to write source code inside a
program file.

Features of C Programming Language

Dennis Ritchie and Ken Thompson developed the C programming language in 1972, primarily to
re-implement the Unix kernel. Because of its features such as low-level memory access,
portability and cross-platform nature etc., C is still extremely popular. Most of the features of C
have found their way in many other programming languages.

The development of C has proven to be a landmark step in the history of computing. Even
though different programming languages and technologies dominate today in different
application areas such as web development, mobile apps, device drivers and utilities, embedded
systems, etc., the underlying technologies of all of them are inspired by the features of C
language.

The utility of any technology depends on its important features. The features also determine its
area of application. In this chapter, we shall take an overview of some of the significant features
of C language.

C is a Procedural and Structured Language

C is described as procedure-oriented and structured programming language. It is procedural


because a C program is a series of instructions that explain the procedure of solving a given
problem. It makes the development process easier.

In C, the logic of a process can be expressed in a structured or modular form with the use
of function calls. C is generally used as an introductory language to introduce programming to
school students because of this feature.

C is a General-Purpose Language

The C language hasn’t been developed with a specific area of application as a target. From
system programming to photo editing software, the C programming language is used in various
applications.
Some of the common applications of C programming include the development of Operating
Systems, databases, device drivers, etc.

C is a Fast Programming Language

C is a compiler-based language which makes the compilation and execution of codes faster. The
source code is translated into a hardware-specific machine code, which is easier for the CPU to
execute, without any virtual machine, as some of the other languages like Java need.

The fact that C is a statically typed language also makes it faster compared to dynamically typed
languages. Being a compiler-based language, it is faster as compared to interpreter-based
languages.

C is Portable

Another feature of the C language is its portability. C programs are machine-independent which
means that you can compile and run the same code on various machines with none or some
machine-specific changes.

C programming provides the functionality of using a single code on multiple systems depending
on the requirement.

C is Extensible

C is an extensible language. It means if a code is already written, you can add new features to it
with a few alterations. Basically, it allows adding new features, functionalities, and operations to
an existing C program.

Standard Libraries in C

Most of the C compilers are bundled with an extensive set of libraries with several built-in
functions. It includes OS-specific utilities, string manipulation, mathematical functions, etc.

Importantly, you can also create your user-defined functions and add them to the existing C
libraries. The availability of such a vast scope of functions and operations allows a programmer
to build a vast array of programs and applications using the C language.

Pointers in C

One of the unique features of C is its ability to manipulate the internal memory of the computer.
With the use of pointers in C, you can directly interact with the memory.

Pointers point to a specific location in the memory and interact directly with it. Using the C
pointers, you can interact with external hardware devices, interrupts, etc.
C is a Mid-Level Programming Language

High-level languages have features such as the use of mnemonic keywords, user-defined
identifiers, modularity etc. C programming language, on the other hand, provides a low-level
access to the memory. This makes it a mid-level language.

As a mid-level programming language, it provides the best of both worlds. For instance, C
allows direct manipulation of hardware, which high-level programming languages do not offer.

C Has a Rich Set of Built-in Operators

C is perhaps the language with the most number of built-in operators which are used in writing
complex or simplified C programs. In addition to the traditional arithmetic and comparison
operators, its binary and pointer related operators are important when bit-level manipulations are
required.

Recursion in C

C language provides the feature of recursion. Recursion means that you can create a function that
can call itself multiple times until a given condition is true, just like the loops.

Recursion in C programming provides the functionality of code reusability and backtracking.

User-defined Data Types in C

C has three basic data types in int, float and char. However, C programming has the provision to
define a data type of any combination of these three types, which makes it very powerful.

In C, you can define structures and union types. You also have the feature of
declaring enumerated data types.

Preprocessor Directives in C

In C, we have preprocessor directives such as #include, #define, etc. They are not the language
keywords. Preprocessor directives in C carry out some of the important roles such as importing
functions from a library, defining and expanding the macros, etc.

File Handling in C

C language doesn’t directly manipulate files or streams. Handling file IO is not a part of the C
language itself but instead is handled by libraries and their associated header files.
File handling is generally implemented through high-level I/O which works through streams. C
identifies stdin, stdout and stderr as standard input, output and error streams. These streams can
be directed to a disk file to perform read/write operations.

These are some of the important features of C language that make it one of the widely used and
popular computer languages.

C - Environment Setup

To start learning programming in C, the first step is to setup an environment that allows you to
enter and edit the program in C, and a compiler that builds an executable that can run on your
operating system. You need two software tools available on your computer, (a) The C Compiler
and (b) Text Editor.

The C Compiler

The source code written in the source file is the human readable source for your program. It
needs to be "compiled", into machine language so that your CPU can actually execute the
program as per the instructions given.

There are many C compilers available. Following is a select list of C compilers that are widely
used −

GNU Compiler Collection (GCC) − GCC is a popular open-source C compiler. It is available


for a wide range of platforms including Windows, macOS, and Linux. GCC is known for its
wide range of features and support for a variety of C standards.

Clang: Clang is an open-source C compiler that is part of the LLVM project. It is available for a
variety of platforms including Windows, macOS, and Linux. Clang is known for its speed and
optimization capabilities.

Microsoft Visual C++ − Microsoft Visual C++ is a proprietary C compiler that is developed by
Microsoft. It is available for Windows only. Visual C++ is known for its integration with the
Microsoft Visual Studio development environment.

Turbo C − Turbo C is a discontinued C compiler that was developed by Borland. It was popular
in the early 1990s, but it is no longer widely used.

The examples in this tutorial are compiled on the GCC compiler. The most frequently used and
free available compiler is the GNU C/C++ compiler. The following section explains how to
install GNU C/C++ compiler on various operating systems. We keep mentioning C/C++ together
because GNU gcc compiler works for both C and C++ programming languages.
Installation on UNIX/Linux

If you are using Linux or UNIX, then check whether GCC is installed on your system by
entering the following command from the command line −

$ gcc -v

If you have GNU compiler installed on your Ubuntu Linux machine, then it should print a
message as follows −

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v . . .
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04)

If GCC is not installed, then you will have to install it yourself using the detailed instructions
available at [Link]

Installation on Mac OS

If you use Mac OS X, the easiest way to obtain GCC is to download the Xcode development
environment from Apple's web site and follow the simple installation instructions. Once you
have Xcode setup, you will be able to use GNU compiler for C/C++.

Xcode is currently available at [Link]/technologies/tools/

Installation on Windows

To install GCC on Windows, you need to install MinGW. To install MinGW, go to the MinGW
downloads page, [Link] and follow the link to the MinGW
download page. Download the latest version of the MinGW installation program, mingw-w64-
[Link] from here.
While installing Min GW, at a minimum, you must install gcc-core, gcc-g++, binutils, and the
MinGW runtime, but you may wish to install more.

Add the bin subdirectory of your MinGW installation to your PATH environment variable, so
that you can specify these tools on the command line by their simple names.

After the installation is complete, you will be able to run gcc, g++, ar, ranlib, dlltool, and several
other GNU tools from the Windows command line.

Text Editor

You will need a Text Editor to type your program. Examples include Windows Notepad, OS Edit
command, Brief, Epsilon, EMACS, and vim or vi.

The name and version of the text editors can vary on different operating systems. For example,
Notepad will be used on Windows, and vim or vi can be used on windows as well as on Linux or
UNIX.

The files you create with your editor are called the source files and they contain the program
source codes. The source files for C programs are typically named with the extension ".c".

Before starting your programming, make sure you have one text editor in place and you have
enough experience to write a computer program, save it in a file, compile it and finally execute
it.

Using an IDE

Using a general-purpose text editor such as Notepad or vi for program development can be very
tedious. You need to enter and save the program with ".c" extension (say "hello.c"), and then
compile it with the following command −

gcc -c hello.c -o hello.o


gcc -o [Link] hello.o

The executable file is then run from the command prompt to obtain the output. However, if the
source code contains errors, the compilation will not be successful. Hence we need to repeatedly
switch between the editor program and command terminal. To avoid this tedious process, we
should an IDE (Integrated Development Environment).

There are many IDEs available for writing, editing, debugging and executing C programs.
Examples are CodeBlocks, NetBeans, VSCode, etc.

CodeBlocks is a popular open-source IDE for C and C++. It is available for installation on
various operating system platforms like Windows, Linux, MacOS.
For Windows, download [Link]
from [Link] URL. This will install CodeBlocks as
well as MinGW compiler on your computer. During the installation process, choose MinGW as
the compiler to use.

Example

After the installation is complete, launch it and enter the following code −

#include <stdio.h>

int main() {
/* my first program in C */
printf("Hello, World! \n");

return 0;
}

Output

On executing this code, you will get the following output −


Hello, World!

From the Build menu, build and run the program (use F9 shortcut). The Build Log window
shows successful compilation messages. The output (Hello World) is displayed in a separate
command prompt terminal.

C - Program Structure

A typical program in C language has certain mandatory sections and a few optional sections,
depending on the program's logic, complexity, and readability. Normally a C program starts with
one or more preprocessor directives (#include statements) and must have a main() function that
serves as the entry point of the program. In addition, there may be global declarations
of variables and functions, macros, other user-defined functions, etc.

The Preprocessor Section

The C compiler comes with several library files, having ".h" as an extension. A ".h" file (called a
"header file") consists of one or more predefined functions (also called "library functions") to be
used in the C program.

The library functions must be loaded in any C program. The "#include" statement is used to
include a header file. It is a "preprocessor directive".

For example, printf() and scanf() functions are needed to perform console I/O operations. They
are defined in the stdio.h file. Hence, you invariably find #include <stdio.h> statement at the top
of any C program. Other important and frequently used header files
include string.h, math.h, stdlib.h, etc.

There are other preprocessor directives such as #define which is used to define constants and
macros and #ifdef for conditional definitions.

The following statement defines a constant PI −

#define PI 3.14159

Example

Once a constant is defined, it can be used in the rest of the C program.

#include <stdio.h>
#define PI 3.14159
int main(){
int radius = 5;
float area = PI*radius*radius;
printf("Area: %f", area);
return 0;
}
Output

On executing this code, you will get the following output −

Area: 78.539749

You can also define a macro with the "#define" directive. It is similar to a function in C. We can
pass one or more arguments to the macro name and perform the actions in the code segment.

The following code defines AREA macro using the #define statement −

Example

#include <stdio.h>
#define PI 3.14159
#define AREA(r) (PI*r*r)
int main(){
int radius = 5;
float area = AREA(radius);
printf("Area: %f", area);
return 0;
}

Output

Area: 78.539749

Macros are generally faster in execution than the functions.

The main() Function

A C program is a collection of one or more functions. There are two types of functions in a C
program: library functions and user-defined functions.

There must be at least one user-defined function in a C program, whose name must be main().
The main() function serves as the entry point of the program. When the program is run, the
compiler looks for the main() function.

The main() function contains one or more statements. By default, each statement must end with a
semicolon. The statement may include variable declarations, decision control or loop constructs
or call to a library or another user-defined function.
In C, a function must have a data type. The data type of return value must match with the data
type of the function. By default, a function in C is of int type. Hence, if a function doesn’t have
a return statement, its type is int, and you may omit it in the function definition, but the
compiler issues a warning −

warning: return type defaults to 'int'

Example

A typical example of main() function is as follows −

#include <stdio.h>
int main() {
/* my first program in C */
printf("Hello, World! \n");
return 0;
}

Output

On executing this code, you will get the following output −

Hello, World!

The Global Declaration Section

This section consists of declaration of variables to be used across all the functions in a program.
Forward declarations of user-defined functions defined later in the program as well as user-
defined data types are also present in the global section.

Example of global variable declaration −

int total = 0;
float average = 0.0;

Example of forward declaration of a function −

float area(float height, float width);

Subroutines in a C Program
There may be more than one user-defined functions in a C program. Programming best practices
require that the programming logic be broken down to independent and reusable functions in a
structured manner.

Depending on the requirements, a C program may have one or more user-defined functions,
which may be called from the main() function or any other user-defined function as well.

Comments in a C Program

Apart from the programming elements of a C program such as variables, structures, loops,
functions, etc., the code may have a certain text inside "/* .. */" recognized as comments. Such
comments are ignored by the compiler.

Inserting comments in the code often proves to be helpful in documenting the program, and in
understanding as well as debugging the programming logic and errors.

If the /* symbol doesn’t have a matching */ symbol, the compiler reports an error: "Unterminated
comment".

A text between /* and */ is called as C-style comment, and is used to insert multi-line comments.

/*
Program to display Hello World
Author: Tutorialspoint
Built with codeBlocks
*/

A single line comment starts with a double forward-slash (//) and ends with a new line. It may
appear after a valid C statement also.

int age = 20; // variable to store age

However, a valid statement can’t be given in a line that starts with "//". Hence, the following
statement is erroneous:

// Variable to store age. int age=20;

Structure of the C Program

The following code shows the different sections in a C program −

/*Headers*/
#include <stdio.h>
#include <math.h>

/*forward declaration*/
float area_of_square(float);

/*main function*/
int main() {
/* my first program in C */
float side = 5.50;
float area = area_of_square(side);
printf ("Side=%5.2f Area=%5.2f", side, area);
return 0;
}

/*subroutine*/
float area_of_square(float side){
float area = pow(side,2);
return area;
}

Output

On executing this code, you will get the following output −

Side= 5.50 Area=30.25

C - Hello World

Every learner aspiring to become a professional software developer starts with writing a Hello
World program in the programming language he/she is learning. In this chapter, we shall learn
how to write a Hello World program in C language.

Hello World in C Language

Before writing the Hello World program, make sure that you have the C programming
environment set up in your computer. This includes the GCC compiler, a text editor, and
preferably an IDE for C programming such as CodeBlocks.
Example

The first step is to write the source code for the Hello World program. Open a text editor on your
computer. On Windows, open Notepad or Notepad++, enter the following code and save it as
"hello.c".

#include <stdio.h>

int main(){

/* my first program in C */
printf("Hello World! \n");

return 0;
}

Output

Run the code and check its output −

Hello World!

The Step-by-Step Execution of a C Program

Let us understand how the above program works in a step-by-step manner.

Step 1

The first statement in the above code is the #include statement that imports the stdio.h file in the
current C program. This is called a preprocessor directive. This header file contains the
definitions of several library functions used for stand IO operations. Since we shall be calling the
printf() function which is defined in the stdio.h library, we need to include it in the first step.

Step 2

Every C program must contain a main() function. The main() function in this program prints the
"Hello World" message on the console terminal.

Inside the main() function, we have inserted a comment statement that is ultimately ignored by
the compiler; it is for the documentation purpose.

The next statement calls the printf() function. In C, every statement must terminate with a
semicolon symbol (;), failing which the compiler reports an error.
The printf() function, imported from the stdio.h library file, echoes the Hello World string to the
standard output stream. In case of Windows, the standard output stream is the Command prompt
terminal and in case of Linux it is the Linux terminal.

In C, every function needs to have a return value. If the function doesn’t return anything, its
value is void. In the example above, the main() function has int as its return value. Since the
main() function doesn’t need to return anything, it is defined to return an integer "0". The "return
0" statement also indicates that the program has been successfully compiled and run.

Step 3

Next, we need to compile and build the executable from the source code ("hello.c").

If you are using Windows, open the command prompt in the folder in which "hello.c" has been
saved. The following command compiles the source code −

gcc -c hello.c -o hello.o

The -c option specifies the source code file to be compiled. This will result in an object file with
the name hello.o if the C program doesn’t have any errors. If it contains errors, they will be
displayed. For example, if we forget to put the semicolon at the end of the printf() statement, the
compilation result will show the following error −

helloworld.c: In function 'main':


helloworld.c:6:30: error: expected ';' before 'return'
printf("Hello, World! \n")
^
;
helloworld.c:8:4:
return 0;

To build an executable from the compiled object file, use the following command −

gcc -o [Link] hello.o

The [Link] is now ready to be run from the command prompt that displays the Hello World
message in the terminal.

C:\Users\user>hello
Hello World!

On Ubuntu Linux, the object file is first given executable permission before running it by
prefixing "./" to it.
$ chmod a+x a.o
$ ./a.o

You can also use an IDE such as CodeBlocks to enter the code, edit, debug and run the Hello
World program more conveniently.

Using CodeBlocks IDE for C Programming

CodeBlocks is one the most popular IDEs for C/C++ development. Install it if you have not
already done and open it. Create a new file from the File menu, enter the following code and
save it as "hello.c".

Example

#include <stdio.h>

int main(){

/* my first program in C */

printf("Hello World! \n");

return 0;
}

Output

Run the code and check its output −

Hello World!

Choose Build and Run option from the Build menu as shown below −
You can also use the F9 shortcut for the same. If the program is error-free, the Build Log tab
shows the following messages −

[Link] -c C:\Users\mlath\hello.c -o C:\Users\mlath\hello.o


[Link] -o C:\Users\mlath\[Link] C:\Users\mlath\hello.o
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))

Checking for existence: C:\Users\mlath \[Link]


Executing: '"C:\Program Files\CodeBlocks/cb_console_runner.exe" "C:\Users\mlath\[Link]"'
(in 'C:\Users\mlath\Documents')

In a separate command prompt window, the output will be displayed −

Hello World!

Process returned 0 (0x0) execution time : 0.236 s


Press any key to continue.

If the code contains errors, the build log tab echoes them. For instance, if we miss the trailing
semicolon in the printf() statement, the log will be as below −

You can use any other IDE to run the C program. You will need to follow the documentation of
the respective IDE for the purpose.

Running the Hello World successfully also confirms that the C programming environment is
working properly on your computer.

Compilation Process in C

C is a compiled language. Compiled languages provide faster execution performance as


compared to interpreted languages. Different compiler products may be used to compile a C
program. They are GCC, Clang, MSVC, etc. In this chapter, we will explain what goes in the
background when you compile a C program using GCC compiler.

Compiling a C Program

A sequence of binary instructions consisting of 1 and 0 bits is called as machine code. High-
level programming languages such as C, C++, Java, etc. consist of keywords that are closer to
human languages such as English. Hence, a program written in C (or any other high-level
language) needs to be converted to its equivalent machine code. This process is
called compilation.

Note that the machine code is specific to the hardware architecture and the operating system. In
other words, the machine code of a certain C program compiled on a computer with Windows
OS will not be compatible with another computer using Linux OS. Hence, we must use the
compiler suitable for the target OS.
C Compilation Process Steps

In this tutorial, we will be using the gcc (which stands for GNU Compiler Collection). The GNU
project is a free-software project by Richard Stallman that allows developers to have access to
powerful tools for free.

The gcc compiler supports various programming languages, including C. In order to use it, we
should install its version compatible with the target computer.

The compilation process has four different steps −

 Preprocessing
 Compiling
 Assembling
 Linking

The following diagram illustrates the compilation process.


Example

To understand this process, let us consider the following source code in C languge (main.c) −

#include <stdio.h>

int main(){

/* my first program in C */

printf("Hello World! \n");

return 0;
}

Output

Run the code and check its output −

Hello World!

The ".c" is a file extension that usually means the file is written in C. The first line is the
preprocessor directive #include that tells the compiler to include the stdio.h header file. The text
inside /* and */ are comments and these are useful for documentation purpose.
The entry point of the program is the main() function. It means the program will start by
executing the statements that are inside this function’s block. Here, in the given program code,
there are only two statements: one that will print the sentence "Hello World" on the terminal, and
another statement that tells the program to "return 0" if it exited or ended correctly. So, once we
compiled it, if we run this program we will only see the phrase "Hello World" appearing.

What Goes Inside the C Compilation Process?

In order for our "main.c" code to be executable, we need to enter the command "gcc main.c", and
the compiling process will go through all of the four steps it contains.

Step 1: Preprocessing

The preprocessor performs the following actions −

 It removes all the comments in the source file(s).


 It includes the code of the header file(s), which is a file with extension .h which contains
C function declarations and macro definitions.
 It replaces all of the macros (fragments of code which have been given a name) by their
values.

The output of this step will be stored in a file with a ".i" extension, so here it will be in "main.i".

In order to stop the compilation right after this step, we can use the option "-E" with the gcc
command on the source file, and press Enter.

gcc -E main.c

Step 2: Compiling

The compiler generates the IR code (Intermediate Representation) from the preprocessed file, so
this will produce a ".s" file. That being said, other compilers might produce assembly code at this
step of compilation.

We can stop after this step with the "-S" option on the gcc command, and press Enter.

gcc -S main.c

This is what the main.s file should look like −

.file "helloworld.c"
.text
.def __main; .scl 2; .type 32; .endef
.section .rdata,"dr"
.LC0:
.ascii "Hello, World! \0"
.text
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $32, %rsp
.seh_stackalloc 32
.seh_endprologue
call __main
leaq .LC0(%rip), %rcx
call puts
movl $0, %eax
addq $32, %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0"
.def puts; .scl 2; .type 32; .endef

Step 3: Assembling

The assembler takes the IR code and transforms it into object code, that is code in machine
language (i.e. binary). This will produce a file ending in ".o".

We can stop the compilation process after this step by using the option "-c" with the gcc
command, and pressing Enter.

Note that the "main.o" file is not a text file, hence its contents won't be readable when you open
this file with a text editor.

Step 4: Linking
The linker creates the final executable, in binary. It links object codes of all the source files
together. The linker knows where to look for the function definitions in the static libraries or
the dynamic libraries.

Static libraries are the result of the linker making a copy of all the used library functions to the
executable file. The code in dynamic libraries is not copied entirely, only the name of the library
is placed in the binary file.

By default, after this fourth and last step, that is when you type the whole "gcc main.c"
command without any options, the compiler will create an executable program
called [Link] (or [Link] in case of Windows) that we can run from the command line.

We can also choose to create an executable program with the name we want, by adding the "-o"
option to the gcc command, placed after the name of the file or files we are compiling.

gcc main.c -o [Link]

So now we could either type "./[Link]" if you didn’t use the "-o" option or "./hello" to
execute the compiled code. The output will be "Hello World" and following it, the shell prompt
will appear again.

Comments in C

Using comments in a C program increases the readability of the code. You must intersperse the
code with comments at appropriate places. As far as the compiler is concerned, the comments are
ignored. In C, the comments are one or more lines of text, that the compiler skips while building
the machine code.

The comments in C play an important part when the program needs to be modified, especially
by somebody else other than those who have written it originally. Putting comments is often not
given importance by the programmer, but using them effectively is important to improve the
quality of the code.

Why to Use Comments in C Programming?

Any programming language, including C, is less verbose as compared to any human language
like English. It has far less number of keywords, C being one of the smallest languages with only
32 keywords. Hence, the instructions in a C program can be difficult to understand, especially for
someone with non-programming background.

The C language syntax also varies and is also complicated. Usually, the programmer tries to add
complexity to optimize the code. However, it makes the code hard to understand. Comments
provide a useful explanation and convey the intention behind the use of a particular
approach.

For example, take the case of the ?: operator in C, which is a shortcut for the if-else statement.
So, instead of the following code −

if (a % 2 == 0){
printf("%d is Even\n", a);
} else {
printf("%d is Odd\n", a);
}

One can use the following statement −

(a % 2 == 0) ? printf("%d is Even\n", a) : printf("%d is Odd\n", a);

Obviously, the second method is more complicated than the first. If useful comments are added,
it makes easier to understand the intention and logic of the statement used.

Types of Comments in C

In C, there are two types of comments −

 Single-line comments
 Multi-line comments/li>

Single-line Comment in C

The C++-style single-line comments were incorporated in C compilers with C99 standards. If
any text begins with the // symbol, the rest of the line is treated as a comment.

The text followed by a double oblique or forward slash [//] in a code is treated as a single-line
comment. All that text after // is ignored by the C compiler during compilation. Unlike the multi-
line or block comment, it need not be closed.

Syntax of Single-line C Comment

//comment text

The // symbol can appear anywhere. It indicates that all the text following it till the end of the
line is a comment. The subsequent line in the editor is again a place to write a valid C statement.

Example: Single-line Comment in C

Take a look at the following program and observe how we have used single-line comments
inside its main function −

/* Online C Compiler and Editor */


#include <stdio.h>
#include <math.h>

/*forward declaration of function*/


float area_of_square(float);

float area_of_square(float side){


float area = pow(side,2);
return area;
}

// main function - entire line is a comment


int main(){

// variable declaration (this comment is after the C statement)


float side = 5.50;

float area = area_of_square(side); // calling a function


printf ("Side = %5.2f Area = %5.2f", side, area);

return 0;
}

Output

When you run this code, it will produce the following output −

Side = 5.50 Area = 30.25

Multi-line Comment in C

In early versions of C (ANSI C), any length of text put in between the symbols /* and */ is
treated as a comment. The text may be spread across multiple lines in the code file. You may call
it a multi-line comment. A block of consecutive lines is treated as a comment.

Syntax of Multi-line C Comment

The general structure of a multi-line comment is as follows −


/* The comment starts here
Line 1
Line 2
…..
…..
Comment ends here*/

For example −

/*
Example of a multi-line comment
program to print Hello World
using printf() function
*/

Obviously, since the comments are ignored by the compiler, the syntax rules of C language don't
apply to the comment text.

Comments can appear anywhere in a program, at the top, in between the code, or at the
beginning of a function or a struct declaration, etc.

Example: Multi-line Comment in C

In this example, we have a multi-line comment that explains the role of a particular user-defined
function used in the given code −

/* program to calculate area of square */

/* headers */
#include <stdio.h>
#include <math.h>

/* forward declaration of function */


float area_of_square(float);

/* main function */
int main(){
/* variable declaration */
float side = 5.50;

/* calling function */
float area = area_of_square(side);
printf("Side = %5.2f Area = %5.2f", side, area);

return 0;
}

/* User-defined function to calculate


the area of square. It takes side as the argument
and returns the area */

float area_of_square(float side){


float area = pow(side, 2);
return area;
}

Output

When you execute the code, it will produce the following output −

Side = 5.50 Area = 30.25

While inserting a comment, you must make sure that for every comment starting with /*, there
must be a corresponding */ symbol. If you start a comment with /* and fail to close it, then the
compiler will throw an error.

Note: A blocked comment or multi-line comment must be put inside /* and */ symbols, whereas
a single-line comment starts with the // symbol and is effective till the end of the line.

Placing comments in a program is always encouraged. Programmers usually avoid the practice of
adding comments. However, they can sometimes find it difficult to debug and modify their code
if it is not properly commented. Comments are especially vital when the development is done in
collaboration. Using comments effectively can be of help to all the members of a team.

Even though comments are ignored by the compiler, they should be clear in meaning and
concise. Whenever the code needs modification, the reason, the timestamp, and the author should
be mentioned in comments.
Tokens in C

A token is referred to as the smallest unit in the source code of a computer language such as C.
The term token is borrowed from the theory of linguistics. Just as a certain piece of text in a
language (like English) comprises words (collection of alphabets), digits, and punctuation
symbols. A compiler breaks a C program into tokens and then proceeds ahead to the next stages
used in the compilation process.

The first stage in the compilation process is a tokenizer. The tokenizer divides the source code
into individual tokens, identifying the token type, and passing tokens one at a time to the next
stage of the compiler.

The parser is the next stage in the compilation. It is capable of understanding the language's
grammar. identifies syntax errors and translates an error-free program into the machine language.

A C source code also comprises tokens of different types. The tokens in C are of the following
types −

 Character set
 Keyword tokens
 Literal tokens
 Identifier tokens
 Operator tokens
 Special symbol tokens

Let us discuss each of these token types.

C Character set

The C language identifies a character set that comprises English alphabets – upper and lowercase
(A to Z, as well as a to z), digits 0 to 9, and certain other symbols with a special meaning
attached to them. In C, certain combinations of characters also have a special meaning attached
to them. For example, \n is known as a newline character. Such combinations are called escape
sequences.

Here is the character set of C language −

 Uppercase: A to Z
 Lowercase: a to z
 Digits: 0 to 9
 Special characters: ! " # $ % & ' ( ) * + - . : , ; ` ~ = < > { } [ ] ^ _ \ /

A sequence of any of these characters inside a pair of double quote symbols " and " are used to
represent a string literal. Digits are used to represent numeric literal. Square brackets are used for
defining an array. Curly brackets are used to mark code blocks. Back slash is an escape
character. Other characters are defined as operators.
C Keywords

In C, a predefined sequence of alphabets is called a keyword. Compared to human languages,


programming languages have fewer keywords. To start with, C had 32 keywords, later on, few
more were added in subsequent revisions of C standards. All keywords are in lowercase. Each
keyword has rules of usage (in programming it is called syntax) attached to it.

The C compiler checks whether a keyword has been used according to the syntax, and translates
the source code into the object code.

C Literals

In computer programming terminology, the term literal refers to a textual representation of a


value to be assigned to a variable, directly hard-coded in the source code.

A numeric literal contains digits, a decimal symbol, and/or the exponentiation character E or e.

The string literal is made up of any sequence of characters put inside a pair of double quotation
symbols. A character literal is a single character inside a single quote.

Arrays can also be represented in literal form by putting a comma-separated sequence of literals
between square brackets.

In C, escape sequences are also a type of literal. Two or more characters, the first being a
backslash \ character, put inside a single quote form an escape sequence. Each escape sequence
has a predefined meaning attached to it.

C Identifiers

In contrast to the keywords, the identifiers are the user-defined elements in a program. You need
to define various program elements by giving them an appropriate name. For example,
variable, constant, label, user-defined type, function, etc.

There are certain rules prescribed in C, to form an identifier. One of the important restrictions is
that a reserved keyword cannot be used as an identifier. For example, for is a keyword in C, and
hence it cannot be used as an identifier, i.e., name of a variable, function, etc.

C Operators

C is a computational language. Hence a C program consists of expressions that perform


arithmetic and comparison operations. The special symbols from the character set of C are
mostly defined as operators. For example, the well-known symbols, +, −, * and / are
the arithmetic operators in C. Similarly, < and > are used as comparison operators.

C Special symbols
Apart from the symbols defined as operators, the other symbols include punctuation symbols like
commas, semicolons, and colons. In C, you find them used differently in different contexts.

Similarly, the parentheses ( and ) are used in arithmetic expressions as well as in function
definitions. The curly brackets are employed to mark the scope of functions, code blocks
in conditional and looping statements, etc.

C - Keywords

Keywords are those predefined words that have special meaning in the compiler and they cannot
be used for any other purpose. As per the C99 standard, C language has 32 keywords. Keywords
cannot be used as identifiers.

The following table has the list of all keywords (reserved words) available in the C language:

auto double int struct

break else long switch

case enum register typedef

char extern return Union

continue for signed Void

do if static While

default goto sizeof Volatile

const float short Unsigned

All the keywords in C have lowercase alphabets, although the keywords that have been newly
added in C, do have uppercase alphabets in them. C is a case-sensitive language. Hence, int is a
keyword but INT, or Int are not recognized as a keyword. The new keywords introduced from
C99 onwards start with an underscore character. The compiler checks the source code for the
correctness of the syntax of all the keywords and then translates it into the machine code.

Example of C Keywords

In the following program, we are using a keyword as an identifier i.e., as the name of the user-
defined function, that will cause a compilation error.

#include <stdio.h>

void register(int, int);


int main () {

/* variable definition: */
int a=5, b=7;
register(a,b);

return 0;
}
void register(int a, int b)
{
printf("%d", a+b);
}

Errors

main.c:3:15: error: expected identifier or '(' before 'int'


3 | void register(int, int);
| ^~~
main.c: In function 'main':
main.c:8:14: error: expected ')' before ',' token
8 | register(a,b);
| ^
| )
main.c: At top level:
main.c:12:15: error: expected identifier or '(' before 'int'
12 | void register(int a, int b)
| ^

The reason for the errors is that we are using a keyword register as the name of a user-defined
function, which is not allowed.

The ANSI C version has 32 keywords. These keywords are the basic element of the program
logic. These keywords can be broadly classified in following types −

 Primary Data types


 User defined types
 Storage types
 Conditionals
 Loops and loop controls
 Others

Let us discuss the keywords in each category.

Primary Types C Keywords

These keywords are used for variable declaration. C is a statically type language, the variable to
be used must be declared. Variables in C are declared with the following keywords:

int Declares an integer variable

long Declares a long integer variable

short Declares a short integer variable

signed Declares a signed variable

double Declares a double-precision variable

char Declares a character variable

float Declares a floating-point variable

unsigned Declares an unsigned variable

void Specifies a void return type

User-defined Types C Keywords

C language allows you to define new data types as per requirement. The user defined type has
one or more elements of primary type.

The following keywords are provided for user defined data types −

struct Declares a structure type

typedef Creates a new data type

union Declares a union type

enum Declares an enumeration type

Storage Types C Keywords


The following set of keywords are called storage specifiers. They indicate the location where in
the memory the variables stored. Default storage type of a variable is auto, although you can ask
the compiler to form a variable with specific storage properties.

auto Specifies automatic storage class

extern Declares a variable or function

static Specifies static storage class

register Specifies register storage class

Conditionals C Keywords

The following set of keywords help you to put conditional logic in the program. The conditional
logic expressed with if and else keywords provides two alternative actions for a condition. For
multi-way branching, use switch – case construct. In C, the jump operation in an assembler is
implemented by the goto keyword.

goto Jumps to a labeled statement

if Starts an if statement

else Executes when the if condition is false

case Labels a statement within a switch

switch Starts a switch statement

default Specifies default statement in switch

Loops and Loop Control C Keywords

Repetition or iteration is an essential aspect of the algorithm. C provides different alternatives for
forming a loop, and keywords for controlling the behaviour of the loop. Each of the keywords let
you form a loop of different characteristics and usage.

For Starts a for-loop

do Starts a do-while loop

while starts a while loop

continue Skips an iteration of a loop


break Terminates a loop or switch statement

Other C Keywords

The following miscellaneous keywords are also extremely important:

const Specifies a constant value

Sizeof Determines the size of a data type

Volatile compiler that the value of the variable may change at any time

In C99 version, five more keywords were added −

 _Bool
 _Complex
 _Imaginary
 inline

In C11, seven more keywords have been added

 _Alignas
 _Alignof
 _Atomic
 _Generic
 _Noreturn
 _Static_assert

When the C23 standard will be released it will introduce 14 more keywords −

 alignas
 alignof
 bool
 constexpr
 false
 nullptr
 static_assert
 thread_local
 true
 typeof
 typeof_unqual
 _Decimal128

Most of the recently reserved words begin with an underscore followed by a capital letter, Since
existing program source code should not have been using these identifiers.
Following points must be kept in mind when using the keywords:

 Keywords are reserved by the programming language and have predefined meaning. They
cannot be used as name of a variable or function.
 Each keyword has to be used as per the syntax stipulated for its use. If the syntax is violated,
the compiler reports compilation errors.
 C is one of the smallest computer languages with only 32 keywords in its ANSI C version,
although a few more keywords have been added afterwards.
C - Identifiers

Identifier in C helps in identifying variables, constants, functions etc., in a C code. C, being a


high-level computer language, allows you to refer to a memory location with a name instead of
using its address in binary or hexadecimal form.

C Identifiers

Identifiers are the user-defined names given to make it easy to refer to the memory. It is also
used to define various elements in the program, such as the function, user-defined type, labels,
etc. Identifiers are thus the names that help the programmer to use programming elements more
conveniently.

When a variable or a function is defined with an identifier, the C compiler allocates it the
memory and associates the memory location to the identifier. As a result, whenever the
identifier is used in the instruction, C compiler can access its associated memory location. For
example, when we declare a variable age and assign it a value as shown in the following figure,
the compiler assigns a memory location to it.
Even if the programmer can use an identifier of his choice to name a variable or a function etc.,
there are certain rules to be followed to form a valid identifier.

Naming Rules of C Identifiers

Given below are the rules using which an identifier is formed −

 Keywords can't be used as identifiers as they are predefined.


 Out of the character set that C uses, only the alphabets (upper and lowercase) and the
underscore symbol (_) are allowed in the identifier. It implies that you can't use characters
like the punctuation symbols etc. as a part of the identifier.
 The identifier must start either with an alphabet (upper or lowercase) or an underscore. It
means, a digit cannot be the first character of the identifier.
 The subsequent characters may be alphabets or digits or an underscore.
 Same identifier can't be used as a name of two entities. An identifier can be used only once
in the current scope.

As per the above rules, some examples of the valid and invalid identifiers are as follows −

Valid C Identifiers

age, Age, AGE, average_age, __temp, address1, phone_no_personal, _my_name


Invalid C Identifiers

Average-age, my name, $age, #phone, 1mg, phy+maths

Examples of C Identifiers

The following program shows an error −

#include <stdio.h>

int main () {

/* variable definition: */
int marks = 50;
float marks = 65.50;
printf("%d %f", marks, marks);

return 0;
}Error
 Identifiers are case-sensitive, as a result age is not the same as AGE.
 ANSI standard recognizes a length of 31 characters for an identifier. Although you can
choose a name with more characters, only the first 31 will be recognized. Thus you can
form a meaningful and descriptive identifier.

Scope of C Identifiers

In C language, the scope of identifiers refers to the place where an identifier is declared and can
be used/accessed. There are two scopes of an identifier:

Global Identifiers

If an identifier has been declared outside before the declaration of any function, it is called as an
global (external) identifier.

Example

#include <stdio.h>

int marks= 100; // external identifier

int main() {
printf("The value of marks is %d\n", marks);
}

Output

The value of marks is 100

This is because marks is defined outside of any blocks, so it is an external identifier.

Local Identifiers

On the other hand, an identifier inside any function is an local (internal) identifier.

Example

#include <stdio.h>

int main() {
int marks= 100; // internal identifier

printf("The value of marks is %d\n", marks);


}

Output

The value of marks is 100

This is because marks is defined inside main function, so it is an internal identifier.

Examples of Different Types of C Identifiers

Identifiers can also appear in a forward declaration of a function. However, the declaration
signature of a function should match with the definition.

Example of Variable Identifier

int marks1 = 50, marks2 = 60;


float avg = (float) (marks1+marks2)/2;

Example of Function Identifier


int average(int marks1, int marks2)
{
return (float) (marks1+marks2)/2;
}

Example of User-defined Type Identifier

struct student
{
int rollno;
char *name;
int m1,m2,m3;
float percent
};
struct student s1 = {1, "Raju", 50, 60, 70, 60.00};

Example of Typedef Identifier

struct student
{
int rollno;
char *name;
int m1,m2,m3;
float percent
};
typedef struct student STUDENT;
STUDENT s1 = {1, "Raju", 50, 60, 70, 60.00};

Example of Label Identifier

#include <stdio.h>
int main()
{
int x=0;
begin:
x++;
if (x>=10)
goto end;
printf("%d\n", x);
goto begin;

end:
return 0;
}

Output

1
2
3
4
5
6
7
8
9

Example of Enum Identifier

#include <stdio.h>
enum week{Mon=10, Tue, Wed, Thur, Fri=10, Sat=16, Sun};

int main() {
printf("The value of enum week: %d\n",Mon);
return 0;
}

Output

The value of enum week: 10


Thus, the identifiers are found everywhere in the C program. Choosing right identifier for the
coding element such as the variable or a function is important for enhancing the readability and
debugging and documentation of the program.

C - User Input

Need for User Input in C

Every computer application accepts certain data from the user, performs a predefined process on
the same to produce the output. There are no keywords in C that can read user inputs.

The standard library that is bundled with the C compiler includes stdio.h header file, whose
library function scanf() is most commonly used to accept user input from the standard input
stream. In addition, the stdio.h library also provides other functions for accepting input.

Example

To understand the need for user input, consider the following C program −

#include <stdio.h>

int main(){
int price, qty, ttl;

price = 100;
qty = 5;
ttl = price*qty;

printf("Total: %d", ttl);

return 0;
}

Output

The above program calculates the total purchase amount by multiplying the price and quantity of
an item purchased by a customer. Run the code and check its output −

Total: 500

For another transaction with different values of price and quantity, you need to edit the program,
put the values, then compile and run again. To do this every time is a tedious activity. Instead,
there must be a provision to assign values to a variable after the program is run.
The scanf() function reads the user input during the runtime, and assigns the value to a variable.

C User Input Function: The scanf()

The C language recognizes the standard input stream as stdin and is represented by the standard
input device such as a keyboard. C always reads the data from the input stream in the form of
characters.

The scanf() function converts the input to a desired data type with appropriate format specifiers.

Syntax of Scanf()

This is how you would use the scanf() function in C −

int scanf(const char *format, &var1, &var2, . . .);

The first argument to the scanf() function is a format string. It indicates the data type of the
variable in which the user input is to be parsed. It is followed by one or more pointers to
the variables. The variable names prefixed by & gives the address of the variable.

User Input Format Specifiers

Following format specifiers are used in the format string −

Format Specifier Type

%c Character

%d Signed integer

%f Float values

%i Unsigned integer

%l or %ld or %li Long

%lf Double

%Lf Long double

%lu Unsigned int or unsigned long

%lli or %lld Long long


%llu Unsigned long long

Example: User Inputs in C

Going back to the previous example, we shall use the scanf() function to accept the value for
"price" and "qty", instead of assigning them any fixed value.

#include <stdio.h>

int main(){

int price, qty, ttl;

printf("Enter price and quantity: ");


scanf("%d %d", &price, &qty);

ttl = price * qty;

printf("Total : %d", ttl);

return 0;
}

Output

When the above program is run, C waits for the user to enter the values −

Enter price and quantity:

When the values are entered and you press Enter, the program proceeds to the subsequent steps.

Enter price and quantity: 100 5


Total : 500

What is more important is that, for another set of values, you don't need to edit and compile
again. Just run the code and the program again waits for the user input. In this way, the program
can be run any number of times with different inputs.

Enter price and quantity: 150 10


Total : 1500

Integer Input

The %d format specifier has been defined for signed integer. The following program reads the
user input and stores it in the integer variable num.

Example: Integer Input in C

Take a look at the following program code −

#include <stdio.h>

int main(){

int num;

printf("Enter an integer: ");


scanf("%d", &num);

printf("You entered an integer: %d", num);

return 0;
}

Output

Run the code and check its output −

Enter an integer: 234


You entered an integer: 234

If you enter a non-numeric value, the output will be "0".

The scanf() function can read values to one or more variables. While providing the input values,
you must separate the consecutive values by a whitespace, a tab or an Enter.

Example: Multiple Integer Inputs in C

#include <stdio.h>
int main(){

int num1, num2;

printf("Enter two integers: ");


scanf("%d %d", &num1, &num2);

printf("You entered two integers : %d and %d", num1, num2);

return 0;
}

Output

Run the code and check its output −

Enter two integers: 45 57


You entered two integers : 45 and 57

or

Enter two integers: 45


57

Float Input

For floating point input, you need to use the %f format specifier.

Example: Float Input in C

#include <stdio.h>

int main(){

float num1;

printf("Enter a number: ");


scanf("%f", &num1);
printf("You entered a floating-point number: %f", num1);

return 0;
}

Output

Run the code and check its output −

Enter a number: 34.56


You entered a floating-point number: 34.560001

Example: Integer and Float Inputs in C

The scanf() function may read inputs for different types of variables. In the following program,
user input is stored in an integer and a float variable −

#include <stdio.h>

int main(){

int num1;
float num2;

printf("Enter two numbers: ");


scanf("%d %f", &num1, &num2);

printf("You entered an integer: %d a floating-point number: %6.2f", num1, num2);

return 0;
}

Output

Run the code and check its output −

Enter two numbers: 65 34.5678


You entered an integer: 65 a floating-point number: 34.57

Character Input
The %c format specifier reads a single character from the keyboard. However, we must give a
blank space before %c in the format string. This is because the %c conversion specifier won't
automatically skip any leading whitespaces.

If there is a stray newline in the input stream (from a previous entry, for example)
the scanf() call will consume it immediately.

scanf(" %c", &c);

The blank space in the format string tells scanf to skip the leading whitespace, and the first non-
whitespace character will be read with the %c conversion specifier.

Example: Character Input in C

Take a look at the following example −

#include <stdio.h>

int main(){

char ch;

printf("Enter a single character: ");


scanf(" %c", &ch);

printf("You entered character : %c", ch);

return 0;
}

Output

Run the code and check its output −

Enter a single character: x


You entered character : x

Example: Multiple Character Inputs in C

The following program reads two characters separated by a whitespace in two char variables.
#include <stdio.h>

int main(){

char ch1, ch2;

printf("Enter two characters: ");


scanf("%c %c", &ch1, &ch2);

printf("You entered characters: %c and %c", ch1, ch2);

return 0;
}

Output

Run the code and check its output −

Enter two characters: x y


You entered characters: x and y

The stdio.h header file also provides the getchar() function. Unlike scanf(), getchar() doesn't
have a format string. Also, it reads a single key stroke without the Enter key.

Example: Character Input Using gets()

The following program reads a single key into a char variable −

#include <stdio.h>

int main(){

char ch;

printf("Enter a character: ");


ch = getchar();

puts("You entered: ");


putchar(ch);

printf("\nYou entered character: %c", ch);

return 0;
}

Output

Run the code and check its output −

Enter a character: W
You entered:
W
You entered character: W

You can also use the unformatted putchar() function to print a single character.

Example: Reading a Character Sequence

The following program shows how you can read a series of characters till the user presses the
Enter key −

#include <stdio.h>

int main(){

char ch;
char word[10];

int i = 0;
printf("Enter characters. End by pressing the Enter key: ");

while(1){
ch = getchar();
word[i] = ch;
if (ch == '\n')
break;
i++;
}
printf("\nYou entered the word: %s", word);

return 0;
}

Output

Run the code and check its output −

Enter characters. End by pressing the Enter key: Hello

You entered the word: Hello

String Input

There is also a %s format specifier that reads a series of characters into a char array.

Example: String Input Using scanf()

The following program accepts a string input from the keyboard −

#include <stdio.h>

int main(){

char name[20];

printf("Enter your name: ");


scanf("%s", name);

printf("You entered the name: %s", name);

return 0;
}

Output

Run the code and check its output −


Enter your name: Ravikant
You entered the name: Ravikant

C uses the whitespace as the delimiter character. Hence, if you try to input a string that contains a
blank space, only the characters before the space are stored as the value.

Enter your name: Ravikant Soni


You entered the name: Ravikant

The gets() function overcomes this limitation. It is an unformatted string input function. All the
characters till you press Enter are stored in the variable.

Example: String Input Using gets()

Take a look at the following example −

#include <stdio.h>
#include <stdlib.h>

int main(){

char name[20];

printf("Enter your name: ");


gets(name);

printf("You entered the name: %s", name);

return 0;
}

Output

Run the code and check its output −

Enter your name: Ravikant Soni


You entered the name: Ravikant Soni
User input is an important aspect of an application in C programming. In this chapter, we
explained the usage of formatted and unformatted console input functions, scanf(), getchar(),
and gets() with different examples.

C - Basic Syntax

In C programming, the term "syntax" refers to the set of rules laid down for the programmer to
write the source code of a certain application. While there is a specific syntax recommended for
each of the keywords in C, certain general rules need to be followed while developing a program
in C.

A typical source code of a C program has the following elements −

/*Hello World program*/ // Comments

#include <stdio.h> // Header File


int a=10; // Global declarations

// The main function


int main() {
char message[] = "Hello World"; // Local variable
printf("%s", message);
return 0;
}

Tokens in C

A C program consists of various tokens and a token is either a keyword, an identifier, a constant,
a string literal, or a symbol. For example, the following C statement consists of five tokens −

printf("Hello, World! \n");

The individual tokens are −

printf
(
"Hello, World! \n"
);
The C compiler identifies whether the token is a keyword, identifier, comment, a literal, an
operator, any of the other recognized special symbols or not. This exercise is done by the
tokenizer in the first stage of the compilation process.

Identifiers in C

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 z, or an underscore '_' followed by zero or more letters,
underscores, and digits (0 to 9).

C prescribes certain rules to form the names of variables, functions or other programming
elements. They are not keywords. An identifier must start with an alphabet or underscore
character, and must not have any other character apart from alphabets, digits and underscore.

C does not allow punctuation characters such as @, $, and % within identifiers. C is


a case−sensitive programming language. Thus, Manpower and manpower are two different
identifiers in C. Here are some examples of acceptable identifiers −

mohd zara abc move_name a_123


myname50 _temp j a23b9 retVal

Keywords in C

The most important part of C language is its keywords. Keywords are the reserved words having
a predefined meaning with prescribed syntax for usage. In ANSI C, all keywords have lowercase
alphabets. The programmer needs to choose the correct keywords to construct the solution of the
problem at hand. To learn programming is basically to learn to correctly use the keywords.

The following list shows the reserved words in C. These reserved words may not be used
as constants or variables or any other identifier names.

auto else long switch

break enum register typedef

case extern return union

char float short unsigned

const for signed void

continue goto sizeof volatile

default if static while

do int struct _Packed


double

Each keyword in C has a well−defined syntax in addition to the basic syntax explained in this
chapter. The usage of each keyword will be explained in the subsequent chapters.

Semicolons in C

In a C program, the semicolon is a statement terminator. That is, each individual statement must
be ended with a semicolon. It indicates the end of one logical entity.

Given below are two different statements −

printf("Hello, World! \n");


return 0;

Since the semicolon ";" is only the delimiter symbol for a C statement, there may be more than
one statements in a one physical line in a C program. Similarly, a single statement may span over
more than one lines in the source code.

The following line is perfectly valid in C. In one line, there are multiple statements −

int a=10; if (a>=50) printf("pass"); else printf("fail");

The following code is also valid even if a statement spills over multiple lines −

if
(a>=50)
printf("pass");
else printf("fail");

Comments in C

Comments are like helping text in your C program and they are ignored by the compiler. They
start with /* and terminate with the characters */ as shown below −

/* my first program in C */

You cannot have comments within comments and they do not occur within a string or character
literals.

Source Code
The C program is a text file, containing a series of statements. The file must have a .c as its
extension. The C compiler identifies only the .c file for compilation process. Only the English
alphabets are used in the keywords and other identifiers of C language, although the string
literals may contain any Unicode characters.

The main() Function

Every C program must have one (and only one) main() function, from where the compiler starts
executing the code. However, it is not necessary that the main() function should be in the
beginning of the code in the .c file. There can be any number of functions in a C program. If a
function calls any other function before its definition, there should be its forward declaration.

Header Files

In addition to the keywords, a C program often needs to call predefined functions from the
library of header files. The required header files are imported with the #include preprocessor
directive. All the #include statements must be in the beginning of the source code.

Variable Declaration

C is a statically typed language. It requires, all the variables appearing in a program to be


declared before using. Variables can be declared globally i.e. outside any function, or locally
within the scope of a function. The variable can store a value only of its declared type. This is
one of the important rules of C.

Statements in a C Program

Statements are the basic building blocks of the program. Statements in the main() function are
executed in a top to bottom order by default. The sequence is controlled
by conditionals or looping constructs. As a basic syntax rule, each statement must have
semicolon (;) at the end.

Whitespaces in a C Program

While compiling the source code, the compiler ignores the whitespaces. Whitespace is the term
used in C to describe blanks, tabs, newline characters and comments. While one can use them for
better readability of the code, they have little significance for the compiler (unless they are a part
of a string literal, appearing inside the double quote symbols). A line containing only whitespace,
possibly with a comment, is known as a blank line, and a C compiler totally ignores it.

Whitespace separates one part of a statement from another and enables the compiler to identify
where one element in a statement, such as int, ends and the next element begins. Therefore, in
the following statement −

int age;
There must be at least one whitespace character (usually a space) between int and age for the
compiler to be able to distinguish them. On the other hand, in the following statement −

fruit = apples + oranges; // get the total fruit

No whitespace characters are necessary between "fruit" and "=", or between "=" and "apples",
although you are free to include some if you wish to increase readability.

Compound Statements in C

Often, you need to define a cohesive block of statements as a single unit of programming logic.
For example, you may want more than one statements to be executed if a certain logical
expression is true, or multiple statements in a looping block. Similarly, a user-defined function
may have more than one statements. In such cases, statements are grouped together to form a
compound statement. C uses curly brackets for such grouping.

{
Statement1;
Statement2;
...
...
}

In the following code, the if and else parts have a block each of statements.

int marks = 40;

if (marks<50) {
printf("Result: Fail\n");
printf ("Better Luck next time");
}
else {
printf("Result: Pass\n");
printf("Congratulations");
}

Curly brackets are also used in the function definition:

float area_of_square(float side) {


float area = pow(side,2);
return area;
}

Defining a custom type with struct, union or enum also requires clubbing more than one
statements together with curly brackets.

struct student {
char name[20];
int marks, age;
};

The curly brackets also declare an array as follows −

int marks[ ]={50,56,76,67,43};

C - Data Types

Data types in C refer to an extensive system used for declaring variables or functions of
different types. The type of a variable determines how much space it occupies in storage and
how the bit pattern stored is interpreted. In this chapter, we will learn about data types in C. A
related concept is that of "variables", which refer to the addressable location in the memory of
the processor. The data captured via different input devices is stored in the computer memory. A
symbolic name can be assigned to the storage location called variable name.

C is a statically typed language. The name of the variable along with the type of data it intends to
store must be explicitly declared before actually using it.

C is also a strongly typed language, which means that the automatic or implicit conversion of
one data type to another is not allowed.

The types in C can be classified as follows −

[Link]. Types & Description

Basic Types
1 They are arithmetic types and are further classified into: (a)
integer types and (b) floating-point types.

Enumerated types
They are again arithmetic types and they are used to define
2
variables that can only assign certain discrete integer values
throughout the program.
The type void
3
The type specifier void indicates that no value is available.

Derived types
4 They include (a) Pointer types, (b) Array types, (c) Structure
types, (d) Union types and (e) Function types.

The array types and structure types are referred collectively as the aggregate types. The type of a
function specifies the type of the function's return value. We will see the basic types in the
following section, where as other types will be covered in the upcoming chapters.

Integer Data Types in C

The following table provides the details of standard integer types with their storage sizes and
value ranges −

Type Storage size Value range

char 1 byte -128 to 127 or 0 to 255

unsigned char 1 byte 0 to 255

signed char 1 byte -128 to 127

-32,768 to 32,767 or -2,147,483,648 to


int 2 or 4 bytes
2,147,483,647

unsigned int 2 or 4 bytes 0 to 65,535 or 0 to 4,294,967,295

short 2 bytes -32,768 to 32,767

unsigned short 2 bytes 0 to 65,535

-9223372036854775808 to
long 8 bytes
9223372036854775807

unsigned long 8 bytes 0 to 18446744073709551615

To get the exact size of a type or a variable on a particular platform, you can use
the sizeof operator. The expressions sizeof(type) yields the storage size of the object or type in
bytes.

Example of Integer Data Types

Given below is an example to get the size of various type on a machine using different constant
defined in limits.h header file −
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>

int main(int argc, char** argv) {

printf("CHAR_BIT : %d\n", CHAR_BIT);


printf("CHAR_MAX : %d\n", CHAR_MAX);
printf("CHAR_MIN : %d\n", CHAR_MIN);
printf("INT_MAX : %d\n", INT_MAX);
printf("INT_MIN : %d\n", INT_MIN);
printf("LONG_MAX : %ld\n", (long) LONG_MAX);
printf("LONG_MIN : %ld\n", (long) LONG_MIN);
printf("SCHAR_MAX : %d\n", SCHAR_MAX);
printf("SCHAR_MIN : %d\n", SCHAR_MIN);
printf("SHRT_MAX : %d\n", SHRT_MAX);
printf("SHRT_MIN : %d\n", SHRT_MIN);
printf("UCHAR_MAX : %d\n", UCHAR_MAX);
printf("UINT_MAX : %u\n", (unsigned int) UINT_MAX);
printf("ULONG_MAX : %lu\n", (unsigned long) ULONG_MAX);
printf("USHRT_MAX : %d\n", (unsigned short) USHRT_MAX);

return 0;
}

Output

When you compile and execute the above program, it produces the following result on Linux−

CHAR_BIT : 8
CHAR_MAX : 127
CHAR_MIN : -128
INT_MAX : 2147483647
INT_MIN : -2147483648
LONG_MAX : 9223372036854775807
LONG_MIN : -9223372036854775808
SCHAR_MAX : 127
SCHAR_MIN : -128
SHRT_MAX : 32767
SHRT_MIN : -32768
UCHAR_MAX : 255
UINT_MAX : 4294967295
ULONG_MAX : 18446744073709551615
USHRT_MAX : 65535

Floating-Point Data Types in C

The following table provides the details of standard floating-point types with storage sizes and
value ranges and their precision −

Storage
Type Value range Precision
size

float 4 byte 1.2E-38 to 3.4E+38 6 decimal places

15 decimal
double 8 byte 2.3E-308 to 1.7E+308
places

long 3.4E-4932 to 19 decimal


10 byte
double 1.1E+4932 places

The header file "float.h" defines the macros that allow you to use these values and other details
about the binary representation of real numbers in your programs.

Example Floating-Point Data Types

The following example prints the storage space taken by a float type and its range values −

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>

int main(int argc, char** argv) {

printf("Storage size for float : %zu \n", sizeof(float));


printf("FLT_MAX : %g\n", (float) FLT_MAX);
printf("FLT_MIN : %g\n", (float) FLT_MIN);
printf("-FLT_MAX : %g\n", (float) -FLT_MAX);
printf("-FLT_MIN : %g\n", (float) -FLT_MIN);
printf("DBL_MAX : %g\n", (double) DBL_MAX);
printf("DBL_MIN : %g\n", (double) DBL_MIN);
printf("-DBL_MAX : %g\n", (double) -DBL_MAX);
printf("Precision value: %d\n", FLT_DIG );

return 0;
}

Output

When you compile and execute the above program, it produces the following result on Linux −

Storage size for float : 4


FLT_MAX : 3.40282e+38
FLT_MIN : 1.17549e-38
-FLT_MAX : -3.40282e+38
-FLT_MIN : -1.17549e-38
DBL_MAX : 1.79769e+308
DBL_MIN : 2.22507e-308
-DBL_MAX : -1.79769e+308
Precision value: 6

Note: "sizeof" returns "size_t". The type of unsigned integer of "size_t" can vary depending on
platform. And, it may not be long unsigned int everywhere. In such cases, we use "%zu" for the
format string instead of "%d".

Earlier versions of C did not have Boolean data type. C99 standardization of ANSI C introduced
_bool type which treats zero value as false and non-zero as true.

User-defined Data Types in C

There are two user-defined data types struct and union, that can be defined by the user with the
help of the combination of other basic data types.

Struct Data Type

One of the unique features of C language is to store values of different data types in one variable.
The keywords struct and union are provided to derive a user-defined data type. For example,
struct student {
char name[20];
int marks, age;
};

Union Data Type

A union is a special case of struct where the size of union variable is not the sum of sizes of
individual elements, as in struct, but it corresponds to the largest size among individual elements.
Hence, only one of elements can be used at a time. Look at following example:

union ab {
int a;
float b;
};

We shall learn more about structure and union types in a later chapter.

The void Data Type in C

The void type specifies that no value is available. It is used in three kinds of situations −

[Link] Types & Description

Function returns as void


There are various functions in C that do not return any value or
1
you can say they return void. A function with no return value has
the return type as void. For example, void exit (int status);

Function arguments as void


There are various functions in C which do not accept any
2
parameter. A function with no parameter can accept a void. For
example, int rand(void);

Pointers to void
A pointer of type void * represents the address of an object, but
3 not its type. For example, a memory allocation function
void *malloc( size_t size ); returns a pointer to void which can
be casted to any data type.

Arrays Data Type in C


An array is a collection of multiple values of same data type stored in consecutive memory
locations. The size of array is mentioned in square brackets []. For example,

int marks[5];

Arrays can be initialized at the time of declaration. The values to be assigned are put in
parentheses.

int marks[ ]={50,56,76,67,43};

C also supports multi-dimensional arrays. To learn more about arrays, refer to the chapter
on Arrays in C.

Pointers Data Type in C

A pointer is a special variable that stores address or reference of another variable/object in the
memory. The name of pointer variable is prefixed by asterisk (*). The type of the pointer
variable and the variable/object to be pointed must be same.

int x;
int *y;
y = &x;

Here, "y" is a pointer variable that stores the address of variable "x" which is of "int" type.

Pointers are used for many different purposes. Text string manipulation and dynamic memory
allocation are some of the processes where the use of pointers is mandatory. Later in this tutorial,
you can find a detailed chapter on Pointers in C.

C - Variables

A variable is nothing but a name given to a storage area that our programs can manipulate. Each
variable in C has a specific type, which determines the size and layout of the variable's memory;
the range of values that can be stored within that memory; and the set of operations that can be
applied to the variable.

Why Do We Use Variables in C?

A variable in C is a user-assigned name to a certain location in the computer’s memory, which is


a collection of a large number of randomly accessible locations capable of holding a single bit.
Each location in the memory is identified by a unique address, expressed in binary (or Hexa-
decimal for convenience) format.
Since it is extremely cumbersome to store and process the data in the memory by referring to
their locations in binary form, high-level languages such as C let the locations be identified by
user-defined names or variables.

Instead of identifying a free memory location and assigning it a value, you can find a suitable
mnemonic identifier and assign it a value. The C compiler will choose an appropriate location
and bind it to the identifier specified by you.

Naming Conventions of C Variables

The name of the variable must start with an alphabet (upper or lowercase) or an underscore (_). It
may consist of alphabets (upper or lowercase), digits, and underscore characters. No other
characters can be a part of the name of a variable in C.

Variable names in C are case-sensitive. For example, "age" is not the same as "AGE".

The ANSI standard recognizes a length of 31 characters for a variable name. Although you can
choose a name with more characters, only the first 31 will be recognized. Using a descriptive
name for a variable, that reflects the value it intends to store is considered to be a good practice.
Avoid using very short variable names that might confuse you.

C is a statically typed language. Hence, the data type of the variable must be mentioned in the
declaration before its name. A variable may be declared inside a function (local variable) or
globally. More than one variable of the same type may be declared in a single statement.

Example

Based on the above set of rules and conventions, here are some valid and invalid variable names:

int _num = 5; // valid integer variable


float marks = 55.50; // valid float variable
char choice = '0'; // valid char variable

// invalid variable name


// cannot use "-"
int sub-1 = 35;

//invalid; must have data type


avg = 50;

// invalid; name can be used for


// declaration only once in a function
int choice = 0;

// Valid integer name


int sal_of_employee = 20000;

// Valid because all are of same type


int phy, che, maths;

// error because variables of


// different types in same statement
int sal, float tax;

In C, variables can store data belonging to any of the types it recognizes. Hence there are as
many number of types of variables as the number of data types in C.

[Link] Type & Description

char
1
Typically a single octet(one byte). It is an integer type.

int
2
The most natural size of integer for the machine.

float
3
A single-precision floating point value.

double
4
A double-precision floating point value.

void
5
Represents the absence of type.

C programming language also allows to define various other types of variables such as
Enumeration type, Pointer type, Array type, Structure type, Union type, etc. For this chapter, let
us study only basic variable types.

Variable Definition in C

A variable definition tells the compiler where and how much storage to create for the variable. A
variable definition specifies a data type and contains a list of one or more variables of that type
as follows −

type variable_list;
Here, type must be a valid C data type including char, w_char, int, float, double, bool, or any
user-defined object; and variable_list may consist of one or more identifier names separated by
commas.

Some valid variable declarations are shown here −

int i, j, k;
char c, ch;
float f, salary;
double d;

The line int i, j, k; declares and defines the variables i, j, and k; which instruct the compiler to
create variables named i, j and k of type int.

Variables can be initialized (assigned an initial value) in their declaration. The initializer consists
of an equal sign followed by a constant expression as follows −

type variable_name = value;

Example: Variable Definition and Initialization

Take a look at the following examples:

// declaration of d and f
extern int d = 3, f = 5;

// definition and initializing d and f


int d = 3, f = 5;

// definition and initializes z


byte z = 22;

// the variable x has the value 'x'


char x = 'x';

For definition without an initializer: variables with static storage duration are implicitly
initialized with NULL (all bytes have the value 0); the initial value of all other variables are
undefined.

Variable Declaration in C
As per the ANSI C standard, all the variables must be declared in the beginning. Variable
declaration after the first processing statement is not allowed. Although the C99 and C11
standard revisions have removed this stipulation, it is still considered a good programming
practice. You can declare a variable to be assigned a value later in the code, or you can initialize
it at the time of declaration.

Example: Variable Declaration

// declaration with initialization


int x = 10;

// declare first and assign later


int y;
y = 20;

// define and initialize two variables


int d = 3, f = 5;

// the variable x has the value 'x'


char x = 'x';

Once a variable of a certain type is declared, it cannot be assigned a value of any other type. In
such a case the C compiler reports a type mismatch error.

A variable declaration provides assurance to the compiler that there exists a variable with the
given type and name so that the compiler can proceed with further compilation without requiring
complete detail about the variable. A variable definition has its meaning at the time of
compilation only, the compiler needs actual variable definition at the time of linking the
program.

A variable declaration is useful when you are using multiple files and you define your variable in
one of the files which will be available at the time of linking the program. You will use the
keyword "extern" to declare a variable at any place. Though you can declare a variable multiple
times in your C program, it can be defined only once in a file, a function, or a block of code.

Example

Try the following example, where variables have been declared at the top, but they have been
defined and initialized inside the main function −

#include <stdio.h>
// Variable declaration:
extern int a, b;
extern int c;
extern float f;

int main () {

/* variable definition: */
int a, b;
int c;
float f;

/* actual initialization */
a = 10;
b = 20;

c = a + b;
printf("value of c : %d \n", c);

f = 70.0/3.0;
printf("value of f : %f \n", f);

return 0;
}

Output

When the above code is compiled and executed, it produces the following result:

value of c : 30
value of f : 23.333334

The same concept applies on function declaration where you provide a function name at the time
of its declaration and its actual definition can be given anywhere else. For example −

// function declaration
int func();
int main() {

// function call
int i = func();
}

// function definition
int func() {
return 0;
}

Lvalues and Rvalues in C

There are two kinds of expressions in C:

 lvalue expressions
 rvalue expressions

Lvalue Expressions in C

Expressions that refer to a memory location are called "lvalue" expressions. An lvalue may
appear as either the left-hand or right-hand side of an assignment.

Variables in C are lvalues and so they may appear on the left-hand side of an assignment.

Rvalue Expressions in C

The term "rvalue" refers to a data value that is stored at some address in memory. An "rvalue" is
an expression that cannot have a value assigned to it which means an rvalue may appear on the
right-hand side but not on the left-hand side of an assignment.

Numeric literals are rvalues and so they may not be assigned and cannot appear on the left-hand
side.

Take a look at the following valid and invalid statements:

// valid statement
int g = 20;

// invalid statement
// it would generate compile-time error
10 = 20;

Variables in C can be classified based on the following parameters:

 Data types − int, float, char or struct types.


 Scope − global or local variables.
 Storage type − automatic, static, register or extern.

Integer Promotions in C

The C compiler promotes certain data types to a higher rank for the sake of achieving
consistency in the arithmetic operations of integers.

In addition to the standard int data type, the C language lets you work with its subtypes such as
char, short int, long int, etc. Each of these data types occupy a different amount of memory
space. For example, the size of a standard int is 4 bytes, whereas a char type is 2 bytes of length.
When an arithmetic operation involves integer data types of unequal length, the compiler
employs the policy of integer promotion.

Integer Promotions

As a general principle, the integer types smaller than int are promoted when an operation is
performed on them. If all values of the original type can be represented as an int, the value of the
smaller type is converted to an int; otherwise, it is converted to an unsigned int.

One must understand the concept of integer promotion to write reliable C code, and avoid
unexpected problems related to the size of data types and arithmetic operations on smaller
integer types.

Example

In this example, the two variables a and b seem to be storing the same value, but they are not
equal.

#include <stdio.h>

int main(){

char a = 251;
unsigned char b = a;

printf("a = %c", a);


printf("\nb = %c", b);

if (a == b)
printf("\n Same");
else
printf("\n Not Same");

return 0;
}

Output

When you run this code, it will produce the following output −

a=√
b=√
Not Same

You get this output because "a" and "b" are treated as integers during comparison. "a" is a signed
char converted to int as -5, while "b" is an unsigned char converted to int as 251.

Example: Mechanism of Integer Promotions

Let us try to understand the mechanism of integer promotions with this example −

#include <stdio.h>

int main(){

char a = 'e', b = '2', c = 'M';


char d = (a * b) / c;

printf("d as int: %d as char: %c", d, d);

return 0;
}

Output
Run the code and check its output −

d as int: 65 as char: A

When Integer Promotion is Applied?

In the arithmetic expression "(a * b) / c", the bracket is solved first. All the variables are of
signed char type, which is of 2 byte length and can store integers between -128 to 127. Hence the
multiplication goes beyond the range of char but the compiler doesn't report any error.

The C compiler applies integer promotion when it deals with arithmetic operations involving
small types like char. Before the multiplication of these char types, the compiler changes them to
int type. So, in this case, (a * b) gets converted to int, which can accommodate the result of
multiplication, i.e., 1200.

Example

Integer promotions are applied as part of the usual arithmetic conversions to certain argument
expressions; operands of the unary +, -, and ~ operators; and operands of the shift operators.
Take a look at the following example −

#include <stdio.h>

int main(){

char a = 10;
int b = a >> 3;

printf("b as int: %d as char: %c", b, b);

return 0;
}

Output

When you run this code, it will produce the following output −

b as int: 1 as char:

In the above example, shifting the bit structure of "a" to the left by three bits still results in its
value within the range of char (a << 3 results in 80).
Example

In this example, the rank of the char variable is prompted to int so that its left shift operation
goes beyond the range of char type.

#include <stdio.h>

int main(){

char a = 50;
int b = a << 2;

printf ("b as int: %d as char: %c", b, b);

return 0;
}

Output

Run the code and check its output −

b as int: 200 as char: ╚

Integer Promotion Rules

Promotion rules help the C compiler in maintaining consistency and avoiding unexpected results.
The fundamental principle behind the rules of promotion is to ensure that the expression's type is
adjusted to accommodate the widest data type involved, preventing data loss or truncation.

Here is a summary of promotion rules as per C11 specifications −

 The integer types in C are char, short, int, long, long long and enum. Booleans are also
treated as an integer type when it comes to type promotions.
 No two signed integer types shall have the same rank, even if they have the same
representation.
 The rank of a signed integer type shall be greater than the rank of any signed integer type
with less precision.
 The rank of long int > the rank of int > the rank of short int > the rank of signed char.
 The rank of char is equal to the rank of signed char and unsigned char.
 Whenever a small integer type is used in an expression, it is implicitly converted to int
which is always signed.
 All small integer types, irrespective of sign, are implicitly converted to (signed) int when
used in most expressions.
In short, we have the following integer promotion rules −

 Byte and short values − They are promoted to int.


 If one operand is a long − The entire expression is promoted to long.
 If one operand is a float − The entire expression is promoted to float.
 If any of the operands is double − The result is promoted to double.

Example

Here, the variables x and y are of char data type. When the division operation is performed on
them, they automatically get promoted to int and the resultant value is stored in z.

#include <stdio.h>

int main(){

char x = 68;
char y = 34;

printf("The value of x is: %d", x);


printf("\nThe value of y is: %d", y);

char z = x/y;
printf("\nThe value of z: %d", z);

return 0;
}

Output

When you run this code, it will produce the following output −

The value of x is: 68


The value of y is: 34
The value of z: 2
Type Conversion in C

The C compiler attempts data type conversion, especially when dissimilar data types appear in an
expression. There are certain times when the compiler does the conversion on its own (implicit
type conversion) so that the data types are compatible with each other. On other occasions, the C
compiler forcefully performs the conversion (explicit type conversion), which is carried out by
the type cast operator.

Implicit Type Conversion in C

In C, implicit type conversion takes place automatically when the compiler converts the type of
one value assigned to a variable to another data type. It typically happens when a type with
smaller byte size is assigned to a "larger" data type. In such implicit data type conversion, the
data integrity is preserved.

While performing implicit or automatic type conversions, the C compiler follows the rules of
type promotions. Generally, the principle followed is as follows −

 Byte and short values: They are promoted to int.


 If one operand is a long: The entire expression is promoted to long.
 If one operand is a float: The entire expression is promoted to float.
 If any of the operands is double: The result is promoted to double.

Integer Promotion

Integer promotion is the process by which values of integer type "smaller" than int or unsigned
int are converted either to int or unsigned int.

Example

Consider an example of adding a character with an integer −

#include <stdio.h>

int main(){

int i = 17;
char c = 'c'; /* ascii value is 99 */

int sum;
sum = i + c;

printf("Value of sum: %d\n", sum);

return 0;
}
Output

When you run this code, it will produce the following output −

Value of sum: 116

Here, the value of sum is 116 because the compiler is doing integer promotion and converting
the value of "c" to ASCII before performing the actual addition operation.

Usual Arithmetic Conversion

Usual arithmetic conversions are implicitly performed to cast their values to a common type. The
compiler first performs integer promotion; if the operands still have different types, then they are
converted to the type that appears highest in the following hierarchy −

Example

Here is another example of implicit type conversion −

#include <stdio.h>
int main(){

char a = 'A';
float b = a + 5.5;

printf("%f", b);

return 0;
}

Output

Run the code and check its output −

70.500000

When the above code runs, the char variable "a" (whose int equivalent value is 70) is promoted
to float, as the other operand in the addition expression is a float.

Explicit Type Conversion in C

When you need to covert a data type with higher byte size to another data type having lower byte
size, you need to specifically tell the compiler your intention. This is called explicit type
conversion.

C provides a typecast operator. You need to put the data type in parenthesis before the operand to
be converted.

type2 var2 = (type1) var1;

Note that if type1 is smaller in length than type2, then you don’t need such explicit casting. It is
only when type1 is greater in length than type2 that you should use the typecast operator.

Typecasting is required when we want to demote a greater data type variable to a comparatively
smaller one or convert it between unrelated types like float to int.

Example

Consider the following code −

#include <stdio.h>
int main(){

int x = 10, y = 4;
float z = x/y;

printf("%f", z);

return 0;
}

Output

On running this code, you will get the following output −

2.000000

While we expect the result to be 10/4 (that is, 2.5), it shows 2.000000. It is because both the
operands in the division expression are of int type. In C, the result of a division operation is
always in the data type with larger byte length. Hence, we have to typecast one of the integer
operands to float, as shown below −

Example

Take a look at this example −

#include <stdio.h>

int main(){

int x = 10, y = 4;
float z = (float)x/y;

printf("%f", z);

return 0;
}

Output

Run the code and check its output −


2.500000

If we change the expression such that the division itself is cast to float, the result will be
different.

Typecasting Functions in C

The standard C library includes a number of functions that perform typecasting. Some of the
functions are explained here −

The atoi() Function

The atoi() function converts a string of characters to an integer value. The function is declared in
the stdlib.h header file.

Example

The following code uses the atoi() function to convert the string "123" to a number 123 −

#include <stdio.h>
#include <stdlib.h>

int main(){

char str[] = "123";


int num = atoi(str);

printf("%d\n", num);

return 0;
}

Output

Run the code and check its output −

123

The itoa() Function

You can use the itoa() function to convert an integer to a null terminated string of characters. The
function is declared in the stdlib.h header file.
Example

The following code uses itoa() function to convert an integer 123 to string "123" −

#include <stdio.h>
#include <stdlib.h>

int main(){

int num = 123;


char str[10];

itoa(num,str, 10);

printf("%s\n", str);

return 0;
}

Output

Run the code and check its output −

123

Other examples of using typecasting include the following −

The malloc() Function − The malloc() function is a dynamic memory allocation function.

Int *ptr = (int*)malloc(n * sizeof(int));

In function arguments and return values − You can apply the typecast operator to formal
arguments or to the return value of a user-defined function.

Example

Here is an example −

#include <stdio.h>
#include <stdlib.h>
float divide(int, int);

int main(){
int x = 10, y = 4;
float z = divide(x, y);

printf("%f", z);

return 0;
}

float divide(int a, int b){


return (float)a/b;
}

Output

When you run this code, it will produce the following output −

2.500000

Employing implicit or explicit type conversion in C helps in type safety and improved code
readability, but it may also lead to loss of precision and its complicated syntax may be confusing.

Booleans in C

Unlike the int, char or float types, the ANSI C standard doesn’t have a built-in or primary
Boolean type. A Boolean or bool data generally refers to the one that can hold one of the two
binary values: true or false (or yes/no, on/off, etc.). Even if the bool type is not available in C,
you can implement the behaviour of Booleans with the help of an enum type.

The new versions of C compilers, complying with the C99 standard or later, support
the bool type, which has been defined in the header file stdbool.h.

Using enum to Implement Boolean Type in C

The enum type assigns user-defined identifiers to integral constants. We can define an
enumerated type with true and false as the identifiers with the values 1 and 0.

Example

1 or any other number that is not 0 represents true, whereas 0 represents false.
#include <stdio.h>

int main (){

enum bool {false, true};


enum bool x = true;
enum bool y = false;

printf ("%d\n", x);


printf ("%d\n", y);
}

Output

Run the code and check its output −

1
0

typedef enum as BOOL

To make it more concise, we can use the typedef keyword to call enum bool by the name BOOL.

Example 1

Take a look at the following example −

#include <stdio.h>

int main(){

typedef enum {false, true} BOOL;

BOOL x = true;
BOOL y = false;

printf ("%d\n", x);


printf ("%d\n", y);
}
Here too, you will get the same output −

Output

1
0

Example 2

We can even use the enumerated constants in the decision-making or loop statements −

#include <stdio.h>

int main(){

typedef enum {false, true} BOOL;

int i = 0;

while(true){
i++;
printf("%d\n", i);

if(i >= 5)
break;
}
return 0;
}

Output

When you run this code, it will produce the following output −

1
2
3
4
5
Boolean Values with #define

The #define preprocessor directive is used to define constants. We can use this to define the
Boolean constants, FALSE as 0 and TRUE as 1.

Example

Take a look at the following example −

#include <stdio.h>

#define FALSE 0
#define TRUE 1

int main(){

printf("False: %d \n True: %d", FALSE, TRUE);

return 0;
}

Output

Run the code and check its output −

False: 0
True: 1

Boolean Type in stdbool.h

The C99 standard of C has introduced the stdbool.h header file. It contains the definition
of bool type, which actually is a typedef alias for _bool type. It also defines the
macros true which expands to 1, and false which expands to 0.

Example 1

We can use the bool type as follows −

#include <stdio.h>
#include <stdbool.h>
int main(){

bool a = true;
bool b = false;

printf("True: %d\n", a);


printf("False: %d", b);

return 0;
}

Output

On executing this code, you will get the following output −

True: 1
False: 0

Example 2

We can use bool type variables in logical expressions too, as shown in the following example −

#include <stdio.h>
#include <stdbool.h>

int main(){

bool x;
x = 10 > 5;

if(x)
printf("x is True\n");
else
printf("x is False\n");

bool y;
int marks = 40;
y = marks > 50;
if(y)
printf("Result: Pass\n");
else
printf("Result: Fail\n");
}

Output

Run the code and check its output −

x is True
Result: Fail

Example 3

Let us implement a while loop with the help of a bool variable −

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main(void){

bool loop = true;


int i = 0;

while(loop){
i++;
printf("i: %d \n", i);

if (i >= 5)
loop = false;
}
printf("Loop stopped!\n");
return EXIT_SUCCESS;
}
Output

When you run this code, it will produce the following output −

i: 1
i: 2
i: 3
i: 4
i: 5
Loop stopped!
C - Constants

A constant in C is a user-assigned name to a location in the memory, whose value cannot be


modified once declared. This is in contrast to a variable in C, which is also a named memory
location, however whose value may be changed during the course of the code.

Instead of repeatedly using hard-coded values in a program, it is advised to define a constant and
use it. Constants in a C program are usually employed to refer to a value which may be error-
prone if it is to be used repetitively in the program, at the same time its value is not likely to
change.

For example, the value of mathematical constant PI is a high-precision floating point number
3.14159265359, and if it is likely to appear frequently, it is declared as a constant and used by its
name.

We may consider a constant in C as a read-only variable, as its value can only be used
subsequently but cannot be modified.

You can declare a constant in C program with either of the following two ways −

 Using the const Keyword


 Using the #define Directive

Let's understand these two ways of declaring a constant in C.

Defining a Constant Using the const Keyword

The syntax of declaring a constant is as follows −

const type NAME = val;

For example,

const float PI = 3.14159265359;


We can now use PI in any expression, as we would use any variable.

Example

Take a look at the following example −

#include <stdio.h>

int main(){
const float PI = 3.14159265359;
float radius = 5;
float area = PI*radius*radius;
printf ("area: %f", area);
return 0;
}

Output

On running this code, you will get following output −

area: 78.539818

However, changing the value of a constant is prohibited. The following statement gives a
compiler error −

const float PI = 3.14159265359;


PI=22/7;

Here, you will get the following error message −

error: assignment of read-only variable 'PI'

In case of variables, you can declare a variable and assign it a value later on in the program,
however you cannot follow the same process in case of a constant.

You can declare a constant in C without assigning it a value. But when you try to assign it a
value afterwords, then the compiler will throw an error.

const float PI;


PI = 3.14159265359;

Here, you will get this error message −


error: assignment of read-only variable 'PI'

Note: "sizeof" returns "size_t". The type of unsigned integer of "size_t" can vary depending on
platform. And, it may not be long unsigned int everywhere. In such cases, we use "%zu" for the
format string instead of "%d".

This is because the compiler assigns a random garbage value at the time of declaration, which
you cannot change afterwards. Hence, you must declare and initialize the constant at once.

A constant in C can be of any of the data types including primary data types such as int, float,
char, and derived data types such as struct.

Defining a Constant Using the #define Directive

Using the #define preprocessor directive is also an effective method to define a constant. Here is
its syntax −

#define name = value

Take a look at the following example:

#define PI = 3.14159265359

Although the constant so defined can also be used in any expression (just as the one with the
const keyword), there is a difference between the two.

The constants created by the #define directive are not handled by the compiler. Instead, they
behave as macros, whose values are substituted at the runtime.

The other notable difference is that you need not mention the data type of the value to be
assigned to the constant when using the #define directive.

Example: Define a Constant Using the #define

Given below is another example of a constant defined using the #define directive −

#include <stdio.h>
#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'

int main() {
int area;
area = LENGTH * WIDTH;
printf("length: %d width: %d", LENGTH, WIDTH);
printf("%c", NEWLINE);
printf("value of area : %d", area);
return 0;
}

Output

Upon running this code, you will get the following output −

length: 10 width: 5
value of area : 50

Since a constant is also an identifier in C, it follows all the rules of forming an identifier.
Identifiers in C are case-sensitive. Hence the convention followed while defining a constant in C
is that it uses uppercase characters, however it is not mandatory.

Changing the Value of a Constant

By definition, constants are immutable. Why would you change the value of a constant in the
first place? We use constants whose value is supposed to remain unchanged. To be able to
change the value, we would define a variable rather than a constant.

We have seen that it is not possible to assign a new value to an already defined constant.
However, there exists a workaround with which a new value can be assigned to a constant.

The technique uses the concept of pointers in C. A Pointer is a variable that stores the address of
another variable. Since it is a variable, its value can be changed. Moreover, this change reflects
in the original variable.

Example: Change the Value of a Constant

The following code demonstrates how to change the value of a constant with the pointer
mechanism −

#include <stdio.h>
int main(){
const int x = 10;
printf("Initial Value of Constant: %d\n", x);

// y is a pointer to constant x
int* y = &x;

// assign new value


*y = 100;
printf("Value of Constant after change: %d", x);
return 0;
}

Output

On executing this code, you will get the following output −

Initial Value of Constant: 10


Value of Constant after change: 100

Note that this technique is effective only for those constants which are defined using
the const qualifier.

If you have defined your constant using the #define directive, then you cannot apply this
process. This is because the pointer has a data type, and it must be of the same type whose
address is to be stored. On the other hand, the constant defined using the #define directive
doesn't really have a data type. It is in fact a macro whose value is substituted during the runtime.

C - Literals

The term "literal" in computer programming terminology refers to a textual representation of a


value to be assigned to a variable.

In C, you can assign a value to a variable in two ways −

 Using literal representation


 Using an expression

The initialization of a variable in C is done as follows −

int x = 10;

On the other hand, an indirect initialization of a variable by assigning it the result of an


expression is as follows −

int x = 10;
int y = x*2;
In the first case, 10 is an integer literal assigned to "x". In the second case, the result of "x*2"
expression is assigned to "y".

A literal is thus a value of a certain data type represented directly into the source code. Normally,
literals are used to set a value of a variable.

On their own, literals don’t form any of the programming element. Different notations are used
to represent the values of different data types.

Integer Literals in C

In the above example, 10 is an integer literal. A positive or negative whole number represented
with digits 0 to 9, without a fractional part is a decimal integer literal. It must be within the
acceptable range for the given OS platform.

Following examples assign decimal literals to int variables −

int x = 200;
int y = -50;

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.

int c = 89U;
long int d = 99998L;

C allows you to represent an integer in octal and hexadecimal number systems. For a literal
representation of an octal, prefix the number with 0 (ensure that the number uses octal digits
only, from 0 to 7).

For a hexadecimal literal, prefix the number with 0x or 0X. The hexadecimal number must have
0 to 9, and A to F (or a to f) symbols.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

int oct = 025;


int hex = 0xa1;
printf("Octal to decimal: %d\n", oct);
printf("Hexadecimal to decimal: %d\n", hex);
}

Output

On running this code, you will get the following output −

Octal to decimal: 21
Hexadecimal to decimal: 161

Modern C compilers also let you represent an integer as a binary number, for which you need to
add a 0b prefix.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

int x = 0b00010000;
printf("binary to decimal: %d", x);
}

Output

Run the code and check its output −

binary to decimal: 16

Here are some examples of integer literals −

212 /* valid */
215u /* valid */
0xFeeL /* valid */
078 /* invalid: 8 is not an octal digit */
032UU /* invalid: cannot repeat a suffix */
Here are some 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 in C

A floating-point literal in C is a real number with an integer part and a fractional part within the
range acceptable to the compiler in use, and represented in digits, decimal point with an optional
exponent symbol (e or E).

A floating point literal is generally used for initializing or setting the value of a float or a double
variable in C.

Example

The following assignment examples use floating point literals with a decimal point separating the
integer and the fractional part −

#include <stdio.h>

int main(){

float x = 10.55;
float y = -1.333;
printf("x and y are: %f, %f", x, y);
}

Output

You will get the following output −

x and y are: 10.550000, -1.333000

Floating point literals with a high degree of precision can be stated with the exponentiation
symbol "e" or "E". This is called the scientific notation of a float literal.
While representing decimal form, you must include the decimal point, the exponent, or both.
While representing exponential form, you must include the integer part, the fractional part, or
both.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

float x = 100E+4;
float y = -1.3E-03;
printf("x: %f\n", x);
printf("y: %f\n", y);
}

Output

When you run this code, it will produce the following output −

x: 1000000.000000
y: -0.001300

Here are some examples of floating-point literals −

3.14159 /* valid */
314159E-5L /* valid */
510E /* invalid: incomplete exponent */
210f /* invalid: no decimal or exponent */
.e55 /* invalid: missing integer or fraction */

Character Literals in C

A character literal in C is a single character enclosed within single quote symbols. Note that C
recognizes straight quotes only. Hence, use ' to form a character literal and not ‘). Here is an
example −

char x = 'I';
Character literals are generally assigned to a char variable that occupies a single byte. Using
the %c format specifier outputs the character. Use %d and you’ll obtain the ASCII value of the
character.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

char x = 'I';
printf("x: %c\n", x);
printf("x: %d\n", x);
}

Output

Run the code and check its output −

x: I
x: 73

Escape Sequences in C

C defines a number of escape sequences as a sequence of characters starting with "\" and an
alternate meaning attached to the following characters.

Even though an escape sequence consists of more than one characters, it is put inside single
quotes. An escape sequence produces the effect of a single non-printable character. For
example, '\n' is an escape sequence that represents a newline character, with the same effect as
pressing the Enter key.

Example

Take a look at the following example −

#include <stdio.h>

int main(){
char x = 'I';
char y = 'J';
printf("x: %c\ny: %c", x,y);
}

Output

Here you will get this output −

x: I
y: J

We shall learn more about escape sequences in a later chapter.

A character literal can also be a UNICODE representation of a character. Such a literal has /u at
the beginning.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

char x = '\u09A9';
printf("x: %c\n", x);
printf("x: %d\n", x);
}

Output

On running this code, you will get the following output −

x: ⌐
y: -87

String Literals in C

A sequence of characters put inside double quotation symbols forms a string literal. C doesn’t
provide a string variable. Instead, we need to use an array of char type to store a string.
Example

Take a look at the following example −

#include <stdio.h>

int main(){

char arr[] = "Hello World";


printf("arr: %s", arr);
}

Output

Run the code and check its output −

arr: Hello World

A string literal may contain plain characters, escape sequences, and Unicode characters. For
example −

char arr[] = "Hello \


World";

You can also have a literal representation of an array by putting its elements inside the curly
brackets { and }. For example:

int arr[] = {10, 20, 30, 40};

Similarly, the curly brackets can also be used for a literal representation of a struct value. For
example −

struct marks {
int phy;
int che;
int math
};
struct marks m1 = {50, 60, 70};
Escape Sequence in C
An escape sequence in C is a literal made up of more than one character put inside single
quotes. Normally, a character literal consists of only a single character inside single quotes.
However, the escape sequence attaches a special meaning to the character that appears after a
backslash character (\).

The \ symbol causes the compiler to escape out of the string and provide meaning attached to the
character following it.

Look at \n as an example. When put inside a string, the \n acts as a newline character, generating
the effect of pressing the Enter key. The following statement −

printf(" Hello \n World ");

Will produce this output −

Hello
World

The new line is an unprintable character. The \n escape sequence is useful to generate its effect.
Similarly, the escape sequence \t is equivalent to pressing the Tab key on the keyboard.

An escape sequence is a sequence of characters that does not represent itself when used inside a
character or string literal but is translated into another character or a sequence of characters that
may be difficult or impossible to represent directly.

All Escape Sequences in C

In C, all escape sequences consist of two or more characters, the first of which is the
backslash \ (called the "Escape character"); the remaining characters have an interpretation of the
escape sequence as per the following table.

Here is a list of escape sequences available in C −

Escape sequence Meaning

\\ \ character

\' ' character

\" " character

\? ? character

\a Alert or bell
\b Backspace

\f Form feed

\n Newline

\r Carriage return

\t Horizontal tab

\v Vertical tab

\ooo Octal number of one to three digits

\xhh . . . Hexadecimal number of one or more digits

Let us understand how these escape sequences work with the help of a set of examples.

Newline Escape Sequence (\n)

The newline character, represented by the escape sequence \n in C, is used to insert the effect of
carriage return on the output screen. You would use this escape sequence to print text in separate
lines and improve the readability of output.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

printf("Hello.\nGood morning.\nMy name is Ravi");


}

Output

On running this code, you will get the following output −

Hello.
Good morning.
My name is Ravi

Tab Escape Sequence (\t)


The tab character (\t) represents the Tab key on the keyboard. When the tab character is
encountered in a string, it causes the cursor to move to the next horizontal tab stop. Horizontal
tab stops are usually set at intervals of eight characters.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

printf("Name:\tRavi\tMarks:\t50");
}

Output

Run the code and check its output −

Name: Ravi Marks: 50

Backslash Escape Sequence (\\)

To add backslash character itself as a part of a string, it must precede by another backslash. First
backslash escapes out of the string, and the second one takes the effect.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

printf("Directory in Windows: C:\\users\\user");


}

Output

On running this code, you will get the following output −

Directory in Windows: C:\users\user


Double and Single Quotes Escape Sequences (\" and \')

These characters have a special meaning in C since " and ' symbols are used for the
representation of a character literal and a string literal respectively. Hence, to treat these
characters as a part of the string, they must be escaped with an additional backslash preceding
them.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

printf("Welcome to \"TutorialsPoint\"\n");
printf ("\'Welcome\' to TutorialsPoint");
}

Output

Run the code and check its output −

Welcome to "TutorialsPoint"
'Welcome' to TutorialsPoint

Backspace Escape Sequence (\b)

The escape sequence "\b", represents the backspace character. It is used erase a character or a
specific portion of a text that has already been printed on the screen.

Example

Check the following example code −

#include <stdio.h>

int main(){

printf("Welcome to\b TutorialsPoint");


}
Output

Run the code and check its output −

Welcome t TutorialsPoint

Note that o from to has been erased.

C also has a \r escape sequence. The newline escape sequence (\n) moves the cursor to the
beginning of the next line, while the carriage return escape sequence (\r) moves the cursor to the
beginning of the current line.

Octal Number Escape Sequence (\ooo)

This escape sequence is used for Octal numbers of one to three digits. An octal escape sequence
is a backslash followed by one, two, or three octal digits (0-7). It matches a character in the
target sequence with the value specified by those digits.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

printf("%c", '\141');

return 0;
}

Output

When you run this code, it will produce the following output −

Hexadecimal Number Escape Sequence (\xhh)

A hexadecimal escape sequence is a backslash followed by the letter "x" followed by two
hexadecimal digits (0-9a-fA-F). It matches a character in the target sequence with the value
specified by the two digits.
Example

Take a look at the following example −

#include <stdio.h>

int main(){

printf("%c", '\x41');

return 0;
}

Output

Here, you will get the following output −

Alert or Bell Number Escape Sequence (\a)

The escape sequence \a represents the alert or bell character. When executed, it produces a sound
or visual alert depending on the terminal or console being used.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

printf("Hello \a world\n");

return 0;
}

Output

Run the code and check its output −


Hello world

Escape sequences are used widely in many other programming languages such as Java, PHP, C#,
etc.

Format Specifiers in C

Format specifiers in C are certain special symbols used in the formatted console IO functions
such as printf() and scanf(), as well as formatted file IO functions such as fprintf() and fscanf().

Format specifiers are formed of a predefined sequence of one or more alphanumeric characters
followed by the % symbol. For example, %d, %s, %f, %lf, etc. are some of the format specifiers
used in C.

Why Do We Use Format Specifiers in C?

The CPU performs IO operations with input and output devices in a streaming manner. The data
read from a standard input device (for example, a keyboard) through the standard input stream is
called stdin. Similarly the data sent to the standard output, which is the computer display screen,
through the standard output device is called stdout.

The computer receives data from the stream in a text form, however you may want to parse it in
variables of different data types such as int, float or a string. Similarly, the data stored in int, float
or char variables has to be sent to the output stream in a text format. Format specifier symbols
are used exactly for this purpose.

Format Specifiers in printf() Function

The printf() function is the most commonly used standard output function, defined in
the stdio.h header file. The prototype of printf() function is as follows −

int printf(format_string, expr1, expr2, . . );

The first argument of this function is a string that is interspersed with one or more format
specifiers. There may be one or more expressions as argument after the first. The compiler
substitutes each format specifier with the value of its successive expression. The resultant
formatted string is then passed to the output stream.

Example

In the following code, we have an int variable age and a float variable percent. The printf()
function prints the values of both as below −
#include <stdio.h>

int main(){

int age = 18;

float percent = 67.75;

printf("Age: %d \nPercent: %f", age, percent);

return 0;
}

Output

When you run the code, it will produce the following output −

Age: 18
Percent: 67.750000

The value of the first variable replaces the first format specifier %d. Similarly, %f is substituted
by the value of the percent variable.

Format Specifiers in scanf() Function

Format specifiers are also used to parse the input stream into the variables of required type. The
following example highlights how it's done.

Example

In this example, the program asks the user to input age and percent values. They are stored in the
int and float variables, respectively.

#include <stdio.h>

int main(){

int age;

float percent;
printf("Enter Age and Percent: \n");

scanf("%d %f", &age, &percent);

printf("Age: %d Percent: %f", age, percent);

return 0;
}

Output

Run the code and check its output −

Enter Age and Percent:


Age: 4096 Percent: 0.000000

Types of Format Specifiers

ANSI C defines a number of format specifiers. The following table lists the different specifiers
and their purpose −

Format Specifier Type

%c Character

%d Signed integer

%e or %E Scientific notation of floats

%f Float values

%g or %G Similar as %e or %E

%hi Signed integer (short)

%hu Unsigned Integer (short)

%i Unsigned integer

%l or %ld or %li Long

%lf Double
%Lf Long double

%lu Unsigned int or unsigned long

%lli or %lld Long long

%llu Unsigned long long

%o Octal representation

%p Pointer

%s String

%u Unsigned int

%x or %X Hexadecimal representation
 A minus symbol (−) tells left alignment.
 A number after % specifies the minimum field width. If a string is less than the width, it
will be filled with spaces.
 A period (.) is used to separate field width and precision.

Integer Format Specifiers

C uses %d for signed integer, %i for unsigned integer, %ld or %li for long
integer, %o or %O for octal representation, and %x or %X for hexadecimal representation of
an integer.

Example

The following example highlights how integer format specifiers are used in C −

#include <stdio.h>

int main(){

int num = 20;

printf("Signed integer: %d\n", num);


printf("Unsigned integer: %i\n", num);
printf("Long integer: %ld\n", num);
printf("Octal integer: %o\n", num);
printf("Hexadecimal integer: %x\n", num);
return 0;
}

Output

When you run this code, it will produce the following output −

Signed integer: 20
Unsigned integer: 20
Long integer: 20
Octal integer: 24
Hexadecimal integer: 14

Floating-point Formats

C uses the %f format specifier for single precision float number, %lf for double
precision, %Lf for long double number. To represent a floating point number in scientific
notation, C uses the %e or %E specifier symbol.

You can specify the width and the precision in the form of number of places after the decimal
point. For example, to state the width of number to 4 digits with 2 digits after the decimal point,
use the form %4.2f.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

float num = 5.347;

printf("float: %f\n", num);


printf("double: %lf\n", num);
printf("Scientific notation: %e\n", num);
printf("width and precision: %4.2f\n", num);

return 0;
}

Output

On running this code, you will get the following output −

float: 5.347000
double: 5.347000
Scientific notation: 5.347000e+000
width and precision: 5.35

String Formats

The char data type in C is actually a subset of int data type. Hence, a char variable
with %c format specifier corresponds to the character in single quotes. On the other hand, if you
use the %d specifier, then the char variable will be formatted to its ASCII value.

In C, a string is an array of char data. To display an array of chars, C uses the %s specifier.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

char ch = 'D';
char word[]="Hello World";

printf("As character: %c\n", ch);


printf("As its ASCII value: %d\n", ch);
printf("String format: %s", word);

return 0;

Output

When you run this code, it will produce the following output −
As character: D
As its ASCII value: 68
String format: Hello World

Format Specifiers in File IO Functions

The stdio.h library defines the functions fscanf() and fprintf() for formatted IO with disk files,
instead of standard input/output streams.

Example 1

The following code opens a file in write mode and saves the values of three variables in it.

#include <stdio.h>

int main(){

int x,y,z;

FILE *fp = fopen("[Link]","w");

x = 10; y = 20; z = 30;

fprintf(fp, "%d, %d, %d", x,y,z);

fclose(fp);

return 0;
}

Output

The fprintf() function uses the file represented by the file pointer fp to write the data.

The next example shows how you can open the same file in read mode to read the formatted
data.

Example 2

The following program reads back the data from the file by opening it in read mode.
#include <stdio.h>

int main(){

int x,y,z;

FILE *fp = fopen("[Link]","r");

fscanf(fp, "%d, %d, %d", &x,&y,&z);

printf("%d, %d, %d", x,y,z);

fclose(fp);

return 0;
}

Output

The fscanf() function reads the formatted input from fp which is the pointer to the file opened.
Here, you will get the following output −

10, 20, 30

Storage Classes in C

A storage class defines the scope (visibility) and lifetime of variables and/or functions within a
C Program. They precede the type that they modify.

Type of Storage Classes in C

We have four different storage classes in a C program −

 auto
 register
 static
 extern

The auto Storage Class

The auto storage class is the default storage class for all local variables.
{
int mount;
auto int month;
}

The example above defines two variables with in the same storage class. 'auto' can only be used
within functions, i.e., local variables.

The register Storage Class

The register storage class is used to define local variables that should be stored in a register
instead of RAM. This means that the variable has a maximum size equal to the register size
(usually one word) and can't have the unary '&' operator applied to it (as it does not have a
memory location).

{
register int miles;
}

The register should only be used for variables that require quick access such as counters. It
should also be noted that defining 'register' does not mean that the variable will be stored in a
register. It means that it MIGHT be stored in a register depending on hardware and
implementation restrictions.

The static Storage Class

The static storage class instructs the compiler to keep a local variable in existence during the
life-time of the program instead of creating and destroying it each time it comes into and goes
out of scope. Therefore, making local variables static allows them to maintain their values
between function calls.

The static modifier may also be applied to global variables. When this is done, it causes that
variable's scope to be restricted to the file in which it is declared.

Example

In C programming, when static is used on a global variable, it causes only one copy of that
member to be shared by all the objects of its class. Look at the example below −

#include <stdio.h>

/* function declaration */
void func(void);
static int count = 5; /* global variable */

main(){

while(count--) {
func();
}

return 0;
}

/* function definition */
void func(void) {

static int i = 5; /* local static variable */


i++;

printf("i is %d and count is %d\n", i, count);


}

Output

When the above code is compiled and executed, it produces the following result −

i is 6 and count is 4
i is 7 and count is 3
i is 8 and count is 2
i is 9 and count is 1
i is 10 and count is 0

The extern Storage Class

The extern storage class is used to give a reference of a global variable that is visible to ALL the
program files. When you use 'extern', the variable cannot be initialized however, it points the
variable name at a storage location that has been previously defined.

When you have multiple files and you define a global variable or function, which will also be
used in other files, then extern will be used in another file to provide the reference of defined
variable or function. Just for understanding, extern is used to declare a global variable or
function in another file.

The extern modifier is most commonly used when there are two or more files sharing the same
global variables or functions as explained below.

First File: main.c

#include <stdio.h>

int count;
extern void write_extern();

main(){
count = 5;
write_extern();
}

Second File: support.c

#include <stdio.h>

extern int count;

void write_extern(void) {
printf("Count is %d\n", count);
}

Here, extern is being used to declare count in the second file, whereas it has its definition in the
first file (main.c). Now, compile these two files as follows −

$gcc main.c support.c

It will produce the executable program [Link]. When this program is executed, it will produce the
following output −

Count is 5
C - Operators
An operator is a symbol that tells the compiler to perform specific mathematical or logical
functions. By definition, an operator performs a certain operation on operands. An operator
needs one or more operands for the operation to be performed.

Depending on how many operands are required to perform the operation, operands are called as
unary, binary or ternary operators. They need one, two or three operands respectively.

 Unary operators − ++ (increment), -- (decrement), ! (NOT), ~ (compliment), & (address


of), * (dereference)
 Binary operators − arithmetic, logical and relational operators except !
 Ternary operators − The ? operator

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. Here, you will get an overview
of all these chapters. Thereafter, we have provided independent chapters on each of these
operators that contain plenty of examples to show how these operators work in C Programming.

Arithmetic Operators

We are most familiar with the arithmetic operators. These operators are used to perform
arithmetic operations on operands. The most common arithmetic operators are addition (+),
subtraction (-), multiplication (*), and division (/).

In addition, the modulo (%) is an important arithmetic operator that computes the remainder of a
division operation. Arithmetic operators are used in forming an arithmetic expression. These
operators are binary in nature in the sense they need two operands, and they operate on numeric
operands, which may be numeric literals, variables or expressions.

For example, take a look at this simple expression −

a+b

Here "+" is an arithmetic operator. We shall learn more about arithmetic operators in C in a
subsequent chapter.

The following table shows all the arithmetic operators supported by the C language. Assume
variable A holds 10 and variable B holds 20 then −
Show Examples

Operator Description Example

A+B=
+ Adds two operands.
30

A−B=
− Subtracts second operand from the first.
-10

A*B=
* Multiplies both operands.
200

/ Divides numerator by de-numerator. B/A=2

Modulus Operator and remainder of after an B%A=


%
integer division. 0

Increment operator increases the integer value A++ =


++
by one. 11

Decrement operator decreases the integer value


-- A-- = 9
by one.

Relational Operators

We are also acquainted with relational operators while learning secondary mathematics. These
operators are used to compare two operands and return a boolean value (true or false). They are
used in a boolean expression.

The most common relational operators are less than (<), greater than (>), less than or equal to
(<=), greater than or equal to (>=), equal to (==), and not equal to (!=). Relational operators are
also binary operators, needing two numeric operands.

For example, in the Boolean expression −

a>b

Here, ">" is a relational operator.

We shall learn more about with relational operators and their usage in one of the following
chapters.

Show Examples
Operator Description Example

(A == B)
Checks if the values of two operands are equal
== is not
or not. If yes, then the condition becomes true.
true.

Checks if the values of two operands are equal


(A != B)
!= or not. If the values are not equal, then the
is true.
condition becomes true.

Checks if the value of left operand is greater (A > B)


> than the value of right operand. If yes, then the is not
condition becomes true. true.

Checks if the value of left operand is less than


(A < B)
< the value of right operand. If yes, then the
is true.
condition becomes true.

Checks if the value of left operand is greater (A >= B)


>= than or equal to the value of right operand. If is not
yes, then the condition becomes true. true.

Checks if the value of left operand is less than or


(A <= B)
<= equal to the value of right operand. If yes, then
is true.
the condition becomes true.

Logical Operators

These operators are used to combine two or more boolean expressions. We can form a compound
Boolean expression by combining Boolean expression with these operators. An example of
logical operator is as follows −

a >= 50 && b >= 50

The most common logical operators are AND (&&), OR(||), and NOT (!). Logical operators are
also binary operators.

Show Examples

Operator Description Example

Called Logical AND operator. If both the (A &&


&& operands are non-zero, then the condition B) is
becomes true. false.
Called Logical OR Operator. If any of the two
(A || B)
|| operands is non-zero, then the condition
is true.
becomes true.

Called Logical NOT Operator. It is used to


!(A &&
reverse the logical state of its operand. If a
! B) is
condition is true, then Logical NOT operator
true.
will make it false.

We will discuss more about Logical Operators in C in a subsequent chapter.

Bitwise Operators

Bitwise operators let you manipulate data stored in computer’s memory. These operators are
used to perform bit-level operations on operands.

The most common bitwise operators are AND (&), OR (|), XOR (^), NOT (~), left shift (<<),
and right shift (>>). Here the "~" operator is a unary operator, while most of the other bitwise
operators are binary in narure.

Bitwise operator works on bits and perform bit−by−bit operation. The truth tables for &, "|", and
"^" are as follows −

p q p&q p|q p^q

0 0 0 0 0

0 1 0 1 1

1 1 1 1 0

1 0 0 1 1

Assume A = 60 and B = 13 in binary format, they will be as follows −

A = 0011 1100

B = 0000 1101
------------------------

A&B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

~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

Operator Description Example

(A & B)
Binary AND Operator copies a bit to the result = 12,
&
if it exists in both operands. i.e., 0000
1100

(A | B) =
Binary OR Operator copies a bit if it exists in 61, i.e.,
|
either operand. 0011
1101

(A ^ B)
Binary XOR Operator copies the bit if it is set in = 49,
^
one operand but not both. i.e., 0011
0001

(~A ) =
Binary One's Complement Operator is unary ~(60),
~
and has the effect of 'flipping' bits. i.e,. -
0111101

A << 2 =
Binary Left Shift Operator. The left operands
240 i.e.,
<< value is moved left by the number of bits
1111
specified by the right operand.
0000

A >> 2 =
Binary Right Shift Operator. The left operands
15 i.e.,
>> value is moved right by the number of bits
0000
specified by the right operand.
1111
Assignment Operators

As the name suggests, an assignment operator "assigns" or sets a value to a named variable in C.
These operators are used to assign values to variables. The "=" symbol is defined as assignment
operator in C, however it is not to be confused with its usage in mathematics.

The following table lists the assignment operators supported by the C language −

Show Examples

Operator Description Example

C=A+
B will
Simple assignment operator. Assigns values assign the
=
from right side operands to left side operand value of
A + B to
C

C += A is
Add AND assignment operator. It adds the
equivalent
+= right operand to the left operand and assign the
to C = C
result to the left operand.
+A

C -= A is
Subtract AND assignment operator. It subtracts
equivalent
-= the right operand from the left operand and
to C = C -
assigns the result to the left operand.
A

Multiply AND assignment operator. It C *= A is


multiplies the right operand with the left equivalent
*=
operand and assigns the result to the left to C = C
operand. *A

C /= A is
Divide AND assignment operator. It divides the
equivalent
/= left operand with the right operand and assigns
to C = C /
the result to the left operand.
A

C %= A
Modulus AND assignment operator. It takes is
%= modulus using two operands and assigns the equivalent
result to the left operand. to C = C
%A
C <<= 2
is same as
<<= Left shift AND assignment operator.
C = C <<
2

C >>= 2
is same as
>>= Right shift AND assignment operator.
C = C >>
2

C &= 2 is
&= Bitwise AND assignment operator. same as C
=C&2

C ^= 2 is
^= Bitwise exclusive OR and assignment operator. same as C
=C^2

C |= 2 is
|= Bitwise inclusive OR and assignment operator. same as C
=C|2

Hence, the expression "a = 5" assigns 5 to the variable "a", but "5 = a" is an invalid expression in
C.

The "=" operator, combined with the other arithmetic, relational and bitwise operators form
augmented assignment operators. For example, the += operator is used as add and assign
operator. The most common assignment operators are =, +=, -=, *=, /=, %=, &=, |=, and ^=.

Misc Operators ↦ sizeof & ternary

Besides the operators discussed above, there are a few other important operators
including sizeof and ? : supported by the C Language.

Show Examples

Operator Description Example

sizeof(a), where a is
sizeof() Returns the size of a variable.
integer, will return 4.

&a; returns the actual


& Returns the address of a variable.
address of the variable.

* Pointer to a variable. *a;


If Condition is true ?
?: Conditional Expression. then value X :
otherwise value Y

Operators Precedence in C

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.

Show Examples

Category Operator Associativity

Postfix () [] -> . ++ - - Left to right

Unary + - ! ~ ++ - - (type)* & sizeof Right to left

Multiplicative */% Left to right

Additive +- Left to right

Shift << >> Left to right

Relational < <= > >= Left to right

Equality == != Left to right

Bitwise AND & Left to right

Bitwise XOR ^ Left to right

Bitwise OR | Left to right

Logical AND && Left to right

Logical OR || Left to right

Conditional ?: Right to left


Assignment = += -= *= /= %=>>= <<= &= ^= |= Right to left

Comma , Left to right

Other Operators in C

Apart from the above, there are a few other operators in C that are not classified into any of the
above categories. For example, the increment and decrement operators (++ and --) are unary in
nature and can appear as a prefix or postfix to the operand.

The operators that work with the address of memory location such as the address-of operator (&)
and the dereference operator (*). The sizeof operator (sizeof) appears to be a keyword but really
an operator.

C also has the type cast operator (()) that forces the type of an operand to be changed. C also uses
the dot (.) and the arrow (->) symbols as operators when dealing with derived data types such
as struct and union.

The C99 version of C introduced a few additional operators such as auto, decltype.

A single expression in C may have multiple operators of different type. The C compiler evaluates
its value based on the operator precedence and associativity of operators. For example, in the
following expression −

a+b*c

The multiplication operand takes precedence over the addition operator.

We shall understand these properties with examples in a subsequent chapter.

Many other programming languages, which are called C-family languages (such
as C++, C#, Java, Perl and PHP) have an operator nomenclature that is similar to C.

Arithmetic Operators in C

Arithmetic operators in C are certain special symbols, predefined to perform arithmetic


operations. We are familiar with the basic arithmetic operations − addition, subtraction,
multiplication and division. C is a computational language, so these operators are essential in
performing a computerised process.

In addition to the above operations assigned to the four symbols +, −, *, and / respectively, C has
another arithmetic operator called the modulo operator for which we use the %symbol.
The following table lists the arithmetic operators in C −

Operator Description

+ Adds two operands.

− Subtracts second operand from the first.

* Multiplies both operands.

/ Divides numerator by denominator.

% Modulus Operator and remainder of after an integer division.

++ Increment operator increases the integer value by one.

-- Decrement operator decreases the integer value by one.

The ++ and -- operators are also listed in the above table. We shall learn about increment and
decrement operators in a separate chapter.

Example: Arithmetic Operators in C

The following example demonstrates how to use these arithmetic operators in a C program −

#include <stdio.h>

int main(){

int op1 = 10;


int op2 = 3;

printf("Operand1: %d Operand2: %d \n\n", op1, op2);


printf("Addition of op1 and op2: %d\n", op1 + op2);
printf("Subtraction of op2 from op1: %d\n", op1 - op2);
printf("Multiplication of op1 and op2: %d\n", op1 * op2);
printf("Division of op1 by op2: %d\n", op1/op2);

return 0;
}
Output

When you run this code, it will produce the following output −

Operand1: 10 Operand2: 3

Addition of op1 and op2: 13


Subtraction of op2 from op1: 7
Multiplication of op1 and op2: 30
Division of op1 by op2: 3

Type Casting in C

The first three results are as expected, but the result of division is not. You expect 10/3 to be a
fractional number (3.333333). Is it because we used the %d format specifier to print the outcome
of the division? If we change the last line of the code as follows −

printf("Division of op1 by op2: %f\n", op1/op2);

Now the outcome of the division operation will be "0.000000", which is even more surprising.
The reason why C behaves like this is because the division of an integer with another integer
always returns an integer.

To obtain floating-point division, at least one operand must be a float, or you need to use the
typecast operator to change one of the integer operands to float.

Now, change the last printf statement of the given program as follows −

printf("Division of op1 by op2: %f\n", (float)op1/op2);

When you run run the code again after making this change, it will show the correct division −

Division of op1 by op2: 3.333333

Note: If you use %d format specifier for a floating-point expression, it will always result in "0".

Example

The result of arithmetic operations with at least one float (or double) operand is always float.
Take a look at the following example −

#include <stdio.h>
int main(){

int op1 = 10;


float op2 = 2.5;

printf("Operand1: %d Operand2: %f\n", op1, op2);


printf("Addition of op1 and op2: %f\n", op1 + op2);
printf("Subtraction of op2 from op1: %f\n", op1 - op2);
printf("Multiplication of op1 and op2: %f\n", op1 * op2);
printf("Division of op1 by op2: %f\n", op1/op2);

return 0;
}

Output

Run the code and check its output −

Operand1: 10 Operand2: 2.500000


Addition of op1 and op2: 12.500000
Subtraction of op2 from op1: 7.500000
Multiplication of op1 and op2: 25.000000
Division of op1 by op2: 4.000000

Arithmetic Operations with char Data Type

In C, char data type is a subset of int type. Hence, we can perform arithmetic operations
with char operands.

Example

The following example shows how you can perform arithmetic operations with two operands out
of which one is a "char" type −

#include <stdio.h>

int main(){

char op1 = 'F';


int op2 = 3;

printf("operand1: %c operand2: %d\n", op1, op2);


printf("Addition of op1 and op2: %d\n", op1 + op2);
printf("Subtraction of op2 from op1: %d\n", op1 - op2);
printf("Multiplication of op1 and op2: %d\n", op1 * op2);
printf("Division of op1 by op2: %d\n", op1/op2);

return 0;
}

Output

Run the code and check its output −

operand1: F operand2: 3

Addition of op1 and op2: 73


Subtraction of op2 from op1: 67
Multiplication of op1 and op2: 210
Division of op1 by op2: 23

Since a char data type is a subset of int, the %c format specifier returns the ASCII character
associated with an integer returned by the %d specifier.

If any arithmetic operation between two char operands results in an integer beyond the range of
char, the %c specifier displays blank.

Modulo Operator in C

The modulo operator (%) returns the remainder of a division operation.

Example

Take a look at the following example −

#include <stdio.h>

int main(){
int op1 = 10;
int op2 = 3;

printf("Operand1: %d Operand2: %d\n", op1, op2);


printf("Modulo of op1 and op2: %d\n", op1%op2);

return 0;
}

Output

Run the code and check its output −

Operand1: 10 Operand2: 3
Modulo of op1 and op2: 1

The modulo operator needs both the operands of int type. If not, the compiler gives a type
mismatch error. For example, change the data type of "op1" to float in the above code and run
the program again −

float op1 = 10;


int op2 = 3;
printf("Modulo of op1 and op2: %d\n", op1%op2);

Now, you will get a type mismatch error with the following message −

error: invalid operands to binary % (have 'float' and 'int')

It does allow char operands for modulo operations though.

Negation Operator in C

The increment and decrement operators represented by the symbols ++ and -- are unary
operators. They have been covered in a separate chapter. The "−" symbol, representing
subtraction operator, also acts a unary negation operator.

Example

The following example highlights how you can use the negation operator in C −
#include <stdio.h>

int main(){

int op1 = 5;
int op2 = -op1;

printf("Operand1: %d Operand2: %d\n", op1, op2);

return 0;
}

Output

When you run this code, it will produce the following output −

Operand1: 5 Operand2: -5

In the above example, the "–" symbol returns the negative value of op1 and assigns the same to
op2.

Relational Operators in C

Relational operators in C are defined to perform comparison of two values. The familiar angular
brackets < and > are the relational operators in addition to a few more as listed in the table
below.

These relational operators are used in Boolean expressions. All the relational operators evaluate
to either True or False.

C doesn’t have a Boolean data type. Instead, "0" is interpreted as False and any non-zero value is
treated as True.

Example 1

Here is a simple example of relational operator in C −

#include <stdio.h>

int main(){
int op1 = 5;
int op2 = 3;

printf("op1: %d op2: %d op1 < op2: %d\n", op1, op2, op1 < op2);

return 0;
}

Output

Run the code and check its output −

op1: 5 op2: 3 op1 < op2: 0

Relational operators have an important role to play in decision-control and looping statements in
C.

The following table lists all the relational operators in C −

Operator Description Example

Checks if the values of two operands are equal or


== (A == B)
not. If yes, then the condition becomes true.

Checks if the values of two operands are equal or


!= not. If the values are not equal, then the condition (A != B)
becomes true.

Checks if the value of left operand is greater than


> the value of right operand. If yes, then the (A > B)
condition becomes true.

Checks if the value of left operand is less than


< the value of right operand. If yes, then the (A < B)
condition becomes true.

Checks if the value of left operand is greater than


>= or equal to the value of right operand. If yes, then (A >= B)
the condition becomes true.

Checks if the value of left operand is less than or


<= equal to the value of right operand. If yes, then (A <= B)
the condition becomes true.
All the relational operators are binary operators. Since they perform comparison, they need two
operands on either side.

We use the = symbol in C as the assignment operator. So, C uses the "==" (double equal) as
the equality operator.

The angular brackets > and < are used as the "greater than" and "less than" operators. When
combined with the "=" symbol, they form the ">=" operator for "greater than or equal" and "<="
operator for "less than or equal" comparison.

Finally, the "=" symbol prefixed with "!" (!=) is used as the inequality operator.

Example 2

The following example shows all the relational operators in use.

#include <stdio.h>

int main(){

int a = 21;
int b = 10;
int c ;

printf("a: %d b: %d\n", a,b);

if(a == b){
printf("Line 1 - a is equal to b\n" );
} else {
printf("Line 1 - a is not equal to b\n" );
}

if (a < b){
printf("Line 2 - a is less than b\n" );
} else {
printf("Line 2 - a is not less than b\n" );
}

if (a > b){
printf("Line 3 - a is greater than b\n" );
} else {
printf("Line 3 - a is not greater than b \n\n" );
}

/* Lets change value of a and b */


a = 5;
b = 20;

printf("a: %d b: %d\n", a,b);

if (a <= b){
printf("Line 4 - a is either less than or equal to b\n" );
}

if (b >= a){
printf("Line 5 - b is either greater than or equal to b\n" );
}

if(a != b){
printf("Line 6 - a is not equal to b\n" );
} else {
printf("Line 6 - a is equal to b\n" );
}

return 0;
}

Output

When you run this code, it will produce the following output −

a: 21 b: 10
Line 1 - a is not equal to b
Line 2 - a is not less than b
Line 3 - a is greater than b
a: 5 b: 20
Line 4 - a is either less than or equal to b
Line 5 - b is either greater than or equal to b
Line 6 - a is not equal to b

Example 3

The == operator needs to be used with care. Remember that "=" is the assignment operator in C.
If used by mistake in place of the equality operator, you get an incorrect output as follows −

#include <stdio.h>

int main(){

int a = 5;
int b = 3;

if (a = b){
printf("a is equal to b");
}
else {
printf("a is not equal to b");
}

return 0;
}

Output

The value of "b" is assigned to "a" which is non-zero, and hence the if expression returns true.

a is equal to b

Example 4

We can have "char" types too as the operand for all the relational operators, as the "char" type is
a subset of "int" type. Take a look at this example −

#include <stdio.h>
int main(){

char a = 'B';
char b = 'd';

printf("a: %c b: %c\n", a,b);

if(a == b){
printf("Line 1 - a is equal to b \n");
} else {
printf("Line 1 - a is not equal to b \n");
}

if (a < b){
printf("Line 2 - a is less than b \n");
} else {
printf("Line 2 - a is not less than b \n");
}

if (a > b) {
printf("Line 3 - a is greater than b \n");
} else {
printf("Line 3 - a is not greater than b \n");
}

if(a != b) {
printf("Line 4 - a is not equal to b \n");
} else {
printf("Line 4 - a is equal to b \n");
}

return 0;
}

Output
Run the code and check its output −

a: B b: d
Line 1 - a is not equal to b
Line 2 - a is less than b
Line 3 - a is not greater than b
Line 4 - a is not equal to b

Relational operators cannot be used for comparing secondary types such as arrays or derived
types such as struct or union types.

Logical Operators in C

Logical operators in C evaluate to either True or False. Logical operators are typically used with
Boolean operands.

The logical AND operator (&&) and the logical OR operator (||) are both binary in nature
(require two operands). The logical NOT operator (!) is a unary operator.

Since C treats "0" as False and any non-zero number as True, any operand to a logical operand is
converted to a Boolean data.

Here is a table showing the logical operators in C −

Operator Description Example

Called Logical AND operator. If both the


(A &&
&& operands are non-zero, then the condition
B)
becomes true.

Called Logical OR Operator. If any of the two


|| operands is non-zero, then the condition becomes (A || B)
true.

Called Logical NOT Operator. It is used to


reverse the logical state of its operand. If a
! !(A)
condition is true, then Logical NOT operator will
make it false.

The result of a logical operator follows the principle of Boolean algebra. The logical operators
follow the following truth tables.
Logical AND (&&) Operator

The && operator in C acts as the logical AND operator. It has the following truth table −

a b a&&b

true true True

true false False

false true False

false false False

The above truth table shows that the result of && is True only if both the operands are True.

Logical OR (||) Operator

C uses the double pipe symbol (||) as the logical OR operator. It has the following truth table −

a b a||b

true true True

true false True

false true true

false false false

The above truth table shows that the result of || operator is True when either of the operands is
True, and False if both operands are false.

Logical NOT (!) Operator

The logical NOT ! operator negates the value of a Boolean operand. True becomes False, and
False becomes True. Here is its truth table −

A !a

True False

False True
Unlike the other two logical operators && and ||, the logical NOT operator ! is a unary operator.

Example 1

The following example shows the usage of logical operators in C −

#include <stdio.h>

int main(){

int a = 5;
int b = 20;

if (a && b){
printf("Line 1 - Condition is true\n" );
}

if (a || b){
printf("Line 2 - Condition is true\n" );
}

/* lets change the value of a and b */


a = 0;
b = 10;

if (a && b){
printf("Line 3 - Condition is true\n" );
} else {
printf("Line 3 - Condition is not true\n" );
}

if (!(a && b)){


printf("Line 4 - Condition is true\n" );
}

return 0;
}
Output

Run the code and check its output −

Line 1 - Condition is true


Line 2 - Condition is true
Line 3 - Condition is not true
Line 4 - Condition is true

Example 2

In C, a char type is a subset of int type. Hence, logical operators can work with char type too.

#include <stdio.h>

int main(){

char a = 'a';
char b = '\0'; // Null character

if (a && b){
printf("Line 1 - Condition is true\n" );
}

if (a || b){
printf("Line 2 - Condition is true\n" );
}

return 0;
}

Output

Run the code and check its output −

Line 2 - Condition is true

Logical operators are generally used to build a compound boolean expression. Along with
relational operators, logical operators too are used in decision-control and looping statements in
C.
Example 3

The following example shows a compound Boolean expression in a C program −

#include <stdio.h>

int main(){

int phy = 50;


int maths = 60;

if (phy < 50 || maths < 50){


printf("Result:Fail");
}
else {
printf("Result:Pass");
}

return 0;
}

Output

Result:Pass

Example 4

The similar logic can also be expressed using the && operator as follows −

#include <stdio.h>

int main(){

int phy = 50;


int maths = 60;

if (phy >= 50 && maths >= 50){


printf("Result: Pass");
}
else {
printf("Result: Fail");
}

return 0;
}

Output

Run the code and check its output −

Result: Pass

Example 5

The following C code employs the NOT operator in a while loop −

#include <stdio.h>

int main(){

int i = 0;

while (!(i > 5)){


printf("i = %d\n", i);
i++;
}

return 0;
}

Output

In the above code, the while loop continues to iterate till the expression "!(i > 5)" becomes false,
which will be when the value of "i" becomes more than 5.

i=0
i=1
i=2
i=3
i=4
i=5

C has bitwise counterparts of the logical operators such as bitwise AND (&), bitwise OR (|), and
binary NOT or complement (~) operator.

Bitwise Operators in C

Bitwise operators in C allow low-level manipulation of data stored in computer’s memory.

Bitwise operators contrast with logical operators in C. For example, the logical AND operator
(&&) performs AND operation on two Boolean expressions, while the bitwise AND operator
(&) performs the AND operation on each corresponding bit of the two operands.

For the three logical operators &&, ||, and !, the corresponding bitwise operators in C
are &, | and ~.

Additionally, the symbols ^ (XOR), << (left shift) and >> (right shift) are the other bitwise
operators.

Operator Description Example

Binary AND Operator copies a bit to the result if


& (A & B)
it exists in both operands.

Binary OR Operator copies a bit if it exists in


| (A | B)
either operand.

Binary XOR Operator copies the bit if it is set in


^ (A ^ B)
one operand but not both.

Binary One's Complement Operator is unary and


~ (~A
has the effect of 'flipping' bits.

Binary Left Shift Operator. The left operands


<< value is moved left by the number of bits A << 2
specified by the right operand.

Binary Right Shift Operator. The left operands


>> value is moved right by the number of bits A >> 2
specified by the right operand.
Even though these operators work on individual bits, they need the operands in the form C data
types or variables only, as a variable occupies a specific number of bytes in the memory.

Bitwise AND Operator (&) in C

The bitwise AND (&) operator performs as per the following truth table −

bit a bit b a&b

0 0 0

0 1 0

1 0 0

1 1 1

Bitwise binary AND performs logical operation on the bits in each position of a number in its
binary form.

Assuming that the two int variables "a" and "b" have the values 60 (equivalent to 0011 1100 in
binary) and 13 (equivalent to 0000 1101 in binary), the "a & b" operation results in 13, as per the
bitwise ANDing of their corresponding bits illustrated below −

0011 1100
& 0000 1101
---------
= 0000 1100

The binary number 00001100 corresponds to 12 in decimal.

Bitwise OR (|) Operator

The bitwise OR (|) operator performs as per the following truth table −

bit a bit b a|b

0 0 0

0 1 1

1 0 1

1 1 1
Bitwise binary OR performs logical operation on the bits in each position of a number in its
binary form.

Assuming that the two int variables "a" and "b" have the values 60 (equivalent to 0011 1100 in
binary) and 13 (equivalent to 0000 1101 in binary), then "a | b" results in 61, as per the bitwise
OR of their corresponding bits illustrated below −

0011 1100
| 0000 1101
---------
= 0011 1101

The binary number 00111101 corresponds to 61 in decimal.

Bitwise XOR (^) Operator

The bitwise XOR (^) operator performs as per the following truth table −

bit a bit b a^b

0 0 0

0 1 1

1 0 1

1 1 0

Bitwise binary XOR performs logical operation on the bits in each position of a number in its
binary form. The XOR operation is called "exclusive OR".

Note: The result of XOR is 1 if and only if one of the operands is 1. Unlike OR, if both bits are
1, XOR results in 0.

Assuming that the two int variables "a" and "b" have the values 60 (equivalent to 0011 1100 in
binary) and 13 (equivalent to 0000 1101 in binary), the "a ^ b" operation results in 49, as per the
bitwise XOR of their corresponding bits illustrated below −

0011 1100
^ 0000 1101
---------
= 0011 0001

The binary number 00110001 corresponds to 49 in decimal.


The Left Shift (<<) Operator

The left shift operator is represented by the << symbol. It shifts each bit in its left-hand operand
to the left by the number of positions indicated by the right-hand operand. Any blank spaces
generated while shifting are filled up by zeroes.

Assuming that the int variable "a" has the value 60 (equivalent to 0011 1100 in binary), the "a <<
2" operation results in 240, as per the bitwise left-shift of its corresponding bits illustrated below

0011 1100 << 2 = 1111 0000

The binary number 11110000 corresponds to 240 in decimal.

The Right Shift (>>) Operator

The right shift operator is represented by the >> symbol. It shifts each bit in its left-hand operand
to the right by the number of positions indicated by the right-hand operand. Any blank spaces
generated while shifting are filled up by zeroes.

Assuming that the int variable a has the value 60 (equivalent to 0011 1100 in binary), the "a >>
2" operation results in 15, as per the bitwise right-shift of its corresponding bits illustrated below

0011 1100 >> 2 = 0000 1111

The binary number 00001111 corresponds to 15 in decimal.

The 1's Complement (~) Operator

The 1's compliment operator (~) in C is a unary operator, needing just one operand. It has the
effect of "flipping" the bits, which means 1s are replaced by 0s and vice versa.

a ~a

0 1

1 0

Assuming that the int variable "a" has the value 60 (equivalent to 0011 1100 in binary), then the
"~a" operation results in -61 in 2’s complement form, as per the bitwise right-shift of its
corresponding bits illustrated below −

~ 0011 1100 = 1100 0011


The binary number 1100 0011 corresponds to -61 in decimal.

Example

In this example, we have highlighted the operation of all the bitwise operators:

#include <stdio.h>

int main(){

unsigned int a = 60; /* 60 = 0011 1100 */


unsigned int b = 13; /* 13 = 0000 1101 */
int c = 0;

c = a & b; /* 12 = 0000 1100 */


printf("Line 1 - Value of c is %d\n", c );

c = a | b; /* 61 = 0011 1101 */
printf("Line 2 - Value of c is %d\n", c );

c = a ^ b; /* 49 = 0011 0001 */
printf("Line 3 - Value of c is %d\n", c );

c = ~a; /*-61 = 1100 0011 */


printf("Line 4 - Value of c is %d\n", c );

c = a << 2; /* 240 = 1111 0000 */


printf("Line 5 - Value of c is %d\n", c );

c = a >> 2; /* 15 = 0000 1111 */


printf("Line 6 - Value of c is %d\n", c );

return 0;
}

Output

When you run this code, it will produce the following output −
Line 1 - Value of c is 12
Line 2 - Value of c is 61
Line 3 - Value of c is 49
Line 4 - Value of c is -61
Line 5 - Value of c is 240
Line 6 - Value of c is 15

Assignment Operators in C

In C language, the assignment operator stores a certain value in an already declared variable. A
variable in C can be assigned the value in the form of a literal, another variable, or an expression.

The value to be assigned forms the right-hand operand, whereas the variable to be assigned
should be the operand to the left of the "=" symbol, which is defined as a simple assignment
operator in C.

In addition, C has several augmented assignment operators.

The following table lists the assignment operators supported by the C language −

Operator Description Example

Simple assignment operator. Assigns C = A + B will


= values from right side operands to left assign the value of
side operand A + B to C

Add AND assignment operator. It adds C += A is


+= the right operand to the left operand and equivalent to C =
assign the result to the left operand. C+A

Subtract AND assignment operator. It


C -= A is
subtracts the right operand from the left
-= equivalent to C =
operand and assigns the result to the left
C-A
operand.

Multiply AND assignment operator. It


C *= A is
multiplies the right operand with the
*= equivalent to C =
left operand and assigns the result to the
C*A
left operand.
Divide AND assignment operator. It
C /= A is
divides the left operand with the right
/= equivalent to C =
operand and assigns the result to the left
C/A
operand.

Modulus AND assignment operator. It C %= A is


%= takes modulus using two operands and equivalent to C =
assigns the result to the left operand. C%A

C <<= 2 is same
<<= Left shift AND assignment operator.
as C = C << 2

C >>= 2 is same
>>= Right shift AND assignment operator.
as C = C >> 2

C &= 2 is same as
&= Bitwise AND assignment operator.
C=C&2

Bitwise exclusive OR and assignment C ^= 2 is same as


^=
operator. C=C^2

Bitwise inclusive OR and assignment C |= 2 is same as


|=
operator. C=C|2

Simple Assignment Operator (=)

The = operator is one of the most frequently used operators in C. As per the ANSI C standard, all
the variables must be declared in the beginning. Variable declaration after the first processing
statement is not allowed.

You can declare a variable to be assigned a value later in the code, or you can initialize it at the
time of declaration.

You can use a literal, another variable, or an expression in the assignment statement.

int x = 10; // declaration with initialization


int y; // declaration
y = 20; // assignment later
int z = x + y; // assign an expression
int d = 3, f = 5; // definition and initializing d and f.
char x = 'x'; // the variable x has the value 'x'.

Once a variable of a certain type is declared, it cannot be assigned a value of any other type. In
such a case the C compiler reports a type mismatch error.
In C, the expressions that refer to a memory location are called "lvalue" expressions. A lvalue
may appear as either the left-hand or right-hand side of an assignment.

On the other hand, the term rvalue refers to a data value that is stored at some address in
memory. A rvalue is an expression that cannot have a value assigned to it which means an rvalue
may appear on the right-hand side but not on the left-hand side of an assignment.

Variables are lvalues and so they may appear on the left-hand side of an assignment. Numeric
literals are rvalues and so they may not be assigned and cannot appear on the left-hand side. Take
a look at the following valid and invalid statements −

int g = 20; // valid statement


10 = 20; // invalid statement

Augmented Assignment Operators

In addition to the = operator, C allows you to combine arithmetic and bitwise operators with
the = symbol to form augmented or compound assignment operator. The augmented operators
offer a convenient shortcut for combining arithmetic or bitwise operation with assignment.

Example 1

For example, the expression "a += b" has the same effect of performing "a + b" first and then
assigning the result back to the variable "a".

#include <stdio.h>

int main(){

int a = 10;
int b = 20;

a += b;
printf("a: %d", a);

return 0;
}

Output

Run the code and check its output −


a: 30

Example 2

Similarly, the expression "a <<= b" has the same effect of performing "a << b" first and then
assigning the result back to the variable "a".

#include <stdio.h>

int main(){

int a = 60;
int b = 2;

a <<= b;
printf("a: %d", a);

return 0;
}

Output

Run the code and check its output −

a: 240

Example 3

Here is a C program that demonstrates the use of assignment operators in C −

#include <stdio.h>

int main(){

int a = 21;
int c ;

c = a;
printf("Line 1 - = Operator Example, Value of c = %d\n", c );
c += a;
printf("Line 2 - += Operator Example, Value of c = %d\n", c );

c -= a;
printf("Line 3 - -= Operator Example, Value of c = %d\n", c );

c *= a;
printf("Line 4 - *= Operator Example, Value of c = %d\n", c );

c /= a;
printf("Line 5 - /= Operator Example, Value of c = %d\n", c );

c = 200;
c %= a;
printf("Line 6 - %%= Operator Example, Value of c = %d\n", c );

c <<= 2;
printf("Line 7 - <<= Operator Example, Value of c = %d\n", c );

c >>= 2;
printf("Line 8 - >>= Operator Example, Value of c = %d\n", c );

c &= 2;
printf("Line 9 - &= Operator Example, Value of c = %d\n", c );

c ^= 2;
printf("Line 10 - ^= Operator Example, Value of c = %d\n", c );

c |= 2;
printf("Line 11 - |= Operator Example, Value of c = %d\n", c );

return 0;
}

Output
When you compile and execute the above program, it will produce the following result −

Line 1 - = Operator Example, Value of c = 21


Line 2 - += Operator Example, Value of c = 42
Line 3 - -= Operator Example, Value of c = 21
Line 4 - *= Operator Example, Value of c = 441
Line 5 - /= Operator Example, Value of c = 21
Line 6 - %= Operator Example, Value of c = 11
Line 7 - <<= Operator Example, Value of c = 44
Line 8 - >>= Operator Example, Value of c = 11
Line 9 - &= Operator Example, Value of c = 2
Line 10 - ^= Operator Example, Value of c = 0
Line 11 - |= Operator Example, Value of c = 2
Unary Operators in C

While most of the operators in C are binary in nature, there are a few unary operators as well. An
operator is said to be unary if it takes just a single operand, unlike a binary operator which needs
two operands.

Some operators in C are binary as well as unary in their usage. Examples of unary operators in C
include ++, --, !, etc.

The Increment Operator in C

The increment operator (++) adds 1 to the value of its operand variable and assigns it back to the
variable.

The statement a++ is equivalent to writing "a = a + 1." The "++" operator can appear before or
after the operand and it will have the same effect. Hence, a++ is equivalent to ++a.

However, when the increment operator appears along with other operators in an expression, its
effect is not the same. The precedence of "prefix ++" is more than "postfix ++". Hence, "b =
a++;" is not the same as "b = ++a;"

In the former case, "a" is assigned to "b" before the incrementation; while in the latter case, the
incrementation is performed before the assignment.

The Decrement Operator in C

The decrement operator (--) subtracts 1 from the value of its operand variable and assigns it back
to the variable.

The statement "a--;" is equivalent to writing "a = a - 1;"


The "--" operator can appear before or after the operand and in either case, it will have the same
effect. Hence, "a--" is equivalent to "--a".

However, when the decrement operator appears along with other operators in an expression, its
effect is not the same. The precedence of "prefix --" is more than "postfix --". Hence, "b = a--" is
not the same as "b = --a".

In the former case, "a" is assigned to "b" before the decrementation; while in the latter case, the
decrementation is performed before the assignment.

The Unary "+" Operator in C

The "+" and "–" operators are well known as binary addition and subtraction operators.
However, they can also be used in unary fashion. When used as unary, they are prefixed to the
operand variable.

The "+" operator is present implicitly whenever a positive value is assigned to any numeric
variable. The statement "int x = 5;" is same as "int x = +5;". The same logic applies to float and
char variable too.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

char x = 'A';
char y = +x;

float a = 1.55;
float b = +a;

printf ("x: %c y: %c\n", x,y);


printf ("a: %f y: %f\n", a,b);

return 0;
}

Output
When you run this code, it will produce the following output −

x: A y: A
a: 1.550000 y: 1.550000

The Unary "−" Operator in C

The "−" symbol, that normally represents the subtraction operator, also acts the unary negation
operator in C. The following code shows how you can use the unary negation operator in C.

Example

In this code, the unary negation operator returns the negative value of "x" and assigns the same
to another variable "y".

#include <stdio.h>

int main(){

int x = 5;
int y = -x;

printf("x: %d y: %d\n", x, y);

return 0;
}

Output

Run the code and check its output −

x: 5 y: -5

The Address-of Operator (&) in C

We use the & symbol in C as the binary AND operator. However, we also use the
same & symbol in unary manner as the "address-of" operator.

Example

The & operator returns the memory address of its variable operand. Take a look at the following
example −
#include <stdio.h>

int main(){

char x = 'A';
printf ("Address of x: %d\n", &x);

return 0;
}

Output

Run the code and check its output −

Address of x: 6422047

Note: The C compiler assigns a random memory address whenever a variable is declared. Hence,
the result may vary every time the address is printed.

The format specifier %p is used to get a hexadecimal representation of the memory address.

char x = 'A';
printf ("Address of x: %p\n", &x);

This prints the address of "x" in hexadecimal format −

Address of x: 000000000061FE1F

The address of a variable is usually stored in a "pointer variable". The pointer variable is
declared with a "*" prefix. In the code snippet below, "x" is a normal integer variable while "y"
is a pointer variable.

int x = 10;
int *y = &x;

The Dereference Operator (*) in C

We normally use the "*" symbol as the multiplication operator. However, it is also used as the
"dereference operator" in C.

When you want to store the memory address of a variable, the variable should be declared with
an asterisk (*) prefixed to it.
int x = 10;
int *y = &x;

Here the variable "y" stores the address of "x", hence "y" acts as a pointer to "x". To access the
value of "x" with the help of its pointer, use the dereference operator (*).

Example 1

Take a look at the following example −

#include <stdio.h>

int main(){

int x = 10;
int *y = &x;

printf ("x: %d Address of x: %d\n", x, &x);


printf("Value at x with Dereference: %d", *y);

return 0;
}

Output

Run the code and check its output −

x: 10 Address of x: 6422036
Value at x with Dereference: 10

Example 2

You can also assign a value to the original variable with the help of the dereference pointer −

#include <stdio.h>

int main(){

int x = 10;
int *y = &x;

printf("x: %d Address of x %d\n", x, &x);

*y = 20;

printf("x: %d with Dereference: %d", x, *y);

return 0;
}

Output

Run the code and check its output −

x: 10 Address of x: 6422036
x: 20 with dereference: 20

The Logical NOT Operator (!) in C

The logical NOT operator (!) in C negates the value of a Boolean operand. True becomes False
and False becomes True. The logical NOT operator (!) is a unary operator.

Example 1

The following example shows the usage of logical operators in C −

#include <stdio.h>

int main(){

int a = 0;
int b = 20;

if (!(a && b)){


printf("Line 1 - Condition is true\n" );
}

return 0;
}

Output

Line 1 - Condition is true

Example 2

The following C code employs the NOT operator in a while loop −

#include <stdio.h>

int main(){

int i = 0;

while (!(i > 5)){


printf("i = %d\n", i);
i++;
}

return 0;
}

Output

In this code, the while loop continues to iterate till the expression "!(i > 5)" becomes False,
which will be when the value of "i" becomes more than 5.

i=0
i=1
i=2
i=3
i=4
i=5

The 1's Complement Operator (~) in C


The 1's complement operator (~) in C is a unary operator, needing just one operand. It has the
effect of "flipping" the bits, which means the 1's are replaced by 0's and vice versa in the binary
representation of any number.

a ~a

0 1

1 0

Assuming that the int variable "a" has the value 60 (equivalent to 0011 1100 in binary), the "~a"
operation results in -61 in 2’s complement form, as per the bitwise right-shift of its
corresponding bits.

~ 0011 1100 = 1100 0011

The binary number "1100 0011" corresponds to -61 in decimal.

Example

Take a look at this example code −

#include <stdio.h>

int main(){

int a = 60; /* 60 = 0011 1100 */


int c = 0;

c = ~a; /* -61 = 1100 0011 */

printf("Value of c is %d \n", c);

return 0;
}

Output

When you run this code, it will produce the following output −

Value of c is -61
Increment and Decrement Operators in C

The increment operator (++) increments the value of a variable by 1, while the decrement
operator (--) decrements the value.

Increment and decrement operators are frequently used in the construction of counted loops in C
(with the for loop). They also have their application in the traversal of array and pointer
arithmetic.

The ++ and -- operators are unary and can be used as a prefix or posfix to a variable.

Syntax

int a = 5;
a++; // postfix increment

int b = 5;
++b; // prefix increment

int c = 5;
c--; // postfix decrement

int d = 5;
--d; // prefix decrement

In other words, "a++" has the same effect as "++a", as both the expressions increment the value
of variable "a" by 1. Similarly, "a--" has the same effect as "--a".

The expression "a++;" can be treated as the equivalent of the statement "a = a + 1;". Here, the
expression on the right adds 1 to "a" and the result is assigned back to 1, therby the value of "a"
is incremented by 1.

Similarly, "b--;" is equivalent to "b = b – 1;".

Example 1

The following example highlights the use of prefix/postfix increment/decrement −

#include <stdio.h>

int main(){
char a = 'a', b = 'M';
int x = 5, y = 23;

printf("a: %c b: %c\n", a, b);

a++;
printf("postfix increment a: %c\n", a);

++b;
printf("prefix increment b: %c\n", b);

printf("x: %d y: %d\n", x, y);

x--;
printf("postfix decrement x : %d\n", x);

--y;
printf("prefix decrement y : %d\n", y);

return 0;
}

Output

When you run this code, it will produce the following output −

a: a b: M
postfix increment a: b
prefix increment b: N

x: 5 y: 23
postfix decrement x: 4
prefix decrement y: 22

The above example shows that the prefix as well as postfix operators have the same effect on the
value of the operand variable. However, when these "++" or "--" operators appear along with the
other operators in an expression, they behave differently.
Example 2

In the following code, the initial values of "a" and "b" variables are same, but the printf()
statement displays different values −

#include <stdio.h>

int main(){

int x = 5, y = 5;

printf("x: %d y: %d\n", x,y);


printf("postfix increment x: %d\n", x++);
printf("prefix increment y: %d\n", ++y);

return 0;
}

Output

Run the code and check its output −

x: 5 y: 5
postfix increment x: 5
prefix increment y: 6

In the first case, the printf() function prints the value of "x" and then increments its value. In the
second case, the increment operator is executed first, the printf() function uses the incremented
value for printing.

Operator Precedence

There are a number of operators in C. When multiple operators are used in an expression, they
are executed as per their order of precedence. Increment and decrement operators behave
differently when used along with other operators.

When an expression consists of increment or decrement operators alongside other operators, the
increment and decrement operations are performed first. Postfix increment and decrement
operators have higher precedence than prefix increment and decrement operators.

Example 1
Take a look at the following example −

#include <stdio.h>

int main(){

int x = 5, z;

printf("x: %d \n", x);

z = x++;
printf("x: %d z: %d\n", x, z);

return 0;
}

Output

Run the code and check its output −

x: 5
x: 6 z: 5

Since "x++" increments the value of "x" to 6, you would expect "z" to be 6 as well. However, the
result shows "z" as 5. This is because the assignment operator has a higher precedence over
postfix increment operator. Hence, the existing value of "x" is assigned to "z", before
incrementing "x".

Example 2

Take a look at another example below −

#include <stdio.h>

int main(){

int x = 5, y = 5, z;

printf("x: %d y: %d\n", x,y);


z = ++y;
printf("y: %d z: %d\n", y ,z);

return 0;
}

Output

When you run this code, it will produce the following output −

y: 5
y: 6 z: 6

The result may be confusing, as the value of "y" as well as "z" is now 6. The reason is that the
prefix increment operator has a higher precedence than the assignment operator. Hence, "y" is
incremented first and then its new value is assigned to "z".

The associativity of operators also plays an important part. For increment and decrement
operators, the associativity is from left to right. Hence, if there are multiple increment or
decrement operators in a single expression, the leftmost operator will be executed first, moving
rightward.

Example 3

In this example, the assignment expression contains both the prefix as well as postfix operators.

#include <stdio.h>

int main(){

int x = 5, y = 5, z;

z = x++ + ++y;
printf("x: %d y: %d z: %d\n", x,y,z);

return 0;
}

Output
Run the code and check its output −

x: 6 y:6 z: 11

In this example, the first operation to be done is "y++" ("y" becomes 6). Secondly the "+"
operator adds "x" (which is 5) and "y", the result assigned to "z" as 11, and then "x++"
increments "x" to 6.

Using the Increment Operator in Loop

In C, the most commonly used syntax of a for loop is as follows −

for (init_val; final_val; increment) {


statement(s);
}

Example

The looping body is executed for all the values of a variable between the initial and the final
values, incrementing it after each round.

#include <stdio.h>

int main(){

int x;

for (x = 1; x <= 5; x++){


printf("x: %d\n", x);
}

return 0;
}

Output

When you run this code, it will produce the following output −

x: 1
x: 2
x: 3
x: 4
x: 5

Pointer Arithmetic in C

In C language, a pointer is a variable that stores the address of another variable. The address is an
integer. A pointer variable can be used as an operand with increment or decrement operator.

However, unlike the normal int, float or char variable where the increment/decrement operator
changes the value by 1, in case of the pointer, its value is changed by the size of the data type.

Example

In this example, the pointer to an int variable increments by 4, as the size of int is 4. Similarly,
the size of char variable is 1, hence its pointer increments by 1.

#include <stdio.h>

int main(){

int x = 50;
int *ptr = &x;

printf("size of int: %d\n", sizeof(x));


printf("The address of x is: %d\n", ptr);

ptr++;
printf("The address of x is: %d\n\n", ptr);

char y = 'a';
char *ptr1 = &y;

printf("size of char: %d\n", sizeof(y));


printf("The address of y is: %d\n", ptr1);

ptr1++;
printf("The address of y is: %d\n", ptr1);

return 0;
}

Output

When you run this code, it will produce the following output −

size of int: 4
The address of x is: 6422028
The address of x is: 6422032

size of char: 1
The address of y is: 6422027
The address of y is: 6422028
Ternary Operator in C

The ternary operator (?:) in C is a type of conditional operator. The term "ternary" implies that
the operator has three operands. The ternary operator is often used to put multiple conditional (if-
else) statements in a more compact manner.

Syntax of Ternary Operator in C

The ternary operator is used with the following syntax −

exp1 ? exp2 : exp3

It uses three operands −

 exp1 − A Boolean expression evaluating to true or false


 exp2 − Returned by the ? operator when exp1 is true
 exp3 − Returned by the ? operator when exp1 is false

Example 1: Ternary Operator in C

The following C program uses the ternary operator to check if the value of a variable is even or
odd.

#include <stdio.h>

int main(){

int a = 10;
(a % 2 == 0) ? printf("%d is Even \n", a) : printf("%d is Odd \n", a);

return 0;
}

Output

When you run this code, it will produce the following output −

10 is Even

Change the value of "a" to 15 and run the code again. Now you will get the following output −

15 is Odd

Example 2

The conditional operator is a compact representation of if–else construct. We can rewrite the
logic of checking the odd/even number by the following code −

#include <stdio.h>

int main(){

int a = 10;

if (a % 2 == 0){
printf("%d is Even\n", a);
}
else{
printf("%d is Odd\n", a);
}

return 0;
}

Output

Run the code and check its output −


10 is Even

Example 3

The following program compares the two variables "a" and "b", and assigns the one with the
greater value to the variable "c".

#include <stdio.h>

int main(){

int a = 100, b = 20, c;

c = (a >= b) ? a : b;

printf ("a: %d b: %d c: %d\n", a, b, c);

return 0;
}

Output

When you run this code, it will produce the following output −

a: 100 b: 20 c: 100

Example 4

The corresponding code with if–else construct is as follows −

#include <stdio.h>

int main(){

int a = 100, b = 20, c;

if (a >= b){
c = a;
}
else {
c = b;
}
printf ("a: %d b: %d c: %d\n", a, b, c);

return 0;
}

Output

Run the code and check its output −

a: 100 b: 20 c: 100

Example 5

If you need to put multiple statements in the true and/or false operand of the ternary operator,
you must separate them by commas, as shown below −

#include <stdio.h>

int main(){

int a = 100, b = 20, c;

c = (a >= b) ? printf ("a is larger "), c = a : printf("b is larger "), c = b;

printf ("a: %d b: %d c: %d\n", a, b, c);

return 0;
}

Output

In this code, the greater number is assigned to "c", along with printing the appropriate message.

a is larger a: 100 b: 20 c: 20

Example 6
The corresponding program with the use of if–else statements is as follows −

#include <stdio.h>

int main(){

int a = 100, b = 20, c;

if(a >= b){


printf("a is larger \n");
c = a;
}
else{
printf("b is larger \n");
c = b;
}
printf ("a: %d b: %d c: %d\n", a, b, c);

return 0;
}

Output

Run the code and check its output −

a is larger
a: 100 b: 20 c: 100

Nested Ternary Operator

Just as we can use nested if-else statements, we can use the ternary operator inside the True
operand as well as the False operand.

exp1 ? (exp2 ? expr3 : expr4) : (exp5 ? expr6: expr7)

First C checks if expr1 is true. If so, it checks expr2. If it is true, the result is expr3; if false, the
result is expr4.

If expr1 turns false, it may check if expr5 is true and return expr6 or expr7.
Example 1

Let us develop a C program to determine whether a number is divisible by 2 and 3, or by 2 but


not 3, or 3 but not 2, or neither by 2 and 3. We will use nested condition operators for this
purpose, as shown in the following code −

#include <stdio.h>

int main(){

int a = 15;
printf("a: %d\n", a);

(a % 2 == 0) ? (
(a%3 == 0)? printf("divisible by 2 and 3") : printf("divisible by 2 but not 3"))
:(
(a%3 == 0)? printf("divisible by 3 but not 2") : printf("not divisible by 2, not divisible by 3")
);

return 0;
}

Output

Check for different values −

a: 15
divisible by 3 but not 2

a: 16
divisible by 2 but not 3

a: 17
not divisible by 2, not divisible by 3

a: 18
divisible by 2 and 3
Example 2

In this program, we have used nested if–else statements for the same purpose instead of
conditional operators −

#include <stdio.h>

int main(){

int a = 15;
printf("a: %d\n", a);

if(a % 2 == 0){
if (a % 3 == 0){
printf("divisible by 2 and 3");
}
else {
printf("divisible by 2 but not 3");
}
}
else{
if(a % 3 == 0){
printf("divisible by 3 but not 2");
}
else {
printf("not divisible by 2, not divisible by 3");
}
}

return 0;
}
Output
When you run this code, it will produce the following output −
a: 15
divisible by 3 but not 2
C - The sizeof Operator

The sizeof operator is a compile−time unary operator. It is used to compute the size of its
operand, which may be a data type or a variable. It returns the size in number of bytes.

It can be applied to any data type, float type, or pointer type variables.

sizeof(type or var);

When sizeof() is used with a data type, it simply returns the amount of memory allocated to that
data type. The outputs can be different on different machines, for example, a 32-bit system can
show a different output as compared to a 64-bit system.

Example 1: Using the sizeof Operator in C

Take a look at the following example. It highlights how you can use the sizeof operator in a C
program −

#include <stdio.h>

int main(){

int a = 16;

printf("Size of variable a: %d \n",sizeof(a));


printf("Size of int data type: %d \n",sizeof(int));
printf("Size of char data type: %d \n",sizeof(char));
printf("Size of float data type: %d \n",sizeof(float));
printf("Size of double data type: %d \n",sizeof(double));

return 0;
}

Output

On running this code, you will get the following output −

Size of variable a: 4
Size of int data type: 4
Size of char data type: 1
Size of float data type: 4
Size of double data type: 8

Example 2: Using sizeof with Struct

In this example, we declare a struct type and find the size of the struct type variable.

#include <stdio.h>

struct employee {
char name[10];
int age;
double percent;
};

int main(){
struct employee e1 = {"Raghav", 25, 78.90};
printf("Size of employee variable: %d\n",sizeof(e1));
return 0;
}

Output

Run the code and check its output −

Size of employee variable: 24

Example 3: Using sizeof with Array

In the following code, we have declared an array of 10 int values. Applying the sizeof operator
on the array variable returns 40. This is because the size of an int is 4 bytes.

#include <stdio.h>

int main(){

int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


printf("Size of arr: %d\n", sizeof(arr));
}

Output
Run the code and check its output −

Size of arr: 40

Example 4: Using sizeof to Find the Length of an Array

In C, we don’t have a function that returns the number of elements in a numeric array (we can
get the number of characters in a string using the strlen() function). For this purpose, we can use
the sizeof() operator.

We first find the size of the array and then divide it by the size of its data type.

#include <stdio.h>

int main(){

int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


int y = sizeof(arr)/sizeof(int);

printf("No of elements in arr: %d\n", y);


}

Output

When you run this code, it will produce the following output −

No of elements in arr: 10

Example 5: Using sizeof in Dynamic Memory Allocation

The sizeof operator is used to compute the memory block to be dynamically allocated with
the malloc() and calloc() functions.

The malloc() function is used with the following syntax −

type *ptr = (type *) malloc(sizeof(type)*number);

The following statement allocates a block of 10 integers and stores its address in the pointer −

int *ptr = (int *)malloc(sizeof(int)*10);


When the sizeof() is used with an expression, it returns the size of the expression. Here is an
example.

#include <stdio.h>

int main(){

char a = 'S';
double b = 4.65;

printf("Size of variable a: %d\n",sizeof(a));


printf("Size of an expression: %d\n",sizeof(a+b));

int s = (int)(a+b);
printf("Size of explicitly converted expression: %d\n",sizeof(s));

return 0;
}

Output

Run the code and check its output −

Size of variable a: 1
Size of an expression: 8
Size of explicitly converted expression: 4

Example 6: The Size of a Pointer in C

The sizeof() operator returns the same value irrespective of the type. This includes the pointer of
a built−in type, a derived type, or a double pointer.

#include <stdio.h>

int main(){

printf("Size of int data type: %d \n", sizeof(int *));


printf("Size of char data type: %d \n", sizeof(char *));
printf("Size of float data type: %d \n", sizeof(float *));
printf("Size of double data type: %d \n", sizeof(double *));
printf("Size of double pointer type: %d \n", sizeof(int **));
}

Output

Run the code and check its output −

Size of int data type: 8


Size of char data type: 8
Size of float data type: 8
Size of double data type: 8
Size of double pointer type: 8
\

Operator Precedence in C

A single expression in C may have multiple operators of different types. The C compiler
evaluates its value based on the operator precedence and associativity of operators.

The precedence of operators determines the order in which they are evaluated in an expression.
Operators with higher precedence are evaluated first.

For example, take a look at this expression −

x = 7 + 3 * 2;

Here, the multiplication operator "*" has a higher precedence than the addition operator "+". So,
the multiplication 3*2 is performed first and then adds into 7, resulting in "x = 13".

The following table lists the order of precedence of operators in C. Here, operators with the
highest precedence appear at the top of the table, and those with the lowest appear at the bottom.

Category Operator Associativity

Postfix () [] -> . ++ - - Left to right

Unary + - ! ~ ++ - - (type)* & sizeof Right to left

Multiplicative */% Left to right

Additive +- Left to right


Shift << >> Left to right

Relational < <= > >= Left to right

Equality == != Left to right

Bitwise AND & Left to right

Bitwise XOR ^ Left to right

Bitwise OR | Left to right

Logical AND && Left to right

Logical OR || Left to right

Conditional ?: Right to left

Assignment = += -= *= /= %=>>= <<= &= ^= |= Right to left

Comma , Left to right

Within an expression, higher precedence operators will be evaluated first.

Operator Associativity

In C, the associativity of operators refers to the direction (left to right or right to left) an
expression is evaluated within a program. Operator associativity is used when two operators of
the same precedence appear in an expression.

In the following example −

15 / 5 * 2

Both the "/" (division) and "*" (multiplication) operators have the same precedence, so the order
of evaluation will be decided by associativity.

As per the above table, the associativity of the multiplicative operators is from Left to Right. So,
the expression is evaluated as −

(15 / 5) * 2

It evaluates to −

3*2=6
Example 1

In the following code, the multiplication and division operators have higher precedence than the
addition operator.

The left−to−right associativity of multiplicative operator results in multiplication of "b" and "c"
divided by "e". The result then adds up to the value of "a".

#include <stdio.h>

int main(){

int a = 20;
int b = 10;
int c = 15;
int d = 5;

int e;
e = a + b * c / d;
printf("e : %d\n" , e );

return 0;
}

Output

When you run this code, it will produce the following output −

e: 50

Example 2

We can use parenthesis to change the order of evaluation. Parenthesis () got the highest priority
among all the C operators.

#include <stdio.h>

int main(){

int a = 20;
int b = 10;
int c = 15;
int d = 5;
int e;

e = (a + b) * c / d;
printf("e: %d\n", e);

return 0;
}

Output

Run the code and check its output −

e: 90

In this expression, the addition of a and b in parenthesis is first. The result is multiplied by c and
then the division by d takes place.

Example 3

In the expression that calculates e, we have placed a+b in one parenthesis, and c/d in another,
multiplying the result of the two.

#include <stdio.h>

int main(){

int a = 20;
int b = 10;
int c = 15;
int d = 5;

int e;
e = (a + b) * (c / d);
printf("e: %d\n", e );

return 0;
}

Output

On running this code, you will get the following output −

e: 90

Precedence of Post / Prefix Increment / Decrement Operators

The "++" and "− −" operators act as increment and decrement operators, respectively. They are
unary in nature and can be used as a prefix or postfix to a variable.

When used as a standalone, using these operators in a prefix or post−fix manner has the same
effect. In other words, "a++" has the same effect as "++a". However, when these "++" or "− −"
operators appear along with other operators in an expression, they behave differently.

Postfix increment and decrement operators have higher precedence than prefix increment and
decrement operators.

Example

The following example shows how you can use the increment and decrement operators in a C
program −

#include <stdio.h>

int main(){

int x = 5, y = 5, z;
printf("x: %d \n", x);

z = x++;
printf("Postfix increment: x: %d z: %d\n", x, z);

z = ++y;
printf("Prefix increment. y: %d z: %d\n", y ,z);

return 0;
}
Output

Run the code and check its output −

x: 5
Postfix increment: x: 6 z: 5
Prefix increment. y: 6 z: 6

Logical operators have left−to−right associativity. However, the compiler evaluates the least
number of operands needed to determine the result of the expression. As a result, some operands
of the expression may not be evaluated.

For example, take a look at the following expression −

x > 50 && y > 50

Here the second operand "y > 50" is evaluated only if the first expression evaluates to True.

C - Misc Operators

Besides the main categories of operators (arithmetic, logical, assignment, etc.), C uses the
following operators that are equally important. Let us discuss the operators classified under this
category.

The "&" symbol, already defined in C as the Binary AND Operator copies a bit to the result if
it exists in both operands. The "&" symbol is also defined as the address−of operator.

The "*" symbol − A well−known arithmetic operator for multiplication, it can also be used as
a dereference operator.

C uses the ">" symbol, defined as a ternary operator, used to evaluate a conditional expression.

In C, the dot "." symbol is used as the member access operator in connection with a struct or
union type.

C also uses the arrow "→" symbol as an indirection operator, used especially with the pointer to
the struct variable.

Operator Description Example

sizeof(a), where a is integer,


sizeof() Returns the size of a variable.
will return 4.
Returns the address of a &a; returns the actual
&
variable. address of the variable.

* Pointer to a variable. *a;

If Condition is true ? then


?: Conditional Expression.
value X, else value Y

. Member access operator [Link]

Access members of a struct


−> ptr −> member;
variable with pointer

The sizeof Operator in C

The sizeof operator is a compile−time unary operator. It is used to compute the size of its
operand, which may be a data type or a variable. It returns the size in number of bytes. It can be
applied to any data type, float type, or pointer type variables.

sizeof(type or var);

When sizeof() is used with the data types, it simply returns the amount of memory allocated to
that data type. The output can be different on different machines like a 32−bit system can show
different output while a 64−bit system can show different of the same data types.

Example

Here is an example in C language

#include <stdio.h>

int main(){

int a = 16;

printf("Size of variable a : %d\n",sizeof(a));


printf("Size of int data type : %d\n",sizeof(int));
printf("Size of char data type : %d\n",sizeof(char));
printf("Size of float data type : %d\n",sizeof(float));
printf("Size of double data type : %d\n",sizeof(double));

return 0;
}

Output

When you run this code, it will produce the following output −

Size of variable a: 4
Size of int data type: 4
Size of char data type: 1
Size of float data type: 4
Size of double data type: 8

Address-of Operator in C

The "&" operator returns the address of an existing variable. We can assign it to a pointer
variable −

int a;

Assuming that the compiler creates the variable at the address 1000 and "x" at the address 2000,
then the address of "a" is stored in "x".

Example

Let us understand this with the help of an example. Here, we have declared an int variable. Then,
we print its value and address −

#include <stdio.h>

int main(){

int var = 100;

printf("var: %d address: %d", var, &var);

return 0;
}

Output

Run the code and check its output −

var: 100 address: 931055924

The Dereference Operator in C

To declare a pointer variable, the following syntax is to be used −

type *var;

The name of the variable must be prefixed with an asterisk (*). The data type indicates it can
store the address of which data type. For example −

int *x;

In this case, the variable x is meant to store the address of another int variable.

float *y;

The "y" variable is a pointer that stores the memory location of a float variable.

The "&" operator returns the address of an existing variable. We can assign it to the pointer
variable −

int a;
int *x = &a;

We can see that the address of this variable (any type of variable for that matter) is an integer.
So, if we try to store it in a pointer variable of int type, see what happens −

float var1 = 10.55;


int *intptr = &var1;

The compiler doesn’t accept this, and reports the following error −

initialization of 'int *' from incompatible pointer type 'float *' [-Wincompatible-pointer-types]

It indicates that the type of a variable and the type of its pointer must be the same.
In C, variables have specific data types that define their size and how they store values.
Declaring a pointer with a matching type (e.g., "float *") enforces type compatibility between
the pointer and the data it points to.

Different data types occupy different amounts of memory in C. For example, an int typically
takes 4 bytes, while a float might take 4 or 8 bytes depending on the system.

Adding or subtracting integers from pointers moves them in memory based on the size of the
data they point to.

Hence, we declare the floatptr variable of float * type.

Example 1

Take a look at the following example −

#include <stdio.h>

int main(){

float var1 = 10.55;


float *floatptr = &var1;

printf("var1: %f \naddress of var1: %d \n\nfloatptr: %d \naddress of floatptr: %d", var1, &var1,


floatptr, &floatptr);

return 0;
}

Output

var1: 10.550000
address of var1: 6422044

floatptr: 6422044
address of floatptr: 6422032

Example 2
The * operator is called the Dereference operator. It returns the value stored in the address which
is stored in the pointer, i.e., the value of the variable it is pointing to. Take a look at the following
example −

#include <stdio.h>

int main(){

float var1 = 10.55;


float *floatptr = &var1;

printf("var1: %f address of var1: %d\n",var1, &var1);


printf("floatptr: %d address of floatptr: %d\n", floatptr, &floatptr);
printf("var1: %f value at floatptr: %f", var1, *floatptr);

return 0;
}

Output

On running this code, you will get the following output −

var1: 10.550000 address of var1: 6422044


floatptr: 6422044 address of floatptr: 6422032
var1: 10.550000 value at floatptr: 10.550000

The Ternary Operator in C

In C language, the "?" character is used as the ternary operator. It is also known as a conditional
operator.

The term "ternary" implies that the operator has three operands. The ternary operator is often
used to put conditional (if−else) statements in a compact way.

The ? operator is used with the following syntax −

exp1 ? exp2 : exp3

It has the following three operands −

 exp1 − a Boolean expression that evaluates to True or False


 exp2 − returned by the ? operator when exp1 is true
 exp3 − returned by the ? operator when exp1 is false

Example

The following C program uses the ? operator to check if the value of a is even or odd.

#include <stdio.h>

int main(){

int a = 10;
(a % 2==0) ? printf("%d is Even\n", a) : printf("%d is Odd\n", a);

return 0;
}

Output

10 is Even

Change the value of "a" to 15 and run the code again. Now you will get the following output −

15 is Odd

The conditional operator is a compact representation of if − else construct.

The Dot (.) Operator in C

In C language, you can define a derived data type with struct and union keywords. A derived or
user−defined data type that groups together member elements of different types.

The dot operator is a member selection operator, when used with the struct or union variable.
The dot (.) operator has the highest operator precedence in C Language and its associativity is
from left to right.

Take a look at its syntax −

[Link];

Here, var is a variable of a certain struct or a union type, and member is one of the elements
defined while creating structure or union.
A new derived data type is defined with struct keyword as following syntax −

struct newtype {
type elem1;
type elem2;
type elem3;
...
...
};

You can then declare a variable of this derived data type as −

struct newtype var;

To access a certain member,

var.elem1;

Example

Let us declare a struct type named book, declare a struct variable. The following example shows
the use of "." operator to access the members in the book structure.

#include <stdio.h>

struct book{
char title[10];
double price;
int pages;
};

int main(){

struct book b1 = {"Learn C", 675.50, 325};


printf("Title: %s\n", [Link]);
printf("Price: %lf\n", [Link]);
printf("No of Pages: %d\n", [Link]);
printf("size of book struct: %d", sizeof(struct book));
return 0;
}

Output

On running this code, you will get the following output −

Title: Learn C
Price: 675.500000
No of Pages: 325
size of book struct: 32

The Indirection Operator in C

A structure is a derived data type in C. In C, the struct keyword has been provided to define a
custom data type.

A new derived data type is defined with a struct keyword as the following syntax −

struct type {
type var1;
type var2;
type var3;
...
...
};

You can then declare a variable of this derived data type as −

struct type = var;

Usually, a struct is declared before the first function is defined in the program, after the include
statements. That way, the derived type can be used for declaring its variable inside any function.

Let us declare a struct type named book as follows −

struct book {
char title[10];
double price;
int pages;
};
To declare a variable of this type, use the following syntax −

struct book b1;

The initialization of a struct variable is done by placing value of each element inside curly
brackets.

struct book b1 = {"Learn C", 675.50, 325};

You can also store the address of a struct variable in the struct pointer variable.

struct book *strptr;

To store the address, use the "&" operator.

strptr = &b1;

C defines the arrow (→) symbol to be used with struct pointer as indirection operator (also called
struct dereference operator). It helps to access the elements of the struct variable to which the
pointer reference to.

Example

In this example, strptr is a pointer to struct book b1 variable. Hence, strrptr−>title returns the
title, similar to [Link] does.

#include <stdio.h>
#include <string.h>

struct book {
char title[10];
double price;
int pages;
};

int main() {
struct book b1 = {"Learn C", 675.50, 325};
struct book *strptr;
strptr = &b1;
printf("Title: %s\n", strptr->title);
printf("Price: %lf\n", strptr->price);
printf("No of Pages: %d\n", strptr->pages);

return 0;
}

Output

Run the code and check its output −

Title: Learn C
Price: 675.500000
No of Pages: 325
C - Decision Making

Every programming language including C has decision-making statements to support


conditional logic. C has a number of alternatives to add decision-making in the code.

Any process is a combination of three types of logic −

 Sequential logic
 Decision or branching
 Repetition or iteration

A computer program is sequential in nature and runs from top to bottom by default. The
decision-making statements in C provide an alternative line of execution. You can ask a group of
statements to be repeatedly executed till a condition is satisfied.

The decision-making structures control the program flow based on conditions. They are
important tools for designing complex algorithms.

We use the following keywords and operators in the decision-making statements of a C


program − if, else, switch, case, default, goto, the ?: operator, break, and continue statements.

In programming, we come across situations when we need to make some decisions. Based on
these decisions, we decide what should we do next. Similar situations arise in algorithms too
where we need to make some decisions and based on these decisions, we will execute the next
block of code.

The next instruction depends on a Boolean expression, whether the condition is determined to be
True or False. C programming language assumes any non-zero and non-null values as True, and
if it is either zero or null, then it is assumed as a False value.

C programming language provides the following types of decision making statements.


[Link]. Statement & Description

if statement
1 An if statement consists of a boolean expression followed by
one or more statements.

if...else statement
2 An if statement can be followed by an optional else statement,
which executes when the Boolean expression is false.

nested if statements
3 You can use one if or else-if statement inside another if or else-
if statement(s).

switch statement
4 A switch statement allows a variable to be tested for equality
against a list of values.

nested switch statements


5 You can use one switch statement inside
another switch statement(s).

If Statement in C Programming

The if statement is used for deciding between two paths based on a True or False outcome. It is
represented by the following flowchart −
Syntax

if (Boolean expr){
expression;
...
}

An if statement consists of a boolean expression followed by one or more statements.

If...else Statement in C Programming

The if–else statement offers an alternative path when the condition isn't met.

Syntax

if (Boolean expr){
expression;
...
}
else{
expression;
...
}
An if statement can be followed by an optional else statement, which executes when the Boolean
expression is false.

Nested If Statements in C Programming

Nested if statements are required to build intricate decision trees, evaluating multiple nested
conditions for nuanced program flow.

You can use one if or else-if statement inside another if or else-if statement(s).

Switch Statement in C Programming

A switch statement simplifies multi-way choices by evaluating a single variable against multiple
values, executing specific code based on the match. It allows a variable to be tested for equality
against a list of values.
Syntax

switch(expression) {

case constant-expression :
statement(s);
break; /* optional */

case constant-expression :
statement(s);
break; /* optional */

/* you can have any number of case statements */


default : /* Optional */
statement(s);
}

As in if statements, you can use one switch statement inside another switch statement(s).
The ?: Operator in C Programming

We have covered the conditional operator (?:) in the previous chapter which can be used to
replace if-else statements. It condenses an if-else statement into a single expression, offering
compact and readable code.

It has the following general form −

Exp1 ? Exp2 : Exp3;

Where Exp1, Exp2, and Exp3 are expressions. Notice the use and placement of the colon (:). The
value of a "?" expression is determined like this −

Exp1 is evaluated. If it is true, then Exp2 is evaluated and becomes the value of the entire ?
expression.

If Exp1 is false, then Exp3 is evaluated and its value becomes the value of the : expression.

You can simulate nested if statements with the ? operator. You can use another ternary operator
in true and/or false operand of an existing ? operator.

An algorithm can also have an iteration logic. In C, the while, do–while and for statements are
provided to form loops.

The loop formed by while and do–while are conditional loops, whereas the for statement forms
a counted loop.

The loops are also controlled by the Boolean expressions. The C compiler decides whether the
looping block is to be repeated again, based on a condition.

The program flow in a loop is also controlled by different jumping statements.


The break and continue keywords cause the loop to terminate or perform the next iteration.

The Break Statement in C Programming

In C, the break statement is used in switch–case constructs as well as in loops. When used inside
a loop, it causes the repetition to be abandoned.
The Continue Statement in C Programming

In C, the continue statement causes the conditional test and increment portions of the loop to
execute.

The goto Statement in C Programming


C also has a goto keyword. You can redirect the program flow to any labelled instruction in the
program.

Here is the syntax of the goto statement in C −

goto label;
..
.
label: statement;

With the goto statement, the flow can be directed to any previous step or any subsequent step.

In this chapter, we had a brief overview of the decision-making statements in C. In the


subsequent chapters, we will have an elaborate explanation on each of these decision-making
statements, with suitable examples.

C - The If Statement

The if statement is a fundamental decision control statement in C programming. One or more


statements in a block will get executed depending on whether the Boolean condition in
the if statement is true or false.

Syntax of if Statement

The if statement is written with the following syntax −

if(boolean_expression) {
/* statement(s) will execute if the boolean expression is true */
}

How if Statement Works?

C uses a pair of curly brackets to form a code block. If the Boolean expression evaluates to true,
then the block of code inside the if statement will be executed.

If the Boolean expression evaluates to false, then the first set of code after the end of
the if statement (after the closing curly brace) will be executed.

C programming treats any non-zero and non-null values as true. And if the values are either zero
or null, then they are treated as false values.

Flowchart of if Statement

The behaviour of the if statement is expressed by the following flowchart −

When the program control comes across the if statement, the condition is evaluated.

If the condition is true, the statements inside the if block are executed.

If the condition is false, the program flow bypasses the conditional block.

Statements after the if block are executed to continue the program flow.

Example 1: Simple Use of if Statement


This example demonstrates the simplest use-case of if statement. It determines and tells the user
if the value of a variable is less than 20.

#include <stdio.h>

int main (){

/* local variable declaration */


int a;

// run the program for different values of "a"


// Assign 12 first and 40 afterwards

a = 12; //change to 40 and run again


printf("Value of a is : %d\n", a);

// check the boolean condition using if statement

if(a < 20){


//if the condition is true, then print the following
printf("a is less than 20\n" );
}
return 0;
}

Output

Run the above program and check its ouput −

Value of a is : 12
a is less than 20

Now assign a number greater than 20. The if condition is not executed.

Value of a is: 40

Example 2: if Statement with Logical Operations


You can put a compound boolean expression with the use of && or || operators in the
parenthesis in the if statement.

In the following example, three variables "a", "b" and "c" are compared. The if block will be
executed when "a" is greater than both "b" and "c".

#include <stdio.h>

int main () {

/* local variable declaration */


int a, b, c;

/*use different values for a, b and c as


10, 5, 7
10, 20, 15
*/

// change to 10,20,15 respectively next time


a = 10; b = 5; c = 7;

if (a>=b && a>=c){


printf ("a is greater than b and c \n");
}
printf("a: %d b:%d c:%d", a, b, c);

return 0;
}

Output

Run the code and check its output −

//when values for a, b and c are 10 5 7


a is greater than b and c
a: 10 b:5 c:7

//when values for a, b and c are 10 20 15


a: 10 b:20 c:15

Note that the statement following the conditional block is executed after the block is executed. If
the condition is false, the program jumps directly to the statement after the block.

Example 3: Multiple if Statements

In this example, the net payable amount is calculated by applying discount on the bill amount.

The discount applicable is 5 percent if the amount is between 1000 to 5000, and 10 percent if the
amount is above 5000. No discount is applicable for purchases below 1000.

#include <stdio.h>

int main () {

// local variable declaration


int amount;
float discount, net;

/*Run the program for different values


of amount – 500, 2250 and 5200. Blocks in
respective conditions will be executed*/

// change to 2250 and 5200 and run again


amount = 500;

if (amount < 1000){


discount=0;
}
if (amount >= 1000 && amount<5000){
discount=5;
}
if (amount >= 5000){
discount=10;
}
net = amount - amount*discount/100;
printf("Amount: %d Discount: %f Net payable: %f", amount, discount, net);
return 0;
}

Output

//when the bill amount is 500


Amount: 500 Discount: 0.000000 Net payable: 500.000000

//when the bill amount is 2250


Amount: 2250 Discount: 5.000000 Net payable: 2137.500000

//when the bill amount is 5200


Amount: 5200 Discount: 10.000000 Net payable: 4680.000000

Example 4: Checking Multiple Conditions

In this program, a student is declared as passed only if the average of "phy" and "maths" marks
is greater than equal to 50. Also, the student should have secured more than 35 marks in both the
subjects. Otherwise, the student is declared as failed.

#include <stdio.h>

int main (){


/* local variable declaration */
int phy, maths;
float avg;

/*use different values of phy and maths


to check conditional execution*/

//change to 40, 40 and 80, 40


phy = 50; maths = 50;
avg = (float)(phy + maths)/2;
printf("Phy: %d Maths: %d Avg: %f\n", phy, maths, avg);

if (avg >= 50 && (maths >= 35 && phy >= 35)){


printf("Result: Pass");
}

if (avg<50) {
printf("Result: Fail\n");
}
return 0;
}

Output

Run the code and check its output −

//when marks in Phy and Maths - 50 50


Phy: 50 Maths: 50 Avg: 50.000000
Result: Pass

//when marks in Phy and Maths - 40 40


Phy: 40 Maths: 40 Avg: 40.000000
Result: Fail

//when marks in Phy and Maths - 80 40


Phy: 80 Maths: 40 Avg: 60.000000
Result: Pass

Conditional execution of instructions is the basic requirement of a computer program.


The if statement in C is the primary conditional statement.

C allows an optional else keyword to specify the statements to be executed if the if condition is
false. For representation of more complex algorithms, you can have nested if–else constructs in a
C program.

C - The if-else Statement

The if-else statement is one of the frequently used decision-making statements in C. The if-
else statement offers an alternative path when the condition isn't met.

The else keyword helps you to provide an alternative course of action to be taken when the
Boolean expression in the if statement turns out to be false. The use of else keyword is optional;
it's up to you whether you want to use it or not.
The C compiler evaluates the condition, and executes a statement or a block of statements
following the if statement if it is true.

If the programming logic needs the computer to execute some other instructions when the
condition is false, they are put as a part of the else clause.

Syntax of if-else Statement

Here is the syntax of if-else clause −

if (Boolean expr){
Expression;
...
}
else{
Expression;
...
}

An if statement is followed by an optional else statement, which executes when the Boolean
expression is false.

Flowchart of if-else Statement

The following flowchart represents how the if-else clause works in C −


Note that the curly brackets in the if as well as the else clause are necessary if you have more
than one statements to be executed. For example, in the following code, we don’t need curly
brackets.

if (marks<50)
printf("Result: Fail\n");
else
printf("Result: Pass\n");

However, when there are more than one statements, either in the if or in the else part, you need to
tell the compiler that they need to be treated as a compound statement.

if-else Statement Examples

Example 1

Consider the following code. It intends to calculate the discount at 10% if the amount is greater
than 100, and no discount otherwise.

#include <stdio.h>

int main() {
int amount = 50;
float discount;
printf("Amount: %d\n", amount);

if (amount >= 100)


discount = amount * 10 / 100;
printf("Discount: %f \n", discount);
else
printf("Discount not applicable\n");

return 0;
}

Output

The program shows the following errors during the compilation −

error: 'else' without a previous 'if'


The compiler will execute the first statement after the if clause and assumes that since the next
statement is not else (it is optional anyway), the subsequent printf() statement is unconditional.
However, the next else is not connected to any if statement, hence the error.

Example 2

Consider the following code too −

#include <stdio.h>

int main() {
int amount = 50;
float discount, nett;
printf("Amount: %d\n", amount);

if (amount<100)
printf("Discount not applicable\n");
else
printf("Discount applicable");
discount = amount*10/100;
nett = amount - discount;
printf("Discount: %f Net payable: %f", discount, nett);

return 0;
}

Output

The code doesn’t give any compiler error, but gives incorrect output −

Amount: 50
Discount not applicable
Discount: 5.000000 Net payable: 45.000000

It produces an incorrect output because the compiler assumes that there is only one statement in
the else clause, and the rest of the statements are unconditional.

The above two code examples emphasize the fact that when there are more than one statements
in the if or else else, they must be put in curly brackets.
To be safe, it is always better to use curly brackets even for a single statement. In fact, it
improves the readability of the code.

The correct solution for the above problem is shown below −

if (amount >= 100){


discount = amount * 10 / 100;
printf("Discount: %f \n", discount);
} else {
printf("Discount not applicable\n");
}

Example 3

In the code given below, the tax on employee’s income is computed. If the income is below
10000, the tax is applicable at 10%. For the income above 10000, the excess income is charged
at 15%.

#include <stdio.h>

int main() {
int income = 5000;
float tax;
printf("Income: %d\n", income);

if (income<10000){
tax = (float)(income * 10 / 100);
printf("tax: %f \n", tax);
}
else {
tax= (float)(1000 + (income-10000) * 15 / 100);
printf("tax: %f", tax);
}
}

Output

Run the code and check its output −


Income: 5000
tax: 500.000000

Set the income variable to 15000, and run the program again.

Income: 15000
tax: 1750.000000

Example 4

The following program checks if a char variable stores a digit or a non-digit character.

#include <stdio.h>

int main() {
char ch='7';

if (ch>=48 && ch<=57){


printf("The character is a digit.");
}
else{
printf("The character is not a digit.");
}
return 0;
}

Output

Run the code and check its output −

The character is a digit.

Assign any other character such as "*" to "ch" and see the result.

The character is not a digit.

The else-if Statement in C

C also allows you to use else-if in the programs. Let's see where you may have to use an else-
if clause.
Let's suppose you have a situation like this. If a condition is true, run the given block that
follows. If it isn't, run the next block instead. However, if none of the above is true and all else
fails, finally run another block. In such cases, you would use an else-if clause.

Syntax of else-if Statement

Here is the syntax of the else-if clause −

if (condition){
// if the condition is true,
// then run this code
} else if(another_condition){
// if the above condition was false
// and this condition is true,
// then run the code in this block

} else{
// if both the above conditions are false,
// then run this code
}

Example of else-if Statement

Take a look at the following example −

#include <stdio.h>

int main(void) {
int age = 15;

if (age < 18) {


printf("You need to be over 18 years old to continue\n");
}else if (age < 21) {
printf("You need to be over 21\n");
} else {
printf("You are over 18 and older than 21 so you can continue \n");
}
}
Output

Run the code and check its output −

You need to be over 18 years old to continue

Now, supply a different value for the variable "age" and run the code again. You will get a
different output if the supplied value is less than 18.

C - Nested If Statements

It is always legal in C programming to nest if-else statements, which means you can use
one if or else-if statement inside another if or else-if statement(s).

In the programming context, the term "nesting" refers to enclosing a particular programming
element inside another similar element. For example, nested loops, nested structures, nested
conditional statements, etc. If an if statement in C is employed inside another if statement, then
we call it as a nested if statement in C.

Syntax

The syntax of nested if statements is as follows −

if (expr1){
if (expr2){
block to be executed when
expr1 and expr2 are true
}
else{
block to be executed when
expr1 is true but expr2 is false
}
}

The following flowchart represents the nesting of if statements −


You can compound the Boolean expressions with && or || to get the same effect. However, for
more complex algorithms, where there are different combinations of multiple Boolean
expressions, it becomes difficult to form the compound conditions. Instead, it is recommended to
use nested structures.

Another if statement can appear inside a top-level if block, or its else block, or inside both.

Example 1

Let us take an example, where the program needs to determine if a given number is less than
100, between 100 to 200, or above 200. We can express this logic with the following compound
Boolean expression −

#include <stdio.h>

int main (){

// local variable definition


int a = 274;
printf("Value of a is : %d\n", a);
if (a < 100){
printf("Value of a is less than 100\n");
}

if (a >= 100 && a < 200){


printf("Value of a is between 100 and 200\n" );
}

if (a >= 200){
printf("Value of a is more than 200\n" );
}
}

Output

Run the code and check its output. Here, we have intialized the value of "a" as 274. Change this
value and run the code again. If the supplied value is less than 100, then you will get a different
output. Similarly, the output will change again if the supplied number is in between 100 and 200.

Value of a is : 274
Value of a is more than 200

Example 2

Now let's use nested conditions for the same problem. It will make the solution more
understandable when we use nested conditions.

First, check if "a >= 100". Inside the true part of the if statement, check if it is <200 to decide if
the number lies between 100-200, or it is >200. If the first condition (a >= 100) is false, it
indicates that the number is less than 100.

#include <stdio.h>

int main (){

// local variable definition


// check with different values 120, 250 and 74
int a = 120;
printf("value of a is : %d\n", a );
// check the boolean condition
if(a >= 100){

// this will check if a is between 100-200


if(a < 200){
// if the condition is true, then print the following
printf("Value of a is between 100 and 200\n" );
}
else{
printf("Value of a is more than 200\n");
}
}
else{
// executed if a < 100
printf("Value of a is less than 100\n");
}

return 0;
}

Output

Run the code and check its output. You will get different outputs for different input values of "a"

Value of a is : 120
Value of a is between 100 and 200

Example 3

The following program uses nested if statements to determine if a number is divisible by 2 and 3,
divisible by 2 but not 3, divisible by 3 but not 2, and not divisible by both 2 and 3.

#include <stdio.h>

int main(){
int a = 15;
printf("a: %d\n", a);

if (a % 2 == 0) {
if (a % 3 == 0){
printf("Divisible by 2 and 3");
}
else {
printf("Divisible by 2 but not 3");
}
}
else {
if (a % 3 == 0){
printf("Divisible by 3 but not 2");
}
else{
printf("Not divisible by 2, not divisible by 3");
}
}

return 0;
}

Output

Run the code and check its output −

a: 15
Divisible by 3 but not 2

For different values of "a", you will get different outputs.

Example 4

Given below is a C program to check if a given year is a leap year or not. Whether the year is a
leap year or not is determined by the following rules −

 Is the year divisible by 4?


 If yes, is it a century year (divisible by 100)?
 If yes, is it divisible by 400? If yes, it is a leap year, otherwise not.
 If it is divisible by 4 and not a century year, it is a leap year.
 If it is not divisible by 4, it is not a leap year.

Here is the C code −

#include <stdio.h>

int main(){

// Test the program with the values 1900, 2023, 2000, 2012
int year = 1900;
printf("year: %d\n", year);

// is divisible by 4?
if (year % 4 == 0){

// is divisible by 100?
if (year % 100 == 0){

// is divisible by 400?
if(year % 400 == 0){
printf("%d is a Leap Year\n", year);
}
else{
printf("%d is not a Leap Year\n", year);
}
}
else{
printf("%d is not a Leap Year\n", year);
}
}
else{
printf("%d is a Leap Year\n", year);
}
}

Output
Run the code and check its output −

year: 1900
1900 is not a Leap Year

Test the program with different values for the variable "year" such as 1900, 2023, 2000, 2012.

The same result can be achieved by using the compound Boolean expressions instead of nested if
statements, as shown below −

If (year % 4 == 0 && (year % 400 == 0 || year % 100 != 0)){


printf("%d is a leap year", year);
}
else{
printf("%d is not a leap year", year);
}

With nested if statements in C, we can write structured and multi-level decision-making


algorithms. They simplify coding the complex discriminatory logical situations. Nesting too
makes the program more readable, and easy to understand.

C - The Switch Statement

A switch statement allows a variable to be tested for equality against a list of values. Each value
is called a case, and the variable being switched on is checked for each switch case.

C switch-case Statement

The switch-case statement is a decision-making statement in C. The if-else statement provides


two alternative actions to be performed, whereas the switch-case construct is a multi-way
branching statement. A switch statement in C simplifies multi-way choices by evaluating a
single variable against multiple values, executing specific code based on the match. It allows
a variable to be tested for equality against a list of values.

Syntax of switch-case Statement

The flow of the program can switch the line execution to a branch that satisfies a given case. The
schematic representation of the usage of switch-case construct is as follows −

switch (Expression){

// if expr equals Value1


case Value1:
Statement1;
Statement2;
break;

// if expr equals Value2


case Value2:
Statement1;
Statement2;
break;
.
.
// if expr is other than the specific values above
default:
Statement1;
Statement2;
}

How switch-case Statement Work?

The parenthesis in front of the switch keyword holds an expression. The expression should
evaluate to an integer or a character. Inside the curly brackets after the parenthesis, different
possible values of the expression form the case labels.

One or more statements after a colon(:) in front of the case label forms a block to be executed
when the expression equals the value of the label.

You can literally translate a switch-case as "in case the expression equals value1, execute the
block1", and so on.

C checks the expression with each label value, and executes the block in front of the first match.
Each case block has a break as the last statement. The break statement takes the control out of
the scope of the switch construct.

You can also define a default case as the last option in the switch construct. The default case
block is executed when the expression doesn’t match with any of the earlier case values.

Flowchart of switch-case Statement

The flowchart that represents the switch-case construct in C is as follows −


Rules for Using the switch-case Statement

The following rules apply to a switch statement −

 The expression used in a switch statement must have an integral or enumerated type, or be
of a class type in which the class has a single conversion function to an integral or
enumerated type.
 You can have any number of case statements within a switch. Each case is followed by the
value to be compared to and a colon.
 The constant-expression for a case must be the same data type as the variable in the switch,
and it must be a constant or a literal.
 When the variable being switched on is equal to a case, the statements following that case
will execute until a break statement is reached.
 When a break statement is reached, the switch terminates, and the flow of control jumps to
the next line following the switch statement.
 Not every case needs to contain a break. If no break appears, the flow of control will fall
through to subsequent cases until a break is reached.
 A switch statement can have an optional default case, which must appear at the end of the
switch. The default case can be used for performing a task when none of the cases is true.
No break is needed in the default case.

The switch-case statement acts as a compact alternative to cascade of if-else statements,


particularly when the Boolean expression in "if" is based on the "=" operator.
If there are more than one statements in an if (or else) block, you must put them inside curly
brackets. Hence, if your code has many if and else statements, the code with that many opening
and closing curly brackets appears clumsy. The switch-case alternative is a compact and clutter-
free solution.

C switch-case Statement Examples

Example 1

In the following code, a series of if-else statements print three different greeting messages based
on the value of a "ch" variable ("m", "a" or "e" for morning, afternoon or evening).

#include <stdio.h>

int main(){

/* local variable definition */


char ch = 'e';
printf("Time code: %c\n\n", ch);

if (ch == 'm')
printf("Good Morning");

else if (ch == 'a')


printf("Good Afternoon");
else
printf("Good Evening");

return 0;
}

The if-else logic in the above code is replaced by the switch-case construct in the code below −

#include <stdio.h>

int main (){

// local variable definition


char ch = 'm';
printf("Time code: %c\n\n", ch);

switch (ch){

case 'a':
printf("Good Afternoon\n");
break;

case 'e':
printf("Good Evening\n");
break;

case 'm':
printf("Good Morning\n");
}
return 0;
}

Output

Change the value of "ch" variable and check the output. For ch = 'm', we get the following output

Time code: m

Good Morning

The use of break is very important here. The block of statements corresponding to each case
ends with a break statement. What if the break statement is not used?

The switch-case works like this: As the program enters the switch construct, it starts comparing
the value of switching expression with the cases, and executes the block of its first match.
The break causes the control to go out of the switch scope. If break is not found, the subsequent
block also gets executed, leading to incorrect result.

Example 2

Let us comment out all the break statements in the above code.

#include <stdio.h>
int main (){

/* local variable definition */


char ch = 'a';
printf("Time code: %c\n\n", ch);

switch (ch){
case 'a':
printf("Good Afternoon\n");
// break;

case 'e':
printf("Good Evening\n");
// break;

case 'm':
printf("Good Morning\n");
}
return 0;
}

Output

You expect the "Good Morning" message to be printed, but you find all the three messages
printed!

Time code: a

Good Afternoon
Good Evening
Good Morning

This is because C falls through the subsequent case blocks in the absence of break statements at
the end of the blocks.

Example 3
In the following program, "grade" is the switching variable. For different cases of grades, the
corresponding result messages will be printed.

#include <stdio.h>

int main(){

/* local variable definition */


char grade = 'B';

switch(grade){
case 'A' :
printf("Outstanding!\n" );
break;
case 'B':
printf("Excellent!\n");
break;
case 'C':
printf("Well Done\n" );
break;
case 'D':
printf("You passed\n" );
break;
case 'F':
printf("Better try again\n" );
break;
default :
printf("Invalid grade\n" );
}
printf("Your grade is %c\n", grade);

return 0;
}

Output

Run the code and check its output −


Excellent!
Your grade is B

Now change the value of "grade" (it is a "char" variable) and check the outputs.

Example 4

The following example displays a menu for arithmetic operations. Based on the value of the
operator code (1, 2, 3, or 4), addition, subtraction, multiplication or division of two values is
done. If the operation code is something else, the default case is executed.

#include <stdio.h>

int main (){

// local variable definition


int a = 10, b = 5;

// Run the program with other values 2, 3, 4, 5


int op = 1;
float result;

printf("1: addition\n");
printf("2: subtraction\n");
printf("3: multiplication\n");
printf("4: division\n");

printf("\na: %d b: %d : op: %d\n", a, b, op);


switch (op){
case 1:
result = a + b;
break;
case 2:
result = a - b;
break;
case 3:
result = a * b;
break;
case 4:
result = a / b;
break;
default:
printf("Invalid operation\n");
}
if (op >= 1 && op <= 4)
printf("Result: %6.2f", result);

return 0;
}

Output

1: addition
2: subtraction
3: multiplication
4: division

a: 10 b: 5 : op: 1
Result: 15.00

For other values of "op" (2, 3, and 4), you will get the following outputs −

a: 10 b: 5 : op: 2
Result: 5.00

a: 10 b: 5 : op: 3
Result: 50.00

a: 10 b: 5 : op: 4
Result: 2.00

a: 10 b: 5 : op: 5
Invalid operation

Combining Multiple Cases


If you have a situation where the same code block is to be executed for more than one case labels
of an expression, you can combine them by putting the two cases one below the other, as shown
below −

switch (exp) {
case 1:
case 2:
statements;
break;
case 3:
statements;
break;
default:
printf("%c is a non-alphanumeric character\n", ch);
}

You can also use the ellipsis (…) to combine a range of values for an expression. For example, to
match the value of switching variable with any number between 1 to 10, you can use "case 1 …
10"

Example 1

#include <stdio.h>

int main (){

// local variable definition


int number = 5;

switch (number){

case 1 ... 10:


printf("The number is between 1 and 10\n");
break;

default:
printf("The number is not between 1 and 10\n");
}
return 0;
}

Output

Run the code and check its output. For "number = 5", we get the following output −

The number is between 1 and 10

Example 2

The following program checks whether the value of the given char variable stores a lowercase
alphabet, an uppercase alphabet, a digit, or any other key.

#include <stdio.h>

int main (){

char ch = 'g';

switch (ch){
case 'a' ... 'z':
printf("%c is a lowercase alphabet\n", ch);
break;

case 'A' ... 'Z':


printf("%c is an uppercase alphabet\n", ch);
break;

case 48 ... 57:


printf("%c is a digit\n", ch);
break;

default:
printf("%c is a non-alphanumeric character\n", ch);
}
return 0;
}
Output

For ch = 'g', we get the following output −

g is a lowercase alphabet

Test the code output with different values of "ch".

C - Nested Switch Statements

It is possible to have a switch as a part of the statement sequence of an outer switch. Even if the
case constants of the inner and outer switch contain common values, no conflicts will arise.

Syntax

The syntax for a nested switch statement is as follows −

switch(ch1){
case 'A':
printf("This A is part of outer switch" );
switch(ch2) {
case 'A':
printf("This A is part of inner switch" );
break;
case 'B': /* case code */
}
break;
case 'B': /* case code */
}

Example

Take a look at the following example −

#include <stdio.h>
int main (){

/* local variable definition */


int a = 100;
int b = 200;
switch(a){
case 100:
printf("This is part of outer switch\n", a);

switch(b){
case 200:
printf("This is part of inner switch\n", a);
}
}
printf("Exact value of a is: %d\n", a);
printf("Exact value of b is: %d\n", b);
return 0;
}

Output

When the above code is compiled and executed, it produces the following output −

This is part of outer switch


This is part of inner switch
Exact value of a is : 100
Exact value of b is : 200

Nested Switch-Case Statements in C

Just like nested if–else, you can have nested switch-case constructs. You may have a different
switch-case construct each inside the code block of one or more case labels of the outer switch
scope.

The nesting of switch-case can be done as follows −

switch (exp1){
case val1:
switch (exp2){
case val_a:
stmts;
break;
case val_b:
stmts;
break;
}
case val2:
switch (expr2){
case val_c:
stmts;
break;
case val_d:
stmts;
break;
}
}

Example

Here is a simple program to demonstrate the syntax of Nested Switch Statements in C −

#include <stdio.h>
int main(){
int x = 1, y = 'b', z='X';

// Outer Switch
switch (x){
case 1:
printf("Case 1 \n");

switch (y){
case 'a':
printf("Case a \n");
break;
case 'b':
printf("Case b \n");
break;
}
break;
case 2:
printf("Case 2 \n");
switch (z){
case 'X':
printf("Case X \n");
break;
case 'Y':
printf("Case Y \n");
break;
}
}
return 0;
}

Output

When you run this code, it will produce the following output −

Case 1
Case b

Change the values of the variables (x, y, and z) and check the output again. The output depends
on the values of these three variables.

C - Loops

Loops are a programming construct that denote a block of one or more statements that are
repeatedly executed a specified number of times, or till a certain condition is reached.

Repetitive tasks are common in programming, and loops are essential to save time and minimize
errors. In C programming, the keywords while, do–while and for are provided to implement
loops.

Looping constructs are an important part of any processing logic, as they help in performing the
same process again and again. A C programmer should be well acquainted with implementing
and controlling the looping construct.

Programming languages provide various control structures that allow for more complicated
execution paths. A loop statement allows us to execute a statement or group of statements
multiple times.

Flowchart of C Loop Statement


Given below is the general flowchart of a loop statement which is applicable to any
programming language −

The statements in a C program are always executed in a top-to-bottom manner. If we ask the
compiler to go back to any of the earlier steps, it constitutes a loop.

Example: Loops in C

To understand the need of loops in a program, consider the following snippet −

#include <stdio.h>
int main (){

// local variable definition


int a = 1;

printf("a: %d\n", a);


a++;

printf("a: %d\n", a);


a++;

printf("a: %d\n", a);


a++;

printf("a: %d\n", a);


a++;

printf("a: %d\n", a);

return 0;
}

Output

On running this code, you will get the following output −

a: 1
a: 2
a: 3
a: 4
a: 5

The program prints the value of "a", and increments its value. These two steps are repeated a
number of times. If you need to print the value of "a" from 1 to 100, it is not desirable to
manually repeat these steps in the code. Instead, we can ask the compiler to repeatedly execute
these two steps of printing and incrementing till it reaches 100.

Example: Using While Loop in C

You can use for, while or do-while constructs to repeat a loop. The following program shows
how you can print 100 values of "a" using the "while" loop in C −

#include <stdio.h>

int main () {

// local variable definition


int a = 1;

while (a <= 100){


printf("a: %d\n", a);
a++;
}

return 0;
}

Output

Run this code and check the output −

a: 1
a: 2
a: 3
a: 4
.....
.....
a: 98
a: 99
a: 100

If a step redirects the program flow to any of the earlier steps, based on any condition, the loop is
a conditional loop. The repetitions will stop as soon as the controlling condition turns false. If the
redirection is done without any condition, it is an infinite loop, as the code block repeats forever.

Parts of C Loops

To constitute a loop, the following elements are necessary −

 Looping statement (while, do–while or for)


 Looping block
 Looping condition

Loops are generally of two types −

Counted Loops in C

If the loop is designed to repeat for a certain number of times, it is a counted loop. In C,
the for loop is an example of counted loop.

Conditional Loops in C
If the loop is designed to repeat till a condition is true, it is a conditional loop. The while and do–
while constructs help you to form conditional loops.

Looping Statements in C

C programming provides the following types of loops to handle looping requirements −

[Link]. Loop Type & Description

while loop
Repeats a statement or group of statements while a given
1
condition is true. It tests the condition before executing the loop
body.

for loop
2 Executes a sequence of statements multiple times and
abbreviates the code that manages the loop variable.

do-while loop
3 It is more like a while statement, except that it tests the
condition at the end of the loop body.

nested loops
4 You can use one or more loops inside any
other while, for or do-while loop.

Each of the above loop types have to be employed depending upon which one is right for the
given situation. We shall learn about these loop types in detail in the subsequent chapters.

Loop Control Statements in C

Loop control statements change the execution from its normal sequence. When execution leaves
a scope, all automatic objects that were created in that scope are destroyed.

C supports the following control statements −

[Link]. Control Statement & Description

break statement
1 Terminates the loop or switch statement and transfers execution
to the statement immediately following the loop or switch.

continue statement
2 Causes the loop to skip the remainder of its body and
immediately retest its condition prior to reiterating.
goto statement
3
Transfers the control to the labeled statement.

The break and continue statements have contrasting purposes. The goto statement acts as a
jump statement if it causes the program to go to a later statement. If the goto statement redirects
the program to an earlier statement, then it forms a loop.

The Infinite Loop in C

A loop becomes an infinite loop if a condition never becomes false. An infinite loop is a loop
that repeats indefinitely because it has no terminating condition, or the termination condition is
never met or the loop is instructed to start over from the beginning.

Although it is possible for a programmer to intentionally use an infinite loop, they are often
mistakes made by new programmers.

Example: Infinite Loop in C

The for loop is traditionally used for creating an infinite loop. Since none of the three
expressions that form the "for" loop are required, you can make an endless loop by leaving the
conditional expression empty.

#include <stdio.h>

int main (){

for( ; ; ){
printf("This loop will run forever. \n");
}

return 0;
}

Output

By running this code, you will get an endless loop that will keep printing the same line forever.

This loop will run forever.


This loop will run forever.
........
........
This loop will run forever.

When the conditional expression is absent, it is assumed to be true. You may have an
initialization and increment expression, but C programmers more commonly use
the for(;;) construct to signify an infinite loop.

Note − You can terminate an infinite loop by pressing the "Ctrl + C" keys.

C - While Loop

In C, while is one of the keywords with which we can form loops. The while loop is one of the
most frequently used types of loops in C. The other looping keywords in C are for and do-while.

The while loop is often called the entry verified loop, whereas the do-while loop is an exit
verified loop. The for loop, on the other hand, is an automatic loop.

Syntax of While Loop

The syntax of constructing a while loop is as follows −

while(expression){
statement(s);
}

The while keyword is followed by a parenthesis, in which there should be a Boolean expression.
Followed by the parenthesis, there is a block of statements inside the curly brackets.

Flowchart of While Loop

The while loop works like this. The C compiler evaluates the expression. If the expression is
true, the code block that follows, will be executed. If the expression is false, the compiler ignores
the block next to the while keyword, and proceeds to the immediately next statement after the
block.

The following flowchart represents how the while loop works −


Since the expression that controls the loop is tested before the program enters the loop,
the while loop is called the entry verified loop. Here, the key point to note is that a while loop
might not execute at all if the condition is found to be not true at the very first instance itself.

The while keyword implies that the compiler continues to execute the ensuing block as long as
the expression is true. The condition sits at the top of the looping construct. After each iteration,
the condition is tested. If found to be true, the compiler performs the next iteration. As soon as
the expression is found to be false, the loop body will be skipped and the first statement after the
while loop will be executed.

Let us try to understand the behaviour of while loop with a few examples.

Example 1

The following program prints the "Hello World" message five times.

#include <stdio.h>

int main(){

// local variable definition


int a = 1;

// while loop execution


while(a <= 5){
printf("Hello World \n");
a++;
}
printf("End of loop");
return 0;
}

Output

Here, the while loop acts as a counted loop. Run the code and check its output −

Hello World
Hello World
Hello World
Hello World
Hello World
End of loop

The variable "a" that controls the number of repetitions is initialized to 1, before
the while statement. Since the condition "a <= 5" is true, the program enters the loop, prints the
message, increments "a" by 1, and goes back to the top of the loop.

In the next iteration, "a" is 2, hence the condition is still true, hence the loop repeats again, and
continues till the condition turns false. The loop stops repeating, and the program control goes to
the step after the block.

Now, change the initial value of "a" to 10 and run the code again. Now the output will show the
following −

End of loop

This is because the condition before the while keyword is false in the very first iteration itself,
hence the block is not repeated.

Example 2

The following program prints all the lowercase alphabets with the help of a while loop.

#include <stdio.h>

int main(){
// local variable definition
char a = 'a';

// while loop execution


while(a <= 'z') {
printf("%c", a);
a++;
}
printf("\n End of loop");
return 0;
}

Output

Run the code and check its output −

abcdefghijklmnopqrstuvwxyz
End of loop

A "char" variable represents a character corresponding to its ASCII value. Hence, it can be
incremented. Hence, we increment the value of the variable from "a" till it reaches "z".

Example 3

In this example, the while loop is used as a conditional loop. The loop continues to repeat till
the input received is non-negative.

#include <stdio.h>

int main(){

// local variable definition


char choice = 'a';

int x = 0;

// while loop execution


while(x >= 0){
(x % 2 == 0) ? printf("%d is Even \n", x) : printf("%d is Odd \n", x);
printf("\n Enter a positive number: ");
scanf("%d", &x);
}
printf("\n End of loop");
return 0;
}

Output

Run the code and check its output −

0 is Even

Enter a positive number: 12


12 is Even

Enter a positive number: 25


25 is Odd

Enter a positive number: -1

End of loop

Example 4

In the code given below, we have two variables "a" and "b" initialized to 10 and 0, respectively.
Inside the loop, "b" is decremented and "a" is incremented on each iteration. The loop is
designed to repeat till "a" and "b" are not equal. The loop ends when both reach 5.

#include <stdio.h>

int main(){

// local variable definition


int a = 10, b = 0;

// while loop execution


while(a != b){
a--;
b++;
printf("a: %d b: %d\n", a,b);
}
printf("\n End of loop");
return 0;
}

Output

When you run this code, it will produce the following output −

a: 9 b: 1
a: 8 b: 2
a: 7 b: 3
a: 6 b: 4
a: 5 b: 5

End of loop

The do-while loop appears similar to the while loop in most cases, although there is a difference
in its syntax. The do-while is called the exit verified loop. In some cases, their behaviour is
different. Difference between while and do-while loop is explained in the do-while chapter of
this tutorial.

While Loop with break and continue

In all the examples above, the while loop is designed to repeat for a number of times, or till a
certain condition is found. C has break and continue statements to control the loop. These
keywords can be used inside the while loop.

Example

The break statement causes a loop to terminate −

while (expr){
...
...
if (condition)
break;
...
}

Example

The continue statement makes a loop repeat from the beginning −

while (expr){
...
...
if (condition)
continue;
...
}

For Loop in C

Most programming languages including C support the for keyword for constructing a loop. In C,
the other loop-related keywords are while and do-while. Unlike the other two types, the for loop
is called an automatic loop, and is usually the first choice of the programmers.

The for loop is an entry-controlled loop that executes the statements till the given condition. All
the elements (initialization, test condition, and increment) are placed together to form a for
loop inside the parenthesis with the for keyword.

Syntax of for Loop

The syntax of the for loop in C programming language is −

for (init; condition; increment){


statement(s);
}

Control Flow of a For Loop

Here is how the control flows in a "for" loop −

The init step is executed first, and only once. This step allows you to declare and initialize any
loop control variables. You are not required to put a statement here, as long as a semicolon
appears.
Next, the condition is evaluated. If it is true, the body of the loop is executed. If it is false, the
body of the loop does not execute and the control jumps to the next statement just after the "for"
loop.

After the body of the "for" loop executes, the control flow jumps back up to the increment
statement. This statement allows you to update any loop control variables. This statement can be
left blank, as long as a semicolon appears after the condition.

The condition is now evaluated again. If it is true, the loop executes and the process repeats itself
(body of loop, then increment step, and then again the condition). After the condition becomes
false, the "for" loop terminates.

Flowchart of for Loop

The following flowchart represents how the for loop works −


Developers prefer to use for loops when they know in advance how many number of iterations
are to be performed. It can be thought of as a shorthand for while and do-while loops that
increment and test a loop variable.

The for loop may be employed with different variations. Let us understand how the for loop
works in different situations.

Example: Basic for Loop

This is the most basic form of the for loop. Note that all the three clauses inside the parenthesis
(in front of the for keyword) are optional.

#include <stdio.h>

int main(){
int a;

// for loop execution


for(a = 1; a <= 5; a++){
printf("a: %d\n", a);
}

return 0;
}

Output

Run the code and check its output −

a: 1
a: 2
a: 3
a: 4
a: 5

Initializing for Loop Counter Before Loop Statement

The initialization step can be placed above the header of the for loop. In that case, the init part
must be left empty by putting a semicolon.

Example
#include <stdio.h>

int main(){
int a = 1;

// for loop execution


for( ; a <= 5; a++){
printf("a: %d\n", a);
}
return 0;
}

Output

You still get the same output −

a: 1
a: 2
a: 3
a: 4
a: 5

Updating Loop Counter Inside for Loop Body

You can also put an empty statement in place of the increment clause. However, you need to put
the increment statement inside the body of the loop, otherwise it becomes an infinite loop.

Example

#include <stdio.h>

int main(){

int a;

// for loop execution


for(a = 1; a <= 5; ){
printf("a: %d\n", a);
a++;
}
return 0;
}

Output

Here too, you will get the same output as in the previous example −

a: 1
a: 2
a: 3
a: 4
a: 5

Using Test Condition Inside for Loop Body

You can also omit the second clause of the test condition in the parenthesis. In that case, you will
need to terminate the loop with a break statement, otherwise the loop runs infinitely.

Example

#include <stdio.h>

int main(){
int a;

// for loop execution


for(a = 1; ; a++){
printf("a: %d\n", a);
if(a == 5)
break;
}
return 0;
}

Output

On executing this code, you will get the following output −


a: 1
a: 2
a: 3
a: 4
a: 5

Using for Loops with Multiple Counters

There may be initialization of more than one variables and/or multiple increment statements in
a for statement. However, there can be only one test condition.

Example

#include <stdio.h>

int main(){
int a, b;

// for loop execution


for(a = 1, b = 1; a <= 5; a++, b++){
printf("a: %d b: %d a*b: %d\n", a, b, a*b);
}

return 0;
}

Output

When you run this code, it will produce the following output −

a: 1 b: 1 a*b: 1
a: 2 b: 2 a*b: 4
a: 3 b: 3 a*b: 9
a: 4 b: 4 a*b: 16
a: 5 b: 5 a*b: 25

Decrement in for Loop


You can also form a decrementing for loop. In this case, the initial value of the looping variable
is more than its value in the test condition. The last clause in the for statement uses decrement
operator.

Example

The following program prints the numbers 5 to 1, in decreasing order −

#include <stdio.h>
int main(){
int a;

// for loop execution


for(a = 5; a >= 1; a--){
printf("a: %d\n", a);
}

return 0;
}

Output

Run the code and check its output −

a: 5
a: 4
a: 3
a: 2
a: 1

Traversing Arrays with for Loops

For loop is well suited for traversal of one element of an array at a time. Note that each element
in the array has an incrementing index starting from "0".

Example

#include <stdio.h>

int main(){
int i;
int arr[] = {10, 20, 30, 40, 50};

// for loop execution


for(i = 0; i < 5; i++){
printf("a[%d]: %d\n", i, arr[i]);
}

return 0;
}

Output

When you run this code, it will produce the following output −

a[0]: 10
a[1]: 20
a[2]: 30
a[3]: 40
a[4]: 50

Example: Sum of Array Elements Using for Loop

The following program computes the average of all the integers in a given array.

#include <stdio.h>
int main(){
int i;
int arr[] = {10, 20, 30, 40, 50};
int sum = 0;
float avg;

// for loop execution


for(i=0; i<5; i++){
sum += arr[i];
}
avg = (float)sum / 5;
printf ("Average = %f", avg);
return 0;
}

Output

Run the code and check its output −

Average = 30.000000

Example: Factorial Using for Loop

The following code uses a for loop to calculate the factorial value of a number. Note that the
factorial of a number is the product of all integers between 1 and the given number. The factorial
is mathematically represented by the following formula −

x! = 1 * 2 * . . . * x

Here is the code for computing the factorial −

#include <stdio.h>

int main(){

int i, x = 5;
int fact = 1;

// for loop execution


for(i=1; i<= x; i++){
fact *= i;
}
printf("%d != %d", x, fact);

return 0;
}

Output

When you run this code, it will produce the following output −
5! = 120

The for loop is ideally suited when the number of repetitions is known. However, the looping
behaviour can be controlled by the break and continue keywords inside the body of
the for loop. Nested for loops are also routinely used in the processing of two
dimensional arrays.

Do-While Loop in C

The do-while loop is one of the most frequently used types of loops in C.
The do and while keywords are used together to form a loop. The do-while is an exit-verified
loop where the test condition is checked after executing the loop's body. Whereas
the while loop is an entry-verified. The for loop, on the other hand, is an automatic loop.

Syntax of do while Loop

The syntax of do-while loop in C is −

do {
statement(s);
} while(condition);

How do while Loop Works?

The loop construct starts with the keword do. It is then followed by a block of statements inside
the curly brackets. The while keyword follows the right curly bracket. There is a parenthesis in
front of while, in which there should be a Boolean expression.

Now let's understand how the while loop works. As the C compiler encounters the do keyword,
the program control enters and executes the code block marked by the curly brackets. As the end
of the code block is reached, the expression in front of the while keyword is evaluated.

If the expression is true, the program control returns back to the top of loop. If the expression is
false, the compiler stops going back to the top of loop block, and proceeds to the immediately
next statement after the block. Note that there is a semicolon at the end of while statement.

Flowchart of do while Loop

The following flowchart represents how the do-while loop works −


Since the expression that controls the loop is tested after the program runs the looping block for
the first time, the do-while loop is called an "exit-verified loop". Here, the key point to note is
that a do-while loop makes sure that the loop gets executed at least once.

The while keyword implies that the compiler continues to execute the ensuing block as long as
the expression is true. However, since the condition sits at the end of the looping construct, it is
checked after each iteration (rather than before each iteration as in the case of a while loop).

The program performs its first iteration unconditionally, and then tests the condition. If found to
be true, the compiler performs the next iteration. As soon as the expression is found to be false,
the loop body will be skipped and the first statement after the while loop will be executed.

Let us try to understand the behaviour of the while loop with a few examples.

Example of do while Loop

The following program prints the Hello world message five times.

#include <stdio.h>
int main(){

// local variable definition


int a = 1;

// while loop execution


do{
printf("Hello World\n");
a++;
} while(a <= 5);
printf("End of loop");

return 0;
}

Output

Here, the do-while loop acts as a counted loop. Run the code and check its output −

Hello World
Hello World
Hello World
Hello World
Hello World
End of loop

The variable "a" that controls the number of repetitions is initialized to 1. The program enters the
loop unconditionally, prints the message, increments "a" by 1.

As it reaches the end of the loop, the condition in the while statement is tested. Since the
condition "a <= 5" is true, the program goes back to the top of the loop and re-enters the loop.

Now "a" is 2, hence the condition is still true, hence the loop repeats again, and continues till the
condition turns false. The loop stops repeating, and the program control goes to the step after the
block.

Now, change the initial value of "a" to 10 and run the code again. It will produce the following
output −
Hello World
End of loop

This is because the program enters the looping block unconditionally. Since the condition before
the while keyword is false, hence the block is not repeated for the next time. Hence, the do-while
loop takes at least one iteration as the test condition is at the end of the loop. For this reason, do-
while loop is called an "exit-verified loop".

Difference Between while and do while Loops

The loops constructed with while and do-while appear similar. You can easily convert
a while loop into a do-while loop and vice versa. However, there are certain key differences
between the two.

The obvious syntactic difference is that the do-while construct starts with the do keyword and
ends with the while keyword. The while loop doesn't need the do keyword. Secondly, you find a
semicolon in front of while in case of a do-while loop. There is no semicolon in while loops.

Example

The location of the test condition that controls the loop is the major difference between the two.
The test condition is at the beginning of a while loop, whereas it is at the end in case of a do-
while loop. How does it affect the looping behaviour? Look at the following code −

#include <stdio.h>

int main(){

// local variable definition


int a = 0, b = 0;

// while loop execution


printf("Output of while loop: \n");

while(a < 5){


a++;
printf("a: %d\n", a);
}

printf("Output of do-while loop: \n");


do{
b++;
printf("b: %d\n",b);
} while(b < 5);

return 0;
}

Output

Initially, "a" and "b" are initialized to "0" and the output of both the loops is same.

Output of while loop:


a: 1
a: 2
a: 3
a: 4
a: 5

Output of do-while loop:


b: 1
b: 2
b: 3
b: 4
b: 5

Now change the initial value of both the variables to 3 and run the code again. There's no change
in the output of both the loops.

Output of while loop:


a: 4
a: 5

Output of do-while loop:


b: 4
b: 5
Now change the initial value of both the variables to 10 and run the code again. Here, you can
observe the difference between the two loops −

Output of while loop:

Output of do-while loop:


b: 11

Note that the while loop doesn't take any iterations, but the do-while executes its body once.
This is because the looping condition is verified at the top of the loop block in case of while, and
since the condition is false, the program doesn't enter the loop.

In case of do-while, the program unconditionally enters the loop, increments "b" to 11 and then
doesn't repeat as the condition is false. It shows that the do-while is guaranteed to take at least
one repetition irrespective of the initial value of the looping variable.

The do-while loop can be used to construct a conditional loop as well. You can also
use break and continue statements inside a do-while loop.

Nested Loops in C

In the programming context, the term "nesting" refers to enclosing a particular programming
element inside another similar element. For example, nested loops, nested structures, nested
conditional statements, etc.

Nested Loops

When a looping construct in C is employed inside the body of another loop, we call it a nested
loop (or, loops within a loop). Where, the loop that encloses the other loop is called the outer
loop. The one that is enclosed is called the inner loop.

General Syntax of Nested Loops

The general form of a nested loop is as follows −

Outer loop {
Inner loop {
...
...
}
...
}
C provides three keywords for loops formation − while, do-while, and for. Nesting can be done
on any of these three types of loops. That means you can put a while loop inside a for loop,
a for loop inside a do-while loop, or any other combination.

The general behaviour of nested loops is that, for each iteration of the outer loop, the inner loop
completes all the iterations.

Nested For Loops

Nested for loops are very common. If both the outer and inner loops are expected to perform
three iterations each, the total number of iterations of the innermost statement will be "3 * 3 = 9".

Example: Nested for Loop

Take a look at the following example −

#include <stdio.h>

int main(){

int i, j;

// outer loop
for(i = 1; i <= 3; i++){

// inner loop
for(j = 1; j <= 3; j++){
printf("i: %d j: %d\n", i, j);
}
printf("End of Inner Loop \n");
}
printf("End of Outer Loop");

return 0;
}

Output

When you run this code, it will produce the following output −
i: 1 j: 1
i: 1 j: 2
i: 1 j: 3
End of Inner Loop

i: 2 j: 1
i: 2 j: 2
i: 2 j: 3
End of Inner Loop

i: 3 j: 1
i: 3 j: 2
i: 3 j: 3
End of Inner Loop

End of Outer loop

Explanation of Nested Loop

Now let's analyze how the above program works. As the outer loop is encountered, "i" which is
the looping variable for the outer loop is initialized to 1. Since the test condition (a <= 3) is true,
the program enters the outer loop body.

The program reaches the inner loop, and "j" which is the variable that controls the inner loop is
initialized to 1. Since the test condition of the inner loop (j <= 3) is true, the program enters the
inner loop. The values of "a" and "b" are printed.

The program reaches the end of the inner loop. Its variable "j" is incremented. The control jumps
to step 4 until the condition (j <= 3) is true.

As the test condition becomes false (because "j" becomes 4), the control comes out of the inner
loop. The end of the outer loop is encountered. The variable "i" that controls the outer variable is
incremented and the control jumps to step 3. Since it is the start of the inner loop, "j" is again set
to 1.

The inner loop completes its iteration and ends again. Steps 4 to 8 will be repeated until the test
condition of the outer loop (i <= 3) becomes false. At the end of the outer loop, "i" and "j" have
become 4 and 4 respectively.

The result shows that, for each value of the outer looping variable, the inner looping variable
takes all the values. The total lines printed are "3 * 3 = 9".
Nesting a While Loop Inside a For Loop

Any type of loop can be nested inside any other type. Let us rewrite the above example by
putting a while loop inside the outer for loop.

Example: Nested Loops (while Loop Inside for Loop)

Take a look at the following example −

#include <stdio.h>

int main(){

int i, j;

// outer for loop


for (i = 1; i <= 3; i++){

// inner while loop


j = 1;
while (j <= 3){
printf("i: %d j: %d\n", i, j);
j++;
}
printf("End of Inner While Loop \n");
}
printf("End of Outer For loop");

return 0;
}

Output

i: 1 j: 1
i: 1 j: 2
i: 1 j: 3
End of Inner While Loop
i: 2 j: 1
i: 2 j: 2
i: 2 j: 3
End of Inner While Loop

i: 3 j: 1
i: 3 j: 2
i: 3 j: 3
End of inner while Loop

End of outer for loop

Programmers use nested loops in a lot of applications. Let us take a look at some more examples
of nested loops.

C Nested Loops Examples

Example: Printing Tables

The following program prints the tables of 1 to 10 with the help of two nested for loops.

#include <stdio.h>

int main(){

int i, j;
printf("Program to Print the Tables of 1 to 10 \n");

// outer loop
for(i = 1; i <= 10; i++){

// inner loop
for(j = 1; j <= 10; j++){
printf("%4d", i*j);
}
printf("\n");
}
return 0;
}

Output

Run the code and check its output −

Program to Print the Tables of 1 to 10


1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100

Example: Printing Characters Pyramid

The following code prints the increasing number of characters from a string.

#include <stdio.h>
#include <string.h>

int main(){

int i, j, l;
char x[] = "TutorialsPoint";
l = strlen(x);

// outer loop
for(i = 0; i < l; i++){

// inner loop
for(j = 0; j <= i; j++){
printf("%c", x[j]);
}
printf("\n");
}
return 0;
}

Output

When you run this code, it will produce the following output −

T
Tu
Tut
Tuto
Tutor
Tutori
Tutoria
Tutorial
Tutorials
TutorialsP
TutorialsPo
TutorialsPoi
TutorialsPoin
TutorialsPoint

Example: Printing Two-Dimensional Array

In this program, we will show how you can use nested loops to display a two-dimensional
array of integers. The outer loop controls the row number and the inner loop controls the
columns.

#include <stdio.h>

int main(){

int i, j;
int x[4][4] = {
{1, 2, 3, 4},
{11, 22, 33, 44},
{9, 99, 999, 9999},
{10, 20, 30, 40}
};

// outer loop
for (i=0; i<=3; i++){

// inner loop
for(j=0; j <= 3; j++){
printf("%5d", x[i][j]);
}
printf("\n");
}
return 0;
}

Output

When you run this code, it will produce the following output −

1 2 3 4
11 22 33 44
9 99 999 9999
10 20 30 40
C - Infinite Loop

In C language, an infinite loop (or, an endless loop) is a never-ending looping construct that
executes a set of statements forever without terminating the loop. It has a true condition that
enables a program to run continuously.

Flowchart of an Infinite Loop

If the flow of the program is unconditionally directed to any previous step, an infinite loop is
created, as shown in the following flowchart −
An infinite loop is very rarely created intentionally. In case of embedded headless systems and
server applications, the application runs in an infinite loop to listen to the client requests. In other
circumstances, infinite loops are mostly created due to inadvertent programming errors.

How to Create an Infinite Loop in C?

To create an infinite loop, you need to use one of the loop constructs (while, do while, or for)
with a non-zero value as a test condition. Generally, 1 is used as the test condition, you can use
any non-zero value. A non-zero value is considered as true.

Example

#include <stdio.h>

int main() {
while (1)
{
printf("Hello World");
}

return 0;
}
Hello WorldHello WorldHello WorldHello WorldHello WorldHello World
Hello WorldHello WorldHello WorldHello WorldHello WorldHello World
Hello WorldHello WorldHello ...
Types of Infinite Loops in C

In C language, infinite while, infinite do while, and infinite for are the three infinite loops. These
loops execute the code statement continuously. Let us understand the implementation of infinite
loops using all loop constructs.

Infinite While Loop

The while keyword is used to form a counted loop. The loop is scheduled to repeat till the value
of some variable successively increments to a predefined value. However, if the programmer
forgets to put the increment statement within the loop body, the test condition doesn’t arrive at
all, hence it becomes endless or infinite.

Example 1

Take a look at the following example −

#include <stdio.h>

// infinite while loop


int main(){

int i = 0;
while (i <= 10){
// i++;
printf("i: %d\n", i);
}
return 0;
}

Output

Since the increment statement is commented out here, the value of "i" continues to remain "0",
hence the output shows "i: 0" continuously until you forcibly stop the execution.

i: 0
i: 0
i: 0
...
...
Example 2

The parenthesis of while keyword has a Boolean expression that initially evaluates to True, and
is eventually expected to become False. Note that any non-zero number is treated as True in C.
Hence, the following while loop is an infinite loop:

#include <stdio.h>

// infinite while loop


int main(){

while(1){
printf("Hello World \n");
}
return 0;
}

Output

It will keep printing "Hello World" endlessly.

Hello World
Hello World
Hello World
...
...

The syntax of while loop is as follows −

while (condition){
...
...
}

Note that the there is no semicolon symbol in front of while, indicating that the following code
block (within the curly brackets) is the body of the loop. If we place a semicolon, the compiler
treats this as a loop without body, and hence the while condition is never met.

Example 3
In the following code, an increment statement is put inside the loop block, but because of the
semicolon in front of while, the loop becomes infinite.

#include <stdio.h>

// infinite while loop


int main(){

int i = 0;
while(i < 10);{
i++;
printf("Hello World \n");
}
return 0;
}

Output

When the program is run, it won't print the message "Hello World". There is no output because
the while loop becomes an infinite loop with no body.

Infinite For Loop

The for loop in C is used for performing iteration of the code block for each value of a variable
from its initial value to the final value, incrementing it on each iteration.

Take a look at its syntax −

for (initial val; final val; increment){


...
...
}

Example 1

Note that all the three clauses of the for statement are optional. Hence, if the middle clause that
specifies the final value to be tested is omitted, the loop turns infinite.

#include <stdio.h>
// infinite for loop
int main(){

int i;
for(i=1; ; i++){
i++;
printf("Hello World \n");
}
return 0;
}

Output

The program keeps printing Hello World endlessly until you stop it forcibly, because it has no
effect of incrementing "i" on each turn.

Hello World
Hello World
Hello World
...
...

You can also construct a for loop for decrementing the values of a looping variable. In that case,
the initial value should be greater than the final test value, and the third clause in for must be a
decrement statement (using the "--" operator).

If the initial value is less than the final value and the third statement is decrement, the loop
becomes infinite. The loop still becomes infinite if the initial value is larger but you mistakenly
used an increment statement.

Hence, both the for loops result in an infinite loop.

Example 2

Take a look at the following example −

#include <stdio.h>

int main(){
// infinite for loop
for(int i = 10; i >= 1; i++){
i++;
printf("Hello World \n");
}
}

Output

The program will print a series of "Hello World" in an infinite loop −

Hello World
Hello World
Hello World
...
...

Example 3

Take a look at the following example −

#include <stdio.h>

int main(){

// infinite for loop


for(int i = 1; i <= 10 ; i--){
i++;
printf("Hello World \n");
}
}

Output

The program keeps printing "Hello World" in a loop −

Hello World
Hello World
Hello World
...
...

Example 4

If all the three statements in the parenthesis are blank, the loop obviously is an infinite loop, as
there is no condition to test.

#include <stdio.h>

int main(){

int i;

// infinite for loop


for ( ; ; ){
i++;
printf("Hello World \n");
}
}

Output

The program prints "Hello World" in an endless loop −

Hello World
Hello World
Hello World
...
...

Infinite Do While Loop

An infinite loop can also be implemented using the do-while loop construct. You have to use 1 as
the test condition with the while.

Example

The following example demonstrates an infinite loop using do while:


#include <stdio.h>

int main() {
do
{
printf("Hello World\n");
} while (1);

return 0;
}
Hello World
Hello World
Hello World
Hello World
...
...

How to Break an Infinite Loop in C?

There may be certain situations in programming where you need to start with an
unconditional while or for statement, but then you need to provide a way to terminate the loop
by placing a conditional break statement.

Example

In the following program, there is no test statement in for, but we used a break statement to
make it a finite loop.

#include <stdio.h>

int main(){

// infinite while loop


for(int i = 1; ; ){
i++;
printf("Hello World \n");

if(i == 5)
break;
}
return 0;
}

Output

The program prints "Hello World" till the counter variable reaches [Link] World

Hello World
Hello World
Hello World

How to Stop an Infinite Loop Forcefully in C?

When the program enters an infinite loop, it doesn’t stop on its own. It has to be forcibly
stopped. This is done by pressing "Crtrl + C" or "Ctrl + Break" or any other key combination
depending on the operating system.

Example

The following C program enters in an infinite loop −

#include <stdio.h>

int main(){

// local variable definition


int a = 0;

// do loop execution
LOOP:
a++;
printf("a: %d\n", a);
goto LOOP;

return 0;
}

Output
When executed, the above program prints incrementing values of "a" from 1 onwards, but it
doesn’t stop. It will have to be forcibly stopped by pressing "Ctrl + Break" keys.

a: 1
a: 2
...
...
a: 10
a: 11
...
...

Infinite loops are mostly unintentionally created as a result of programming bug. Even if the
looping keyword doesn’t specify the termination condition, the loop has to be terminated with
the break keyword.
Break Statement in C

The break statement in C is used in two different contexts. In switch-case, break is placed as the
last statement of each case block. The break statement may also be employed in the body of any
of the loop constructs (while, do–while as well as for loops).

When used inside a loop, break causes the loop to be terminated. In the switch-case
statement, break takes the control out of the switch scope after executing the
corresponding case block.

Flowchart of Break Statement in C

The flowchart of break in loop is as follows −

The following flowchart shows how to use break in switch-case −


In both the scenarios, break causes the control to be taken out of the current scope.

Break Statements in While Loops

The break statement is never used unconditionally. It always appears in the True part of
an if statement. Otherwise, the loop will terminate in the middle of the first iteration itself.

while(condition1){
...
...
if(condition2)
break;
...
...
}

Example of break Statement with while Loop


The following program checks if a given number is prime or not. A prime number is not divisible
by any other number except itself and 1.

The while loop increments the divisor by 1 and tries to check if it is divisible. If found divisible,
the while loop is terminated.

#include <stdio.h>

/*break in while loop*/


int main () {

int i = 2;
int x = 121;
printf("x: %d\n", x);

while (i < x/2){


if (x % i == 0)
break;
i++;
}
if (i >= x/2)
printf("%d is prime", x);
else
printf("%d is not prime", x);

return 0;
}

Output

On executing this code, you will get the following output −

x: 121
121 is not prime

Now, change the value of "x" to 25 and run the code again. It will produce the following output

x: 25
25 is not prime

Break Statements in For Loops

You can use a break statement inside a for loop as well. Usually, a for loop is designed to
perform a certain number of iterations. However, sometimes it may be required to abandon the
loop if a certain condition is reached.

The usage of break in for loop is as follows −

for (init; condition; increment) {


...
if (condition)
break;
...
}

Example of break Statement with for Loop

The following program prints the characters from a given string before a vowel (a, e, I, or u) is
detected.

#include <stdio.h>
#include <string.h>

int main () {

char string[] = "Rhythmic";


int len = strlen(string);
int i;

for (i = 0; i < len; i++){


if (string[i] == 'a' || string[i] == 'e' || string[i] == 'i' || string[i] == 'o' || string[i] == 'u')
break;
printf("%c\n", string[i]);
}

return 0;
}
Output

Run the code and check its output −

R
h
y
t
h
m

If break appears in an inner loop of a nested loop construct, it abandons the inner loop and
continues the iteration of the outer loop body. For the next iteration, it enters the inner loop
again, which may be broken again if the condition is found to be true.

Example of break Statement with Nested for Loops

In the following program, two nested loops are employed to obtain a list of all the prime numbers
between 1 to 30. The inner loop breaks out when a number is found to be divisible, setting the
flag to 1. After the inner loop, the value of flag is checked. If it is "0", the number is a prime
number.

#include <stdio.h>

int main(){
int i, num, n, flag;
printf("The prime numbers in between the range 1 to 30:\n");

for(num = 2; num <= 30; num++){


flag = 0;
for(i = 2; i <= num/2; i++){
if(num % i == 0){
flag++;
break;
}
}
if(flag == 0)
printf("%d is prime\n",num);
}
return 0;
}

Output

2 is prime
3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
23 is prime
29 is prime

Break Statement in an Infinite Loop

An infinite loop is rarely created intentionally. However, in some cases, you may start an infinite
loop and break from it when a certain condition is reached.

Example of break Statement with Infinite Loop

In the following program, an infinite for loop is used. On each iteration, a random number
between 1 to 100 is generated till a number that is divisible by 5 is obtained.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(){
int i, num;
printf ("Program to get the random number from 1 to 100: \n");

srand(time(NULL));

for (; ; ){
num = rand() % 100 + 1; // random number between 1 to 100
printf (" %d\n", num);
if (num%5 == 0)
break;

}
}

Output

On running this code, you will get an output like the one shown here −

Program to get the random number from 1 to 100:


6
56
42
90

Break Statements in Switch Case

To transfer the control out of the switch scope, every case block ends with a break statement. If
not, the program falls through all the case blocks, which is not desired.

Example of break Statement with switch

In the following code, a series of if-else statements print three different greeting messages based
on the value of a "ch" variable ("m", "a" or "e" for morning, afternoon or evening).

#include <stdio.h>

int main(){

/* local variable definition */


char ch = 'm';
printf("Time code: %c\n\n", ch);

switch(ch) {

case 'm':
printf("Good Morning \n");
break;

case 'a':
printf("Good Afternoon \n");
break;

case 'e':
printf("Good Evening \n");
break;

default:
printf("Hello");
}
}

Output

Here, the break statement breaks the program execution after checking the first case.

Time code: m

Good Morning

Now, comment the break statements and run the code again. You will now get the following
output −

Time code: m

Good Morning
Good Afternoon
Good Evening
Hello
Continue Statement in C

The behaviour of continue statement in C is somewhat opposite to the break statement. Instead
of forcing the termination of a loop, it forces the next iteration of the loop to take place, skipping
the rest of the statements in the current iteration.

What is Continue Statement in C?

The continue statement is used to skip the execution of the rest of the statement within the loop
in the current iteration and transfer it to the next loop iteration. It can be used with all the C
language loop constructs (while, do while, and for).

Continue Statement Syntax

The continue statement is used as per the following structure −

while (expr){
...
...
if (condition)
continue;
...
}

Continue Statement Flowchart

The following flowchart represents how continue works −


You must use the continue statement inside a loop. If you use a continue statement outside a
loop, then it will result in compilation error. Unlike the break statement, continue is not used
with the switch-case statement.

Continue Statement with Nested Loops

In case of nested loops, continue will continue the next iteration of the nearest loop.
The continue statement is often used with if statements.

Continue Statement Examples

Example: Continue Statement with While Loop

In this program the loop generates 1 to 10 values of the variable "i". Whenever it is an even
number, the next iteration starts, skipping the printf statement. Only the odd numbers are printed.

#include <stdio.h>

int main(){
int i = 0;

while (i < 10){


i++;
if(i%2 == 0)
continue;
printf("i: %d\n", i);

}
}

Output

i: 1
i: 3
i: 5
i: 7
i: 9

Example: Continue Statement with For Loop

The following program filters out all the vowels in a string −

#include <stdio.h>
#include <string.h>

int main () {

char string[] = "Welcome to TutorialsPoint C Tutorial";


int len = strlen(string);
int i;

printf("Given string: %s\n", string);


printf("after removing the vowels\n");

for (i=0; i<len; i++){


if (string[i]=='a' || string[i]=='e' || string[i] == 'i' || string[i] == 'o' || string[i] == 'u')
continue;
printf("%c", string[i]);
}

return 0;
}

Output

Run the code and check its output −

Given string: Welcome to TutorialsPoint C Tutorial


after removing the vowels
Wlcm t TtrlsPnt C Ttrl

Example: Continue Statement with Nested Loops

If a continue statement appears inside an inner loop, the program control jumps to the beginning
of the corresponding loop.

In the example below, there are three for loops one inside the other. These loops are controlled
by the variables i, j, and k respectively. The innermost loop skips the printf statement if k is
equal to either i or j, and goes to its next value of k. The second j loop executes
the continue when it equals i. As a result, all the unique combinations of three digits 1, 2 and 3
are displayed.

#include <stdio.h>

int main (){

int i, j, k;

for(i = 1; i <= 3; i++){

for(j = 1; j <= 3; j++){


if (i == j)
continue;

for (k=1; k <= 3; k++){


if (k == j || k == i)
continue;

printf("%d %d %d \n", i,j,k);


}
}
}
return 0;
}

Output

Run the code and check its output −

123
132
213
231
312
321

Example: Removing Spaces Between Words in a String

The following code detects the blankspaces between the words in a string, and prints each word
on a different line.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main(){

char string[] = "Welcome to TutorialsPoint C Tutorial";


int len = strlen(string);
int i;

printf("Given string: %s\n", string);

for (i = 0; i < len; i++){


if (string[i] == ' '){
printf("\n");
continue;
}
printf("%c", string[i]);
}
return 0;
}

Output

On executing this code, you will get the following output −

Given string: Welcome to TutorialsPoint C Tutorial


Welcome
to
TutorialsPoint
C
Tutorial

Example: Finding Prime Factors of a Number

One of the cases where the continue statement proves very effective is in the problem of writing
a program to find prime factors of a given number.

The algorithm of this program works like this −

The given number is successively divided by numbers starting with 2. If the number is divisible,
the given number is reduced to the division, and the resultant number is checked for divisibility
with 2 until it is no longer divisible.

If not by 2, the process is repeated for all the odd numbers starting with 3. The loop runs while
the given number reduces to 1.

Here’s the program to find the prime factors −

#include <stdio.h>

int main (){


int n = 64;
int i, m = 2;

printf("Prime factors of %d: \n", n);


while (n > 1){
if (n % m == 0){
n = n/m;
printf("%d ", m);
continue;
}
if (m == 2)
m++;
else
m = m+2;
}
return 0;
}

Output

Here, the given number is 64. So, when you run this code, it will produce the following output −

Prime factors of 64:


222222

Change the number to 45 and then 90. Run the code again. Now you will get the following
outputs −

Prime factors of 45:


335

Prime factors of 90:


2335
Goto Statement in C

What is goto Statement in C?

The goto statement is used to transfer the program's control to a defined label within the
same function. It is an unconditional jump statement that can transfer control forward or
backward.

The goto keyword is followed by a label. When executed, the program control is redirected to
the statement following the [Link] the label points to any of the earlier statements in a code, it
constitutes a loop. On the other hand, if the label refers to a further step, it is equivalent to a
Jump.

goto Statement Syntax

The syntax of goto statement is −

goto label;
...
...
label: statement;

The label is any valid identifier in C. A label must contain alphanumeric characters along with
the underscore symbol (_). As in case of any identifier, the same label cannot be specified more
than once in a program. It is always followed by a colon (:) symbol. The statement after this
colon is executed when goto redirects the program here.

goto Statement Flowchart

The following flowchart represents how the goto statement works −

goto Statement Examples

Example 1
In the following program, the control jumps to a given label which is after the current statement.
It prints a given number, before printing the end of the program message. If it is "0", it jumps
over to the printf statement, displaying the message.

#include <stdio.h>

int main (){


int n = 0;

if (n == 0)
goto end;
printf("The number is: %d", n);

end:
printf ("End of program");

return 0;
}

Output

Run the code and check its output −

End of program

Example 2

Here is a program to check if a given number is even or odd. Observe how we used
the goto statement in this program −

#include <stdio.h>

int main (){

int i = 11;
if (i % 2 == 0){
EVEN:
printf("The number is even \n");
goto END;
}
else{
ODD:
printf("The number is odd \n");
}
END:
printf("End of program");

return 0;
}

Output

Since the given number is 11, it will produce the following output −

The number is odd


End of program

Change the number and check the output for different numbers.

Example 3

If goto appears unconditionally and it jumps backwards, an infinite loop is created.

#include <stdio.h>

int main (){


START:
printf("Hello World \n");
printf("How are you? \n");
goto START;
return 0;
}

Output

Run the code and check its output −

Hello World
How are you?
.......
.......

The program prints the two strings continuously until forcibly stopped.

Example 4

In this program, we have two goto statements. The second goto statement forms a loop because
it makes a backward jump. The other goto statement jumps out of the loop when the condition is
reached.

#include <stdio.h>
int main(){
int i = 0;
START:
i++;
printf("i: %d\n", i);
if (i == 5)
goto END;
goto START;
END:
printf("End of loop");
return 0;
}

Output

Run the code and check its output −

i: 1
i: 2
i: 3
i: 4
i: 5
End of loop

Example 5
The goto statement is used here to skip all the values of a looping variable that matches with that
of others. As a result, all the unique combinations of 1, 2 and 3 are obtained.

#include <stdio.h>

int main (){

int i, j, k;

for(i = 1; i <= 3; i++){

for(j = 1; j <= 3; j++){


if (i == j)
goto label1;

for (k = 1; k <= 3; k++){


if (k == j || k == i)
goto label2;

printf("%d %d %d \n", i,j,k);

label2: ;
}
label1: ;
}
}
return 0;
}

Output

Run the code and check its output −

123
132
213
231
312
321

Avoid Using the goto Statement in C

Note that goto in C is considered unstructured, as it allows the program to jump to any location
in the code, it can make the code hard to understand, follow, and maintain. Too many goto
statements sending the program control back and forth can make the program logic difficult to
understand.

Noted computer scientist dsger Dijkstra recommended that goto be removed from all the
programming languages. He observed that if the program control jumps in the middle of a loop,
it may yield unpredictable behaviour. The goto statements can be used to create programs that
have multiple entry and exit points, which can make it difficult to track the flow of control of the
program.

Dijkstra's strong observations against the use of goto statement have been influential, as many
mainstream languages do not support goto statements. However, it is still available in some
languages, such as C and C++.

In general, it is best to avoid using goto statements in C. You can instead effectively use if-
else statements, loops and loop controls, function and subroutine calls, and try-catch-throw
statements. Use goto if and only if these alternatives don’t fulfil the needs of your algorithm.

Functions in C

A function in C is a block of organized reusuable code that is performs a single related action.
Every C program has at least one function, which is main(), and all the most trivial programs can
define additional functions.

When the algorithm of a certain problem involves long and complex logic, it is broken into
smaller, independent and reusable blocks. These small blocks of code are known by different
names in different programming languages such as a module, a subroutine, a function or
a method.

You can divide up your code into separate functions. How you divide up your code among
different functions is up to you, but logically the division is such that each function performs a
specific task.

A function declaration tells the compiler about a function's name, return type, and parameters. A
function definition provides the actual body of the function.

The C standard library provides numerous built-in functions that your program can call. For
example, strcat() to concatenate two strings, memcpy() to copy one memory location to another
location, and many more functions.
Modular Programming in C

Functions are designed to perform a specific task that is a part of an entire process. This
approach towards software development is called modular programming.

Modular programming takes a top-down approach towards software development. The


programming solution has a main routine through which smaller independent modules
(functions) are called upon.

Each function is a separate, complete and reusable software component. When called, a function
performs a specified task and returns the control back to the calling routine, optionally along
with result of its process.

The main advantage of this approach is that the code becomes easy to follow, develop and
maintain.

Library Functions in C

C offers a number of library functions included in different header files. For example,
the stdio.h header file includes printf() and scanf() functions. Similarly, the math.h header file
includes a number of functions such as sin(), pow(), sqrt() and more.

These functions perform a predefined task and can be called upon in any program as per
requirement. However, if you don't find a suitable library function to serve your purpose, you
can define one.

Defining a Function in C

In C, it is necessary to provide the forward declaration of the prototype of any function. The
prototype of a library function is present in the corresponding header file.

For a user-defined function, its prototype is present in the current program. The definition of a
function and its prototype declaration should match.

After all the statements in a function are executed, the flow of the program returns to the calling
environment. The function may return some data along with the flow control.

Function Declarations in C

A function declaration tells the compiler about a function name and how to call the function.
The actual body of the function can be defined separately.

A function declaration has the following parts −

return_type function_name(parameter list);


For the above defined function max(), the function declaration is as follows −

int max(int num1, int num2);

Parameter names are not important in function declaration only their type is required, so the
following is also a valid declaration −

int max(int, int);

A function declaration is required when you define a function in one source file and you call that
function in another file. In such cases, you should declare the function at the top of the file
calling the function.

Parts of a Function in C

The general form of a function definition in C programming language is as follows −

return_type function_name(parameter list){

body of the function


}

A function definition in C programming consists of a function header and a function body. Here
are all the parts of a function −

 Return Type − A function may return a value. The return_type is the data type of the value
the function returns. Some functions perform the desired operations without returning a
value. In this case, the return_type is the keyword void.
 Function Name − This is the actual name of the function. The function name and the
parameter list together constitute the function signature.
 Argument List − An argument (also called parameter) is like a placeholder. When a
function is invoked, you pass a value as a parameter. This value is referred to as the actual
parameter or argument. The parameter list refers to the type, order, and number of the
parameters of a function. Parameters are optional; that is, a function may contain no
parameters.
 Function Body − The function body contains a collection of statements that defines what
the function does.

A function in C should have a return type. The type of the variable returned by the function must
be the return type of the function. In the above figure, the add() function returns an int type.

Example: User-defined Function in C


In this program, we have used a user-defined function called max(). This function takes two
parameters num1 and num2 and returns the maximum value between the two −

#include <stdio.h>

/* function returning the max between two numbers */


int max(int num1, int num2){

/* local variable declaration */


int result;

if(num1 > num2)


result = num1;
else
result = num2;

return result;
}

int main(){
printf("Comparing two numbers using max() function: \n");
printf("Which of the two, 75 or 57, is greater than the other? \n");
printf("The answer is: %d", max(75, 57));

return 0;
}

Output

When you runt this code, it will produce the following output −

Comparing two numbers using max() function:


Which of the two, 75 or 57, is greater than the other?
The answer is: 75

Calling a Function in C
While creating a C function, you give a definition of what the function has to do. To use a
function, you will have to call that function to perform the defined task.

To call a function properly, you need to comply with the declaration of the function prototype. If
the function is defined to receive a set of arguments, the same number and type of arguments
must be passed.

When a function is defined with arguments, the arguments in front of the function name are
called formal arguments. When a function is called, the arguments passed to it are the actual
arguments.

When a program calls a function, the program control is transferred to the called function. A
called function performs a defined task and when its return statement is executed or when its
function-ending closing brace is reached, it returns the program control back to the main
program.

Example: Calling a Function

To call a function, you simply need to pass the required parameters along with the function
name. If the function returns a value, then you can store the returned value. Take a look at the
following example −

#include <stdio.h>

/* function declaration */
int max(int num1, int num2);

int main (){

/* local variable definition */


int a = 100;
int b = 200;
int ret;

/* calling a function to get max value */


ret = max(a, b);

printf( "Max value is : %d\n", ret );

return 0;
}
/* function returning the max between two numbers */
int max(int num1, int num2){

/* local variable declaration */


int result;

if (num1 > num2)


result = num1;
else
result = num2;

return result;
}

Output

We have kept max() along with main() and compiled the source code. While running the final
executable, it would produce the following result −

Max value is : 200

The main() Function in C

A C program is a collection of one or more functions, but one of the functions must be named
as main(), which is the entry point of the execution of the program.

From inside the main() function, other functions are called. The main() function can call a library
function such as printf(), whose prototype is fetched from the header file (stdio.h) or any other
user-defined function present in the code.

In C, the order of definition of the program is not material. In a program, wherever there is
main(), it is the entry point irrespective of whether it is the first function or not.

Note: In C, any function can call any other function, any number of times. A function can call
itself too. Such a self-calling function is called a recursive function.

Function Arguments

If a function is to use arguments, it must declare variables that accept the values of the
arguments. These variables are called the formal parameters of the function.
Formal parameters behave like other local variables inside the function and are created upon
entry into the function and destroyed upon exit.

While calling a function, there are two ways in which arguments can be passed to a function −

[Link] Call Type & Description

Call by value
This method copies the actual value of an argument into the
1
formal parameter of the function. In this case, changes made to
the parameter inside the function have no effect on the argument.

Call by reference
This method copies the address of an argument into the formal
2 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 affect the argument.

By default, C uses call by value to pass arguments. In general, it means the code within a
function cannot alter the arguments used to call the function.

C - Main Function

In a C program, the main() function is the entry point. The program execution starts with
the main() function. It is designed to perform the main processing of the program and clean up
any resources that were allocated by the program. In a C code, there may be any number of
functions, but it must have a main() function. Irrespective of its place in the code, it is the first
function to be executed.

Syntax of C main() Function

The following is the syntax of the main() function in C language −

int main(){
//one or more statements;
return 0;
}

Syntax Explained

As a part of its syntax, a function has a name that follows the rules of forming an identifier
(starting with an alphabet or underscore and having alphabet, digit or underscore). The name is
followed by a parenthesis. Typically, the main() function is defined with no arguments, although
it may have argv and argv argument to receive values from the command line.
Valid Signatures of C main() Function

The signatures (prototype) of a main() function may be −

int main() {
..
return 0;
}

Or

int main(void){
..
return 0;
}

Or

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


..
return 0;
}

Example of C main() Function

The following example demonstrates the main() function:

#include <stdio.h>

int main() {
// Write code from here
printf("Hello World");
return 0;
}

Important Points about C main() Function

 A C program must have a main() function.


 The main is not aC keyword.
It is classified as a user-defined function because its body is not pre−decided, it depends
on the processing logic of the program.
By convention, int is the return type of main(). The last statement in the function body
of main() returns 0, to indicate that the function has been successfully executed. Any
non−zero return value indicates failure.
 Some old C compilers let you define main() function with void return type.
 However, this is considered to be non−standard and is not recommended.
 As compared to other functions, the main() function:
o Can't be declared as inline.
o Can't be declared as static.
o Can't have its address taken.
o Can't be called from your program.

How does main() Works in C?

The program's execution starts from the main() function as it is an entry point of the program, it
starts executing the statements written inside it. Other functions within the source program are
defined to perform certain task. The main function can call any of these functions. When main
calls another function, it passes execution control to the function, optionally passing the requisite
number and type of arguments, so that execution begins at the first statement in the called
function. The called function returns control to main when a return statement is executed or
when the end of the function is reached. Note that return statement is implicitly present as the
last statement when its return type is int.

A program usually stops executing when it returns from or reaches the end of main, although it
can terminate at other points in the program for various reasons. For example, you may want to
force the termination of your program when some error condition is detected. To do so, you can
use the exit function.

The exit() in C main() Function

The C exit() function is a standard library function used to terminate the calling process. Use
exit(0) to indicate no error, and exit(1) to indicate that the program is exiting with because of an
error encountered.

Example: Using exit() in the main() Function

#include <stdio.h>
#include <stdlib.h>

int add(int, int);

int main (){


int i;
for ( i = 1; i<=5; i++){
if ( i == 3 ){
printf (" \n exiting ..");
exit(0);
}
else

printf (" \n Number is %d", i);


}

return 0;
}

Output

Number is 1
Number is 2
exiting ..

Command-line Arguments with main() in C

Typically, the main() function is defined without any arguments. However, you may define
main() with arguments to let it accept the values from the command line. In this type of usage,
main() function is defined as follows −

Syntax

The following is the syntax of main() function with command-line arguments:

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


..
return 0;
}

Argument Definitions

The argument definitions are as follows −

argc − The first argument is an integer that contains the count of arguments that follow in argv.
The argc parameter is always greater than or equal to 1.
argv − The second argument is an array of null−terminated strings representing command-line
arguments entered by the user of the program. By convention, argv[0] is the command with
which the program is invoked. argv[1] is the first command−line argument. The last argument
from the command line is argv[argc − 1], and argv[argc] is always NULL.

Example: Using main() Function with Command-line Arguments

Consider the following program to understand command−line arguments.

#include <stdio.h>
#include <stdlib.h>

int add(int, int);

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


int x, y, z;

if (argc<3){
printf("insufficient arguments");
}
else{
x = atoi(argv[1]);
y = atoi(argv[2]);
z = x+y;
printf("addition : %d", z);
}
return 0;
}

Just compile and build the program as test.c, don’t run from the IDE in which you have edited
and compiled. Go to the command prompt and run the program as follows −

C:\Users\mlath>test 10 20
addition : 30

In this chapter, we learned the importance and syntax of defining a main() function in C. Any C
program must have a main() function. As a convention it should return 0 to indicate successful
execution. You can also define arguments to a main() function, they can be passed from the
command−line.
Function Call by Value in C

In C language, a function can be called from any other function, including itself. There are two
ways in which a function can be called − (a) Call by Value and (b) Call by Reference. By
default, the Call by Value mechanism is employed.

Formal Arguments and Actual Arguments

You must know the terminologies to understand how the call by value method works −

Formal arguments − A function needs certain data to perform its desired process. When a
function is defined, it is assumed that the data values will be provided in the form of parameter
or argument list inside the parenthesis in front of the function name. These arguments are the
variables of a certain data type.

Actual arguments − When a certain function is to be called, it should be provided with the
required number of values of the same type and in the same sequence as used in its definition.

Take a look at the following snippet −

type function_name(type var1, type var2, ...)

Here, the argument variables are called the formal arguments. Inside the function’s scope, these
variables act as its local variables.

Consider the following function −

int add(int x, int y){

int z = x + y;

return z;

The arguments x and y in this function definition are the formal arguments.

Example: Call by Value in C

If the add() function is called, as shown in the code below, then the variables inside the
parenthesis (a and b) are the actual arguments. They are passed to the function.
Take a look at the following example −

#include <stdio.h>

int add(int x, int y){

int z = x + y;

return z;
}

int main(){

int a = 10, b = 20;

int c = add(a, b);

printf("Addition: %d", c);


}

Output

When you run this code, it will produce the following output −

Addition: 30

The Call by Value method implies that the values of the actual arguments are copied in the
formal argument variables. Hence, "x" takes the value of "a" and "b" is assigned to "y". The local
variable "z" inside the add() function stores the addition value. In the main() function, the value
returned by the add() function is assigned to "c", which is printed.

Note that a variable in C language is a named location in the memory. Hence, variables are
created in the memory and each variable is assigned a random memory address by the compiler.

How Does "Call by Value" Work in C?

Let us assume that the variables a, b and c in the main() function occupy the memory locations
100, 200 and 300 respectively. When the add() function is called with a and b as actual
arguments, their values are stored in x and y respectively.
The variables x, y, and z are the local variables of the add() function. In the memory, they will be
assigned some random location. Let's assume that they are created in memory address 1000,
2000 and 3000, respectively.

Since the function is called by copying the value of the actual arguments to their corresponding
formal argument variables, the locations 1000 and 2000 which are the address of x and y will
hold 10 and 20, respectively. The compiler assigns their addition to the third local
variable z which is returned.

As the control comes back to the main() function, the returned data is assigned to c, which is
displayed as the output of the program.

Example

Call by Value is the default function calling mechanism in C. It eliminates a function’s potential
side effects, making your software simpler to maintain and easy to understand. It is best suited
for a function expected to do a certain computation on the argument received and return the
result.

Here is another example of Call by Value −

#include <stdio.h>

/* function declaration */
void swap(int x, int y);

int main(){
/* local variable definition */
int a = 100;
int b = 200;

printf("Before swap, value of a: %d\n", a);


printf("Before swap, value of b: %d\n", b);

/* calling a function to swap the values */


swap(a, b);

printf("After swap, value of a: %d\n", a);


printf("After swap, value of b: %d\n", b);

return 0;
}

void swap(int x, int y){

int temp;

temp = x; /* save the value of x */


x = y; /* put y into x */
y = temp; /* put temp into y */

return;
}

Output

When you run this code, it will produce the following output −

Before swap, value of a: 100


Before swap, value of b: 200
After swap, value of a: 100
After swap, value of b: 200
It shows that there are no changes in the values, although they had been changed inside the
function.

Since the values are copied in different local variables of another function, any manipulation
doesn’t have any effect on the actual argument variables in the calling function.

However, the Call by Value method is less efficient when we need to pass large objects such as
an array or a file to another function. Also, in some cases, we may need the actual arguments to
be manipulated by another function. In such cases, the Call by Value mechanism is not useful.
We have to explore the Call by Reference mechanism for that purpose. Refer the next chapter for
a detailed explanation on the Call by Reference mechanism of C.

The Call by Reference approach involves passing the address of the variable holding the value of
the actual argument. You can devise a calling method that is a mix of Call by Value and Call by
Reference. In this case, some arguments are passed by value and others by reference.

Function Call by Reference in C

There are two ways in which a function can be called: (a) Call by Value and (b) Call by
Reference. In this chapter, we will explain the mechanism of calling a function by reference.

Let us start this chapter with a brief overview on "pointers" and the "address operator (&)". It is
important that you learn these two concepts in order to fully understand the mechanism of Call
by Reference.

The Address Operator (&) in C

In C language, a variable is a named memory location. When a variable declared, the compiler
allocates a random location in the memory and internally identifies the location with the user-
defined name.

To fetch the address at which the variable has been created, we use the address (&) operator.

Example

Take a look at the following example −

#include <stdio.h>

int main(){

int x = 10;

printf("x: %d Address of x: %d", x, &x);


}

Output

This will print the value of x and its address −

x: 10 Address of x: -1990957196

What is a Pointer in C?

A pointer is a variable that stores the address of another variable. To declare a pointer variable,
its name is prefixed with the * symbol. The type of the pointer variable and its host variable must
be same.

The address is assigned with the & operator. The dereference operator (*) is used with the
pointer. It fetches the value of a variable whose address is assigned to the pointer.

Example

The following example demonstrates how referening and dereferencing work in C −

#include <stdio.h>

int main(){

int x = 10;
int *y = &x;

printf("x: %d Address of x: %d\n", x, &x);


printf("Address of y: %d \n", &y);
printf("Value at address in y: %d\n", *y);
}

Output

Run the code and check its output −

x: 10 Address of x: -1742755108
Address of y: -1742755104
Value at address in y: 10
How Does Call by Reference Work in C?

When a function is called by reference, the address of the actual argument variables passed,
instead of their values.

Let us define the add() function that receives the references of two variables −

int add(int *x, int *y){

int z = *x + *y;

return z;
}

When such a function is called, we pass the address of the actual argument.

Example

Let us call the add() function by reference from inside the main() function −

#include <stdio.h>

/* function declaration */
int add(int *, int *);

int main(){

int a = 10, b = 20;


int c = add(&a, &b);

printf("Addition: %d", c);


}

int add(int *x, int *y){

int z = *x + *y;

return z;
}
Output

When you run this code, it will produce the following output −

Addition: 30

Now let's understand how this code actually works. The main() function passes the address
of a and b to the add() function. The addresses of a and b are assigned to the pointer
variables x and y.

Now focus on the statement "z = *x + *y;" inside the add() function. Remember that x stores the
address of a. The dereference operator in *x and *y fetches the values of a and b respectively,
hence z is the addition of a and b in the main() function.

Example: Swap Values with Call by Reference

Let us understand in more detail how the Call by Reference mechanism works, with the help of
the following example that interchanges value of two variables.

#include <stdio.h>

/* Function definition to swap the values */


/* It receives the reference of two variables whose values are to be swapped */

int swap(int *x, int *y){

int z;

z = *x; /* save the value at address x */


*x = *y; /* put y into x */
*y = z; /* put z into y */

return 0;
}

/* The main() function has two variables "a" and "b" */


/* Their addresses are passed as arguments to the swap() function. */

int main(){
/* local variable definition */
int a = 10;
int b = 20;

printf("Before swap, value of a: %d\n", a );


printf("Before swap, value of b: %d\n", b );

/* calling a function to swap the values */


swap(&a, &b);

printf("After swap, value of a: %d\n", a);


printf("After swap, value of b: %d\n", b);

return 0;
}

Output

When you run this code, it will produce the following output −

Before swap, value of a: 10


Before swap, value of b: 20
After swap, value of a: 20
After swap, value of b: 10

Explanation

Assume that the variables a and b in the main() function are allotted locations with the memory
address 100 and 200 respectively. As their addresses are passed to x and y (remember that they
are pointers), the variables x, y and z in the swap() function are created at addresses 1000, 2000
and 3000 respectively.
Since "x" and "y" store the address of "a" and "b", "x" becomes 100 and "y" becomes 200, as the
above figure shows.

Inside the swap() function, the first statement "z = *x" causes the value at address in "x" to be
stored in "x" (which is 10). Similarly, in the statement "*x = *y;", the value at the address in "y"
(which is 20) is stored in the location whose pointer is "x".

Finally, the statement "*y = z;" assigns the "z" to the variable pointed to by "y", which is "b" in
the main() function. The values of "a" and "b" now get swapped.

The following figure visually demonstrates how it works −

Mixing Call by Value and Call by Reference


You can use a function calling mechanism that is a combination of Call by Value and Call by
Reference. It can be termed as "mixed calling mechanism", where some of the arguments are
passed by value and others by reference.

A function in C can have more than one arguments, but can return only one value. The Call by
Reference mechanism is a good solution to overcome this restriction.

Example

In this example, the calculate() function receives an integer argument by value, and two pointers
where its square and cube are stored.

#include <stdio.h>
#include <math.h>

/* function declaration */
int calculate(int, int *, int *);

int main(){

int a = 10;
int b, c;

calculate(a, &b, &c);

printf("a: %d \nSquare of a: %d \nCube of a: %d", a, b, c);


}

int calculate(int x, int *y, int *z){

*y = pow(x,2);
*z = pow(x, 3);

return 0;
}

Output

When you run this code, it will produce the following output −
a: 10
Square of a: 100
Cube of a: 1000

The Call by Reference mechanism is widely used when a function needs to perform memory-
level manipulations such as controlling the peripheral devices, performing dynamic allocation,
etc.

Nested Functions in C

The term nesting, in programming context refers to enclosing a particular programming element
inside another similar element. Just like nested loops, nested structures, etc., a nested function is
a term used to describe the use of one or more functions inside another function.

What is Lexical Scoping?

In C language, defining a function inside another one is not possible. In short, nested functions
are not supported in C. A function may only be declared (not defined) within another function.

When a function is declared inside another function, it is called lexical scoping. Lexical scoping
is not valid in C because the compiler cannot reach the correct memory location of inner
function.

Nested Functions Have Limited Use

Nested function definitions cannot access local variables of surrounding blocks. They can access
only global variables. In C, there are two nested scopes: local and global. So, nested functions
have limited use.

Example: Nested Function

If you want to create a nested function like the one shown below, then it will generate an error −

#include <stdio.h>
int main(void){

printf("Main Function");

int my_fun(){

printf("my_fun function");

// Nested Function
int nested(){
printf("This is a nested function.");
}
}
nested();
}

Output

On running this code, you will get an error −

main.c:(.text+0x3d): undefined reference to `nested'


collect2: error: ld returned 1 exit status

Trampolines for Nested Functions

Nested functions are supported as an extension in "GNU C". GCC implements taking the address
of a nested function using a technique called trampolines.

A trampoline is a piece of code created at runtime when the address of a nested function is taken.
It requires the function to be prefixed with the keyword auto in the declaration.

Example 1

Take a look at the following example −

#include <stdio.h>

int main(){

auto int nested();


nested();

printf("In Main Function now\n");

int nested(){
printf("In the nested function now\n");
}

printf("End of the program");


}

Output

When you run this code, it will produce the following output −

In the nested function now


In Main Function now
End of the program

Example 2

In thi program, a function square() is nested inside another function myfunction(). The nested
function is declared with the auto keyword.

#include <stdio.h>
#include <math.h>

double myfunction (double a, double b);

int main(){
double x = 4, y = 5;
printf("Addition of squares of %f and %f = %f", x, y, myfunction(x, y));
return 0;
}

double myfunction (double a, double b){


auto double square (double c) { return pow(c,2); }
return square (a) + square (b);
}

Output

Run the code and check its output −

Addition of squares of 4.000000 and 5.000000 = 41.000000

Nested Functions: Points to Note

One needs to be aware of the following points while using nested functions −

 A nested function can access all the identifiers of the containing function that precede its
definition.
 A nested function must not be called before the containing function exits.
 A nested function cannot use a goto statement to jump to a label in the containing function.
 Nested function definitions are permitted within functions in any block, mixed with the
other declarations and statements in the block.
 If you try to call a nested function through its address after the containing function exits, it
throws an error.
 A nested function always has no linkage. Declaring one with "extern" or "static" always
produces errors.

Variadic Functions in C

Variadic functions are one of the powerful but very rarely used features in C language. A
function that can take a variable number of arguments is called a variadic function.

The most frequently used library functions in C, i.e., printf() and scanf() are in fact the best-
known examples of variadic functions, as we can put a variable number of arguments after the
format specifier string.

printf("format specifier",arg1, arg2, arg3, . . .);

Syntax of Variadic Functions

Variadic functions add a lot of flexibility in programming the application structure. In C, a


variadic function is defined to have at least one fixed argument, and then followed by an ellipsis
symbol (...) that enables the compiler to parse the variable number of arguments.
return_type function_name(type arg1, ...);

You need to include the stdarg.h header file at the top of the code to handle the variable
arguments. This header file provides the following macros to work with the arguments received
by the ellipsis symbol.

Methods Description

va_start(va_list ap, Arguments after the last fixed argument are


arg) stored in the va_list.

Each time, the next argument in the variable list


va_arg(va_list ap,
va_list and coverts it to the given type, till it
type)
reaches the end of list.

va_copy(va_list dest,
This creates a copy of the arguments in va_list
va_list src)

This ends the traversal of the variadic function


va_end(va_list ap) arguments. As the end of va_list is reached, the
list object is cleaned up.

Example: Sum of Numbers Using a Variadic Function

The following code uses the concept of a variadic function to return the sum of a variable
number of numeric arguments passed to such a function. The first argument to the addition()
function is the count of the remaining arguments.

Inside the addition() function, we initialize the va_list variable as follows −

va_list args;
va_start (args, n);

Since there are "n" number of arguments that follow, fetch the next argument with "va_arg()"
macro for "n" number of times and perform cumulative addition −

for(i = 0; i < n; i++){


sum += va_arg (args, int);
}

Finally, clean up the va_list variable −

va_end (args);
The function ends by returning the sum of all the arguments.

The complete code is given below −

#include <stdio.h>
#include <stdarg.h>

// Variadic function to add numbers

int addition(int n, ...){

va_list args;
int i, sum = 0;

va_start (args, n);

for (i = 0; i < n; i++){


sum += va_arg (args, int);
}

va_end (args);

return sum;
}

int main(){

printf("Sum = %d ", addition(5, 1, 2, 3, 4, 5));

return 0;
}

Output

Run the code and check its output −

Sum = 15
You can try providing a different set of numbers as the variadic arguments to the addition()
function.

Example: Finding the Largest Number Using a Variadic Function

We can extend the concept of variadic function to find the largest number in a given list of
variable number of values.

#include <stdio.h>
#include <stdarg.h>

// Variadic function to add numbers


int largest(int n, ...){
va_list args;
int i, max = 0;

va_start (args, n);

for(i = 0; i < n; i++){


int x = va_arg (args, int);
if (x >= max)
max = x;
}

va_end (args);
return max;
}

int main(){

printf("Largest number in the list = %d ", largest(5, 12, 34, 21, 45, 32));

return 0;
}

Output

When you run this code, it will produce the following output −
Largest number in the list = 45

Example: Concatenation of Multiple Strings Using Variadic Function

In the following code, we pass multiple strings to a variadic function that returns a concatenated
string.

#include <stdio.h>
#include <string.h>
#include <stdarg.h>

char * concat(int n, ...){


va_list args;
int i;
static char string[100], *word;

va_start (args, n);


strcpy(string, "");

for (i = 0; i < n; i++){


word= va_arg (args, char *);
strcat(string, word);
strcat(string, " ");
}

va_end (args);

return string;
}

int main(){

char * string1 = concat(2, "Hello", "World");


printf("%s\n", string1);
char * string2 = concat(3, "How", "are", "you?");
printf("%s\n", string2);
return 0;
}

Output

Run the code and check its output −

Hello World
How are you?

User-defined Functions in C

Previous
Next

A function in C is a block of organized, reusable code that is used to perform a single related
action. In any C program, there are one or more functions − classified as library functions and
user-defined functions.

There are two types of functions in C −

 Library functions
 User-defined functions

Any C compiler (e.g. GCC compiler, Clang, MSVC compiler, etc.) is distributed with a number
precompiled header files (stdio.h, math.h, etc.), each consisting of one or more predefined library
functions such as printf(), scanf(), pow(), sqrt(), etc. To be able to use the library function, the
corresponding header file must be made available with the #include directive.

However, if you don’t find a suitable library function to serve your purpose, then you can define
a customized function for the program. Normally, we find a C program with a main() function.
Obviously, the main() function is a user-defined function, as it contains the instructions provided
by the user. It can of course call the other library or user-defined functions.

Creating a User-defined Function in C

For creating a user-defined function, first you need to understand the purpose of the function,
that is, what do you want the function to do?

A function may need one or more data items to process. The data that the function needs from
the calling environment are called arguments. Inside the body of the function, one or more local
variables may be needed for processing the data. Decide the set of steps that the program will use
to accomplish this goal (the algorithm).

After all the statements in the function are executed, the flow of the program returns to the
calling environment. The function may return some data along with the flow control.

Forward Declaration

In C language, it is necessary to provide the declaration of the prototype of any function. The
prototype of a library function is present in the corresponding header file.

For a user-defined function, its prototype is present in the current program. The definition of a
function and its prototype declaration should match.

If you wish to define a function called add() that performs the addition of two integer arguments
and returns the value as an integer, then the function declaration would be as follows −

int add(int, int);

Function Definition

The definition of a function and its prototype declaration should match. The definition consists
of a function header that matches the declaration and a function body.

return_type function_name(arg1, arg2, ...){

// Function body;

return val;

Using this template, you can write the user-defined function add() as follows −

int add(int a, int b){


int c;
c = a + b;
return c;
}

Note that the order of definition of user-defined functions is not important in a C program.
However, its prototype must be declared before calling the function.
In a program, the main() function is always the entry point, irrespective of whether it is the first
function or not. We needn't provide the prototype declaration of the main() function.

Calling a Function

To call a function, you should use a statement that complies with the declaration of the function
prototype. If the function is defined to receive a certain number of arguments, then the same
number and type of arguments must be passed to call that function.

The following statement calls the add() function that we defined above −

int result = add(10, 20);

Formal and Actual Arguments

When a function is defined with arguments, the arguments in the parenthesis in front of the
function name are called formal arguments. In the above example, the function is defined with
"int a" and "int b" arguments; they are formal arguments.

When the function is called, the arguments passed to it are called the actual arguments. In the
example below, the variables "x" and "y" are the actual arguments.

int x = 10, y = 20;


int result = add(x, y);

A user-defined function may be defined to have any type of variables as formal arguments. It
includes primary types (int, float, char), array, pointer, or struct/union type variables.

A function should return a value to the calling environment. By default, the return type of a
function is int type. However, it can return any data type − primary type, array, pointer, or a
struct as well as a pointer. You can even define a function that returns a void type.

Example

If either the number or the type of actual and formal arguments or the return type as in the
forward declaration of a function and its definition don’t match, then the compiler reports an
error.

Look at the example below −

#include <stdio.h>

float divide (int, int);


int main(){

int x = 15, y = 5;

float z = divide (x, y);

printf("%f", z);

return 0;
}

int divide (int a, int b){

int c = a/b;

return c;
}

Output

In the code above, the declaration of the divide() function doesn’t match with its definition,
hence the compiler shows the following error −

error: conflicting types for 'divide'

In C, any function can call any other function, any number of times. A function can call itself
too. Such a self-calling function is called a recursive function.

The following program calls the main() function from inside main() itself −

#include <stdio.h>

int main(){

printf("Hello");

main();
return 0;
}

When executed, the program goes into an infinite loop. In practice, recursion has to be used so
that the program eventually terminates.

Callback Function in C

In C language, a function is called a callback function when it is passed as an argument to


another function. It is commonly referred to as a handle.

Callback functions are extremely versatile, particularly in event-driven programming. When a


specific event is triggered, a callback function mapped to it is executed in response to these
events. This is typically used in GUI applications, an action like a button click can initiate a
series of predefined actions.

The callback is basically any executable code that is passed as an argument to other code, that is
expected to call back or execute the argument at a given time. We can define it in other words
like this: If the reference of a function is passed to another function argument for calling, then it
is called a callback function.

The mechanism of callbacks depends on function pointers. A function pointer is a variable that
stores the memory address of a function.

Here is a simple hello() function in C −

void hello(){
printf("Hello World.");
}

We declare a pointer to this function as follows −

void (*ptr)() = &hello;

We can now call the function with the help of this function pointer, (*ptr)();

Example

In this example, the hello() function is defined as an argument to myfunction().

#include <stdio.h>

void hello(){
printf("Hello World\n");
}

void callback(void (*ptr)()){

printf("Calling a function with its pointer\n");

(*ptr)(); // calling the callback function


}

main(){

void (*ptr)() = hello;

callback(ptr);
}

Output

Calling a function with its pointer


Hello World

Callback with Arguments

In the example given below, we have also declared two functions with identical prototypes −
square() and root().

int square(int val){


return val*val;
}

int root(int val){


return pow(val, 0.5);
}

The callback function is defined to receive an argument as well as a function pointer with an
integer argument that matches with the above functions.
int callback(int a, int (*ptr)(int)){

int ret = (*ptr)(a);

return ret;

In the main() function, we place a call to the callback by passing an integer and the name of the
function (square / root) which becomes the function pointer in callback’s definition.

Example

The complete code is as follows −

#include <stdio.h>
#include <math.h>

int callback(int a, int (*print_callback)(int));


int square(int value);
int root (int value);

int main(){

int x = 4;

printf("Square of x: %d is %d\n", x, callback(x, square));


printf("Square root of x: %d is %d\n", x, callback(x, root));

return 0;
}

int callback(int a, int (*ptr)(int)){


int ret = (*ptr)(a);
return ret;
}
int square(int val){
return val*val;
}

int root(int val){


return pow(val, 0.5);
}

Output

Square of x: 4 is 16
Square root of x: 4 is 2

In this chapter, we explained how you can use function pointers so that we can enhance the
flexibility of our C programs. Additionally, we showed how you can create generic callback
functions that are not limited to a specific function pointer type.

There are two types of callbacks −

Synchronous Callback − A callback is synchronous when it is given to another function, which


executes it as part of its process. The calling function waits for the callback to complete before
proceeding. This is useful when you need immediate results or want to ensure a task is finished
before moving on.

Asynchronous Callback − In this case, the calling function triggers the callback but doesn’t
wait for it to finish. Instead, it continues its execution. It results in non-blocking operations. It’s
commonly used in event-driven programming.

Generic callback functions help developers write C programs that are versatile and better
adaptable.

Return Statement in C

The return statement terminates the execution of a function and returns control to the calling
function. Every function should have a return statement as its last statement. While using the
returns statement, the return type and returned value (expression) must be the same.

Syntax of return Statement

Here is the syntax of the return statement:

return value_or_expression;
The following main() function shows return as its last statement −

int main(){
// function body;
return 0;
}

The main() function returning 0 indicates the successful completion of the function. To indicate
failure of the function, a non−zero expression is returned.

The void return statement

A function's return type can be void. In such a case, return statement is optional. It may be
omitted, or return without any expression is used.

Example

#include <stdio.h>
/* function declaration */
void test(){
return;
}
int main() {
test();
printf("end");
return 0;
}

Return type mismatch in return statement

Each function in the program must have a forward declaration of its prototype. By default, each
function returns an integer. However, function of other return types without prototype is not
accepted.

Example

int main(){
test(5);
printf("end");
return 0;
}
float test(int a) {
return 1.1 ;
}

Output

Error: C:\Users\mlath\test.c|12|error: conflicting types for 'test'

This is because, function without prototype is assumed as of int type, which conflicts with the
definition.

The same error occurs if the return type of a function in the prototype doesn't match with the
type of return expression, an error is reported as below −

float test(int);
int main(){
test(5);
printf("end");
return 0;
}
float test(float a){
return 1.1 ;
}

Multiple return values with return statement

A function can be defined with more than one arguments, but can return only one value. You can
however use multiple conditional return statements as shown below −

Example

int test(int);
int main() {
test(5);
printf("end");
return 0;
}

int test(int a){


if (a<3)
return 1;
else
return 0;
}

Function returning an array

It is not possible to return an entire array as an argument to a function. However, you can return
a pointer to an array by specifying the array's name without an index.

Example

The following program shows how to pass an array to a function that returns an array after
performing a certain process.

#include <stdio.h>
int* test(int *);
int main(){
int a[] = {1,2,3,4};
int i;
int *b = test(a);
for (i=0; i<4; i++){
printf("%d\n", b[i]);
}
return 0;
}
int * test(int*a){
int i;
for (i=0; i<4; i++){
a[i] = 2*a[i];
}
return a;
}

Output

2
4
6
8

function can only return a single value using return statement. To return multiple values, we use
pointers or structures

exit() instead of return statement

Unlike the return statement, the exit() function is also used to terminate the execution of the
program without transferring the control back to the calling function. It is used inside a function
when the program has finished its execution or when an unrecoverable error occurs. It is a
standard way of handling exception errors in C. When exit() is called, the program control does
not return to the point where exit() was invoked. Instead, the control is handed back to the
operating system.

The exit() function is library function defined in stdlib.h header file.

Syntax

void exit(int status);

exit() is typically called from the main() function or any other function to terminate the entire
program.

It is included in the <stdlib.h> header file.

Since it results in termination of the program, exit() does not return a value directly to the caller
function. Instead, it terminates the program and returns a status code. It is an integer that
represents the exit status of the program, indicating success or failure.

Recursion in C

Recursion is the process by which a function calls itself. C language allows writing of such
functions which call itself to solve complicated problems by breaking them down into simple and
easy problems. These functions are known as recursive functions.

What is a Recursive Function in C?

A recursive function in C is a function that calls itself. A recursive function is used when a
certain problem is defined in terms of itself. Although it involves iteration, using iterative
approach to solve such problems can be tedious. Recursive approach provides a very concise
solution to seemingly complex problems.

Syntax

This is how a general recursive function looks like −


void recursive_function(){
recursion(); // function calls itself
}

int main(){
recursive_function();
}

While using recursion, programmers need to be careful to define an exit condition from the
function, otherwise it will go into an infinite loop.

Why Recursion is Used in C?

Recursion is used to perform complex tasks such as tree and graph structure traversals. Popular
recursive programming solutions include factorial, binary search, tree traversal, tower of Hanoi,
eight queens problem in chess, etc.

A recursive program becomes concise, it is not easily comprehendible. Even if the size of the
code may reduce, it needs more resources of the processor, as it involves multiple IO calls to the
function.

Factorial Using Recursion

Recursive functions are very useful to solve many mathematical problems such as calculating the
factorial of a number, generating Fibonacci series, etc.

The most popular example of recursion is calculation of factorial. Mathematically, a factorial is


defined as −

n! = n X (n-1)!

It can be seen that we use factorial itself to define factorial. Hence this is a fit case to write a
recursive function. Let us expand the above definition for calculating the factorial value of 5.

5! = 5 X 4!
5 X 4 X 3!
5 X 4 X 3 X 2!
5 X 4 X 3 X 2 X 1!
5X4X3X 2X1
= 120
While we can perform this calculation using a loop, its recursive function involves successively
calling it by decrementing the number till it reaches 1.

Example: Non-Recursive Factorial Function

The following program shows how you can use a non-recursive function to calculate the factorial
of a number −

#include <stdio.h>
#include <math.h>

// function declaration
int factorial(int);

int main(){
int a = 5;
int f = factorial(a);

printf("a: %d \n", a);


printf("Factorial of a: %d", f);
}
int factorial(int x){
int i;
int f = 1;

for (i = 5; i >= 1; i--){


f *= i;
}
return f;
}

Output

When you run this code, it will produce the following output −

a: 5
Factorial of a: 120

Example: Recursive Factorial Function


Let us now write a recursive function for calculating the factorial of a given number.

The following example calculates the factorial of a given number using a recursive function −

#include <stdio.h>
#include <math.h>

/* function declaration */
int factorial(int i){

if(i <= 1){


return 1;
}
return i * factorial(i - 1);
}
int main(){
int a = 5;
int f = factorial(a);

printf("a: %d \n", a);


printf("Factorial of a: %d", f);
return 0;
}

Output

Run the code and check its output −

a: 5
Factorial of a: 120

When the main() function calls the factorial() function by passing the variable "a", its value is
stored in "i". The factorial() function successively calls itself.

In each call, the value of "i" is multiplied by its earlier value after reducing it by 1, till it reaches
1. As it reaches 1, the product of all the values between the initial value of the argument and 1 is
returned to the main() function.

Binary Search Using Recursion


Let us have a look at another example to understand how recursion works. The problem at hand
is to check whether a given number is present in an array.

While we can perform a sequential search for a certain number in the list using a for loop and
comparing each number, the sequential search is not efficient, especially if the list is too long.

The binary search algorithm checks if the index "start" is greater than the index "end". Based on
the value present at the variable "mid", the function is called again to search for the element.

We have a list of numbers arranged in ascending order. Then we find the midpoint of the list and
restrict the checking to either left or right of the midpoint, depending on whether the desired
number is less than or greater than the number at the midpoint.

Example: Recursive Binary Search

The following code implements the recursive binary searching technique −

#include <stdio.h>

int bSearch(int array[], int start, int end, int element){

if (end >= start){

int mid = start + (end - start ) / 2;

if (array[mid] == element)
return mid;

if (array[mid] > element)


return bSearch(array, start, mid-1, element);
return bSearch(array, mid+1, end, element);
}
return -1;
}

int main(void){
int array[] = {5, 12, 23, 45, 49, 67, 71, 77, 82};
int n = 9;
int element = 67;
int index = bSearch(array, 0, n-1, element);

if(index == -1 ){
printf("Element not found in the array ");
}
else{
printf("Element found at index: %d", index);
}
return 0;
}

Output

Run the code and check its output −

Element found at index: 5

Fibonacci Series Using Recursion

In Fibonacci series, a number is the sum of its previous two numbers. To generate Fibonacci
series, the ith number is the addition of i−1 and i−2.

Example

The following example generates the first 10 numbers in the Fibonacci series for a given number
using a recursive function −

#include <stdio.h>

int fibonacci(int i){

if(i == 0){
return 0;
}

if(i == 1){
return 1;
}
return fibonacci(i-1) + fibonacci(i-2);
}

int main(){

int i;

for (i = 0; i < 10; i++){

printf("%d\t\n", fibonacci(i));

}
return 0;
}

Output

When the above code is compiled and executed, it produces the following result −

0
1
1
2
3
5
8
13
21
34

Implementing recursion in a program is difficult for beginners. While any iterative process can
be converted in a recursive process, not all cases of recursion can be easily expressed iteratively.

Scope Rules in C

A scope in any programming is a region of the program where a defined variable can have its
existence and beyond that, the variable cannot be accessed.

There are three places where variables can be declared in a C program −


 Inside a function or a block (local variables)
 Outside of all functions (global variables)
 In the definition of function parameters (formal parameters)

Let us understand what are local and global variables, and formal parameters.

Local Variables in C

Variables that are declared inside a function or block are called local variables. They can be used
only by the statements that are inside that function or block of code. Local variables are not
known to functions outside their own.

Example

The following example shows how local variables are used. Here all the variables a, b, and c are
local to the main() function.

#include <stdio.h>

int main(){

/* local variable declaration */


int a, b;
int c;

/* actual initialization */
a = 10;
b = 20;
c = a + b;

printf ("Value of a = %d, b = %d and c = %d\n", a, b, c);

return 0;
}

Output

When you run this code, it will produce the following output −

Value of a = 10, b = 20 and c = 30


Global Variables in C

Global variables are defined outside the function, usually at the top of the program. Global
variables hold their values throughout the lifetime of a program and they can be accessed inside
any of the functions defined for the program.

A global variable can be accessed by any function. That is, a global variable is available for use
throughout your entire program after its declaration.

Example

The following code shows how global variables are used in a C program −

#include <stdio.h>

int g; /* global variable declaration */

int main(){

int a, b; /* local variable declaration */

/* actual initialization */
a = 10;
b = 20;
g = a + b;

printf ("Value of a = %d, b = %d and g = %d\n", a, b, g);

return 0;
}

Output

Run the code and check its output −

Value of a = 10, b = 20 and g = 30

Example: Precedence of Local and Global Variable

A program can have the same name for local and global variables but the value of local variable
inside a function will take preference. Here is an example −
#include <stdio.h>

int g = 20; /* global variable declaration */

int main(){

int g = 10; /* local variable declaration */

printf ("Value of g = %d\n", g);

return 0;
}

Output

When the above code is compiled and executed, it produces the following result −

Value of g = 10

Formal Parameters in C

Formal parameters are treated as local variables within a function and they take precedence over
global variables.

Example

Take a look at this example −

#include <stdio.h>

int a = 20; /* global variable declaration */

int main(){

/* local variable declaration in main function */


int a = 10;
int b = 20;
int c = 0;
printf ("Value of 'a' in main() = %d\n", a);
c = sum(a, b);
printf ("value of 'c' in main() = %d\n", c);

return 0;
}

/* function to add two integers */

int sum(int a, int b){

printf("Value of 'a' in sum() = %d\n", a);


printf("Value of 'b' in sum() = %d\n", b);

return a + b;
}

Output

When the above code is compiled and executed, it produces the following result −

Value of 'a' in main() = 10


Value of 'a' in sum() = 10
Value of 'b' in sum() = 20
value of 'c' in main() = 30

Initializing Local and Global Variables

When a local variable is defined, it is not initialized by the system, you must initialize it yourself.
In contrast, global variables are initialized automatically by the system when you define them as
follows −

Data Type Initial Default Value

int 0

char '\0'

float 0
double 0

pointer NULL

It is a good programming practice to initialize variables properly, otherwise your program may
produce unexpected results, because uninitialized variables will take some garbage value already
available at their memory location.

Static Variables in C

In a C program, if a variable is declared as static, it belongs to the static storage class. Static
variables are initialized only once. The compiler persists with the variable till the end of the
program.

By default, a C variable is classified as an auto storage type. A static variable is useful when
you want to preserve a certain value between calls to different functions. Static variables are also
used to store data that should be shared between multiple functions.

Features of Static Storage Class

Following features characterize the static storage class −

 The compiler allocates space to a static variable in the computer’s main memory.
 Unlike auto, a static variable is initialized to zero and not garbage.
 A static variable is not re-initialized on every function call, if it is declared inside a function.
 A static variable has local scope.

Here is the syntax of declaring a static variable in C language −

static datatype var = value;

Here,

datatype represents the type of variable like int, char, float, etc.

var is the name of variable given by user.

value is any value given to initialize the variable. By default, it is zero.

Example 1

Here is an example of how you can use a static variable in C language −

#include <stdio.h>
int main(){

auto int a = -28;


static int b = 8;

printf("The value of auto variable: %d\n", a);


printf("The value of static variable b: %d\n",b);

if(a != 0)
printf("The sum of static variable and auto variable: %d\n",(b+a));

return 0;
}

Output

When you run this code, it will produce the following output −

The value of auto variable: -28


The value of static variable b: 8
The sum of static variable and auto variable: -20

Example 2

In this example, x is an auto variable by default and initialized to 0 every time when the
counter() function is called. On each subsequent call, it gets re-initialized.

#include <stdio.h>

int counter();

int main(){
counter();
counter();
counter();
return 0;
}
int counter(){
int x;
printf("Value of x as it enters the function: %d\n", x);
x++;
printf("Incremented value of x: %d\n", x);
}

Output

Run the code and check its output −

Value of x as it enters the function: 0


Incremented value of x: 1
Value of x as it enters the function: 0
Incremented value of x: 1
Value of x as it enters the function: 0
Incremented value of x: 1

However, when the variable x in the counter() function is declared as static, it is initialized to "0"
when the counter() function is called for the first time. On each subsequent call, it is not re-
initialized. Instead, it retains the earlier value.

Example 3

Change the declaration of "x" to "static int x = 0;" and run the program again −

#include <stdio.h>

int counter();

int main(){
counter();
counter();
counter();
return 0;
}

int counter(){
static int x = 0;
printf("Value of x as it enters the function: %d\n", x);
x++;
printf("Incremented value of x: %d\n", x);
}

Output

Now, when you run this code, it will produce the following output −

Value of x as it enters the function: 0


Incremented value of x: 1
Value of x as it enters the function: 1
Incremented value of x: 2
Value of x as it enters the function: 2
Incremented value of x: 3

You can pass a static variable to a function. However, a formal parameter cannot be declared as
static, as C uses the function parameters as local auto variables inside a function.

Example 4

In this code, we pass a static variable to a function. However, the change in its value is not
reflected in the calling function.

#include <stdio.h>

int myfunction(int x);

int main(){

static int x = 5;
myfunction(x);
printf("in main - x:%d\n", x);

return 0;
}

int myfunction(int x){


x++;
printf("Incremented value of x: %d\n", x);
}

Output

Run the coce and check its output −

Incremented value of x: 6
in main - x:5

Similarities between Static and Global Variables

A static variable has certain similarities with a global variable. Both of them, if not explicitly
initialized, both are initialized to "0" (for numeric types) or "null pointers" (for pointers).

The scope of a static variable is restricted to the function or the block in which it is declared.
This is unlike a global variable, which is accessible throughout the program. Also, a static
variable can be imported in another code file, as we do by using the extern keyword.

Example

You can declare a global variable as static too. Take a look at the following example −

#include <stdio.h>

int myfunction();

static int x = 5;

int main(){
myfunction(x);
printf("Inside the main function, x: %d\n", x);
return 0;
}

int myfunction(){
x++;
printf("Incremented value of x: %d\n", x);
}
Output

When you run this code, it will produce the following output −

Incremented value of x: 6
Inside the main function, x: 6

It is better to use static variables to be accessible only within a file. On the other hand, use global
(with extern) variables to be accessible from anywhere in a program (if declared extern in other
files).

Global Variables in C

Global variables are defined outside a function, usually at the top of a program. Global variables
hold their values throughout the lifetime of a program and they can be accessed inside any of the
functions defined for the program.

If a function accesses and modifies the value of a global variable, then the updated value is
available for other function calls.

If a variable defined in a certain file, then you can still access it inside another code module as a
global variable by using the extern keyword. The extern keyword can also be used to access a
global variable instead of a local variable of the same name.

Example: Using Global Variables in a C Program

The following program shows how global variables are used in a program.

#include <stdio.h>

/* global variable declaration */


int g = 10;

int main(){

/* local variable declaration */


int a;

/* actual initialization */
a = g * 2;
printf("Value of a = %d, and g = %d\n", a, g);
return 0;
}

Output

When you run this code, it will produce the following output −

Value of a = 20, and g = 10

Example: Accessbility of Global Variables

Global variables are accessible in all the functions in a C program. If any function updates the
value of a global variable, then its updated value will subsequently be available for all the other
functions.

#include <stdio.h>

/* global variable declaration */


int g = 10;

int function1();
int function2();

int main(){

printf("Value of Global variable g = %d\n", g);

function1();
printf("Updated value of Global variable g = %d\n", g);

function2();
printf("Updated value of Global variable g = %d\n", g);

return 0;
}

int function1(){
g = g + 10;
printf("New value of g in function1(): %d\n", g);
return 0;
}

int function2(){
printf("The value of g in function2(): %d\n", g);
g = g + 10;
return 0;
}

Output

Run the code and check its output −

Value of Global variable g = 10


New value of g in function1(): 20
Updated value of Global variable g = 20
The value of g in function2(): 20
Updated value of Global variable g = 30

Example: Declare the Global Variables at the Top

Global variables are available to only those functions which are defined after their declaration.

In this example, we declared a global variable (x) before the main() function. There is another
global variable y that is declared after the main() function but before function1(). In such a case,
the variable y, even thought it is a global variable, is not available for use in the main() function,
as it is declared afterwards. As a result, you get an error.

#include <stdio.h>

/* global variable declaration */


int x = 10;

int function1();

int main(){
printf("value of Global variable x= %d y=%d\n", x, y);
function1();
return 0;
}

int y = 20;

int function1(){
printf ("Value of Global variable x = %d y = %d\n", x, y);
}

Output

When you run this code, it will produce an error −

Line no 11: error: 'y' undeclared (first use in this function)


11 | printf ("Value of Global variable x = %d y = %d\n", x, y);
| ^

Example: Using the "extern" Keyword

If you want to access a global variable when a local variable with same name is also there in the
program, then you should use the extern keyword.

In this C Program, we have a global variable and a local variable with the same name (x). Now,
let's see how we can use the keyword "extern" to avoid confusion −

#include <stdio.h>

// Global variable x
int x = 50;

int main(){

// Local variable x
int x = 10;{
extern int x;
printf("Value of global x is %d\n", x);
}
printf("Value of local x is %d\n", x);

return 0;
}

Output

When you run this code, it will produce the following output −

Value of global x is 50
Value of local x is 10

Avoid Using Global Variables

Global variables can simplify the programming logic. Global variables can be accessed across
functions and you need not use a parameter passing technique to pass variables from one
function to another. However, it is not wise or efficient to have too many global variables in a C
program, as the memory occupied by these variables is not released till the end of the program.

Using global declaration is not considered a good programming practice because it doesn’t
implement structured approach. Global declaration is also not advised from security point of
view, as they are accessible to all the functions. Finally, using global declarations can make a
program difficult to debug, maintain, and scale u

Arrays in C

What are Arrays?

Arrays in C are a kind of data structure that can store a fixed-size sequential collection of
elements of the same type. Arrays are used to store a collection of data, but it is often more
useful to think of an array as a collection of variables of the same type.
An array in C is a collection of data items of similar data type. One or more values same data
type, which may be primary data types (int, float, char), or user-defined types such as struct or
pointers can be stored in an array. In C, the type of elements in the array should match with the
data type of the array itself.

The size of the array, also called the length of the array, must be specified in the declaration
itself. Once declared, the size of a C array cannot be changed. When an array is declared, the
compiler allocates a continuous block of memory required to store the declared number of
elements.

Why Do We Use Arrays?

Suppose we want to store the marks of 10 students and find the average. We declare 10 different
variables to store 10 different values as follows −

int a = 50, b = 55, c = 67, . . . ;


float avg = (float)(a + b + c +. . . ) / 10;

These variables will be scattered in the memory with no relation between them. Importantly, if
we want to extend the problem of finding the average of 100 (or more) students, then it becomes
impractical to declare so many individual variables.

Arrays offer a compact and memory-efficient solution. Since the elements in an array are stored
in adjacent locations, we can easily access any element in relation to the current element. As
each element has an index, it can be directly manipulated.

Example: Finding the Average Using an Array

To go back to the problem of storing the marks of 10 students and find the average, the solution
with the use of array would be −

#include <stdio.h>

int main(){
int marks[10] = {50, 55, 67, 73, 45, 21, 39, 70, 49, 51};
int i, sum = 0;
float avg;

for (i = 0; i <= 9; i++){


sum += marks[i];
}
avg = (float)sum / 10;
printf("Average: %f", avg);
return 0;
}

Output

Run the code and check its output −

Average: 52.000000

Array elements are stored in contiguous memory locations. Each element is identified by an
index starting with "0". The lowest address corresponds to the first element and the highest
address to the last element.

Declaring an Array in C

To declare an array in C, you need to specify the type of the elements and the number of
elements to be stored in it.

type arrayName[size];

The "size" must be an integer constant greater than zero and its "type" can be any valid C data
type. There are different ways in which an array is declared in C.

Declaring an Uninitialized Array

In such type of declaration, the uninitialized elements in the array may show certain random
garbage values.

int a[5];

Example

Take a look at the following example −

#include <stdio.h>
int main(){
int arr[5];
int i;

for (i = 0; i <= 4; i++){


printf("a[%d]: %d\n", i, arr[i]);
}
return 0;
}

Output

Run the code and check its output −

a[0]: -133071639
a[1]: 32767
a[2]: 100
a[3]: 0
a[4]: 4096

Initializing an Array in C

If a set of comma-separated sequence values put inside curly brackets is assigned in the
declaration, the array is created with each element initialized with their corresponding value.

int arr[5] = {1,2,3,4,5};

Example 1: Initializing All the Elements to 0

To initialize all elements to 0, put it inside curly brackets

#include <stdio.h>

int main(){
int arr[5] = {0};
int i;

for(i = 0; i <= 4; i++){


printf("a[%d]: %d\n", i, arr[i]);
}
return 0;
}

Output

When you run this code, it will produce the following output −

a[0]: 0
a[1]: 0
a[2]: 0
a[3]: 0
a[4]: 0

Example 2

If the list of values is less than the size of the array, the rest of the elements are initialized with
"0".

#include <stdio.h>

int main(){
int arr[5] = {1,2};
int i;

for(i = 0; i <= 4; i++){


printf("a[%d]: %d\n", i, arr[i]);
}
return 0;
}

Output

When you run this code, it will produce the following output −

a[0]: 1
a[1]: 2
a[2]: 0
a[3]: 0
a[4]: 0

Example 3

When an array may be partially initialized, you can specify the element in the square brackets.

#include <stdio.h>

int main(){
int a[5] = {1,2, [4] = 4};
int i;

for(i = 0; i <= 4; i++){


printf("a[%d]: %d\n", i, a[i]);
}
return 0;
}

Output

On execution, it will produce the following output −

a[0]: 1
a[1]: 2
a[2]: 0
a[3]: 0
a[4]: 4

Array Size

The compiler allocates a continuous block of memory. The size of the allocated memory depends
on the data type of the array.

Example 1: Size of Integer Array

If an integer array of 5 elements is declared, the array size in number of bytes would be
"sizeof(int) x 5"

#include <stdio.h>
int main(){
int arr[5] = {1, 2, 3, 4, 5};
printf("Size of array: %ld", sizeof(arr));
return 0;
}

Output

On execution, you will get the following output −

Size of array: 20

The sizeof operator returns the number of bytes occupied by the variable.

Example 2: Adjacent Address of Array Elements

The size of each int is 4 bytes. The compiler allocates adjacent locations to each element.

#include <stdio.h>

int main(){
int a[] = {1, 2, 3, 4, 5};
int i;

for(i = 0; i < 4; i++){


printf("a[%d]: %d \t Address: %d\n", i, a[i], &a[i]);
}
return 0;
}

Output

Run the code and check its output −

a[0]: 1 Address: 2102703872


a[1]: 2 Address: 2102703876
a[2]: 3 Address: 2102703880
a[3]: 4 Address: 2102703884
In this array, each element is of int type. Hence, the 0th element occupies the first 4 bytes
642016 to 19. The element at the next subscript occupies the next 4 bytes and so on.

Example 3: Array of Double Type

If we have the array type of double type, then the element at each subscript occupies 8 bytes

#include <stdio.h>

int main(){
double a[] = {1.1, 2.2, 3.3, 4.4, 5.5};
int i;

for(i = 0; i < 4; i++){


printf("a[%d]: %f \t Address: %ld\n", i, a[i], &a[i]);
}
return 0;
}

Output

Run the code and check its output −

a[0]: 1.100000 Address: 140720746288624


a[1]: 2.200000 Address: 140720746288632
a[2]: 3.300000 Address: 140720746288640
a[3]: 4.400000 Address: 140720746288648

Example 4: Size of Character Array

The length of a "char" variable is 1 byte. Hence, a char array length will be equal to the array
size.

#include <stdio.h>

int main(){
char a[] = "Hello";
int i;

for (i=0; i<5; i++){


printf("a[%d]: %c address: %ld\n", i, a[i], &a[i]);
}
return 0;
}

Output

Run the code and check its output −

a[0]: H address: 6422038


a[1]: e address: 6422039
a[2]: l address: 6422040
a[3]: l address: 6422041
a[4]: o address: 6422042

Accessing Array Elements

Each element in an array is identified by a unique incrementing index, stating with "0". To
access the element by its index, this is done by placing the index of the element within square
brackets after the name of the array.

The elements of an array are accessed by specifying the index (offset) of the desired element
within the square brackets after the array name. For example −

double salary = balance[9];

The above statement will take the 10th element from the array and assign the value to the
"salary".

Example: Declare, Assign and Access

The following example shows how to use all the three above-mentioned concepts viz.
declaration, assignment, and accessing arrays.

#include <stdio.h>

int main(){

int n[5]; /* n is an array of 5 integers */


int i, j;
/* initialize elements of array n to 0 */
for(i = 0; i < 5; i++){
n[i] = i + 100;
}

/* output each array element's value */


for(j = 0; j < 5; j++){
printf("n[%d] = %d\n", j, n[j]);
}
return 0;
}

Output

On running this code, you will get the following output −

n[0] = 100
n[1] = 101
n[2] = 102
n[3] = 103
n[4] = 104

The index gives random access to the array elements. An array may consist of struct variables,
pointers and even other arrays as its elements.

Arrays in Detail

Arrays, being an important concept in C, need a lot more attention. The following important
concepts related to arrays should be clear to a C programmer −

[Link] Concept & Description

Multi-dimensional arrays
1 C supports multidimensional arrays. The simplest form of an
multidimensional array is the two-dimensional array.

Passing arrays to functions


2 You can pass to the function a pointer to an array by specifying
the array's name without an index.

3 Return array from a function


C allows a function to return an array.

Pointer to an array
4 You can generate a pointer to the first element of an array by
simply specifying the array name, without any index.
C - Properties of Array

Arrays are a very important data structure in C. Arrays make it easier to handle large amounts of
data. Due to their unique properties, arrays have a number of advantages over singular variables.

An array is a collection of values of same data type, and in a continuous block of memory. Most
of the important properties of arrays are a result of this unique composition.

Read this chapter to learn the properties of arrays that make them so useful in C programming.

Array is a Collection of Values of Same Data Type

All the elements of an array must be of the same data type. It ensures consistent access and
operations on the data.

If you declare an array as follows −

int arr[] = {50, 67.55, "hello", 21};

Then, the compiler will issue a warning −

initialization of 'int' from 'char *' makes integer from pointer without a cast
[-Wint-conversion]|

Contiguous Memory Allocation

All the elements of an array are stored in contiguous memory locations, meaning they occupy a
block of memory next to each other. This feature of arrays allows for efficient random access
and memory management.

Arrays Have Fixed Size


The size of an array is fixed at the time of declaration and it cannot be changed during the
program's execution. It means you need to know the maximum number of elements you need
beforehand. In C, an array cannot have a size defined in terms of a variable.

// This is accepted
#define SIZE = 10
int arr[SIZE];

// This is also accepted


const SIZE = 10;
int arr[SIZE];

// This is not accepted


int SIZE = 10;
int arr[SIZE];

// The size must be an integer; this will give an error


float num[10.5] = {50, 55, 67, 73, 45, 21, 39, 70, 49, 51};

Length of an Array Depends on Its Type

Since an array can store all the elements of same type, the total memory occupied by it depends
on the data type.

Example

Take a look at this following example −

#include<stdio.h>

int main(){

int num[10] = {50, 55, 67, 73, 45, 21, 39, 70, 49, 51};
int size = sizeof(num) / sizeof(int);

printf("Element at lower bound num[0]: %d \n", num[0]);


printf("At upper bound: %d byte \n", num[size-1]);
printf("Length of int array: %ld \n", sizeof(num));
double nm[10] = {50, 55, 67, 73, 45, 21, 39, 70, 49, 51};
size = sizeof(nm) / sizeof(double);

printf("Element at lower bound nm[0]: %f \n", nm[0]);


printf("Element at upper bound: %f \n", nm[size-1]);
printf("Byte length of double array: %ld \n", sizeof(nm));

return 0;
}

Output

When you run this code, it will produce the following output −

Element at lower bound num[0]: 50


At upper bound: 51 byte
Length of int array: 40
Element at lower bound nm[0]: 50.000000
Element at upper bound: 51.000000
Byte length of double array: 80

Array Elements Have Unique Index

Each element in an array has a unique index, starting from "0". You can access individual
elements using their index within square brackets. Usually, an array is traversed with a for
loop running over its length and using the loop variable as the index.

Example

The following example demonstrates how you can traverse an array using a for loop −

#include <stdio.h>

int main(){

int a[] = {1,2,3,4,5};


int i;

for(i = 0; i < 4; i++){


printf("a[%d]: %d \n", i, a[i]);
}

return 0;
}

Output

Run the code and check its output −

a[0]: 1
a[1]: 2
a[2]: 3
a[3]: 4

Array Pointer Relationship

The name of an array is equivalent to a constant pointer to its first element. This feature lets you
use array names and pointers interchangeably in certain contexts.

Example

Take a look at this example −

#include <stdio.h>

int main(){

int num[10] = {50, 55, 67, 73, 45, 21, 39, 70, 49, 51};

printf("num[0]: %d Address of 0th element: %d\n", num[0], &num[0]);


printf("Address of array: %d", num);

return 0;
}

Output

Run the code and check its output −


num[0]: 50 Address of 0th element: 6422000
Address of array: 6422000

Lower and Upper Bound of Arrays

Each element in an array is identified by an index starting with "0". The lower bound of an array
is the index of its first element, which is always "0". The last element in the array "size−1" as its
index.

Example

The following code shows how you can print the elments at the lower bound and at the upper
bound of an array −

#include <stdio.h>

int main(){

int num[10] = {50, 55, 67, 73, 45, 21, 39, 70, 49, 51};
int size = sizeof(num) / sizeof(int);

printf("Element at lower bound: %d", num[0]);


printf("\nElement at upper bound: %d", num[size-1]);
printf("\nSize of array: %d", size);

return 0;
}

Output

When you run this code, it will produce the following output −

Element at lower bound: 50


Element at upper bound: 51
Size of array: 10

Multi−dimensional Arrays in C

When an array is declared with one value of size in square brackets, it is called a one-
dimensional array. In a one-dimensional array, each element is identified by its index or
subscript. However, you can declare an array in C with more number of indices to simulate a
two, three or multidimensional array.

For instance, here is an example of a two-dimensional array −

int a[3][3] = {{1, 2, 3}, {11, 22, 33}, {111, 222, 333}};

You can think of a one-dimensional array as a list, and a two dimensional array as a table or a
matrix. Theoretically, there is no limit to the number of dimensions of an array, but in practice,
two-dimensional arrays are used in design of spreadsheets, databases, etc.

Implementation of Complex Data Structures Using Arrays

We can use an array in the construction of a struct data type to implement data structures such as
stacks, linked lists, and trees. For example, take a look at this stack that we have created using an
array.

typedef struct stack {


int top;
int arr[10];
} Stack;

Thus, arrays are an important tool in the armoury of a C programmer, as they can be used for
different applications. The concept of arrays in C is implemented by many subsequent
programming languages such as C++, C#, Java, etc.
Multi-dimensional Arrays in C

When an array is declared with one value of size in square brackets, it is called a one-
dimensional array. In a one-dimensional array, each element is identified by its index or
subscript. However, you can declare an array in C with more number of indices to simulate a
two, three or multidimensional array.

Multi-dimensional arrays can be termed as nested arrays. In such a case, each element in the
outer array is an array itself. Such type of nesting can be upto any level. If each element in the
outer array is another one-dimensional array, it forms a two-dimensional array. In turn, if the
inner array is an array of another set of one-dimensional array, it becomes a three-dimensional
array, and so on.

Depending on the nesting level, a multi-dimensional array is declared as follows −

type name[size1][size2]...[sizeN];

For example, the following declaration creates a three-dimensional integer array −

int threedim[3][3][3];

Two-dimensional Arrays in C

A one-dimensional array is similar to a list of elements. It is called as one-dimensional because


only one index is needed to access any element in the array. A two-dimensional array, in
contrast, is like a table or a matrix. The elements can be considered to be logically arranged in
rows and columns. Hence, the location of any element is characterized by its row number and
column number. Both the row and column index start from "0".

The following statement declares and initializes a two-dimensional array −

int arr[3][5] = {1,2,3,4,5, 10,20,30,40,50, 5,10,15,20,25};

This array arr has three rows and five columns. In C, a two-dimensional array is a row-major
array. The first square bracket always represents the dimension size of rows, and the second is
the number of columns. Obviously, the array has 3 x 5 = 15 elements. The array is initialized
with 15 comma-separated values put inside the curly brackets.

Elements are read into the array in a row-wise manner, which means the first 5 elements are
stored in the first row, and so on. Hence, the first dimension is optional in the array declaration.

int arr[ ][5] = {1,2,3,4,5, 10,20,30,40,50, 5,10,15,20,25};

To increase the readability, elements of each row can be optionally put in curly brackets as
follows −

int arr[ ][5] = {


{1,2,3,4,5},
{10,20,30,40,50},
{5,10,15,20,25}
};

The numbers are logically arranged in a tabular manner as follows −

1 2 3 4 5

10 20 30 40 50

5 10 15 20 25

The cell with row index 1 and column index 2 has 30 in it.

Example 1

The program below displays the row and column indices of each element in a 2D array −

#include <stdio.h>

int main(){

/* an array with 5 rows and 2 columns*/


int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8} };
int i, j;

/* output each array element's value */


for(i = 0; i < 5; i++){
for(j = 0; j < 2; j++){
printf("a[%d][%d] = %d\n", i,j, a[i][j] );
}
}

return 0;
}

Output

When you run this code, it will produce the following output −

a[0][0] = 0
a[0][1] = 0
a[1][0] = 1
a[1][1] = 2
a[2][0] = 2
a[2][1] = 4
a[3][0] = 3
a[3][1] = 6
a[4][0] = 4
a[4][1] = 8

In case of a two- or multi-dimensional array, the compiler assigns a memory block of the size
which is the product of dimensions multiplied by the size of the data type. In this case, the size is
3 x 5 x 4 = 60 bytes, 4 being the size of "int" data type.

Even though all the elements are stored in consecutive memory locations, we can print the
elements in row and column format with the use of nested loops.

Example 2

The following program prints a two-dimensional array in row and columns −

#include <stdio.h>

int main(){

int arr[3][5] = {1,2,3,4,5, 10,20,30,40,50, 5,10,15,20,25};


int i, j;

for(i=0; i<3; i++){


for(j=0; j<5; j++){
printf("%4d", arr[i][j]);
}
printf("\n");
}

return 0;
}

Output

When you run this code, it will produce the following output −

1 2 3 4 5
10 20 30 40 50
5 10 15 20 25

Three-dimensional Arrays in C

A 3D (three-dimensional) array is a array of 2D arrays. Such an array is declared with three


subscripts. Imagine the students appearing for an exam are seated in five halls, each hall having
twenty rows of desks, and each row has 5 tables. Such an arrangement is represented by a three-
dimensional array such as −

Students[hall][row][column]

To locate each student, you need to have three indices − hall number, row and column of the
table in the hall.

Example

The following program stores the numbers in a 3 x 3 x 3 array −

#include<stdio.h>

int main(){
int i, j, k;

int arr[3][3][3]= {
{
{11, 12, 13},
{14, 15, 16},
{17, 18, 19}
},
{
{21, 22, 23},
{24, 25, 26},
{27, 28, 29}
},
{
{31, 32, 33},
{34, 35, 36},
{37, 38, 39}
},
};

printf("Printing 3D Array Elements:\n");

for(i=0;i<3;i++){
for(j=0;j<3;j++){
for(k=0;k<3;k++){
printf("%4d",arr[i][j][k]);
}
printf("\n");
}
printf("\n");
}

return 0;
}

Output
When you run this code, it will produce the following output −

Printing 3D Array Elements:


11 12 13
14 15 16
17 18 19

21 22 23
24 25 26
27 28 29

31 32 33
34 35 36
37 38 39

Example: Row-wise Sum of Numbers

In this program, the sum of integer elements in each row of a two-dimensional array is displayed

#include <stdio.h>

int main(){

int arr[3][5] = {{1,2,3,4,5}, {10,20,30,40,50}, {5,10,15,20,25}};


int i, j;
int sum;

for(i=0; i < 3; i++){


sum = 0;
for(j = 0; j < 5; j++){
sum += arr[i][j];
}
printf("Sum of row %d: %d\n", i, sum);
}

return 0;
}

Output

When you run this code, it will produce the following output −

Sum of row 0: 15
Sum of row 1: 150
Sum of row 2: 75

Matrix Multiplication

Matrix algebra is a branch of mathematics, where a matrix is a 2D array of numbers arranged in


rows and columns. Multiplication of two matrices is possible only if the number of columns in
the first matrix is equal to the number of rows in the second matrix.

The product of two compatible matrices is equal to the dot products between rows of the first
matrix and columns of the second matrix.

If the two matrices are of size "a[m][n]" and "b[p][q]", the result of their multiplication is a
matrix of the size (the multiplication is possible only if "n" is equal to "p") is c[m][q].

The product of two matrices is the sum of the products across some row of matrix A with the
corresponding entries down some column of matrix B.

Example

The following program performs the multiplication of two matrices −

#include<stdio.h>

int main(){

int mat1[3][3] = { {2, 4, 1} , {2, 3, 9} , {3, 1, 8} };


int mat2[3][3] = { {1, 2, 3} , {3, 6, 1} , {2, 4, 7} };
int mat3[3][3], sum = 0, i, j, k;

for(i = 0; i < 3; i++){


for(j = 0; j < 3; j++){
sum = 0;
for(k = 0; k < 3; k++)
sum = sum + mat1[i][k] * mat2[k][j];
mat3[i][j] = sum;
}
}

printf("\nMatrix 1 ...\n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++)
printf("%d\t", mat1[i][j]);

printf("\n");
}

printf("\nMatrix 2 ...\n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++)
printf("%d\t", mat2[i][j]);

printf("\n");
}

printf("\nMultiplication of the two given Matrices: \n");


for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++)
printf("%d\t", mat3[i][j]);

printf("\n");
}

return 0;
}

Output

When you run this code, it will produce the following output −

Matrix 1 ...
2 4 1
2 3 9
3 1 8

Matrix 2 ...
1 2 3
3 6 1
2 4 7

Multiplication of the two given Matrices:


16 32 17
29 58 72
22 44 66
Passing Arrays as Function Arguments in C

If you want to pass an array to a function, you can use either call by value or call by
reference method. In "call by value" method, the argument to the function should be an
initialized array. Here, an array of fixed size equal to the size of the array to be passed. In "call
by reference" method, the function argument is a pointer to the array.

Passing an Array with Call by Value Method

In the following code, the main() function has an array of integers. A user-defined function
average() is called by passing the array to it. The average() function receives the array and adds
its elements using a for loop. It returns a float value representing the average of numbers in the
array.

Example 1

Take a look at the example −

#include <stdio.h>

float average(int arr[5]);

int main(){

int arr[] = {10, 34, 21, 78, 5};


float avg = average(arr);
printf("Average: %f", avg);
}

float average(int arr[5]){

int sum = 0;
int i;

for(i = 0; i < 5; i++){


printf("arr[%d]: %d\n", i, arr[i]);
sum += arr[i];
}
return (float)sum/5;
}

Output

When you run this code, it will produce the following output −

arr[0]: 10
arr[1]: 34
arr[2]: 21
arr[3]: 78
arr[4]: 5
Average: 29.600000

In the following variation, the average() function is defined with two arguments, an uninitialized
array without any size specified. The length of the array declared in the main() function is
obtained by divising the size of the array with the size of int data type.

Example 2

Take a look at the example −

#include <stdio.h>

float average(int arr[], int length);

int main(){

int arr[] = {10, 34, 21, 78, 5};


int length = sizeof(arr)/sizeof(int);
float avg = average(arr, length);
printf("Average: %f", avg);
}

float average(int arr[], int length){

int sum = 0;
int i;
for(i = 0; i < length; i++){
printf("arr[%d]: %d\n", i, arr[i]);
sum += arr[i];
}
return (float)sum/length;
}

Output

When you run this code, it will produce the following output −

arr[0]: 10
arr[1]: 34
arr[2]: 21
arr[3]: 78
arr[4]: 5
Average: 29.600000

Passing an Array with Call by Reference Method

To use this approach, we should understand that the elements in an array are of similar data type
stored in continuous memory locations, and the array size depends on the data type. Also, the
address of the 0th element is the pointer to the array.

In the following example −

int a[5] = {1,2,3,4,5};

The size of the array is 20 bytes (4 bytes for each int).

int *x = a;

Here x is the pointer to the array. It points to the 0th element. If the pointer is incremented by 1,
it points to the next element.

Example 1

Take a look at the example −

#include <stdio.h>
int main(){

int a[] = {1,2,3,4,5};


int *x = a, i;

for(i = 0; i < 5; i++){


printf("%d\n", *x);
x++;
}
return 0;
}

Output

When you run this code, it will produce the following output −

1
2
3
4
5

Let us use this characteristics for passing the array by reference. In the main() function, we
declare an array and pass its address to the max() function. The max() function traverses the
array using the pointer and returns the largest number in the array, back to the main() function.

Example 2

Take a look at the example −

#include <stdio.h>

int max(int *arr, int length);

int main(){

int arr[] = {10, 34, 21, 78, 5};


int length = sizeof(arr)/sizeof(int);
int maxnum = max(arr, length);
printf("max: %d", maxnum);
}

int max(int *arr, int length){


int max = *arr;
int i;

for(i = 0; i < length; i++){


printf("arr[%d]: %d\n", i, (*arr));
if((*arr) > max)
max = (*arr);
arr++;
}
return max;
}

Output

When you run this code, it will produce the following output −

arr[0]: 10
arr[1]: 34
arr[2]: 21
arr[3]: 78
arr[4]: 5
max: 78

The max() function receives the address of the array from main() in the pointer arr. Each time,
when it is incremented, it points to the next element in the original array.

The max() function can also access the array elements as a normal subscripted array as in the
following definition −

int max(int *arr, int length){


int max = *arr;
int i;
for(i = 0; i < length; i++){
printf("arr[%d]: %d\n", i, arr[i]);
if (arr[i] > max)
max = arr[i];
}
return max;
}

Pass a Two-dimensional Array to a Function

You can also pass the pointer of a two-dimensional array to a function. Inside the function, the
two-dimensional array is traversed with a nested for loop construct.

Example

Take a look at the following example −

#include <stdio.h>

int twoDarr(int *arr);

int main(){

int arr[][3]= {10, 34, 21, 78, 5, 25};


twoDarr(*arr);
}

int twoDarr(int *arr){


int max = *arr;
int i, j;
for(i = 0; i < 2; i++){
for(j = 0; j < 3; j++){
printf("%d\t", arr[i]);
arr++;
}
printf("\n");
}
}
Output

When you run this code, it will produce the following output −

10 34 21
5 25 16

Function to Compare String Lengths

In the following program, two strings are passed to the compare() function. In C, a string is an
array of char data type. We use the strlen() function to find the length of a string which is the
number of characters in it.

Example

Take a look at the following example −

#include <stdio.h>
#include <string.h>

int compare(char *, char *);

int main(){
char a[] = "BAT";
char b[] = "BALL";
int ret = compare(a, b);
return 0;
}

int compare (char *x, char *y){


int val;
if (strlen(x) > strlen(y)){
printf("The length of string 'a' is greater than or equal to the length of string 'b'");
}
else{
printf("The length of string 'a' is less than the length of string 'b'");
}
}
Output

When you run this code, it will produce the following output −

The length of string 'a' is less than the length of string 'b'
Return an Array from a Function in C

Functions in C help programmers to apply modular program design. A function can be defined to
accept one or more than one arguments but it can return a single value to the calling
environment. However, the function can be defined to return an array of values.

In C, a function can be made to return an array by one of following methods −

 Passing an array as argument and returning the pointer


 Declaring a static array in a function and returning its pointer
 Using the malloc() function
 Embedding an array inside a struct variable and passing it to a function

We implement these methods to calculate the square, the cube, and the square root of a given
number.

Passing an Array by Reference

In the following example, we declare an uninitialized array in main() and pass it to a function
along with an integer. Inside the function, the array is filled with the square, cube, and square
root. The function returns the pointer of this array, using which the values are access and printed
in the main() function.

Example

Take a look at the example −

#include <stdio.h>
#include <math.h>

int arrfunction(int, float *);

int main(){

int x = 100;
float arr[3];
arrfunction(x, arr);

printf("Square of %d: %f\n", x, arr[0]);


printf("Cube of %d: %f\n", x, arr[1]);
printf("Square root of %d: %f\n", x, arr[2]);

return 0;
}

int arrfunction(int x, float *arr){


arr[0] = pow(x,2);
arr[1] = pow(x, 3);
arr[2] = pow(x, 0.5);
}

Output

When you run this code, it will produce the following output −

Square of 100: 10000.000000


Cube of 100: 1000000.000000
Square root of 100: 10.000000

Return a Static Array

Instead of passing an empty array from main(), we can declare an array inside the called function
itself, fill it with the required values, and return its pointer. However, returning a pointer of a
local variable is not acceptable, as it points to a variable that no longer exists.

Note that a local variable ceases to exist as soon as the scope of the function is over. Hence, we
need to use a static array inside the called function (arrfunction) and return its pointer back to the
main() function.

Example 1

Take a look at the example −

#include <stdio.h>
#include <math.h>
float * arrfunction(int);

int main(){

int x = 100, i;
float *arr = arrfunction(x);

printf("Square of %d: %f\n", x, *arr);


printf("Cube of %d: %f\n", x, arr[1]);
printf("Square root of %d: %f\n", x, arr[2]);

return 0;
}

float *arrfunction(int x){


static float arr[3];
arr[0] = pow(x,2);
arr[1] = pow(x, 3);
arr[2] = pow(x, 0.5);

return arr;
}

Output

When you run this code, it will produce the following output −

Square of 100: 10000.000000


Cube of 100: 1000000.000000
Square root of 100: 10.000000

Example 2

Now, consider the following function which will generate 10 random numbers and return them
using an array and call this function as follows −

#include <stdio.h>
/* function to generate and return random numbers */
int * getRandom(){
static int r[10];
int i;

/* set the seed */


srand((unsigned)time(NULL));
for(i = 0; i < 10; ++i){
r[i] = rand();
printf("r[%d] = %d\n", i, r[i]);
}
return r;
}

/* main function to call above defined function */


int main(){

/* a pointer to an int */
int *p;
int i;
p = getRandom();
for(i = 0; i < 10; i++){
printf("*(p + %d): %d\n", i, *(p + i));
}
return 0;
}

Output

When the above code is compiled together and executed, it produces the following output −

r[0] = 2110147662
r[1] = 1427553496
r[2] = 1243625529
r[3] = 857484361
r[4] = 513293736
r[5] = 964923407
r[6] = 36104419
r[7] = 1248464892
r[8] = 1838450240
r[9] = 2096489563
*(p + 0): 2110147662
*(p + 1): 1427553496
*(p + 2): 1243625529
*(p + 3): 857484361
*(p + 4): 513293736
*(p + 5): 964923407
*(p + 6): 36104419
*(p + 7): 1248464892
*(p + 8): 1838450240
*(p + 9): 2096489563

Using the malloc() Function

The malloc() function is available as a library function in the stdlib.h header file. It dynamically
allocates a block of memory during the runtime of a program. Normal declaration of variables
causes the memory to be allocated at the compile time.

void *malloc(size_t size);

The malloc() function returns a generic void pointer. To assign values of a certain data type in
the allocated memory, it must be typecast to the required type. For example, to store "int" data, it
must be typecast to "int *" as follows −

int *x = (int *)malloc(sizeof(int);

Example

Let us allocate a block of memory sufficient to store three float values corresponding to the
square, cube and square root of a number, and return the float pointer to main(), inside which the
computed values are displayed.

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
float * arrfunction(int);

int main(){

int x = 16, i;
float *arr = arrfunction(x);

printf("Square of %d: %f\n", x, arr[0]);


printf("Cube of %d: %f\n", x, arr[1]);
printf("Square root of %d: %f\n", x, arr[2]);

return 0;
}

float *arrfunction(int x){


float *arr = (float *)malloc(3*sizeof(float));
arr[0] = pow(x,2);
arr[1] = pow(x, 3);
arr[2] = pow(x, 0.5);

return arr;
}

Output

When you run this code, it will produce the following output −

Square of 16: 256.000000


Cube of 16: 4096.000000
Square root of 16: 4.000000

Using Array Element in Struct

In this method, we will declare a struct, inside which there is a float array as its element. The
called function (myfunction) declares a struct variable, populates the array element with square,
cube and the square root of the argument received by it, and returns it to the main() function.
Example

Take a look at the example −

#include <stdio.h>
#include <math.h>

struct mystruct{
float arr[3];
};

struct mystruct myfunction(int x);

int main(){

int x = 9;
struct mystruct s = myfunction(x);
printf("Square of %d: %f\n", x, [Link][0]);
printf("Cube of %d: %f\n", x, [Link][1]);
printf("Square root of %d: %f\n", x, [Link][2]);

return 0;
}

struct mystruct myfunction(int x){


struct mystruct s1;
[Link][0] = pow(x,2);
[Link][1] = pow(x,3);
[Link][2] = pow(x, 0.5);

return s1;
}

Output

When you run this code, it will produce the following output −

Square of 9: 81.000000
Cube of 9: 729.000000
Square root of 9: 3.000000

Return a String from a Function

Using the same approaches, you can pass and return a string to a function. A string in C is an
array of char type. In the following example, we pass the string with a pointer, manipulate it
inside the function, and return it back to the main() function.

Inside the called function, there is a local string. The string passed is concatenated with the local
string before returning.

Example

Take a look at the example −

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char * hellomsg(char *);

int main(){
char * name = "TutorialsPoint";
char *arr = hellomsg(name);
printf("%s\n", arr);

return 0;
}

char * hellomsg(char *x){


char *arr = (char *)malloc(50*sizeof(char));
strcpy(arr, "Hello ");
strcat(arr, x);

return arr;
}

Output
When you run this code, it will produce the following output −

Hello TutorialsPoint
Variable Length Arrays in C

A variable length array in C is also called a variable-sized or runtime-sized array. It is an array


whose length is determined at the runtime rather than at the time of compiling the program. Its
size depends on a value generated during the runtime of a program, usually received as an input
from the user.

Usually, the array size is declared beforehand in the program as follows −

int arr[10];

The size of an array, once declared, remains fixed during the execution of a program and cannot
be changed during its runtime. However, in case of a Variable Length Array (VLA), the compiler
allocates the memory with automatic storage duration on the stack. The support for VLAs was
added in the C99 standard.

Creating a Variable Length Array

The syntax for creating a variable length arrays is as follows −

void arr_init(int length){

int arr[length];

//code using arr;

};

Example

The following example demonstrates how you can create a variable length array −

#include <stdio.h>

int main(){

int i, j;
int size; // variable to hold size of one-dimensional array
printf("Enter the size of one-dimensional array: ");
scanf("%d", &size);

int arr[size];

for(i = 0; i < size; ++i){


printf("Enter a number: ");
scanf("%d", &j);
arr[i] = j;
}

for(i = 0; i < size; ++i)


printf("a[%d]: %d\n", i, arr[i]);

return 0;
}

Output

When you run this code, it will ask you enter the size of the array. Notice that the length of the
array is not fixed at the time of declaration. You define its size at runtime.

Enter the size of one-dimensional array: 5


Enter a number: 1
Enter a number: 5
Enter a number: 7
Enter a number: 8
Enter a number: 7

a[0]: 1
a[1]: 5
a[2]: 7
a[3]: 8
a[4]: 7

Two-dimensional Variable Length Arrays


We can also declare and use a two-dimensional variable length array.

Example 1

Take a look at the following example −

#include <stdio.h>

int main(){

int i, j, x;

int row, col; // number of rows & columns of two D array

printf("Enter number of rows & columns of 2-D array:\n");


scanf("%d %d", &row, &col);

int arr2D[row][col];
for(i = 0; i < row; ++i){
for(j = 0; j < col; ++j){
printf("Enter a number: ");
scanf("%d", &x);
arr2D[i][j] = x;
}
}

for(i = 0; i < row; ++i){


printf("\n");
for(j = 0; j < col; ++j)
printf("%d\t", arr2D[i][j]);
}

return 0;
}

Output

Run the code and check its output −


Enter number of rows & columns of 2-D array:
2
3
Enter a number: 10
Enter a number: 20
Enter a number: 30
Enter a number: 40
Enter a number: 50
Enter a number: 60
10 20 30
40 50 60

Example 2

The following code declares a variable length one-dimensional array and populates it with
incrementing numbers −

#include <stdio.h>

int main(){

int n;

printf("Enter the size of the array: \n");


scanf("%d", &n);

int arr[n];

for(int i = 0; i < n; i++)


arr[i] = i+1;

printf("The array elements are: ");

for(int i = 0; i < n; i++)


printf("%d ", arr[i]);

return 0;
}

Output

Run the code and check its output −

Enter the size of the array:


5
The array elements are: 1 2 3 4 5 ....

Example 3

The following code fills the variable length array with randomly generated numbers using the
functions srand() and rand() from the stdlib.h header file.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void oneDArray(int length, int a[length]);

// function prototype
void twoDArray(int row, int col, int a[row][col]);

// function prototype
int main(){

int i, j;

// counter variable
int size;

// variable to hold size of one dimensional array


int row, col;

// number of rows & columns of two D array


srand(time(NULL));
printf("Enter the size of one-dimensional array: ");
scanf("%d", &size);

printf("Enter the number of rows & columns of 2-D array:\n");


scanf("%d %d", &row, &col);

// declaring arrays
int arr[size];

// 2-D array
int arr2D[row][col];

// one dimensional array


for(i = 0; i < size; ++i){
arr[i] = rand() % 100 + 1;
}

// two dimensional array


for(i = 0; i < row; ++i){
for(j = 0; j < col; ++j){
arr2D[i][j] = rand() % 100 + 1;
}
}

// printing arrays
printf("One-dimensional array:\n");

// oneDArray(size, arr);
for(i = 0; i < size; ++i)
printf("a[%d]: %d\n", i, arr[i]);
printf("\nTwo-dimensional array:\n");

// twoDArray(row1, col1, arr2D);


for(i = 0; i < row; ++i){
printf("\n");
for (j = 0; j < col; ++j)
printf("%5d", arr2D[i][j]);
}
}

Output

Run the code and check its output −

Enter the size of one-dimensional array: 5


Enter the number of rows & columns of 2-D array:
44
One-dimensional array:
a[0]: 95
a[1]: 93
a[2]: 4
a[3]: 52
a[4]: 68

Two-dimensional array:
92 19 79 23
56 21 44 98
8 22 89 54
93 1 63 38

Jagged Array

A jagged array is a collection of two or more arrays of similar data types of variable length. In C,
the concept of jagged array is implemented with the help of pointers of arrays.

A jagged array is represented by the following figure −


Example

In this program, we declare three one-dimensional arrays of different sizes and store their
pointers in an array of pointers that acts as a jagged array.

#include <stdio.h>

int main(){

int a[] = {1,2};


int b[] = {3,4,5};
int c[] = {6,7,8,9};

int l1 = sizeof(a)/sizeof(int),
l2 = sizeof(b)/sizeof(int),
l3 = sizeof(c)/sizeof(int);

int *arr[] = {a,b,c};


int size[] = {l1, l2, l3};
int *ptr;
int i, j, k = 0;

for(i = 0; i < 3; i++){


ptr = arr[i];
for(j = 0; j < size[k]; j++){
printf("%d\t", *ptr);
ptr++;
}
printf("\n");
k++;
arr[i]++;
}

return 0;
}

Output

When you run this code, it will produce the following output −

1 2
3 4 5
6 7 8 9

VLA is a fast and more straightforward option compared to heap allocation. VLAs are supported
by most modern C compilers such as GCC, Clang etc. and are used by most compilers.

Pointers in C

Pointers in C are easy and fun to learn. Some complex C programming tasks can be performed
more easily with pointers, while some other tasks such as dynamic memory allocation cannot be
performed without using pointers. So it becomes necessary to learn pointers to become a perfect
C programmer.

With pointers, you can access and modify the data located in the memory, pass the data
efficiently between the functions, and create dynamic data structures like linked lists, trees, and
graphs.

Example: Address of the Variables

As you know, every variable is a memory location and every memory location has its address
defined which can be accessed using the ampersand (&) operator, which denotes an address in
memory.

Consider the following example, which prints the address of the variables defined −

#include <stdio.h>
int main(){

int var1;
char var2[10];

printf("Address of var1 variable: %x\n", &var1);


printf("Address of var2 variable: %x\n", &var2);

return 0;
}

Output

When the above code is compiled and executed, it will print the address of the variables −

Address of var1 variable: 61e11508


Address of var2 variable: 61e1150e

What are Pointers?

A pointer is a variable that stores the reference to another variable, which may be of any type
such as int, float or char, an array (one or multidimensional), struct or union, or even a pointer
type itself.

A pointer is a variable whose value is the address of another variable, i.e., the direct address of a
memory location. Like any variable or constant, you must declare a pointer before using it to
store any variable address. The general form of a pointer variable declaration is −

type *var-name;

Here, type is the pointer's base type; it must be a valid C data type and var-name is the name of
the pointer variable. The asterisk * used to declare a pointer is the same asterisk used for
multiplication. However, in this statement the asterisk is being used to designate a variable as a
pointer. Take a look at some of the valid pointer declarations −

int *ip; /* pointer to an integer */


double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is
the same, a long hexadecimal number that represents a memory address. The only difference
between pointers of different data types is the data type of the variable or constant that the
pointer points to.

Referencing and Dereferencing in C

A pointer references a location in memory. Obtaining the value stored at that location is known
as dereferencing the pointer.

In C, it is important to understand the purpose of the following two operators in the context of
pointer mechanism −

 The & Operator − It is also known as the "Address-of operator". It is used for Referencing
which means taking the address of an existing variable (using &) to set a pointer variable.
 The * Operator − It is also known as the "dereference operator". Dereferencing a pointer
is carried out using the * operator to get the value from the memory address that is pointed
by the pointer.

Pointers are used to pass parameters by reference. This is useful if a programmer wants a
function's modifications to a parameter to be visible to the function's caller. This is also useful
for returning multiple values from a function.

How to Use Pointers?

There are a few important operations, which we will do with the help of pointers very
frequently. (a) We define a pointer variable, (b) assign the address of a variable to a pointer
and (c) finally access the value at the address available in the pointer variable. This is done by
using unary operator * that returns the value of the variable located at the address specified by its
operand.

Example 1: Using Pointers in C

The following example shows how you can use the & and * operators to carry out pointer-related
opeartions in C −

#include <stdio.h>

int main(){

int var = 20; /* actual variable declaration */


int *ip; /* pointer variable declaration */

ip = &var; /* store address of var in pointer variable*/


printf("Address of var variable: %x\n", &var);

/* address stored in pointer variable */


printf("Address stored in ip variable: %x\n", ip);

/* access the value using the pointer */


printf("Value of *ip variable: %d\n", *ip );

return 0;
}

Output

Execute the code and check its output −

Address of var variable: db7d8b8c


Address stored in ip variable: db7d8b8c
Value of *ip variable: 20

To declare a pointer variable, the following syntax is to be used −

type *var;

The name of the variable must be prefixed with an asterisk (*).

The data type indicates the type of variable the address of which it can store. For example, "int
*x;". Here, the variable "x" is meant to store the address of another int variable.

Similarly, in "float *y; the variable "y" is a pointer that stores the memory location of a float
variable.

The & operator returns the address of an existing variable. We can assign it to the pointer
variable. Take a look at the following code snippet −

int a;
int *x = &a;

Assuming that the compiler creates the variable "a" at the address 1000 and "x" at the address
2000, then the address of "a" is stored in "x".
The deference operator returns the value at the address stored in the pointer variable. Here "*x"
will return the value of "a", i.e., the value stored in the memory address 1000, which in fact is the
value of "x". Let us understand this with the help of the following example.

Example 2

We will declare an int variable and display its value and address −

#include <stdio.h>

int main(){

int var = 100;

printf("Variable: %d \t Address: %d", var, &var);


}

Output

Run the code and check its output −

Variable: 100 Address: 6422044

Example 3

We can also use %p format specifier to obtain the hexadecimal number of the memory address.

#include <stdio.h>
int main(){

int var = 100;

printf("Variable: %d \nAddress: %p", var, &var);


}

Output

Run the code and check its output −

Variable: 100
Address: 000000000061FE1C

Example 4

In this example, the address of var is stored in the intptr variable with & operator

#include <stdio.h>

int main(){

int var = 100;


int *intptr = &var;

printf("Variable: %d \nAddress of Variable: %d \n\n", var, &var);


printf("intptr: %ld \nAddress of intptr: %d \n\n", intptr, &intptr);
}

Output

Run the code and check its output −

Variable: 100
Address of Variable: 2043225868

intptr: 140722351712012
Address of intptr: 2043225872
Example 5

Now let's take an example of a float variable and find its address −

#include <stdio.h>

int main(){

float var1 = 10.55;

printf("var1: %f \n", var1);


printf("Address of var1: %d", &var1);
}

Output

Run the code and check its output −

var1: 10.550000
Address of var1: 1512452612

We can see that the address of this variable (any type of variable for that matter) is an integer.
So, if we try to store it in a pointer variable of "float" type, see what happens −

float var1 = 10.55;


int *intptr = &var1;

The compiler doesn’t accept this, and reports the following error −

initialization of 'int *' from incompatible pointer type


'float *' [-Wincompatible-pointer-types]

Note: The type of a variable and the type of its pointer must be same.

In C, variables have specific data types that define their size and how they store values.
Declaring a pointer with a matching type (e.g., float *) enforces "type compatibility" between the
pointer and the data it points to.

Different data types occupy different amounts of memory space in C. For example, an "int"
typically takes 4 bytes, while a "float" might take 4 or 8 bytes depending on the system. Adding
or subtracting integers from pointers moves them in memory based on the size of the data they
point to.
Example 6

In this example, we declare a variable "floatptr" of "float *" type.

#include <stdio.h>

int main(){

float var1 = 10.55;


float *floatptr = &var1;

printf("var1: %f \nAddress of var1: %d \n\n", var1, &var1);


printf("floatptr: %d \nAddress of floatptr: %d", floatptr, &floatptr);
}

Output

var1: 10.550000
Address of var1: 443414940

floatptr: 443414940
Address of floatptr: 443414944

The * operator is called the dereference operator. It returns the value of the variable that the
pointer is pointing to.

Example 7

Take a look at the following example −

#include <stdio.h>

int main(){

float var1 = 10.55;


float *floatptr = &var1;

printf("var1: %f \nAddress of var1: %d \n\n",var1, &var1);


printf("floatptr: %d \nAddress of floatptr: %d \n\n", floatptr, &floatptr);
printf("var1: %f \nValue at floatptr: %f", var1, *floatptr);
}

Output

Run the code and check its output −

var1: 10.550000
Address of var1: 451729484

floatptr: 451729484
Address of floatptr: 451729488

var1: 10.550000
Value at floatptr: 10.550000

We may have a pointer variable that stores the address of another pointer itself.

In the above figure, "a" is a normal "int" variable, whose pointer is "x". In turn, the variable
stores the address of "x".

Note that "y" is declared as "int **" to indicate that it is a pointer to another pointer variable.
Obviously, "y" will return the address of "x" and "*y" is the value in "x" (which is the address of
"a").

To obtain the value of "a" from "y", we need to use the expression "**y". Usually, "y" will be
called as the pointer to a pointer.

Example 8
Take a look at the following example −

#include <stdio.h>

int main(){

int var = 10;


int *intptr = &var;
int **ptrptr = &intptr;

printf("var: %d \nAddress of var: %d \n\n",var, &var);


printf("inttptr: %d \nAddress of inttptr: %d \n\n", intptr, &intptr);
printf("var: %d \nValue at intptr: %d \n\n", var, *intptr);
printf("ptrptr: %d \nAddress of ptrtptr: %d \n\n", ptrptr, &ptrptr);
printf("intptr: %d \nValue at ptrptr: %d \n\n", intptr, *ptrptr);
printf("var: %d \n*intptr: %d \n**ptrptr: %d", var, *intptr, **ptrptr);

return 0;
}

Output

Run the code and check its output −

var: 10
Address of var: 951734452

inttptr: 951734452
Address of inttptr: 951734456

var: 10
Value at intptr: 10

ptrptr: 951734456
Address of ptrtptr: 951734464
intptr: 951734452
Value at ptrptr: 951734452
var: 10
*intptr: 10
**ptrptr: 10

You can have a pointer to an array as well as a derived type defined with struct. Pointers have
important applications. They are used while calling a function by passing the reference. Pointers
also help in overcoming the limitation of a function’s ability to return only a single value. With
pointers, you can get the effect of returning multiple values or arrays.

NULL Pointers

It is always a good practice to assign a NULL value to a pointer variable in case you do not have
an exact address to be assigned. This is done at the time of variable declaration. A pointer that is
assigned NULL is called a null pointer.

The NULL pointer is a constant with a value of "0" defined in several standard libraries.

Example

Consider the following program −

#include <stdio.h>

int main(){

int *ptr = NULL;

printf("The value of ptr is : %x\n", ptr);

return 0;
}

Output

When the above code is compiled and executed, it produces the following result −

The value of ptr is 0


In most operating systems, programs are not permitted to access memory at address "0" because
that memory is reserved by the operating system.

The memory address "0" has a special significance; it signals that the pointer is not intended to
point to an accessible memory location. But by convention, if a pointer contains the null (zero)
value, it is assumed to point to nothing.

To check for a null pointer, you can use an if statement as follows −

if(ptr) /* succeeds if p is not null */


if(!ptr) /* succeeds if p is null */

Pointers in Detail

Pointers have many but easy concepts and they are very important to C programming. The
following important pointer concepts should be clear to any C programmer −

[Link] Concept & Description

Pointer arithmetic
1 There are four arithmetic operators that can be used in pointers:
++, --, +, -

Array of pointers
2
You can define arrays to hold a number of pointers.

Pointer to pointer
3
C allows you to have pointer on a pointer and so on.

Passing pointers to functions in C


Passing an argument by reference or by address enable the
4
passed argument to be changed in the calling function by the
called function.

Return pointer from functions in C


5 C allows a function to return a pointer to the local variable, static
variable, and dynamically allocated memory as well.
C - Pointer arithmetic

A pointer variable in C stores the address of another variable. The address is always an integer.
So, can we perform arithmetic operations such as addition, subtraction etc. on the pointers? In
this chapter, we discuss which arithmetic operators use pointers in C as operands, and which
operations are not defined to be performed with pointers.

Increment/decrement operators
We know that the symbols ++ and -- are defined as increment and decrement operators in C.
They are unary operators, used in prefix or postfix manner with numeric variable operands, and
increment or decrement the value of the variable by one.

Assume that an integer variable x is created at address 1000 in the memory, with 10 as its value.
The x++ statement makes x as 11.

int x = 10; //created at address 1000


x++; // x becomes 11

What happens if we declare y as pointer to x and increment y by 1 (with y++)? Assume that the
address of y itself is 2000.

int x = 10; //created at address 1000


int *y = &x ; // y is created at address 2000 and holds 1000 – address of x
y++; //y becomes 1004

Since the variable y stores 1000 (the address of x), we expect it to become 1001 because of ++
operator, but increment by 4, which is the size of int variable.

The reason behind this is, if address of x 1000, it occupies 4 bytes 1000, 1001, 1002 and 1003.
Hence, the next integer can be put only in 1004 and not before it. Hence y the pointer to x
becomes 1004 when incremented.

Example

Let us see the realistic example −

#include <stdio.h>
int main(){
int x = 10;
int *y = &x;
printf("value of y before increment: %d\n", y);
y++;
printf("value of y after increment: %d", y);
}

Output

value of y before increment: 6422036


value of y after increment: 6422040
You can see that the value has increased by 4.

Similarly, the -- operator decrements the value by the size of the data type. Let us change the
types of x and y to double and float * and see the effect of decrement operator.

Example

#include <stdio.h>
int main(){
double x = 10;
double *y = &x;
printf("value of y before decrement: %ld\n", y);
y--;
printf("value of y after decrement: %ld", y);
}

Output

value of y before decrement: 6422032


value of y after decrement: 6422024

When an array is declared, the elements are stored in adjacent memory locations. In case of int
array, each array subscript is placed apart by 4 bytes, as the following figure shows −

Hence, if a variable stores the address of 0th element of the array, increment takes it to the 1st
element. Likewise, we can traverse the array by incrementing the pointer successively.

Example

#include <stdio.h>
int main(){
int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int len = sizeof(a)/sizeof(int);
int *x = a;
int i = 0;
for (i=0; i<len; i++){
printf("Address of subscript %d = %d Value = %d\n", i, x, *x);
x++;
}
return 0;
}

Output

Address of subscript 0 = 6421984 Value = 10


Address of subscript 1 = 6421988 Value = 20
Address of subscript 2 = 6421992 Value = 30
Address of subscript 3 = 6421996 Value = 40
Address of subscript 4 = 6422000 Value = 50
Address of subscript 5 = 6422004 Value = 60
Address of subscript 6 = 6422008 Value = 70
Address of subscript 7 = 6422012 Value = 80
Address of subscript 8 = 6422016 Value = 90
Address of subscript 9 = 6422020 Value = 100

Addition/subtraction of pointers

We are familiar with + and − operators when used with normal numeric operands. When used
with pointers, their behaviour is a little different.

Since the pointers are fairly large integers (especially in modern 64 bit systems), addition of two
pointers is meaningless. When we add a 1 to a pointer, it points to next location where an integer
may be stored. Obviously, when we add a pointer (itself a large integer), the location it points,
may not be in the memory layout.

However, subtraction of two pointers is realistic. It returns the number of data types that can fit
in the two pointers.

Let us the array in the previous example, and perform the subtraction of pointers of a[0] and a[9]

Example

#include <stdio.h>
int main(){
int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *x = &a[0]; //zeroth element
int *y = &a[9]; //last element
printf("Add of a[0]: %ld add of a[9]: %ld\n", x, y);
printf("subtraction of two pointers: %ld", y-x);
}

Output

Add of a[0]: 140729162482768 add of a[9]: 140729162482804


subtraction of two pointers: 9

It can be seen that the numerical difference between the two integers is 36, it tells that the
subtraction is 9, because it can accommodate 9 integers between the two pointers.

Pointer Comparisons

Pointers may be compared by using relational operators, such as ==, <, and >. If p1 and p2 point
to variables that are related to each other, such as elements of the same array, then p1 and p2 can
be meaningfully compared.

The following program modifies the previous example − one by incrementing the variable
pointer so long as the address to which it points is either less than or equal to the address of the
last element of the array, which is &var[MAX − 1]

Example

#include <stdio.h>
const int MAX = 3;
int main () {
int var[] = {10, 100, 200};
int i, *ptr;

/* let us have address of the first element in pointer */


ptr = var;
i = 0;
while ( ptr <= &var[MAX - 1] ) {
printf("Address of var[%d] = %d\n", i, ptr );
printf("Value of var[%d] = %d\n", i, *ptr );

/* point to the previous location */


ptr++;
i++;
}
return 0;
}

Output

Address of var[0] = 6422020


Value of var[0] = 10
Address of var[1] = 6422024
Value of var[1] = 100
Address of var[2] = 6422028
Value of var[2] = 200

Passing pointers to functions in C

A pointer In C is a variable that stores the address of another variable. The pointer acts as a
reference to the original variable. A pointer can be passed to a function, just like any other is
passed. A function in C can be called in two ways −

 Call by value and


 Call by reference.

To call a function by reference, you need to define it to receive the pointer to a variable in the
calling function.

Syntax

type function_name(type *var1, type *var2, . . .)

When a function is called by reference, the pointer of the actual argument variables passed,
instead of their values.

Passing pointer to a function has two advantages −

 It overcomes the limitation of pass by value. Changes to the value inside the called function
are done directly at the address stored in the pointer. Hence, we can manipulate the
variables in one scope from another.
 It also overcomes the limitation of a function that it is able to return only one expression.
By passing pointers, the effect of processing of a function takes place directly at the
address. Secondly, imore than one values can be returned if we return pointer of an array
or struct variable.
In this chapter, we shall see how to −

 Pass pointers to int variables


 pass pointers to array
 pass pointer to structure

Let us define add() function that receives the references of two variables. When such a function
is called, we pass the address of the actual argument. Let us call add() function by reference from
inside main() function.

Example

#include <stdio.h>

/* function declaration */
int add(int *, int *);
int main(){
int a=10, b=20;
int c = add(&a, &b);
printf("addition : %d", c);
}
int add(int *x, int *y){
int z = *x + *y;

return z;
}

Output

addition :30

One of the most cited applications of passing a pointer to a function is how we can swap the
values of two variables.

Swap values by passing pointers

The following function receives the reference of two variables whose values are to be swapped.

/* function definition to swap the values */


int swap(int *x, int *y){
int z;
z = *x; /* save the value at address x */
*x = *y; /* put y into x */
*y = z; /* put z into y */

return 0;
}

The main() function has two variables a and b, their addresses are passes as arguments to swap()
function.

Example

#include <stdio.h>
int swap(int *x, int *y){
int z;
z = *x;
*x = *y;
*y = z;
}
int main () {

/* local variable definition */


int a = 10;
int b = 20;
printf("Before swap, value of a : %d\n", a );
printf("Before swap, value of b : %d\n", b );

/* calling a function to swap the values */


swap(&a, &b);
printf("After swap, value of a : %d\n", a );
printf("After swap, value of b : %d\n", b );

return 0;
}

Output

The result of the program when executed is −


Before swap, value of a : 10
Before swap, value of b : 20
After swap, value of a : 20
After swap, value of b : 10

Pass array pointer to a function

In C, the name of array is the address of the first element of the array, or in other words, the
pointer to array. In the following example, we declare an uninitialized array in main() and pass
its pointer to a function, along with an integer. Inside the function, the array is filled with the
square, cube and square root. The function returns the pointer of this array, using which the
values are access and printed in main() function.

Example

#include <stdio.h>
#include <math.h>
int arrfunction(int, float *);
int main(){
int x=100;
float arr[3];
arrfunction(x, arr);
printf("Square of %d: %f\n", x, arr[0]);
printf("cube of %d: %f\n", x, arr[1]);
printf("Square root of %d: %f\n", x, arr[2]);

return 0;
}
int arrfunction(int x, float *arr){
arr[0]=pow(x,2);
arr[1]=pow(x, 3);
arr[2]=pow(x, 0.5);
}

Output

Square of 100: 10000.000000


cube of 100: 1000000.000000
Square root of 100: 10.000000
Pass string pointers to Function to compare lengths

Let us have a look at another example, where pointers are passed to a function. In the following
program, two strings are passed to compare() functions. In C, as string is an array of char data
type. We use strlen() function to find the length of string which is the number of characters in it.

Example

#include <stdio.h>
#include <string.h>
int compare( char *, char *);
int main() {
char a[] = "BAT";
char b[] = "BALL";
int ret = compare(a, b);
return 0;
}
int compare (char *x, char *y){
int val;
if (strlen(x)>strlen(y)){
printf("length of string a is greater than or equal to length of string b");
}
else{
printf("length of string a is less than length of string b");
}
}

Output

length of string a is less than length of string b

Pass struct pointer to function

In C, a structure is a heterogenous data type, with its elements of different data types. In the
example explained below, a struct variable of rectangle type is declared in main() and its address
is passed to a user−defined function − area(). When called, the area() function is able to use the
elements of the variable with the indirection operator −>. It computes the result and assigns it to
the area element r−>area.
Example

#include <stdio.h>
#include <string.h>
struct rectangle{
float len, brd;
double area;
};
int area(struct rectangle *);
int main () {
struct rectangle s;
printf("Input length and breadth of a rectangle");
scanf("%f %f", &[Link], &[Link]);
area(&s);
return 0;
}
int area(struct rectangle *r){
r->area = (double)(r->len*r->brd);
printf("Length: %f \n Breadth: %f \n Area: %lf\n", r->len, r->brd, r->area);
return 0;
}

Output

Input length and breadth of a rectangle


10.5 20.5
Length: 10.500000
Breadth: 20.500000
Area: 215.250000

The logical extension of the concept of passing pointer to a function leads to passing Union
pointer, pointer of a multi−dimensional array, passing pointer of a self−referential structure etc.,
all these have important uses in different application areas such as complex data structures,
hardware control programming etc.

C - Strings

Strings are actually one-dimensional array of characters terminated by a null character '\0'. Thus
a null-terminated string contains the characters that comprise the string followed by a null.
The following declaration and initialization create a string consisting of the word "Hello". To
hold the null character at the end of the array, the size of the character array containing the string
is one more than the number of characters in the word "Hello."

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

If you follow the rule of array initialization then you can write the above statement as follows −

char greeting[] = "Hello";

Following is the memory presentation of the above defined string in C/C++ −

Actually, you do not place the null character at the end of a string constant. The C compiler
automatically places the '\0' at the end of the string when it initializes the array. Let us try to print
the above mentioned string −

Live Demo
#include <stdio.h>

int main () {

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};


printf("Greeting message: %s\n", greeting );
return 0;
}

When the above code is compiled and executed, it produces the following result −

Greeting message: Hello

C supports a wide range of functions that manipulate null-terminated strings –


[Link]. Function & Purpose

strcpy(s1, s2);
1
Copies string s2 into string s1.

strcat(s1, s2);
2
Concatenates string s2 onto the end of string s1.

strlen(s1);
3
Returns the length of string s1.

strcmp(s1, s2);
4 Returns 0 if s1 and s2 are the same; less than 0 if s1<s2; greater
than 0 if s1>s2.

strchr(s1, ch);
5 Returns a pointer to the first occurrence of character ch in string
s1.

strstr(s1, s2);
6
Returns a pointer to the first occurrence of string s2 in string s1.

The following example uses some of the above-mentioned functions −

Live Demo
#include <stdio.h>
#include <string.h>

int main () {

char str1[12] = "Hello";


char str2[12] = "World";
char str3[12];
int len ;

/* copy str1 into str3 */


strcpy(str3, str1);
printf("strcpy( str3, str1) : %s\n", str3 );

/* concatenates str1 and str2 */


strcat( str1, str2);
printf("strcat( str1, str2): %s\n", str1 );
/* total lenghth of str1 after concatenation */
len = strlen(str1);
printf("strlen(str1) : %d\n", len );

return 0;
}

When the above code is compiled and executed, it produces the following result −

strcpy( str3, str1) : Hello


strcat( str1, str2): HelloWorld
strlen(str1) : 10

C - Array of Strings

In C, a string is a one−dimensional array of char data type. It is a sequence of characters


terminated by null character (\0). An array of strings therefore is an array of char arrays. An
array of strings in C is a two−dimensional array of char type. Each row stores one null
terminated string.

To declare a string we use the statement −

char string[] = {'H', 'e', 'l', 'l', 'o', '\0'};

or

char string = "Hello";

To construct an array of strings, the following syntax is used −

char strings [no of strings] [max size of each string];

Let us declare and initialize an array of strings to store names of Ten computer languages, each
with the maximum length of fifteen characters.

char langs [10][15] = {


"PYTHON",
"JAVASCRIPT",
"PHP",
"NODE JS",
"HTML",
"KOTLIN",
"C++",
"REACT JS",
"RUST",
"VBSCRIPT"
};

How is this array stored in the memory? We know that each char type occupies 1 byte in the
memory. Hence, this array will be allocated a block of 150 bytes. Although this block is
contagious memory locations, each group of 15 bytes constitutes a row.

Assuming that the array is situated at memory address 1000, the logical layout of this array can
be shown as in the following figure −

We can employ a loop to print the contents of this string array.

Example

#include <stdio.h>
int main () {
char langs [10][15] = {
"PYTHON",
"JAVASCRIPT",
"PHP",
"NODE JS",
"HTML",
"KOTLIN",
"C++",
"REACT JS",
"RUST",
"VBSCRIPT"
};
int i;
for (i=0; i<10; i++){
printf("%s\n", langs[i]);
}
return 0;
}

Output

PYTHON
JAVASCRIPT
PHP
NODE JS
HTML
KOTLIN
C++
REACT JS
RUST
VBSCRIPT

Note that, the size of each string is not equal to the row size in the declaration of the array. The
\0 symbol signals the termination of the string, and the remaining cells in the row are empty.
Thus a substantial part of the memory allocated to the array is unused and thus wasted.

To use the memory more efficiently, we can use the pointers. Instead of a two−dimensional char
array, we declare a one−dimensional array of char * type.

char *langs [10] = {


"PYTHON",
"JAVASCRIPT",
"PHP",
"NODE JS",
"HTML",
"KOTLIN",
"C++",
"REACT JS",
"RUST",
"VBSCRIPT"
};

In the two−dimensional array of characters, the strings occupied 150 bytes. As against this, in
array of pointers, the strings occupy far less number of bytes, as each string is randomly
allocated memory as shown below −

The lang[] array is an array of pointers of individual strings.

We can use the for loop as follows to print the array of strings −
Example

#include <stdio.h>
int main(){
char *langs [10] = {
"PYTHON",
"JAVASCRIPT",
"PHP",
"NODE JS",
"HTML",
"KOTLIN",
"C++",
"REACT JS",
"RUST",
"VBSCRIPT"
};
int i;
for (i=0; i<10; i++)
printf("%s\n", langs[i]);
return 0;
}

Output

PYTHON
JAVASCRIPT
PHP
NODE JS
HTML
KOTLIN
C++
REACT JS
RUST
VBSCRIPT

The langs is a pointer to an array of 10 strings. Therefore, if langs[0] points to address 5000 then
langs+1 will point to address 5004 which stores the pointer to the second string..
Hence, we can also use the following variation of the loop to print the array of strings.

int i;
for (i=0; i<10; i++){
printf("%s\n", *(langs+i));
}

When strings are stored in array, there are a lot use cases. Let study some of the use cases.

Find the string with largest length

We store the length of first string and its position (which is 0) in the variables l and p
respectively. Inside a for loop, we update these variables whenever a string of larger length is
found.

Example

#include <stdio.h>
#include <string.h>
int main () {
char langs [10][15] = {
"PYTHON",
"JAVASCRIPT",
"PHP",
"NODE JS",
"HTML",
"KOTLIN",
"C++",
"REACT JS",
"RUST",
"VBSCRIPT"
};
int i;
int l = strlen(langs[0]); int p = 0;
for (i=0; i<10; i++){
if (strlen(langs[i])>=l){
l=strlen(langs[i]);
p=i;
}

}
printf("Language with longest name: %s Length: %d", langs[p], l);
return 0;
}

Output

Language with longest name: JAVASCRIPT Length: 10

Sort string array in ascending order

We need to use the strcmp() function for comparison of two strings. If the value of comparison
of strings is greater than 0, it means that the first argument string appears later than the second in
alphabetical order. We then swap these two strings with strcmp() function.

Example

#include <stdio.h>
#include <string.h>
int main () {
char langs [10][15] = {
"PYTHON",
"JAVASCRIPT",
"PHP",
"NODE JS",
"HTML",
"KOTLIN",
"C++",
"REACT JS",
"RUST",
"VBSCRIPT"
};
int i, j;
char temp[15];
for (i=0; i<9; i++){
for (j=i+1; j<10; j++){
if (strcmp(langs[i], langs[j])>0){
strcpy(temp, langs[i]);
strcpy(langs[i], langs[j]);
strcpy(langs[j], temp);
}
}
}
for (i=0; i<10; i++){
printf("%s\n", langs[i]);
}
return 0;
}

Output

C++
HTML
JAVASCRIPT
KOTLIN
NODE JS
PHP
PYTHON
REACT JS
RUST
VBSCRIPT

In this chapter, we have learned how to declare an array of strings, and how to manipulate it with
the help of string functions. The string.h header file provides a number of library functions for
string manipulations. These functions will be discussed in a separate chapter in this tutorial.

Structures in C

A structure in C is a derived or user-defined data type. We use the keyword struct to define a
custom data type that groups together the elements of different types. The difference between an
array and a structure is that an array is a homogenous collection of similar types, whereas a
structure can have elements of different type stored adjacently and identified by a name.

We are often required to work with values of different data types having certain relationship
among them. For example, a book is described by
its title (string), author (string), price (double), number of pages (integer), etc. Instead of using
four different variables, these values can be stored in a single struct variable.

Defining a Structure

To define a structure, you must use the struct statement. The struct statement defines a new data
type, with more than one member.

The format of the struct statement is as follows −

struct [structure tag]{


member definition;
member definition;
...
member definition;
} [one or more structure variables];

The structure tag is optional and each member definition is a normal variable definition, such as
"int i;" or "float f;" or any other valid variable definition.

At the end of the structure's definition, before the final semicolon, you can specify one or more
structure variables but it is optional.

Here is the way you would declare the Books structure −

struct book{
char title[50];
char author[50];
double price;
int pages;
} book1;

Here, we declared the structure variable book1 at the end of the structure definition. However,
you can do it separately in a different statement.

To declare a variable of this type, use the following syntax −

struct book book1;

Usually, a structure is declared before the first function is defined in the program, after
the include statements. That way, the derived type can be used for declaring its variable inside
any function.
The initialization of a struct variable is done by placing the value of each element inside curly
brackets.

struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325};

Accessing the Structure Members

The four elements of the struct variable book1 are accessed with the dot (.) operator. Hence,
"[Link]" refers to the title element, "[Link]" is the author name, "[Link]" is the
price, "[Link]" is the fourth element (number of pages).

Example 1

Take a look at the following example −

#include <stdio.h>

struct book{
char title[10];
char author[20];
double price;
int pages;
};

int main(){
struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325};

printf("Title: %s \n", [Link]);


printf("Author: %s \n", [Link]);
printf("Price: %lf\n", [Link]);
printf("Pages: %d \n", [Link]);
printf("Size of book struct: %d", sizeof(struct book));
return 0;
}

Output

Run the code and check its output −

Title: Learn C
Author: Dennis Ritchie
Price: 675.500000
Pages: 325
Size of book struct: 48

Example 2

In the above program, we will make a small modification. Here, we will put the type
definition and the variable declaration together, like this −

struct book{
char title[10];
char author[20];
double price;
int pages;
} book1;

Note that if you a declare a struct variable in this way, then you cannot initialize it with curly
brackets. Instead, the elements need to be assigned individually.

#include <stdio.h>
#include <string.h>

struct book{
char title[10];
char author[20];
double price;
int pages;
} book1;

int main(){
strcpy([Link], "Learn C");
strcpy([Link], "Dennis Ritchie");
[Link] = 675.50;
[Link] = 325;

printf("Title: %s \n", [Link]);


printf("Author: %s \n", [Link]);
printf("Price: %lf \n", [Link]);
printf("Pages: %d \n", [Link]);
return 0;
}

Output

When you execute this code, it will produce the following output −

Title: Learn C
Author: Dennis Ritchie
Price: 675.500000
Pages: 325

The "= operator" can be used to assign one struct variable to another. Let's have two struct book
variables, book1 and book2. The variable book1 is initialized with declaration, and we wish to
assign the same values of its elements to that of book2.

We can assign individual elements as follows −

struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}, book2;
strcpy([Link], [Link]);
strcpy([Link], [Link]);
[Link] = [Link];
[Link] = [Link];

Note the use of strcpy() function to assign the value to a string variable instead of using the "=
operator".

Example 3

You can also assign book1 to book2 so that all the elements of book1 are respectively assigned
to the elements of book2. Take a look at the following program code −

#include <stdio.h>
#include <string.h>

struct book{
char title[10];
char author[20];
double price;
int pages;
};

int main(){
struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}, book2;
book2 = book1;

printf("Title: %s \n", [Link]);


printf("Author: %s \n", [Link]);
printf("Price: %lf \n", [Link]);
printf("Pages: %d \n", [Link]);
printf("Size of book struct: %d", sizeof(struct book));
return 0;
}

Output

Run the code and check its output −

Title: Learn C
Author: Dennis Ritchie
Price: 675.500000
Pages: 325
Size of book struct: 48

Structures as Function Arguments

You can pass a structure as a function argument in the same way as you pass any other variable
or pointer.

Example

Take a look at the following program code. It demonstrates how you can pass a structure as a
function argument −

#include <stdio.h>
#include <string.h>
struct Books{
char title[50];
char author[50];
char subject[100];
int book_id;
};

/* function declaration */
void printBook(struct Books book);

int main(){
struct Books Book1; /* Declare Book1 of type Book */
struct Books Book2; /* Declare Book2 of type Book */

/* book 1 specification */
strcpy([Link], "C Programming");
strcpy([Link], "Nuha Ali");
strcpy([Link], "C Programming Tutorial");
Book1.book_id = 6495407;

/* book 2 specification */
strcpy([Link], "Telecom Billing");
strcpy([Link], "Zara Ali");
strcpy([Link], "Telecom Billing Tutorial");
Book2.book_id = 6495700;

/* print Book1 info */


printBook(Book1);

/* Print Book2 info */


printBook(Book2);
return 0;
}

void printBook(struct Books book){


printf("Book title : %s\n", [Link]);
printf("Book author : %s\n", [Link]);
printf("Book subject : %s\n", [Link]);
printf("Book book_id : %d\n", book.book_id);
}

Output

When the above code is compiled and executed, it produces the following result −

Book title : C Programming


Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
Book title : Telecom Billing
Book author : Zara Ali
Book subject : Telecom Billing Tutorial
Book book_id : 6495700

Pointers to Structures

You can define pointers to structures in the same way as you define pointers to any other
variable −

struct Books *struct_pointer;

You can store the address of a structure variable in the above pointer variable struct_pointer. To
find the address of a structure variable, place the '&' operator before the structure's name as
follows −

struct_pointer = & book1;

Let's store the address of a struct variable in a struct pointer variable.

struct book{
char title[10];
char author[20];
double price;
int pages;
};
struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325},
struct book *strptr;

To access the members of a structure using a pointer to that structure, you must use the →
operator as follows −

struct_pointer->title;

C defines the → symbol to be used with struct pointer as the indirection operator (also
called struct dereference operator). It helps to access the elements of the struct variable to
which the pointer reference to.

Example

In this example, strptr is a pointer to struct book book1 variable. Hence, strrptr→title returns
the title, just like [Link] does.

#include <stdio.h>
#include <string.h>

struct book{
char title[10];
char author[20];
double price;
int pages;
};

int main (){


struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325};
struct book *strptr;
strptr = &book1;

printf("Title: %s \n", strptr -> title);


printf("Author: %s \n", strptr -> author);
printf("Price: %lf \n", strptr -> price);
printf("Pages: %d \n", strptr -> pages);
return 0;
}
Output

When you run this code, it will produce the following output −

Title: Learn C
Author: Dennis Ritchie
Price: 675.500000
Pages: 325

Note: The dot (.) operator is used to access the struct elements via the struct variable. To access
the elements via its pointer, we must use the indirection (->) operator

A struct variable is like a normal variable of primary type, in the sense that you can have an array
of struct, you can pass the struct variable to a function, as well as return a struct from a function.

You may have noted that you need to prefix "struct type" to the name of the variable or pointer at
the time of declaration. This can be avoided by creating a shorthand notation with the help
of typedef keyword, which we will explain in a subsequent chapter.

Structures are used in different applications such as databases, file management applications, and
for handling complex data structures such as tree and linked lists.

Bit Fields

Bit Fields allow the packing of data in a structure. This is especially useful when memory or data
storage is at a premium. Typical examples include −

 Packing several objects into a machine word, for example, 1-bit flags can be compacted.
 Reading external file formats − non-standard file formats could be read in, for example, 9-
bit integers.

C allows us to do this in a structure definition by putting :bit length after the variable. For
example −

struct packed_struct{
unsigned int f1:1;
unsigned int f2:1;
unsigned int f3:1;
unsigned int f4:1;
unsigned int type:4;
unsigned int my_int:9;
} pack;

Here, the packed_struct contains 6 members: Four 1 bit flags f1..f3, a 4-bit type and a 9-bit
my_int.

C automatically packs the above bit fields as compactly as possible, provided that the maximum
length of the field is less than or equal to the integer word length of the computer. If this is not
the case, then some compilers may allow memory overlap for the fields while others would store
the next field in the next word.

C - Structures and Functions

In C, struct is a derived data type. Just as we can pass arguments of primary data types, a variable
of struct data type can also be passed to a function. You can also pass structures using call by
value as well as call by reference methods. A function in C may also return a struct data type.

In this chapter, we shall learn to −

 Pass elements of struct type


 Pass struct variable
 Return struct from function
 Return struct pointer

Pass struct elements

A derived type is a combination of one or more elements of any of the primary types as well as
the same or different derived type. It is possible to pass elements to a function, either by value or
by reference.

In the following example, a derived type called rectangle with two elements. A struct variable r
with has the elements [Link] and [Link], and they are passed to a function. The area() function then
computes the area of rectangle.

Example

#include <stdio.h>
#include <string.h>
struct rectangle{
float len, brd;
};
int area(float, float);
int main () {
struct rectangle r;
printf("Input length and breadth of a rectangle\n");
//scanf("%f %f", &[Link], &[Link]);
[Link]=10.50; [Link]=20.5;
area([Link], [Link]);
return 0;
}
int area(float a, float b){
double area = (double)(a*b);
printf("Length: %f \n Breadth: %f \n Area: %lf\n", a, b, area);
return 0;
}

Output

Input length and breadth of a rectangle


Length: 10.500000
Breadth: 20.500000
Area: 215.250000

Pass struct variable

Let us modify the above example, to pass the struct variable itself (instead of its elements) to the
area() function. The rectangle struct type also has an additional element called area. Inside the
function, the elements of the struct variable are accessed though the dot operator, and the area is
calculated.

Example

#include <stdio.h>
#include <string.h>
struct rectangle{
float len, brd;
double area;
};
int area(struct rectangle);
int main () {
struct rectangle r;
printf("Input length and breadth of a rectangle\n");
//scanf("%f %f", &[Link], &[Link]);
[Link]=10.50; [Link]=20.5;
area(r);
return 0;
}
int area(struct rectangle r){
[Link] = (double)([Link]*[Link]);
printf("Length: %f \n Breadth: %f \n Area: %lf\n", [Link], [Link], [Link]);
return 0;
}

Output

Input length and breadth of a rectangle


Length: 10.500000
Breadth: 20.500000
Area: 215.250000

Return struct from function

We know that a function in C is able to return a value of any of the types. In this example, the
area() function is defined to return a struct variable.

In main(), inputs are accepted from the user for length and breadth, and are passed to the
function. Inside the function, the area is computed, and a struct variable is populated and
returned to the main() function, where its elements are displayed.

Example

#include <stdio.h>
#include <string.h>
struct rectangle{
float len, brd;
double area;
};
struct rectangle area(float x, float y);
int main () {
struct rectangle r;
float x, y;
printf("Input length and breadth of a rectangle\n");
//scanf("%f %f", &x, &y);
x=10.5; y=20.5;
r=area(x, y);
printf("Length: %f \n Breadth: %f \n Area: %lf\n", [Link], [Link], [Link]);
return 0;
}
struct rectangle area(float x, float y){
double area = (double)(x*y);
struct rectangle r = {x, y, area};
return r;
}

Output

Input length and breadth of a rectangle


Length: 10.500000
Breadth: 20.500000
Area: 215.250000

Pass struct by reference

In C, a function may be defined to have its arguments passed by value or reference. A reference
is the pointer to an existing variable. In the example explained below, a struct variable of
rectangle type is declared in main() and its address is passed to a user−defined function − area().
When called, the area() function is able to use the elements of the variable with the indirection
operator −>. It computes the result and assigns it to the area element r−>area.

Example

#include <stdio.h>
#include <string.h>
struct rectangle{
float len, brd;
double area;
};
int area(struct rectangle *);
int main () {
struct rectangle r;
printf("Input length and breadth of a rectangle\n");
//scanf("%f %f", &[Link], &[Link]);
[Link]=10.50; [Link]=20.5;
area(&r);
return 0;
}
int area(struct rectangle *r){
r->area = (double)(r->len*r->brd);
printf("Length: %f \n Breadth: %f \n Area: %lf\n", r->len, r->brd, r->area);
return 0;
}

Output

Input length and breadth of a rectangle


Length: 10.500000
Breadth: 20.500000
Area: 215.250000

Return struct pointer

Let us rewrite the above code to define the area() function and return a pointer to a struct
rectangle data type. The area() function has two call by value arguments. The main() function
reads the length and breadth from the user and passes them to the area() function, which
populates a struct variable and passes its reference back to main().

Example

#include <stdio.h>
#include <string.h>
struct rectangle{
float len, brd;
double area;
};
struct rectangle * area(float x, float y);
int main (){
struct rectangle *r;
float x, y;
printf("Input length and breadth of a rectangle\n");
//scanf("%f %f", &x, &y);
x=10.5; y=20.5;
r=area(x, y);
printf("Length: %f \n Breadth: %f \n Area: %lf\n", r->len, r->brd, r->area);
return 0;
}
struct rectangle * area(float x, float y){
double area = (double)(x*y);
static struct rectangle r;
[Link] = x; [Link]=y; [Link]=area;
return &r;
}

Output

Input length and breadth of a rectangle


Length: 10.500000
Breadth: 20.500000
Area: 215.250000
C - Arrays of Structures

In C, the struct keyword is used to define a derived data type. Once defined, you can declare an
array of struct variables, just like an array of int, float or char types is declared. An array of struct
has a number of use cases, such as in storing records similar to a database table, where you have
each row with different data types.

Usually, a struct type is defined in the beginning of the code, so that its type can be used inside
any of the functions. You can declare an array of structure and later on fill data in it, or you can
initialize it at the time of declaration itself.

Initialize struct array

Let use define a struct type named as book as follows −

struct book{
char title[10];
double price;
int pages;
};
During the program, you can declare an array and initialize it by giving the values of each
element inside curly brackets. Each element in the struct array is a struct value itself. Hence, we
have the nested curly brackets as shown below −

struct book b[3] ={


{"Learn C", 650.50, 325}, {"C Pointers", 175, 225}, {"C Pearls", 250, 250}
};

How does the compiler allocate the memory? Since we have an array of three elements, of struct
whose size is 32 bytes, the array occupies 32X3 bytes. Each block of 32 bytes will accommodate
a title, price and pages element.

L E A R N C 675.50 325

C P O I N T E R S 175 225

C P E A R L S 250 250

Declare struct array

You can also declare an empty struct array. Afterwards, you can either read the data in it with
scanf() statements, or assign value to each element as shown below −

struct book b[3];


strcpy(b[0].title, " Learn C ");
b[0].price = 650.50;
b[0].pages=325;

strcpy(b[1].title, " C Pointers ");


b[1].price = 175;
b[1].pages=225;

strcpy(b[2].title, "C Pearls ");


b[2].price = 250;250
b[2].pages=325;

We can also accept data from the user to fill the array

Read struct array


In the following code, a for loop is employed to accept inputs for the title, price and pages
elements of each struct element of the array.

Example

#include <stdio.h>
#include <string.h>
struct book{
char title[10];
double price;
int pages;
};
int main (){
struct book b[3];
strcpy(b[0].title, " Learn C ");
b[0].price = 650.50;
b[0].pages=325;
strcpy(b[1].title, " C Pointers ");
b[1].price = 175;
b[1].pages=225;
strcpy(b[2].title, "C Pearls ");
b[2].price = 250;
b[2].pages=325;
printf("\nList of books\n");
for (int i=0; i<3; i++){
printf("Title: %s Price: %7.2lf No of Pages: %d\n", b[i].title, b[i].price, b[i].pages);
}
return 0;
}

Output

List of books
Title: Learn C Price: 650.50 No of Pages: 325
Title: C Pointers Price: 175.00 No of Pages: 225
Title: C Pearls Price: 250.00 No of Pages: 325

Example
In the example below, a struct type call student is defined. Its elements are name, marks in phy,
che and maths; and the percentage. An array of three struct student types is declared and first
four elements are populated by user input, with a for loop. Inside the loop itself, the percent
element of each subscript is computed.

Finally, an array of students with their names, marks and percentage is printed to show the
marklist.

#include <stdio.h>
#include <string.h>
struct student{
char name[10];
int physics, chem, math;
double percent;
};
int main (){
struct student s[3];
strcpy(s[0].name, " Ravi ");
s[0].physics = 50;
s[0].chem = 60;
s[0].math =70;

strcpy(s[1].name, " Kiran ");


s[1].physics = 55;
s[1].chem = 66;
s[1].math =77;

strcpy(s[2].name, " Anil ");


s[2].physics = 45;
s[2].chem = 55;
s[2].math = 65;

int i;
for (i=0; i<3; i++){
s[i].percent = (double)(s[i].physics + s[i].math + s[i].chem)/3;
}
printf("\nName\tPhy\tChe\t\Maths\tPercent\n");
for (i=0; i<3; i++) {
printf("%s\t%d\t%d\t%d\t%5.2lf\n", s[i].name, s[i].physics, s[i].chem, s[i].math,
s[i].percent);
}

return 0;
}

Output

Name Phy Che Maths Percent


Ravi 50 60 70 60.00
Kiran 55 66 77 66.00
Anil 45 55 65 55.00

Sort struct array

Let us take another example of struct array. The assay of book struct type is sorted in ascending
order of the price by implementing bubble sort technique. Note that elements of one struct
variable can be directly assigned to other struct variable directly with assignment operator.

Example

#include <stdio.h>
#include <string.h>
struct book{
char title[10];
double price;
int pages;
};
int main (){
struct book b[3] ={
{"Learn C", 650.50, 325}, {"C Pointers", 175, 225}, {"C Pearls", 250, 250}
};
int i, j;
struct book temp;
for (i=0; i<2; i++){
for (j=i; j<3; j++){
if (b[i].price>b[j].price){
temp = b[i];
b[i] = b[j];
b[j] = temp;
}
}
}
printf("\nList of books in ascending order of price\n");
for (i=0; i<3; i++){
printf("Title: %s Price: %7.2lf No of Pages: %d\n", b[i].title, b[i].price, b[i].pages);
}
return 0;
}

Output

List of books in ascending order of price


Title: C Pointers Price: 175.00 No of Pages: 225
Title: C Pearls Price: 250.00 No of Pages: 250
Title: Learn C Price: 650.50 No of Pages: 325

Pointer to struct array

We can also declare a pointer to struct array. C uses −> operator as the indirection operator to
access internal elements of the struct variables.

Example

#include <stdio.h>
#include <string.h>
struct book{
char title[10];
double price;
int pages;
};
int main () {
struct book b[3] ={
{"Learn C", 650.50, 325}, {"C Pointers", 175, 225}, {"C Pearls", 250, 250}
};
struct book *ptr = b;
int i;
for (i=0; i<3; i++){
printf("Title: %s Price: %7.2lf No of Pages: %d\n", ptr->title, ptr->price, ptr->pages);
ptr++;
}
return 0;
}

Output

Title: Learn C Price: 650.50 No of Pages: 325


Title: C Pointers Price: 175.00 No of Pages: 225
Title: C Pearls Price: 250.00 No of Pages: 250
C - Pointers to Structures

In C, a pointer is a variable that holds the address of another variable. If you have defined a
derived data type with the struct keyword, you can declare a variable of this type, and hence you
can also declare a pointer variable to store its address. A pointer to struct is thus a variable that
refers to a struct variable.

A new derived data type is defined with struct keyword as following syntax −

struct type{
type var1;
type var2;
type var3;
...
...
};

You can then declare a variable of this derived data type as −

struct type var;

You can then declare a pointer variable and store the address of var. We know that to declare a
variable as a pointer, it must be prefixed by *, and to obtain the address of a variable, we use the
& operator.
struct type *ptr = &var;

To access the elements of the structure with pointer, we use a special operator called as an
indirection operator ( −>> ).

A user−defined struct type book is defined below. We declare a book variable and a pointer.

struct book{
char title[10];
double price;
int pages;
};
struct book b1 = {"Learn C", 675.50, 325},
struct book *strptr;

To store the address, use the & operator.

strptr = &b1;

C defines −>: symbol to be used with struct pointer as indirection operator (also called struct
dereference operator). It helps to access the elements of the struct variable to which the pointer
reference to.

To access an individual element in the struct, the indirection operator is used as follows

Ptr-> membername;

For example −

strptr->title, strptr->price, strptr->pages

The struct pointer uses indirection operator or dereference operator to fetch the values of the
struct elements of a struct variable. The dot operator is used to fetch the values with reference to
the struct variable.

Hence

[Link] is the same as strpr->title


[Link] is the same as strptr->price
[Link] is the same as strptr->pages

The following program shows the usage of pointers to structures −


In this example, strptr is a pointer to struct book b1 variable. Hence, strrptr−>title returns the
title, similar to [Link] does.

Example

#include <stdio.h>
#include <string.h>
struct book{
char title[10];
double price;
int pages;
};
int main () {
struct book b1 = {"Learn C", 675.50, 325};
struct book *strptr;
strptr = &b1;
printf("Title: %s\n", strptr->title);
printf("Price: %lf\n", strptr->price);
printf("No of Pages: %d\n", strptr->pages);

return 0;
}

Output

Title: Learn C
Price: 675.500000
No of Pages: 325

It may be noted that −

 The dot operator (.) is used to access the struct elements via the struct variable.
 To access the elements via its pointer, we must use the indirection (−>) operator.

Example

Consider another example which explains the functioning of pointers to structures. A new
derived data type person is defined with the struct keyword. A variable of its type and a pointer
is declared.
The user is asked to input name, age and weight. The values are stored in the structure elements
by accessing them with the indirection operator −>

#include <stdio.h>
#include <string.h>
struct person{
char *name;
int age;
float weight;
};
int main(){
struct person *personPtr, person1;
strcpy([Link], "Meena");
[Link] = 40;
[Link] = 60;
personPtr = &person1;
printf("Displaying: \n");
printf("Name: %s\n", personPtr->name);
printf("Age: %d\n", personPtr->age);
printf("weight: %f", personPtr->weight);

return 0;
}

Output

Let us run the above program that will produce the following result −

Displaying:
Name: Meena
Age: 40
weight: 60.000000

C allows you to declare an array of struct, as well as an array of pointers. Here, each element in
the struct pointer array is a reference to a struct variable.

A struct variable is like a normal variable of primary type, in the sense that you can have an array
of struct, you can pass the struct variable to a function, as well as return a struct from the
function.
You may have noted that you need to prefix struct type to the name of the variable or pointer at
the time of declaration. This can be avoided by creating a shorthand notation with the help of
typedef keyword, which we shall learn in a latter chapter.

Pointers to structures are very important, as they are employed to create complex and dynamic
data structures such as linked lists, trees, graphs, etc. Such data structures use self−referential
structs, where we define a struct type that has one of its elements as a pointer to the same type.

An example of a self−referential structure with a pointer to an element of its own type is defined
as follows −

struct mystruct{
int a;
struct mystruct *b;
};

We shall learn about self−referential structures in the next chapter.

C - Self-referential Structures

As the name suggests, a self−referential structure is a struct data type in C, where one or more of
its elements are pointer to variables of its own type. Self−referential user−defined types are of
immense use in C programming. They are extensively used to build complex and dynamic data
structures such as linked lists, and trees etc. In C, an array is allocated the required memory at
the compile−time, and the array size cannot be modified during the runtime. Self−referential
structures let you emulates the arrays by handling the size dynamically.

The file management systems in OS software are built upon dynamically constructed tree
structures, which are manipulated by self−referential structures. Self−referential structures are
also employed in many complex algorithms.

A general syntax of defining a self−referential structure is as follows −

strut typename{
type var1;
type var2;
..
struct typename *var3;
}

Let us understand how self−referential structure is used, with the help of the following example

We define a struct type called mystruct. It has an int element a, and b is the pointer to mystruct
type itself.

We declare three variables of mystruct type −

struct mystruct x = {10, NULL}, y = {20, NULL}, z = {30, NULL};

Next, we declare three mystruct pointers and assign references to x,y and z to them.

struct mystruct * p1, *p2, *p3;

p1=&x;
p2=&y;
p3=&z;

The variables x, y and z are unrelated, as they will be located at random locations, unlike the
array where all its elements are in adjacent locations. To explicitly establish link between them,
we can store address of y in x, and address of z in y.

Let us implement this in the following program −

Example

#include <stdio.h>
struct mystruct{
int a;
struct mystruct *b;
};
int main(){
struct mystruct x = {10, NULL}, y = {20, NULL}, z = {30, NULL};
struct mystruct * p1, *p2, *p3;
p1=&x;
p2=&y;
p3=&z;
x.b = p2;
y.b = p3;
printf("Add of x: %d a: %d add of next: %d\n", p1, x.a, x.b);
printf("add of y: %d a: %d add of next: %d\n", p2, y.a, y.b);
printf("add of z: %d a: %d add of next: %d\n", p3, z.a, z.b);

return 0;
}

Output

Add of x: 6422000 a: 10 add of next: 6421984


add of y: 6421984 a: 20 add of next: 6421968
add of z: 6421968 a: 30 add of next: 0

Let us refine the above program further. Instead of declaring variables and then storing their
address in pointers, we shall use malloc() function to dynamically allocate memory whose
address is stored in pointer variables. We then establish links between the three nodes as shown
below −

Example

#include <stdio.h>
#include <stdlib.h>
struct mystruct{
int a;
struct mystruct *b;
};
int main(){
struct mystruct *p1, *p2, *p3;
p1=(struct mystruct *)malloc(sizeof(struct mystruct));
p2=(struct mystruct *)malloc(sizeof(struct mystruct));
p3=(struct mystruct *)malloc(sizeof(struct mystruct));
p1->a=10; p1->b=NULL;
p2->a=20; p2->b=NULL;
p3->a=30; p3->b=NULL;
p1->b = p2;
p2->b = p3;
printf("Add of x: %d a: %d add of next: %d\n", p1, p1->a, p1->b);
printf("add of y: %d a: %d add of next: %d\n", p2, p2->a, p2->b);
printf("add of z: %d a: %d add of next: %d\n", p3, p3->a, p3->b);

return 0;
}

Output

Add of x: 10032160 a: 10 add of next: 10032192


add of y: 10032192 a: 20 add of next: 10032224
add of z: 10032224 a: 30 add of next: 0

We can reach the next element in the link from its address stored in the earlier element, as p1−>b
points to the address of p2. This while loop displays the linked list −

Example

#include <stdio.h>
#include <stdlib.h>
struct mystruct{
int a;
struct mystruct *b;
};
int main(){
struct mystruct *p1, *p2, *p3;
p1=(struct mystruct *)malloc(sizeof(struct mystruct));
p2=(struct mystruct *)malloc(sizeof(struct mystruct));
p3=(struct mystruct *)malloc(sizeof(struct mystruct));
p1->a=10; p1->b=NULL;
p2->a=20; p2->b=NULL;
p3->a=30; p3->b=NULL;
p1->b = p2;
p2->b = p3;
while (p1!=NULL){
printf("Add of current: %d a: %d add of next: %d\n", p1, p1->a, p1->b);
p1=p1->b;
}
return 0;
}

Output

Add of current: 10032160 a: 10 add of next: 10032192


Add of current: 10032192 a: 20 add of next: 10032224
Add of current: 10032224 a: 30 add of next: 0

Linked List

In the above examples, the dynamically constructed list has three discrete elements linked with
pointers. We can use a for loop to set up required number of elements by allocating memory
dynamically, and store the address of next element in the previous node. The following example
is a more generalized solution of creating a linked list with self−referential structure.

Example

#include <stdio.h>
#include <stdlib.h>
struct mystruct{
int a;
struct mystruct *b;
};
int main(){
struct mystruct *p1, *p2, *start;
int i;
p1=(struct mystruct *)malloc(sizeof(struct mystruct));
p1->a=10; p1->b=NULL;
start=p1;
for (i=1; i<=5; i++){
p2=(struct mystruct *)malloc(sizeof(struct mystruct));
p2->a=i*2;
p2->b=NULL;
p1->b=p2;
p1=p2;
}
p1=start;
while (p1!=NULL){
printf("Add of current: %d a: %d add of next: %d\n", p1, p1->a, p1->b);
p1=p1->b;
}
return 0;
}

Output

Add of current: 11408416 a: 10 add of next: 11408448


Add of current: 11408448 a: 2 add of next: 11408480
Add of current: 11408480 a: 4 add of next: 11408512
Add of current: 11408512 a: 6 add of next: 11408544
Add of current: 11408544 a: 8 add of next: 11408576
Add of current: 11408576 a: 10 add of next: 0

Doubly linked list

This is linked list is traversed from beginning till it reaches NULL. You can also construct a
doubly linked list, where the structure has two pointers, each referring to the address of previous
and next element.

The struct definition for this purpose should be as below:

struct node {
int data;
int key;
struct node *next;
struct node *prev;
};
Tree

Self−referential structures are also used to construct non−linear data structures as trees. A binary
search tree is logically represented by the following figure −

The struct definition for the implementing a tree is as follows −

struct node {
int data;
struct node *leftChild;
struct node *rightChild;
};

To learn these complex data structure in detail, you can visit the DSA tutorial
− [Link]

C - Nested Structures

In the programming context, the term “nesting” refers to enclosing a particular programming
element inside the similar element. For example, nested loops and nested conditional statements,
etc. In this chapter, we shall learn about nested structures. When one of the elements in the
definition of a struct type is of another struct type, the we call it as nested structure in C.

Nested structures are defined when one of the elements of a struct type is itself a composite
representation of one or more types.

A general syntax of nested structure is as follows −

struct struct1{
type var1;
type var2;
struct struct2 strvar;
}
We can think of nested structures in the following situation.

If we want to define a struct type representing a student with name and age as its elements, and
other element is the course that is characterized by the course ID, the title, and the credit points.
Here, the student structure has an inner course structure.

struct student{
char *name;
int age;
struct course c1;
};

The student variable will be stored in the memory as follows −

Name Age Course

kiran 25 001 C Programming 6

The nesting of structures can be performed by two methods −

 Defining inline structure


 Including the element of a structure already defined

Let us learn these methods by suitable examples.

Method 1

In this method, we shall define an employee data type, with one of its elements being date of
birth. C doesn’t have a built−in date type. We shall declare the dob struct with three int types d,
m and y inside the employee structure and its variable d1 is one of the elements of the outer type.

Example

#include <stdio.h>
#include <string.h>
struct employee{
char name[10];
float salary;
struct dob{
int d, m, y;
} d1;
};
int main(){
struct employee e1 = {"Kiran", 25000, {12, 5, 1990}};
printf("Name: %s\n", [Link]);
printf("Salary: %f\n", [Link]);
printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y);
return 0;
}

Output

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990

You can see that the variable of employee type is initialized with its date element having another
pair of curly brackets.

Method 2

The other approach for using nested structures is to define the inner struct type first, and then use
its variable as one of the elements in the outer struct type, which is defined afterwards.

Here, the dob type is defined in the beginning, it has three int elements − d, m and y. The
employee struct type is defined afterwards. Since dob is already defined, we can have an element
of its type inside employee.

Example

#include <stdio.h>
#include <string.h>
struct dob{
int d, m, y;
};
struct employee{
char name[10];
float salary;
struct dob d1;
};
int main(){
struct employee e1 = {"Kiran", 25000, {12, 5, 1990}};
printf("Name: %s\n", [Link]);
printf("Salary: %f\n", [Link]);
printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y);
return 0;
}

Output

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990

Note that the inner struct type should be defined before the outer type. We can also declare a
variable of dob type and then include it in the initialization of employee type variable, as shown
below −

struct dob d1 = {12, 5, 1990};


struct employee e1 = {"Kiran", 25000, d1};

Example

In the following code, the nesting of structure goes upto two levels. In other words, the outer
struct type employee has one element that is a variable of experience struct type. In turn, the
experience structure has two elements of another struct type called date.

Hence, the memory allocation for employee variable can be understood with the following
illustration −

Name Salary Designation from to

kiran 25000 Clerk 12 5 1990 31 3 2021

Here is the complete code −

Example

#include <stdio.h>
#include <string.h>
struct date{
int d, m, y;
};
struct experience{
char designation[10];
struct date from;
struct date to;
};
struct employee{
char name[10];
float salary;
struct experience exp;
};
int main(){
struct date d1 = {12, 5, 1990};
struct date d2 = {31, 3, 2021};
struct experience exp = {"Clerk", d1, d2};
struct employee e1 = {"Kiran", 25000, exp};
printf("Name: %s\n", [Link]);
printf("Salary: %f\n", [Link]);
printf("Experience: Designation: %s\n", [Link]);
printf("From : %d-%d-%d\n", [Link].d,[Link].m, [Link].y );
printf("To : %d-%d-%d\n", [Link].d, [Link].m, [Link].y );
return 0;
}

Output

Name: Kiran
Salary: 25000.000000
Experience: Designation: Clerk
From : 12-5-1990
To : 31-3-2021

Pointer to nested structure

We know that the address of a struct variable can be stored in a pointer variable. Further, C uses
the indirection operator -> to access the elements of a variable that is referenced by the pointer.
In case of the nested structure, the elements of the inner struct elements are accessed by ptr-
>inner_struct_var.element;
In the example below, we have declared a pointer ptr to an employee struct variable. the date,
month and year elements of inner dob struct variable are accessed as ptr->d1.d, ptr->d1.m and
ptr->d1.y expressions.

Example

#include <stdio.h>
#include <string.h>
struct employee{
char name[10];
float salary;
struct dob{
int d, m, y;
} d1;
};
int main(){
struct employee e1 = {"Kiran", 25000, {12, 5, 1990}};
struct employee *ptr = &e1;
printf("Name: %s\n", ptr->name);
printf("Salary: %f\n", ptr->salary);
printf("Date of Birth: %d-%d-%d\n", ptr->d1.d, ptr->d1.m, ptr->d1.y);
return 0;
}

Output

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990
Unions in C

A union is a special data type available in C that allows to store different data types in the same
memory location. You can define a union with many members, but only one member can contain
a value at any given time. Unions provide an efficient way of using the same memory location
for multiple purpose.

All the members of a union share the same memory location. Therefore, if we need to use the
same memory location for two or more members, then union is the best data type for that. The
largest union member defines the size of the union.
Defining a Union

Union variables are created in same manner as structure variables. The keyword union is used to
define unions in C language.

Here is the syntax of unions in C language −

union [union tag]{


member definition;
member definition;
...
member definition;
} [one or more union variables];

The "union tag" is optional and each member definition is a normal variable definition, such as
"int i;" or "float f;" or any other valid variable definition.

At the end of the union's definition, before the final semicolon, you can specify one or more
union variables.

Difference between Structure and Union

Both structures and unions are composite data types in C programming. The most significant
difference between a structure and a union is the way they store their data. A structure stores
each member in separate memory locations, whereas a union stores all its members in the same
memory location.

Here is a definition of union type called myunion −

union myunion{
int a;
double b;
char c;
};

The definition of a union is similar to the definition of a structure. A definition of "struct type
mystruct" with the same elements looks like this −

struct mystruct{
int a;
double b;
char c;
};

The main difference between a struct and a union is the size of the variables. The compiler
allocates the memory to a struct variable, to be able to store the values for all the elements.
In mystruct, there are three elements − an int, a double, and char, requiring 13 bytes (4 + 8 + 1).
Hence, sizeof(struct mystruct) returns 13.

On the other hand, for a union type variable, the compiler allocates a chunk of memory of the
size enough to accommodate the element of the largest byte size. The myunion type has an int, a
double and a char element. Out of the three elements, the size of the double variable is the
largest, i.e., 8. Hence, sizeof(union myunion) returns 8.

Another point to take into consideration is that a union variable can hold the value of only one its
elements. When you assign value to one element, the other elements are undefined. If you try to
use the other elements, it will result in some garbage.

Example 1: Memory Occupied by a Union

In the code below, we define a union type called Data having three members i, f, and str. A
variable of type Data can store an integer, a floating point number, or a string of characters. It
means a single variable, i.e., the same memory location, can be used to store multiple types of
data. You can use any built-in or user-defined data types inside a union, as per your requirement.

The memory occupied by a union will be large enough to hold the largest member of the union.
For example, in the above example, Data will occupy 20 bytes of memory space because this is
the maximum space which can be occupied by a character string.

The following example displays the total memory size occupied by the above union −

#include <stdio.h>
#include <string.h>

union Data{
int i;
float f;
char str[20];
};

int main(){
union Data data;
printf("Memory occupied by Union Data: %d \n", sizeof(data));
return 0;
}

Output

When you compile and execute the code, it will produce the following output −

Memory occupied by Union Data: 20

Example 2: Memory Occupied by a Structure

Now, let's create a structure with the same elements and check how much space it occupies in the
memory.

#include <stdio.h>
#include <string.h>

struct Data{
int i;
float f;
char str[20];
};

int main(){
struct Data data;
printf("Memory occupied by Struct Data: %d \n", sizeof(data));
return 0;
}

Output

This stucture will occupy 28 bytes (4 + 4 + 20). Run the code and check its output −

Memory occupied by Struct Data: 28

Accessing the Union Members

To access any member of a union, we use the member access operator (.). The member access
operator is coded as a period between the union variable name and the union member that we
wish to access. You would use the keyword union to define variables of union type. The
following example shows how to use unions in a program −
Example 1

#include <stdio.h>
#include <string.h>

union Data{
int i;
float f;
char str[20];
};

int main(){
union Data data;

data.i = 10;
data.f = 220.5;
strcpy([Link], "C Programming");

printf("data.i: %d \n", data.i);


printf("data.f: %f \n", data.f);
printf("[Link]: %s \n", [Link]);
return 0;
}

Output

When the above code is compiled and executed, it produces the following result −

data.i: 1917853763
data.f: 4122360580327794860452759994368.000000
[Link]: C Programming

Here, we can see that the values of i and f (members of the union) show garbage values because
the final value assigned to the variable has occupied the memory location and this is the reason
that the value of str member is getting printed very well.

Example 2
Now let's look at the same example once again where we will use one variable at a time which is
the main purpose of having unions −

#include <stdio.h>
#include <string.h>

union Data{
int i;
float f;
char str[20];
};

int main(){

union Data data;

data.i = 10;
printf("data.i: %d \n", data.i);

data.f = 220.5;
printf("data.f: %f \n", data.f);

strcpy([Link], "C Programming");


printf("[Link]: %s \n", [Link]);
return 0;
}

Output

When the above code is compiled and executed, it produces the following result −

data.i: 10
data.f: 220.500000
[Link]: C Programming

Here, the values of all the Union members are getting printed very well because one member is
being used at a time.
C - Bit Fields

Suppose your C program contains a number of TRUE/FALSE variables grouped in a structure


called status, as follows −

struct {
unsigned int widthValidated;
unsigned int heightValidated;
} status;

This structure requires 8 bytes of memory space but in actual, we are going to store either 0 or 1
in each of the variables. The C programming language offers a better way to utilize the memory
space in such situations.

If you are using such variables inside a structure then you can define the width of a variable
which tells the C compiler that you are going to use only those number of bytes. For example,
the above structure can be re-written as follows −

struct {
unsigned int widthValidated : 1;
unsigned int heightValidated : 1;
} status;

The above structure requires 4 bytes of memory space for status variable, but only 2 bits will be
used to store the values.

If you will use up to 32 variables each one with a width of 1 bit, then also the status structure will
use 4 bytes. However as soon as you have 33 variables, it will allocate the next slot of the
memory and it will start using 8 bytes. Let us check the following example to understand the
concept −

Live Demo
#include <stdio.h>
#include <string.h>

/* define simple structure */


struct {
unsigned int widthValidated;
unsigned int heightValidated;
} status1;

/* define a structure with bit fields */


struct {
unsigned int widthValidated : 1;
unsigned int heightValidated : 1;
} status2;

int main( ) {
printf( "Memory size occupied by status1 : %d\n", sizeof(status1));
printf( "Memory size occupied by status2 : %d\n", sizeof(status2));
return 0;
}

When the above code is compiled and executed, it produces the following result −

Memory size occupied by status1 : 8


Memory size occupied by status2 : 4

Bit Field Declaration

The declaration of a bit-field has the following form inside a structure −

struct {
type [member_name] : width ;
};

The following table describes the variable elements of a bit field −

[Link]. Element & Description

type
1 An integer type that determines how a bit-field's value is
interpreted. The type may be int, signed int, or unsigned int.

member_name
2
The name of the bit-field.

width
3 The number of bits in the bit-field. The width must be less than
or equal to the bit width of the specified type.

The variables defined with a predefined width are called bit fields. A bit field can hold more
than a single bit; for example, if you need a variable to store a value from 0 to 7, then you can
define a bit field with a width of 3 bits as follows −

struct {
unsigned int age : 3;
} Age;
The above structure definition instructs the C compiler that the age variable is going to use only
3 bits to store the value. If you try to use more than 3 bits, then it will not allow you to do so. Let
us try the following example −

Live Demo
#include <stdio.h>
#include <string.h>

struct {
unsigned int age : 3;
} Age;

int main( ) {

[Link] = 4;
printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
printf( "[Link] : %d\n", [Link] );

[Link] = 7;
printf( "[Link] : %d\n", [Link] );

[Link] = 8;
printf( "[Link] : %d\n", [Link] );

return 0;
}

When the above code is compiled it will compile with a warning and when executed, it produces
the following result −

Sizeof( Age ) : 4
[Link] : 4
[Link] : 7
[Link] : 0
C - typedef

The C programming language provides a keyword called typedef, which you can use to give a
type a new name. Following is an example to define a term BYTE for one-byte numbers −

typedef unsigned char BYTE;

After this type definition, the identifier BYTE can be used as an abbreviation for the
type unsigned char, for example..
BYTE b1, b2;

By convention, uppercase letters are used for these definitions to remind the user that the type
name is really a symbolic abbreviation, but you can use lowercase, as follows −

typedef unsigned char byte;

You can use typedef to give a name to your user defined data types as well. For example, you
can use typedef with structure to define a new data type and then use that data type to define
structure variables directly as follows −

Live Demo
#include <stdio.h>
#include <string.h>

typedef struct Books {


char title[50];
char author[50];
char subject[100];
int book_id;
} Book;

int main( ) {

Book book;

strcpy( [Link], "C Programming");


strcpy( [Link], "Nuha Ali");
strcpy( [Link], "C Programming Tutorial");
book.book_id = 6495407;

printf( "Book title : %s\n", [Link]);


printf( "Book author : %s\n", [Link]);
printf( "Book subject : %s\n", [Link]);
printf( "Book book_id : %d\n", book.book_id);

return 0;
}

When the above code is compiled and executed, it produces the following result −

Book title : C Programming


Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407

typedef vs #define

#define is a C-directive which is also used to define the aliases for various data types similar
to typedef but with the following differences −

 typedef is limited to giving symbolic names to types only where as #define can be used to
define alias for values as well, q., you can define 1 as ONE etc.
 typedef interpretation is performed by the compiler whereas #define statements are
processed by the pre-processor.

The following example shows how to use #define in a program −

Live Demo
#include <stdio.h>

#define TRUE 1
#define FALSE 0

int main( ) {
printf( "Value of TRUE : %d\n", TRUE);
printf( "Value of FALSE : %d\n", FALSE);

return 0;
}

When the above code is compiled and executed, it produces the following result −

Value of TRUE : 1
Value of FALSE : 0
C - Input and Output

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

Standard input stdin Keyboard

Standard output stdout Screen

Standard error stderr Your screen

The file pointers are the means to access the file for reading and writing purpose. This section
explains how to read values from the screen and how to print the result on the screen.

The getchar() and putchar() Functions

The int getchar(void) function reads the next available character from the screen and returns it
as an integer. This function reads only single character at a time. You can use this method in the
loop in case you want to read more than one character from the screen.

The int putchar(int c) function puts the passed character on the screen and returns the same
character. This function puts only single character at a time. You can use this method in the loop
in case you want to display more than one character on the screen. Check the following example

#include <stdio.h>
int main( ) {

int c;

printf( "Enter a value :");


c = getchar( );

printf( "\nYou entered: ");


putchar( 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 −

$./[Link]
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.

NOTE: Though it has been deprecated to use gets() function, Instead of using gets, you want to
use fgets().

#include <stdio.h>
int main( ) {

char str[100];

printf( "Enter a value :");


gets( str );

printf( "\nYou entered: ");


puts( str );

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 the complete line till end, and
displays it as follows −

$./[Link]
Enter a value : this is test
You entered: this is test

The scanf() and printf() Functions

The int scanf(const char *format, ...) function reads the input from the standard input
stream stdin and scans that input according to the format provided.

The int printf(const char *format, ...) function writes the output to the standard output
stream stdout and produces the output according to the format provided.
The format can be a simple constant string, but you can specify %s, %d, %c, %f, etc., to print or
read strings, integer, character or float respectively. There are many other formatting options
available which can be used based on requirements. Let us now proceed with a simple example
to understand the concepts better −

#include <stdio.h>
int main( ) {

char str[100];
int i;

printf( "Enter a value :");


scanf("%s %d", str, &i);

printf( "\nYou entered: %s %d ", str, 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

$./[Link]
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().

C - File I/O

The last chapter explained the standard input and output devices handled by C programming
language. This chapter cover how C programmers can create, open, close text or binary files for
their data storage.

A file represents a sequence of bytes, regardless of it being a text file or a binary file. C
programming language provides access on high level functions as well as low level (OS level)
calls to handle file on your storage devices. This chapter will take you through the important
calls for file management.

Opening Files
You can use the fopen( ) function to create a new file or to open an existing file. This call will
initialize an object of the type FILE, which contains all the information necessary to control the
stream. The prototype of this function call is as follows −

FILE *fopen( const char * filename, const char * mode );

Here, filename is a string literal, which you will use to name your file, and access mode can
have one of the following values −

[Link]. Mode & Description

r
1
Opens an existing text file for reading purpose.

w
Opens a text file for writing. If it does not exist, then a new file
2
is created. Here your program will start writing content from the
beginning of the file.

a
Opens a text file for writing in appending mode. If it does not
3
exist, then a new file is created. Here your program will start
appending content in the existing file content.

r+
4
Opens a text file for both reading and writing.

w+
Opens a text file for both reading and writing. It first truncates
5
the file to zero length if it exists, otherwise creates a file if it
does not exist.

a+
Opens a text file for both reading and writing. It creates the file
6
if it does not exist. The reading will start from the beginning but
writing can only be appended.

If you are going to handle binary files, then you will use following access modes instead of the
above mentioned ones −

"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"

Closing a File

To close a file, use the fclose( ) function. The prototype of this function is −
int fclose( FILE *fp );

The fclose(-) function returns zero on success, or EOF if there is an error in closing the file. This
function actually flushes any data still pending in the buffer to the file, closes the file, and
releases any memory used for the file. The EOF is a constant defined in the header file stdio.h.

There are various functions provided by C standard library to read and write a file, character by
character, or in the form of a fixed length string.

Writing a File

Following is the simplest function to write individual characters to a stream −

int fputc( int c, FILE *fp );

The function fputc() writes the character value of the argument c to the output stream referenced
by fp. It returns the written character written on success otherwise EOF if there is an error. You
can use the following functions to write a null-terminated string to a stream −

int fputs( const char *s, FILE *fp );

The function fputs() writes the string s to the output stream referenced by fp. It returns a non-
negative value on success, otherwise EOF is returned in case of any error. You can use int
fprintf(FILE *fp,const char *format, ...) function as well to write a string into a file. Try the
following example.

Make sure you have /tmp directory available. If it is not, then before proceeding, you must
create this directory on your machine.

#include <stdio.h>

main() {
FILE *fp;

fp = fopen("/tmp/[Link]", "w+");
fprintf(fp, "This is testing for fprintf...\n");
fputs("This is testing for fputs...\n", fp);
fclose(fp);
}

When the above code is compiled and executed, it creates a new file [Link] in /tmp directory
and writes two lines using two different functions. Let us read this file in the next section.

Reading a File
Given below is the simplest function to read a single character from a file −

int fgetc( FILE * fp );

The fgetc() function reads a character from the input file referenced by fp. The return value is the
character read, or in case of any error, it returns EOF. The following function allows to read a
string from a stream −

char *fgets( char *buf, int n, FILE *fp );

The functions fgets() reads up to n-1 characters from the input stream referenced by fp. It copies
the read string into the buffer buf, appending a null character to terminate the string.

If this function encounters a newline character '\n' or the end of the file EOF before they have
read the maximum number of characters, then it returns only the characters read up to that point
including the new line character. You can also use int fscanf(FILE *fp, const char *format,
...) function to read strings from a file, but it stops reading after encountering the first space
character.

#include <stdio.h>

main() {

FILE *fp;
char buff[255];

fp = fopen("/tmp/[Link]", "r");
fscanf(fp, "%s", buff);
printf("1 : %s\n", buff );

fgets(buff, 255, (FILE*)fp);


printf("2: %s\n", buff );

fgets(buff, 255, (FILE*)fp);


printf("3: %s\n", buff );
fclose(fp);

When the above code is compiled and executed, it reads the file created in the previous section
and produces the following result −

1 : This
2: is testing for fprintf...
3: This is testing for fputs...

Let's see a little more in detail about what happened here. First, fscanf() read just This because
after that, it encountered a space, second call is for fgets() which reads the remaining line till it
encountered end of line. Finally, the last call fgets() reads the second line completely.

Binary I/O Functions

There are two functions, that can be used for binary input and output −

size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);

size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE


*a_file);

Both of these functions should be used to read or write blocks of memories - usually arrays or
structures.

C - Preprocessors

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 −

[Link]. Directive & Description

#define
1
Substitutes a preprocessor macro.

#include
2
Inserts a particular header from another file.

#undef
3
Undefines a preprocessor macro.

#ifdef
4
Returns true if this macro is defined.

5 #ifndef
Returns true if this macro is not defined.

#if
6
Tests if a compile time condition is true.

#else
7
The alternative for #if.

#elif
8
#else and #if in one statement.

#endif
9
Ends preprocessor conditional.

#error
10
Prints error message on stderr.

#pragma
11 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.

[Link]. Macro & Description

__DATE__
1 The current date as a character literal in "MMM DD YYYY"
format.

__TIME__
2
The current time as a character literal in "HH:MM:SS" format.

__FILE__
3
This contains the current filename as a string literal.

__LINE__
4
This contains the current line number as a decimal constant.

__STDC__
Defined as 1 when the compiler complies with the ANSI
standard.

Let's try the following example −


#include <stdio.h>

int main() {

printf("File :%s\n", __FILE__ );


printf("Date :%s\n", __DATE__ );
printf("Time :%s\n", __TIME__ );
printf("Line :%d\n", __LINE__ );
printf("ANSI :%d\n", __STDC__ );

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 −

Live Demo
#include <stdio.h>

#define tokenpaster(n) printf ("token" #n " = %d", token##n)

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 −

Live Demo
#include <stdio.h>
#if !defined (MESSAGE)
#define MESSAGE "You wish!"
#endif

int main(void) {
printf("Here is the message: %s\n", MESSAGE);
return 0;
}

When the above code is compiled and executed, it produces the following result −

Here is the message: You wish!

Parameterized Macros

One of the powerful functions of the CPP is the ability to simulate functions using parameterized
macros. For example, we might have some code to square a number as follows −

int square(int x) {
return x * x;
}

We can rewrite above the code using a macro as follows −

#define square(x) ((x) * (x))

Macros with arguments must be defined using the #define directive before they can be used. The
argument list is enclosed in parentheses and must immediately follow the macro name. Spaces
are not allowed between the macro name and open parenthesis. For example −

Live Demo
#include <stdio.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

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 20C - Header Files


A header file is a file with extension .h which contains C function declarations and macro
definitions to be shared between several source files. There are two types of header files: the files
that the programmer writes and the files that comes with your compiler.

You request to use a header file in your program by including it with the C preprocessing
directive #include, like you have seen inclusion of stdio.h header file, which comes along with
your compiler.

Including a header file is equal to copying the content of the header file but we do not do it
because it will be error-prone and it is not a good idea to copy the content of a header file in the
source files, especially if we have multiple source files in a program.

A simple practice in C or C++ programs is that we keep all the constants, macros, system wide
global variables, and function prototypes in the header files and include that header file wherever
it is required.

Include Syntax

Both the user and the system header files are included using the preprocessing
directive #include. It has the following two forms −

#include <file>

This form is used for system header files. It searches for a file named 'file' in a standard list of
system directories. You can prepend directories to this list with the -I option while compiling
your source code.

#include "file"

This form is used for header files of your own program. It searches for a file named 'file' in the
directory containing the current file. You can prepend directories to this list with the -I option
while compiling your source code.

Include Operation

The #include directive works by directing the C preprocessor to scan the specified file as input
before continuing with the rest of the current source file. The output from the preprocessor
contains the output already generated, followed by the output resulting from the included file,
followed by the output that comes from the text after the #include directive. For example, if you
have a header file header.h as follows −

char *test (void);

and a main program called program.c that uses the header file, like this −

int x;
#include "header.h"

int main (void) {


puts (test ());
}

the compiler will see the same token stream as it would if program.c read.

int x;
char *test (void);

int main (void) {


puts (test ());
}

Once-Only Headers

If a header file happens to be included twice, the compiler will process its contents twice and it
will result in an error. The standard way to prevent this is to enclose the entire real contents of
the file in a conditional, like this −

#ifndef HEADER_FILE
#define HEADER_FILE

the entire header file file

#endif

This construct is commonly known as a wrapper #ifndef. When the header is included again, the
conditional will be false, because HEADER_FILE is defined. The preprocessor will skip over
the entire contents of the file, and the compiler will not see it twice.

Computed Includes

Sometimes it is necessary to select one of the several different header files to be included into
your program. For instance, they might specify configuration parameters to be used on different
sorts of operating systems. You could do this with a series of conditionals as follows −
#if SYSTEM_1
# include "system_1.h"
#elif SYSTEM_2
# include "system_2.h"
#elif SYSTEM_3
...
#endif

But as it grows, it becomes tedious, instead the preprocessor offers the ability to use a macro for
the header name. This is called a computed include. Instead of writing a header name as the
direct argument of #include, you simply put a macro name there −

#define SYSTEM_H "system_1.h"


...
#include SYSTEM_H

SYSTEM_H will be expanded, and the preprocessor will look for system_1.h as if
the #include had been written that way originally. SYSTEM_H could be defined by your
Makefile with a -D option.

C - Type Casting

Converting one datatype into another is known as type casting or, type-conversion. For example,
if you want to store a 'long' value into a simple integer then you can type cast 'long' to 'int'. You
can convert the values from one type to another explicitly using the cast operator as follows −

(type_name) expression

Consider the following example where the cast operator causes the division of one integer
variable by another to be performed as a floating-point operation −

Live Demo
#include <stdio.h>

main() {

int sum = 17, count = 5;


double mean;

mean = (double) sum / count;


printf("Value of mean : %f\n", mean );
}

When the above code is compiled and executed, it produces the following result −
Value of mean : 3.400000

It should be noted here that the cast operator has precedence over division, so the value of sum is
first converted to type double and finally it gets divided by count yielding a double value.

Type conversions can be implicit which is performed by the compiler automatically, or it can be
specified explicitly through the use of the cast operator. It is considered good programming
practice to use the cast operator whenever type conversions are necessary.

Integer Promotion

Integer promotion is the process by which values of integer type "smaller" than int or unsigned
int are converted either to int or unsigned int. Consider an example of adding a character with
an integer −

Live Demo
#include <stdio.h>

main() {

int i = 17;
char c = 'c'; /* ascii value is 99 */
int sum;

sum = i + c;
printf("Value of sum : %d\n", sum );
}

When the above code is compiled and executed, it produces the following result −

Value of sum : 116

Here, the value of sum is 116 because the compiler is doing integer promotion and converting
the value of 'c' to ASCII before performing the actual addition operation.

Usual Arithmetic Conversion

The usual arithmetic conversions are implicitly performed to cast their values to a common
type. The compiler first performs integer promotion; if the operands still have different types,
then they are converted to the type that appears highest in the following hierarchy −
The usual arithmetic conversions are not performed for the assignment operators, nor for the
logical operators && and ||. Let us take the following example to understand the concept −

Live Demo
#include <stdio.h>

main() {

int i = 17;
char c = 'c'; /* ascii value is 99 */
float sum;

sum = i + c;
printf("Value of sum : %f\n", sum );
}

When the above code is compiled and executed, it produces the following result −
Value of sum : 116.000000

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 the compiler converts i and c into 'float' and adds
them yielding a 'float' result.

C - Error Handling

As such, C programming does not provide direct support for error handling but being a system
programming language, it provides you access at lower level in the form of return values. Most
of the C or even Unix function calls return -1 or NULL in case of any error and set an error
code errno. It is set as a global 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 values and can take appropriate action depending on
the return value. It is a good practice, to set errno to 0 at the time of initializing a program. A
value of 0 indicates that there is no error in the program.

errno, perror(). and strerror()

The C programming language provides perror() and strerror() functions which can be used to
display the text message associated with errno.

 The perror() function displays the string you pass to it, followed by a colon, a space, and
then the textual representation of the current errno value.
 The strerror() function, which returns a pointer to the textual representation of the current
errno value.

Let's try to simulate an error condition and try to open a file which does not exist. Here I'm using
both the functions to show the usage, but you can use one or more ways of printing your errors.
Second important point to note is that you should use stderr file stream to output all the errors.

#include <stdio.h>
#include <errno.h>
#include <string.h>

extern int errno ;

int main () {

FILE * pf;
int errnum;
pf = fopen ("[Link]", "rb");

if (pf == NULL) {
errnum = errno;
fprintf(stderr, "Value of errno: %d\n", errno);
perror("Error printed by perror");
fprintf(stderr, "Error opening file: %s\n", strerror( errnum ));
} else {

fclose (pf);
}

return 0;
}

When the above code is compiled and executed, it produces the following result −

Value of errno: 2
Error printed by perror: No such file or directory
Error opening file: No such file or directory

Divide by Zero Errors

It is a common problem that at the time of dividing any number, programmers do not check if a
divisor is zero and finally it creates a runtime error.

The code below fixes this by checking if the divisor is zero before dividing −

Live Demo
#include <stdio.h>
#include <stdlib.h>

main() {

int dividend = 20;


int divisor = 0;
int quotient;

if( divisor == 0){


fprintf(stderr, "Division by zero! Exiting...\n");
exit(-1);
}
quotient = dividend / divisor;
fprintf(stderr, "Value of quotient : %d\n", quotient );

exit(0);
}

When the above code is compiled and executed, it produces the following result −

Division by zero! Exiting...

Program Exit Status

It is a common practice to exit with a value of EXIT_SUCCESS in case of program coming out
after a successful operation. Here, EXIT_SUCCESS is a macro and it is defined as 0.

If you have an error condition in your program and you are coming out then you should exit with
a status EXIT_FAILURE which is defined as -1. So let's write above program as follows −

Live Demo
#include <stdio.h>
#include <stdlib.h>

main() {

int dividend = 20;


int divisor = 5;
int quotient;

if( divisor == 0) {
fprintf(stderr, "Division by zero! Exiting...\n");
exit(EXIT_FAILURE);
}

quotient = dividend / divisor;


fprintf(stderr, "Value of quotient : %d\n", quotient );

exit(EXIT_SUCCESS);
}

When the above code is compiled and executed, it produces the following result −

Value of quotient : 4
C - Variable Arguments

Sometimes, you may come across a situation, when you want to have a function, which can take
variable number of arguments, i.e., parameters, instead of predefined number of parameters. The
C programming language provides a solution for this situation and you are allowed to define a
function which can accept variable number of parameters based on your requirement. The
following example shows the definition of such a function.

int func(int, ... ) {


.
.
.
}

int main() {
func(1, 2, 3);
func(1, 2, 3, 4);
}

It should be noted that the function func() has its last argument as ellipses, i.e. three dotes (...)
and the one just before the ellipses is always an int which will represent the total number
variable arguments passed. To use such functionality, you need to make use of stdarg.h header
file which provides the functions and macros to implement the functionality of variable
arguments and follow the given steps −

 Define a function with its last parameter as ellipses and the one just before the ellipses is
always an int which will represent the number of arguments.
 Create a va_list type variable in the function definition. This type is defined in stdarg.h
header file.
 Use int parameter and va_start macro to initialize the va_list variable to an argument list.
The macro va_start is defined in stdarg.h header file.
 Use va_arg macro and va_list variable to access each item in argument list.
 Use a macro va_end to clean up the memory assigned to va_list variable.

Now let us follow the above steps and write down a simple function which can take the variable
number of parameters and return their average −
Live Demo
#include <stdio.h>
#include <stdarg.h>

double average(int num,...) {

va_list valist;
double sum = 0.0;
int i;

/* initialize valist for num number of arguments */


va_start(valist, num);

/* access all the arguments assigned to valist */


for (i = 0; i < num; i++) {
sum += va_arg(valist, int);
}

/* clean memory reserved for valist */


va_end(valist);

return sum/num;
}

int main() {
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}

When the above code is compiled and executed, it produces the following result. It should be
noted that the function average() has been called twice and each time the first argument
represents the total number of variable arguments being passed. Only ellipses will be used to
pass variable number of arguments.

Average of 2, 3, 4, 5 = 3.500000
Average of 5, 10, 15 = 10.000000
C - Memory Management

This chapter explains dynamic memory management in C. The C programming language


provides several functions for memory allocation and management. These functions can be
found in the <stdlib.h> header file.

[Link]. Function & Description

1 void *calloc(int num, int size);


This function allocates an array of num elements each of which
size in bytes will be size.

void free(void *address);


2 This function releases a block of memory block specified by
address.

void *malloc(size_t size);


3 This function allocates an array of num bytes and leave them
uninitialized.

void *realloc(void *address, int newsize);


4
This function re-allocates memory extending it upto newsize.

Allocating Memory Dynamically

While programming, if you are aware of the size of an array, then it is easy and you can define it
as an array. For example, to store a name of any person, it can go up to a maximum of 100
characters, so you can define something as follows −

char name[100];

But now let us consider a situation where you have no idea about the length of the text you need
to store, for example, you want to store a detailed description about a topic. Here we need to
define a pointer to character without defining how much memory is required and later, based on
requirement, we can allocate memory as shown in the below example −

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {

char name[100];
char *description;

strcpy(name, "Zara Ali");

/* allocate memory dynamically */


description = malloc( 200 * sizeof(char) );

if( description == NULL ) {


fprintf(stderr, "Error - unable to allocate required memory\n");
} else {
strcpy( description, "Zara ali a DPS student in class 10th");
}

printf("Name = %s\n", name );


printf("Description: %s\n", description );
}

When the above code is compiled and executed, it produces the following result.

Name = Zara Ali


Description: Zara ali a DPS student in class 10th

Same program can be written using calloc(); only thing is you need to replace malloc with calloc
as follows −

calloc(200, sizeof(char));

So you have complete control and you can pass any size value while allocating memory, unlike
arrays where once the size defined, you cannot change it.

Resizing and Releasing Memory

When your program comes out, operating system automatically release all the memory allocated
by your program but as a good practice when you are not in need of memory anymore then you
should release that memory by calling the function free().

Alternatively, you can increase or decrease the size of an allocated memory block by calling the
function realloc(). Let us check the above program once again and make use of realloc() and
free() functions −

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {

char name[100];
char *description;

strcpy(name, "Zara Ali");

/* allocate memory dynamically */


description = malloc( 30 * sizeof(char) );
if( description == NULL ) {
fprintf(stderr, "Error - unable to allocate required memory\n");
} else {
strcpy( description, "Zara ali a DPS student.");
}

/* suppose you want to store bigger description */


description = realloc( description, 100 * sizeof(char) );

if( description == NULL ) {


fprintf(stderr, "Error - unable to allocate required memory\n");
} else {
strcat( description, "She is in class 10th");
}

printf("Name = %s\n", name );


printf("Description: %s\n", description );

/* release memory using free() function */


free(description);
}

When the above code is compiled and executed, it produces the following result.

Name = Zara Ali


Description: Zara ali a DPS [Link] is in class 10th

You can try the above example without re-allocating extra memory, and strcat() function will
give an error due to lack of available memory in description.

C - Command Line Arguments

It is possible to pass some values from the command line to your C programs when they are
executed. These values are called command line arguments and many times they are important
for your program especially when you want to control your program from outside instead of hard
coding those values inside the code.

The command line arguments are handled using main() function arguments where argc refers to
the number of arguments passed, and argv[] is a pointer array which points to each argument
passed to the program. Following is a simple example which checks if there is any argument
supplied from the command line and take action accordingly −

#include <stdio.h>

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


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 single argument, it produces the following
result.

$./[Link] testing
The argument supplied is testing

When the above code is compiled and executed with a two arguments, it produces the following
result.

$./[Link] testing1 testing2


Too many arguments supplied.

When the above code is compiled and executed without passing any argument, it produces the
following result.

$./[Link]
One argument expected

It should be noted that argv[0] holds the name 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.

$./[Link] "testing1 testing2"

Program name ./[Link]


The argument supplied is testing1 testing2

You might also like