Learn C Programming in 1 Day

By Krishna Rungta

Copyright 2019 - All Rights Reserved – Krishna Rungta

ALL RIGHTS RESERVED. No part of this publication may be reproduced or transmitted in any form whatsoever, electronic, or mechanical, including photocopying, recording, or by any informational storage or retrieval system without express written, dated and signed permission from the author.

Table Of Content

Chapter 1: What is C Programming Language? Basics, Introduction and History

1. What is C programming?

2. History of C language

3. Where is C used? Key Applications

4. Why learn 'C'?

5. How 'C' Works?

Chapter 2: How to Download & Install GCC Compiler for C in Windows, Linux, Mac

1. Install C on Windows

2. Install C in Linux

3. Install C on MAC

Chapter 3: C Hello World! Example: Your First Program

Chapter 4: How to write Comments in C Programming

1. What Is Comment In C Language?

2. Example Single Line Comment

3. Example Multi Line Comment

4. Why do you need comments?

Chapter 5: C Tokens, Keywords, Identifiers, Constants, Variables, Data Types

1. What is a Character set?

2. Token

3. Keywords and Identifiers

4. What is a Variable?

5. Data types

6. Integer data type

7. Floating point data type

8. Constants

Chapter 6: C Conditional Statement: IF, IF Else and Nested IF Else with Example

1. What is a Conditional Statement?

2. If statement

3. Relational Operators

4. The If-Else statement

5. Conditional Expressions

6. Nested If-else Statements

7. Nested Else-if statements

Chapter 7: C Loops: For, While, Do While, Break, Continue with Example

1. What are Loops?

2. Types of Loops

3. While Loop

4. Do-While loop

5. For loop

6. Break Statement

7. Continue Statement

8. Which loop to Select?

Chapter 8: Switch Case Statement in C Programming with Example

1. What is a Switch Statement?

2. Syntax

3. Flow Chart Diagram of Switch Case

4. Example

5. Nested Switch

6. Why do we need a Switch case?

7. Rules for switch statement:

Chapter 9: C Strings: Declare, Initialize, Read, Print with Example

1. What is a String?

2. Declare and initialize a String

3. String Input: Read a String

4. String Output: Print/Display a String

5. The string library

6. Converting a String to a Number

Chapter 10: Storage Classes in C: auto, extern, static, register with Example

1. What is a Storage Class?

2. Auto storage class

3. Extern storage class

4. Static storage class

5. Register storage class

Chapter 11: C Files I/O: Create, Open, Read, Write and Close a File

1. How to Create a File

2. How to Close a file

3. Writing to a File

4. Reading data from a File

5. Interactive File Read and Write with getc and putc

Chapter 12: Functions in C Programming with Examples: Recursive, Inline

1. What is a Function?

2. Library Vs. User-defined Functions

3. Function Declaration

4. Function Definition

5. Function call

6. Function Arguments

7. Variable Scope

8. Static Variables

9. Recursive Functions

10. Inline Functions

Chapter 13: Pointers in C Programming with Examples

1. What is a Pointer?

2. How does Pointer Work?

3. Types of a pointer

4. Direct and Indirect Access Pointers

5. Pointers Arithmetic

6. Pointers and Arrays

7. Pointers and Strings

8. Advantages of Pointers

9. Disadvantages of Pointers

Chapter 14: Functions Pointers in C Programming with Examples

Chapter 15: C Bitwise Operators: AND, OR, XOR, Shift & Complement (with Example)

1. What are Bitwise Operators?

2. Bitwise AND

3. Bitwise OR

4. Bitwise Exclusive OR

5. Bitwise shift operators

6. Bitwise complement operator

Chapter 16: C Dynamic Memory Allocation using malloc(), calloc(), realloc(), free()

1. How Memory Management in C works?

2. Dynamic memory allocation

3. The malloc Function

4. The free Function

5. The calloc Function

6. calloc vs. malloc: Key Differences

7. The realloc Function

8. Dynamic Arrays

Chapter 17: TypeCasting in C: Implicit, Explicit with Example

1. What is Typecasting in C?

2. Implicit type casting

3. Explicit type casting

Chapter 1: What is C Programming Language? Basics, Introduction and History

What is C programming?

C is a general-purpose programming language that is extremely popular, simple and flexible. It is machine-independent, structured programming language which is used extensively in various applications.

C was the basics language to write everything from operating systems (Windows and many others) to complex programs like the Oracle database, Git, Python interpreter and more.

It is said that 'C' is a god's programming language. One can say, C is a base for the programming. If you know 'C,' you can easily grasp the knowledge of the other programming languages that uses the concept of 'C'

It is essential to have a background in computer memory mechanisms because it is an important aspect when dealing with the C programming language.

IEEE-the best 10 top programming language in 2018

History of C language

The base or father of programming languages is 'ALGOL.' It was first introduced in 1960. 'ALGOL' was used on a large basis in European countries. 'ALGOL' introduced the concept of structured programming to the developer community. In 1967, a new computer programming language was announced called as 'BCPL' which stands for Basic Combined Programming Language. BCPL was designed and developed by Martin Richards, especially for writing system software. This was the era of programming languages. Just after three years, in 1970 a new programming language called 'B' was introduced by Ken Thompson that contained multiple features of 'BCPL.' This programming language was created using UNIX operating system at AT&T and Bell Laboratories. Both the 'BCPL' and 'B' were system programming languages.

In 1972, a great computer scientist Dennis Ritchie created a new programming language called 'C' at the Bell Laboratories. It was created from 'ALGOL', 'BCPL' and 'B' programming languages. 'C' programming language contains all the features of these languages and many more additional concepts that make it unique from other languages.

'C' is a powerful programming language which is strongly associated with the UNIX operating system. Even most of the UNIX operating system is coded in 'C'. Initially 'C' programming was limited to the UNIX operating system, but as it started spreading around the world, it became commercial, and many compilers were released for cross-platform systems. Today 'C' runs under a variety of operating systems and hardware platforms. As it started evolving many different versions of the language were released. At times it became difficult for the developers to keep up with the latest version as the systems were running under the older versions. To assure that 'C' language will remain standard, American National Standards Institute (ANSI) defined a commercial standard for 'C' language in 1989. Later, it was approved by the International Standards Organization (ISO) in 1990. 'C' programming language is also called as 'ANSI C'.

History of C

Languages such as C++/Java are developed from 'C'. These languages are widely used in various technologies. Thus, 'C' forms a base for many other languages that are currently in use.

Where is C used? Key Applications

1. 'C' language is widely used in embedded systems.

2. It is used for developing system applications.

3. It is widely used for developing desktop applications.

4. Most of the applications by Adobe are developed using 'C' programming language.

5. It is used for developing browsers and their extensions. Google's Chromium is built using 'C' programming language.

6. It is used to develop databases. MySQL is the most popular database software which is built using 'C'.

7. It is used in developing an operating system. Operating systems such as Apple's OS X, Microsoft's Windows, and Symbian are developed using 'C' language. It is used for developing desktop as well as mobile phone's operating system.

8. It is used for compiler production.

9. It is widely used in IOT applications.

Why learn 'C'?

As we studied earlier, 'C' is a base language for many programming languages. So, learning 'C' as the main language will play an important role while studying other programming languages. It shares the same concepts such as data types, operators, control statements and many more. 'C' can be used widely in various applications. It is a simple language and provides faster execution. There are many jobs available for a 'C' developer in the current market.

'C' is a structured programming language in which program is divided into various modules. Each module can be written separately and together it forms a single 'C' program. This structure makes it easy for testing, maintaining and debugging processes.

'C' contains 32 keywords, various data types and a set of powerful built-in functions that make programming very efficient.

Another feature of 'C' programming is that it can extend itself. A 'C' program contains various functions which are part of a library. We can add our features and functions to the library. We can access and use these functions anytime we want in our program. This feature makes it simple while working with complex programming.

Various compilers are available in the market that can be used for executing programs written in this language.

It is a highly portable language which means programs written in 'C' language can run on other machines. This feature is essential if we wish to use or execute the code on another computer.

How 'C' Works?

C is a compiled language. A compiler is a special tool that compiles the program and converts it into the object file which is machine readable. After the compilation process, the linker will combine different object files and creates a single executable file to run the program. The following diagram shows the execution of a 'C' program

Nowadays, various compilers are available online, and you can use any of those compilers. The functionality will never differ and most of the compilers will provide the features required to execute both 'C' and 'C++' programs.

Following is the list of popular compilers available online:

- Clang compiler

- MinGW compiler (Minimalist GNU for Windows)

- Portable 'C' compiler

- Turbo C

Summary

- 'C' was developed by Dennis Ritchie in 1972.

- It is a robust language.

- It is a low programming level language close to machine language

- It is widely used in the software development field.

- It is a procedure and structure oriented language.

- It has the full support of various operating systems and hardware platforms.

- Many compilers are available for executing programs written in 'C'.

- A compiler compiles the source file and generates an object file.

- A linker links all the object files together and creates one executable file.

- It is highly portable.

Chapter 2: How to Download & Install GCC Compiler for C in Windows, Linux, Mac

In this tutorial, we will learn to install C in Windows, Mac, and Linux.

Install C on Windows

We will use an open-source Integrated Development environment named Code::Blocks which bundles a compiler (named gcc offered by Free Software Foundation GNU), editor and debugger in a neat package.

Step 1) Go to http://www.codeblocks.org/downloads and click Binary Release.

Step 2) Choose the installer with GCC Compiler, e.g., codeblocks-17.12mingw-setup.exe which includes MinGW's GNU GCC compiler and GNU GDB debugger with Code::Blocks source files.

Step 3) Run the downloaded installer and accept the default options.

Step 4) Accept the Agreement

Step 5) Keep the component selection default and click Next.

Step 6) You may change the installation folder and click Next.

Step 7) To launch Code::Blocks double click on the icon.

Step 8) It will detect the gcc compiler automatically, set it as default.

Associate C/C++ files with code::blocks

Step 9) You will see the IDE Home screen.

Install C in Linux

Linux operating systems mostly comes with GCC preinstalled. To verify if the compiler is installed on the machine, run the following command in the terminal:

gcc --version

After executing this command if the gcc is installed on the machine then it will return the information about the compiler otherwise it will ask you to install the compiler.

To set up the 'C' environment on Linux distributions follow the given steps:

1. Open terminal.

2. For red-hat, Fedora users, type and execute this command

# yum groupinstall 'Development Tools'

3. For Debian and Ubuntu users, type and execute following command

$ sudo apt-get update
$ sudo apt-get install build-essential manpages-dev

4. To verify that the GCC has been successfully installed on the machine as we discussed earlier, execute the following command

gcc --version

Install C on MAC

To set up a 'C' programming environment on MAC operating system, follow the given steps:

1. Visit the given link https://developer.apple.com/downloads/index.action and download. You will need an Apple developer ID

"Command Line Tools for X-Code," pick any version (latest version is always recommended) and download the .dmg file.

2. After the file is being downloaded on the machine, double click and follow the wizard and install the file. Always keep the default settings as suggested by the installation wizard.

3. After the installation process, open a terminal and run gcc -v command to check if everything is successfully installed.

Conclusion:

'C' program can be written and executed on any machine that has a suitable environment to run the program. Its recommended using an IDE to run C programs. An IDE includes a compiler, editor and debugger. Clanfg, MinGW compiler (Minimalist GNU for Windows), Portable 'C' compiler, Turbo C are popular compilers available.

Chapter 3: C Hello World! Example: Your First Program

Here, is a Hello World program in C

#include<stdio.h> //Pre-processor directive
void main() //main function declaration
{
printf("Hello World"); //to output the string on a display
getch (); //terminating function
}

Here is the code explanation:

Pre-processor directive

#include is a pre-processor directive in 'C.'

#include <stdio.h>, stdio is the library where the function printf is defined. printf is used for generating output. Before using this function, we have to first include the required file, also known as a header file (.h).

You can also create your own functions, group them in header files and declare them at the top of the program to use them. To include a file in a program, use pre-processor directive

#include <file-name>.h

File-name is the name of a file in which the functions are stored. Pre-processor directives are always placed at the beginning of the program.

The main function

The main function is a part of every 'C' program. We can represent the main function in various forms, such as:

- main()

- int main()

- void main()

- main(void)

- void main(void)

- int main(void)

The empty parentheses indicate that this function does not take any argument, value or a parameter. You can also represent this explicitly by placing the keyword void inside the parentheses. The keyword void means the function does not return any value, in this case, the last statement is always getch ().

#include<stdio.h> //Pre-processor directive
int main() //main function declaration
{
printf("Hello World"); //to output the string on a display
return 0; //terminating function
}

In the above example, the keyword int means the function will return an integer value. In this case, the last statement should always return 0.

The source code

After the main function has been declared, we have to specify the opening and closing parentheses. Curly brackets { }, indicate the starting and end of a program. These brackets must be always put after the main function. All the program code is written inside these brackets, such as declarative and executable part.

The printf function generates the output by passing the text "Hello World!"

The semicolon ; determines the end of the statement. In C, each statement must end with a semicolon.

So we have successfully installed the compiler and now can begin working in 'C.' We will write a simple program that will say hello to us. Let's start.

How to run C Program

Step 1) Create a new Project

Step 2) In the pop-up,

1. Select File

2. Choose the "C/C++ Source"

3. Click "Go."

Step 3) Continue, by clicking on "Next."

Step 4) To create the new file ,select a "C" file then click on "Next" button to continue.

Step 5) Set the file path by clicking the "..." button, the explorer window permits to create the C file.

Step 6) Select the path of your new C File then its name which has .c extension and save it.

Step 7) Finally, to confirm the C file creation click "Finish."

Step 8) Enter the code, save it and compile it by clicking on the "Build & Run "button.

Here is the result:

Hello, World!

Summary

- The main function is a mandatory part of every 'C' program.

- To use the functionality of a header file, we have to include the file at the beginning of our program.

- Every 'C' program follows a basic structure.

Chapter 4: How to write Comments in C Programming

What Is Comment In C Language?

A comment is an explanation or description of the source code of the program. It helps a developer explain logic of the code and improves program readability. At run-time, a comment is ignored by the compiler.

There are two types of comments in C:

1) A comment that starts with a slash asterisk /* and finishes with an asterisk slash */ and you can place it anywhere in your code, on the same line or several lines.

2) Single-line Comments which uses a double slash // dedicated to comment single lines

Example Single Line Comment

// single line comment example

Here is an example of comments type

// C program to demo
// Single Line comment
#include <stdio.h>
int main(void)
{

// This is a single line comment
printf("Guru99");
return 0; // return zero
}

Example Multi Line Comment

/* Sample Multiline Comment
Line 1
Line 2
….
…
*/

Example Single Line Comment

#include <stdio.h>
int main() {
/* in main function
I can write my principal code
And this in several comments line /*
int x = 42; //x is a integer variable
printf("%d", x);
return 0;}

Why do you need comments?

A good programmer who writes codes understood by a human is better than a programmer who generates codes understood only by the machine.

So, it is highly recommended to insert comments to your code because it is good programming practice. Comments do not affect a program because the compiler ignores them.

Comments help the developer understand the logic/algorithm of the code if he revisits it after a long time.

Chapter 5: C Tokens, Keywords, Identifiers, Constants, Variables, Data Types

What is a Character set?

Like every other language 'C' also has its own character set. A program is a set of instructions that when executed, generate an output. The data that is processed by a program consists of various characters and symbols. The output generated is also a combination of characters and symbols.

A character set in 'C' is divided into,

- Letters

- Numbers

- Special characters

- White spaces (blank spaces)

A compiler always ignores the use ofcharacters, but it is widely used for formatting the data. Following is the character set in 'C' programming:

1. Letters

- Uppercase characters (A-Z)

- Lowercase characters (a-z)

2. Numbers

- All the digits from 0 to 9

3. White spaces

- Blank space

- New line

- Carriage return

- Horizontal tab

4. Special characters

- Special characters in 'C' are shown in the given table,

, (comma)

{ (opening curly bracket)

. (period)

} (closing curly bracket)

; (semi-colon)

[ (left bracket)

: (colon)

] (right bracket)

? (question mark)

( (opening left parenthesis)

' (apostrophe)

) (closing right parenthesis)

" (double quotation mark)

& (ampersand)

! (exclamation mark)

^ (caret)

|(vertical bar)

+ (addition)

/ (forward slash)

- (subtraction)

\ (backward slash)

* (multiplication)

~ (tilde)

/ (division)

_ (underscore)

> (greater than or closing angle bracket)

$ (dollar sign)

< (less than or opening angle bracket)

% (percentage sign)

# (hash sign)

Token

A token is the smallest unit in a 'C' program. A token is divided into six different types as follows,

Tokens in C

Keywords and Identifiers

In 'C' every word can be either a keyword or an identifier.

Keywords have fixed meanings, and the meaning cannot be changed. They act as a building block of a 'C' program. There are total 32 keywords in 'C'. Keywords are written in lowercase letters.

Following table represents the keywords in 'C',

auto

double

int

struct

break

else

long

switch

case

enum

register

typedef

char

extern

return

union

const

short

float

unsigned

continue

for

signed

void

default

goto

sizeof

volatile

do

if

static

while

An identifier is nothing but a name assigned to an element in a program. Example, name of a variable, function, etc. Identifiers are the user-defined names consisting of 'C' standard character set. As the name says, identifiers are used to identify a particular element in a program. Each identifier must have a unique name. Following rules must be followed for identifiers:

1. The first character must always be an alphabet or an underscore.

2. It should be formed using only letters, numbers, or underscore.

3. A keyword cannot be used as an identifier.

4. It should not contain any whitespace character.

5. The name must be meaningful.

What is a Variable?

A variable is an identifier which is used to store some value. Constants can never change at the time of execution. Variables can change during the execution of a program and update the value stored inside it.

A single variable can be used at multiple locations in a program. A variable name must be meaningful. It should represent the purpose of the variable.

Example: Height, age, are the meaningful variables that represent the purpose it is being used for. Height variable can be used to store a height value. Age variable can be used to store the age of a person

A variable must be declared first before it is used somewhere inside the program. A variable name is formed using characters, digits and an underscore.

Following are the rules that must be followed while creating a variable:

1. A variable name should consist of only characters, digits and an underscore.

2. A variable name should not begin with a number.

3. A variable name should not consist of whitespace.

4. A variable name should not consist of a keyword.

5. 'C' is not a case sensitive language that means a variable named 'age' and 'AGE' are different.

Following are the examples of valid variable names in a 'C' program:

height or HEIGHT
_height
_height1
My_name

Following are the examples of invalid variable names in a 'C' program:

1height
Hei$ght
My name

For example, we declare an integer variable my_variable and assign it the value 48:

int my_variable;
my_variable = 48;

By the way, we can both declare and initialize (assign an initial value) a variable in a single statement:

int my_variable = 48;

Data types

'C' provides various data types to make it easy for a programmer to select a suitable data type as per the requirements of an application. Following are the three data types:

1. Primitive data types

2. Derived data types

3. User-defined data types

There are five primary fundamental data types,

1. int for integer data

2. char for character data

3. float for floating point numbers

4. double for double precision floating point numbers

5. void

Array, functions, pointers, structures are derived data types. 'C' language provides more extended versions of the above mentioned primary data types. Each data type differs from one another in size and range. Following table displays the size and range of each data type.

Data type

Size in bytes

Range

Char or signed char

1

-128 to 127

Unsigned char

1

0 to 255

int or signed int

2

-32768 to 32767

Unsigned int

2

0 to 65535

Short int or Unsigned short int

2

0 to 255

Signed short int

2

-128 to 127

Long int or Signed long int

4

-2147483648 to 2147483647

Unsigned long int

4

0 to 4294967295

float

4

3.4E-38 to 3.4E+38

double

8

1.7E-308 to 1.7E+308

Long double

10

3.4E-4932 to 1.1E+4932

Note: In C, there is no Boolean data type.

Integer data type

Integer is nothing but a whole number. The range for an integer data type varies from machine to machine. The standard range for an integer data type is -32768 to 32767.

An integer typically is of 2 bytes which means it consumes a total of 16 bits in memory. A single integer value takes 2 bytes of memory. An integer data type is further divided into other data types such as short int, int, and long int.

Each data type differs in range even though it belongs to the integer data type family. The size may not change for each data type of integer family.

The short int is mostly used for storing small numbers, int is used for storing averagely sized integer values, and long int is used for storing large integer values.

Whenever we want to use an integer data type, we have place int before the identifier such as,

int age;

Here, age is a variable of an integer data type which can be used to store integer values.

Floating point data type

Like integers, in 'C' program we can also make use of floating point data types. The 'float' keyword is used to represent the floating point data type. It can hold a floating point value which means a number is having a fraction and a decimal part. A floating point value is a real number that contains a decimal point. Integer data type doesn't store the decimal part hence we can use floats to store decimal part of a value.

Generally, a float can hold up to 6 precision values. If the float is not sufficient, then we can make use of other data types that can hold large floating point values. The data type double and long double are used to store real numbers with precision up to 14 and 80 bits respectively.

While using a floating point number a keyword float/double/long double must be placed before an identifier. The valid examples are,

float division;
double BankBalance;

Character data type

Character data types are used to store a single character value enclosed in single quotes.

A character data type takes up-to 1 byte of memory space.

Example,

Char letter;

Void data type

A void data type doesn't contain or return any value. It is mostly used for defining functions in 'C'.

Example,

void displayData()

Type declaration of a variable

int main() {
int x, y;
float salary = 13.48;
char letter = 'K';
x = 25;
y = 34;
int z = x+y;
printf("%d \n", z);
printf("%f \n", salary);
printf("%c \n", letter);
return 0;}

Output:

59
13.480000
K

We can declare multiple variables with the same data type on a single line by separating them with a comma. Also, notice the use of format specifiers in printf output function float (%f) and char (%c) and int (%d).

Constants

Constants are the fixed values that never change during the execution of a program. Following are the various types of constants:

Integer constants

An integer constant is nothing but a value consisting of digits or numbers. These values never change during the execution of a program. Integer constants can be octal, decimal and hexadecimal.

1. Decimal constant contains digits from 0-9 such as,

Example, 111, 1234

Above are the valid decimal constants.

2. Octal constant contains digits from 0-7, and these types of constants are always preceded by 0.

Example, 012, 065

Above are the valid decimal constants.

3. Hexadecimal constant contains a digit from 0-9 as well as characters from A-F. Hexadecimal constants are always preceded by 0X.

Example, 0X2, 0Xbcd

Above are the valid hexadecimal constants.

The octal and hexadecimal integer constants are very rarely used in programming with 'C'.

Character constants

A character constant contains only a single character enclosed within a single quote (''). We can also represent character constant by providing ASCII value of it.

Example, 'A', '9'

Above are the examples of valid character constants.

String constants

A string constant contains a sequence of characters enclosed within double quotes ("").

Example, "Hello", "Programming"

These are the examples of valid string constants.

Real Constants

Like integer constants that always contains an integer value. 'C' also provides real constants that contain a decimal point or a fraction value. The real constants are also called as floating point constants. The real constant contains a decimal point and a fractional value.

Example, 202.15, 300.00

These are the valid real constants in 'C'.

A real constant can also be written as,

Mantissa e Exponent

For example, to declare a value that does not change like the classic circle constant PI, there are two ways to declare this constant

1. By using the const keyword in a variable declaration which will reserve a storage memory

#include <stdio.h>
int main() {
const double PI = 3.14;
printf("%f", PI);
//PI++; // This will generate an error as constants cannot be changed
return 0;}

2. By using the #define pre-processor directive which doesn't use memory for storage and without putting a semicolon character at the end of that statement

#include <stdio.h>
#define PI 3.14
int main() {
printf("%f", PI);
return 0;}

Summary

- A constant is a value that doesn't change throughout the execution of a program.

- A token is the smallest unit in a program.

- A keyword is reserved words by language.

- There are total 32 keywords.

- An identifier is used to identify elements of a program.

- A variable is an identifier which is used to store a value.

- There are four commonly used data types such as int, float, char and a void.

- Each data type differs in size and range from one another.

Chapter 6: C Conditional Statement: IF, IF Else and Nested IF Else with Example

What is a Conditional Statement?

In a 'C' program are executed sequentially. This happens when there is no condition around the statements. If you put some condition for a block of statements the flow of execution might change based on the result evaluated by the condition. This process is referred to as decision making in 'C.' The decision-making statements are also called as control statements.

In 'C' programming conditional statements are possible with the help of the following two constructs:

1. If statement

2. If-else statement

It is also called as branching as a program decides which statement to execute based on the result of the evaluated condition.

If statement

It is one of the powerful conditional statement. If statement is responsible for modifying the flow of execution of a program. If statement is always used with a condition. The condition is evaluated first before executing any statement inside the body of If. The syntax for if statement is as follows:

if (condition)
instruction;

The condition evaluates to either true or false. True is always a non-zero value, and false is a value that contains zero. Instructions can be a single instruction or a code block enclosed by curly braces { }.

Following program illustrates the use of if construct in 'C' programming:

#include<stdio.h>
int main()
{
int num1=1;
int num2=2;
if(num1<num2) //test-condition
{
printf("num1 is smaller than num2");
}
return 0;
}

Output:

num1 is smaller than num2

The above program illustrates the use of if construct to check equality of two numbers.

1. In the above program, we have initialized two variables with num1, num2 with value as 1, 2 respectively.

2. Then, we have used if with a test-expression to check which number is the smallest and which number is the largest. We have used a relational expression in if construct. Since the value of num1 is smaller than num2, the condition will evaluate to true.

3. Thus it will print the statement inside the block of If. After that, the control will go outside of the block and program will be terminated with a successful result.

Relational Operators

C has six relational operators that can be used to formulate a Boolean expression for making a decision and testing conditions, which returns true or false :

< less than

<= less than or equal to

> greater than

>= greater than or equal to

== equal to

!= not equal to

Notice that the equal test (==) is different from the assignment operator (=) because it is one of the most common problems that a programmer faces by mixing them up.

For example:

int x = 41;
x =x+ 1;
if (x == 42) {
printf("You succeed!");}

Output :

You succeed

Keep in mind that a condition that evaluates to a non-zero value is considered as true.

For example:

int present = 1;
if (present)
printf("There is someone present in the classroom \n");

Output :

There is someone present in the classroom

The If-Else statement

The if-else is statement is an extended version of If. The general form of if-else is as follows:

if (test-expression)
{
True block of statements
}
Else
{
False block of statements
}
Statements;

n this type of a construct, if the value of test-expression is true, then the true block of statements will be executed. If the value of test-expression if false, then the false block of statements will be executed. In any case, after the execution, the control will be automatically transferred to the statements appearing outside the block of If.

Following programs illustrate the use of the if-else construct:

We will initialize a variable with some value and write a program to determine if the value is less than ten or greater than ten.

Let's start.

#include<stdio.h>
int main()
{
int num=19;
if(num<10)
{
printf("The value is less than 10");
}
else
{
printf("The value is greater than 10");
}
return 0;
}

Output:

The value is greater than 10

1. We have initialized a variable with value 19. We have to find out whether the number is bigger or smaller than 10 using a 'C' program. To do this, we have used the if-else construct.

2. Here we have provided a condition num<10 because we have to compare our value with 10.

3. As you can see the first block is always a true block which means, if the value of test-expression is true then the first block which is If, will be executed.

4. The second block is an else block. This block contains the statements which will be executed if the value of the test-expression becomes false. In our program, the value of num is greater than ten hence the test-condition becomes false and else block is executed. Thus, our output will be from an else block which is "The value is greater than 10". After the if-else, the program will terminate with a successful result.

In 'C' programming we can use multiple if-else constructs within each other which are referred to as nesting of if-else statements.

Conditional Expressions

There is another way to express an if-else statement is by introducing the ?: operator. In a conditional expression the ?: operator has only one statement associated with the if and the else.

For example:

#include <stdio.h>
int main() {
int y;
int x = 2;
y = (x >= 6) ? 6 : x;/* This is equivalent to: if (x >= 5) y = 5; else y = x; */
printf("y =%d ",y);
return 0;}

Output :

y =2

Nested If-else Statements

When a series of decision is required, nested if-else is used. Nesting means using one if-else construct within another one.

Let's write a program to illustrate the use of nested if-else.

#include<stdio.h>
int main()
{
int num=1;
if(num<10)
{
if(num==1)
{
printf("The value is:%d\n",num);
}
else
{
printf("The value is greater than 1");
}
}
else
{
printf("The value is greater than 10");
}
return 0;
}

Output:

The value is:1

The above program checks if a number is less or greater than 10 and prints the result using nested if-else construct.

1. Firstly, we have declared a variable num with value as 1. Then we have used if-else construct.

2. In the outer if-else, the condition provided checks if a number is less than 10. If the condition is true then and only then it will execute the inner loop. In this case, the condition is true hence the inner block is processed.

3. In the inner block, we again have a condition that checks if our variable contains the value 1 or not. When a condition is true, then it will process the If block otherwise it will process an else block. In this case, the condition is true hence the If a block is executed and the value is printed on the output screen.

4. The above program will print the value of a variable and exit with success.

Try changing the value of variable see how the program behaves.

NOTE: In nested if-else, we have to be careful with the indentation because multiple if-else constructs are involved in this process, so it becomes difficult to figure out individual constructs. Proper indentation makes it easy to read the program.

Nested Else-if statements

Nested else-if is used when multipath decisions are required.

The general syntax of how else-if ladders are constructed in 'C' programming is as follows:

if (test - expression 1) {
statement1;
} else if (test - expression 2) {
Statement2;
} else if (test - expression 3) {
Statement3;
} else if (test - expression n) {
Statement n;
} else {
default;
}
Statement x;

This type of structure is known as the else-if ladder. This chain generally looks like a ladder hence it is also called as an else-if ladder. The test-expressions are evaluated from top to bottom. Whenever a true test-expression if found, statement associated with it is executed. When all the n test-expressions becomes false, then the default else statement is executed.

Let us see the actual working with the help of a program.

#include<stdio.h>
int main()
{
int marks=83;
if(marks>75){
printf("First class");
}
else if(marks>65){
printf("Second class");
}
else if(marks>55){
printf("Third class");
}
else{
printf("Fourth class");
}
return 0;
}

Output:

First class

The above program prints the grade as per the marks scored in a test. We have used the else-if ladder construct in the above program.

1. We have initialized a variable with marks. In the else-if ladder structure, we have provided various conditions.

2. The value from the variable marks will be compared with the first condition since it is true the statement associated with it will be printed on the output screen.

3. If the first test condition turns out false, then it is compared with the second condition.

4. This process will go on until the all expression is evaluated otherwise control will go out of the else-if ladder, and default statement will be printed.

Try modifying the value and notice the change in the output.

Summary

- Decision making or branching statements are used to select one path based on the result of the evaluated expression.

- It is also called as control statements because it controls the flow of execution of a program.

- 'C' provides if, if-else constructs for decision-making statements.

- We can also nest if-else within one another when multiple paths have to be tested.

- The else-if ladder is used when we have to check various ways based upon the result of the expression.

Chapter 7: C Loops: For, While, Do While, Break, Continue with Example

What are Loops?

In looping, a program executes the sequence of statements many times until the stated condition becomes false. A loop consists of two parts, a body of a loop and a control statement. The control statement is a combination of some conditions that direct the body of the loop to execute until the specified condition becomes false.

Types of Loops

Depending upon the position of a control statement in a program, a loop is classified into two types:

1. Entry controlled loop

2. Exit controlled loop

In an entry controlled loop, a condition is checked before executing the body of a loop. It is also called as a pre-checking loop.

In an exit controlled loop, a condition is checked after executing the body of a loop. It is also called as a post-checking loop.

Sample Loop

The control conditions must be well defined and specified otherwise the loop will execute an infinite number of times. The loop that does not stop executing and processes the statements number of times is called as an infinite loop. An infinite loop is also called as an "Endless loop." Following are some characteristics of an infinite loop:

1. No termination condition is specified.

2. The specified conditions never meet.

The specified condition determines whether to execute the loop body or not.

'C' programming language provides us with three types of loop constructs:

1. The while loop

2. The do-while loop

3. The for loop

While Loop

A while loop is the most straightforward looping structure. The basic format of while loop is as follows:

while (condition) {
statements;
}

It is an entry-controlled loop. In while loop, a condition is evaluated before processing a body of the loop. If a condition is true then and only then the body of a loop is executed. After the body of a loop is executed then control again goes back at the beginning, and the condition is checked if it is true, the same process is executed until the condition becomes false. Once the condition becomes false, the control goes out of the loop.

After exiting the loop, the control goes to the statements which are immediately after the loop. The body of a loop can contain more than one statement. If it contains only one statement, then the curly braces are not compulsory. It is a good practice though to use the curly braces even we have a single statement in the body.

In while loop, if the condition is not true, then the body of a loop will not be executed, not even once. It is different in do while loop which we will see shortly.

Following program illustrates a while loop:

#include<stdio.h>
#include<conio.h>
int main()
{
int num=1; //initializing the variable
while(num<=10) //while loop with condition
{
printf("%d\n",num);
num++; //incrementing operation
}
return 0;
}

Output:

1
2
3
4
5
6
7
8
9
10

The above program illustrates the use of while loop. In the above program, we have printed series of numbers from 1 to 10 using a while loop.

1. We have initialized a variable called num with value 1. We are going to print from 1 to 10 hence the variable is initialized with value 1. If you want to print from 0, then assign the value 0 during initialization.

2. In a while loop, we have provided a condition (num<=10), which means the loop will execute the body until the value of num becomes 10. After that, the loop will be terminated, and control will fall outside the loop.

3. In the body of a loop, we have a print function to print our number and an increment operation to increment the value per execution of a loop. An initial value of num is 1, after the execution, it will become 2, and during the next execution, it will become 3. This process will continue until the value becomes 10 and then it will print the series on console and terminate the loop.

\n is used for formatting purposes which means the value will be printed on a new line.

Do-While loop

A do-while loop is similar to the while loop except that the condition is always executed after the body of a loop. It is also called an exit-controlled loop.

The basic format of while loop is as follows:

do {
statements
} while (expression);

As we saw in a while loop, the body is executed if and only if the condition is true. In some cases, we have to execute a body of the loop at least once even if the condition is false. This type of operation can be achieved by using a do-while loop.

In the do-while loop, the body of a loop is always executed at least once. After the body is executed, then it checks the condition. If the condition is true, then it will again execute the body of a loop otherwise control is transferred out of the loop.

Similar to the while loop, once the control goes out of the loop the statements which are immediately after the loop is executed.

The critical difference between the while and do-while loop is that in while loop the while is written at the beginning. In do-while loop, the while condition is written at the end and terminates with a semi-colon (;)

The following program illustrates the working of a do-while loop:

We are going to print a table of number 2 using do while loop.

#include<stdio.h>
#include<conio.h>
int main()
{
int num=1; //initializing the variable
do //do-while loop
{
printf("%d\n",2*num);
num++; //incrementing operation
}while(num<=10);
return 0;
}

Output:

2
4
6
8
10
12
14
16
18
20

In the above example, we have printed multiplication table of 2 using a do-while loop. Let's see how the program was able to print the series.

1. First, we have initialized a variable 'num' with value 1. Then we have written a do-while loop.

2. In a loop, we have a print function that will print the series by multiplying the value of num with 2.

3. After each increment, the value of num will increase by 1, and it will be printed on the screen.

4. Initially, the value of num is 1. In a body of a loop, the print function will be executed in this way: 2*num where num=1, then 2*1=2 hence the value two will be printed. This will go on until the value of num becomes 10. After that loop will be terminated and a statement which is immediately after the loop will be executed. In this case return 0.

For loop

A for loop is a more efficient loop structure in 'C' programming. The general structure of for loop is as follows:

for (initial value; condition; incrementation or decrementation )
{
statements;
}

- The initial value of the for loop is performed only once.

- The condition is a Boolean expression that tests and compares the counter to a fixed value after each iteration, stopping the for loop when false is returned.

- The incrementation/decrementation increases (or decreases) the counter by a set value.

Following program illustrates the use of a simple for loop:

#include<stdio.h>
int main()
{
int number;
for(number=1;number<=10;number++) //for loop to print 1-10 numbers
{
printf("%d\n",number); //to print the number
}
return 0;
}

Output:

1
2
3
4
5
6
7
8
9
10

The above program prints the number series from 1-10 using for loop.

1. We have declared a variable of an int data type to store values.

2. In for loop, in the initialization part, we have assigned value 1 to the variable number. In the condition part, we have specified our condition and then the increment part.

3. In the body of a loop, we have a print function to print the numbers on a new line in the console. We have the value one stored in number, after the first iteration the value will be incremented, and it will become 2. Now the variable number has the value 2. The condition will be rechecked and since the condition is true loop will be executed, and it will print two on the screen. This loop will keep on executing until the value of the variable becomes 10. After that, the loop will be terminated, and a series of 1-10 will be printed on the screen.

In C, the for loop can have multiple expressions separated by commas in each part.

For example:

for (x = 0, y = num; x < y; i++, y--) {
statements;
}

Also, we can skip the initial value expression, condition and/or increment by adding a semicolon.

For example:

int i=0;
int max = 10;
for (; i < max; i++) {
printf("%d\n", i);
}

Notice that loops can also be nested where there is an outer loop and an inner loop. For each iteration of the outer loop, the inner loop repeats its entire cycle.

Consider the following example, that uses nested for loops output a multiplication table:

#include <stdio.h>
int main() {
int i, j;
int table = 2;
int max = 5;
for (i = 1; i <= table; i++) { // outer loop
for (j = 0; j <= max; j++) { // inner loop
printf("%d x %d = %d\n", i, j, i*j);
}
printf("\n"); /* blank line between tables */
}}

Output:

1 x 0 = 0
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
1 x 5 = 5

2 x 0 = 0
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10

The nesting of for loops can be done up-to any level. The nested loops should be adequately indented to make code readable. In some versions of 'C,' the nesting is limited up to 15 loops, but some provide more.

The nested loops are mostly used in array applications which we will see in further tutorials.

Break Statement

The break statement is used mainly in in the switch statement. It is also useful for immediately stopping a loop.

We consider the following program which introduces a break to exit a while loop:

#include <stdio.h>
int main() {
int num = 5;
while (num > 0) {
if (num == 3)
break;
printf("%d\n", num);
num--;
}}

Output:

5
4

Continue Statement

When you want to skip to the next iteration but remain in the loop, you should use the continue statement.

For example:

#include <stdio.h>
int main() {
int nb = 7;
while (nb > 0) {
nb--;
if (nb == 5)
continue;
printf("%d\n", nb);
}}

Output:

6
4
3
2
1
0

So, the value 5 is skipped.

Which loop to Select?

Selection of a loop is always a tough task for a programmer, to select a loop do the following steps:

- Analyze the problem and check whether it requires a pre-test or a post-test loop.

- If pre-test is required, use a while or for a loop.

- If post-test is required, use a do-while loop.

Summary

- Looping is one of the key concepts on any programming language.

- It executes a block of statements number of times until the condition becomes false.

- Loops are of 2 types: entry-controlled and exit-controlled.

- 'C' programming provides us 1) while 2) do-while and 3) for loop.

- For and while loop is entry-controlled loops.

- Do-while is an exit-controlled loop.

Chapter 8: Switch Case Statement in C Programming with Example

What is a Switch Statement?

A switch statement tests the value of a variable and compares it with multiple cases. Once the case match is found, a block of statements associated with that particular case is executed.

Each case in a block of a switch has a different name/number which is referred to as an identifier. The value provided by the user is compared with all the cases inside the switch block until the match is found.

If a case match is found, then the default statement is executed, and the control goes out of the switch block.

Syntax

A general syntax of how switch-case is implemented in a 'C' program is as follows:

switch( expression )
{
case value-1:
Block-1;
Break;
case value-2:
Block-2;
Break;
case value-n:
Block-n;
Break;
default:
Block-1;
Break;
}
Statement-x;

- The expression can be integer expression or a character expression.

- Value-1, 2, n are case labels which are used to identify each case individually. Remember that case labels should not be same as it may create a problem while executing a program. Suppose we have two cases with the same label as '1'. Then while executing the program, the case that appears first will be executed even though you want the program to execute a second case. This creates problems in the program and does not provide the desired output.

- Case labels always end with a colon ( : ). Each of these cases is associated with a block.

- A block is nothing but multiple statements which are grouped for a particular case.

- Whenever the switch is executed, the value of test-expression is compared with all the cases which we have defined inside the switch. Suppose the test expression contains value 4. This value is compared with all the cases until case whose label four is found in the program. As soon as a case is found the block of statements associated with that particular case is executed and control goes out of the switch.

- The break keyword in each case indicates the end of a particular case. If we do not put the break in each case then even though the specific case is executed, the switch will continue to execute all the cases until the end is reached. This should not happen; hence we always have to put break keyword in each case. Break will terminate the case once it is executed and the control will fall out of the switch.

- The default case is an optional one. Whenever the value of test-expression is not matched with any of the cases inside the switch, then the default will be executed. Otherwise, it is not necessary to write default in the switch.

- Once the switch is executed the control will go to the statement-x, and the execution of a program will continue.

Flow Chart Diagram of Switch Case

Following diagram illustrates how a case is selected in switch case:

How Switch Works

Example

Following program illustrates the use of switch:

#include <stdio.h>
int main() {
int num = 8;
switch (num) {
case 7:
printf("Value is 7");
break;
case 8:
printf("Value is 8");
break;
case 9:
printf("Value is 9");
break;
default:
printf("Out of range");
break;
}
return 0;
}

Output:

Value is 8

1. In the given program we have initialized a variable num with value 8.

2. A switch construct is used to compare the value stored in variable num and execute the block of statements associated with the matched case.

3. In this program, since the value stored in variable num is eight, a switch will execute the case whose case-label is 8. After executing the case, the control will fall out of the switch and program will be terminated with the successful result by printing the value on the output screen.

Try changing the value of variable num and notice the change in the output.

For example, we consider the following program which defaults:

#include <stdio.h>
int main() {
int language = 10;
switch (language) {
case 1:
printf("C#\n");
break;
case 2:
printf("C\n");
break;
case 3:
printf("C++\n");
break;
default:
printf("Other programming language\n");}}

Output:

Other programming language

When working with switch case in C, you group multiple cases with unique labels. You need to introduce a break statement in each case to branch at the end of a switch statement.

The optional default case runs when no other matches are made.

We consider the following switch statement:

#include <stdio.h>
int main() {
int number=5;
switch (number) {
case 1:
case 2:
case 3:
printf("One, Two, or Three.\n");
break;
case 4:
case 5:
case 6:
printf("Four, Five, or Six.\n");
break;
default:
printf("Greater than Six.\n");}}

Output:

Four, Five, or Six.

Nested Switch

In C, we can have an inner switch embedded in an outer switch. Also, the case constants of the inner and outer switch may have common values and without any conflicts.

We considere the following program which the user to type his own ID, if the ID is valid it will ask him to enter his password, if the password is correct the program will print the name of the user, otherwise ,the program will print Incorrect Password and if the ID does not exist , the program will print Incorrect ID

#include <stdio.h>
int main() {
int ID = 500;
int password = 000;
printf("Plese Enter Your ID:\n ");
scanf("%d", & ID);
switch (ID) {
case 500:
printf("Enter your password:\n ");
scanf("%d", & password);
switch (password) {
case 000:
printf("Welcome Dear Programmer\n");
break;
default:
printf("incorrect password");
break;
}
break;
default:
printf("incorrect ID");
break;
}
}

OUTPUT:

Plese Enter Your ID:
500
Enter your password:
000
Welcome Dear Programmer

1. In the given program we have initialized two variables: ID and password

2. An outer switch construct is used to compare the value entered in variable ID. It execute the block of statements associated with the matched case(when ID==500).

3. If the block statement is executed with the matched case, an inner switch is used to compare the values entered in the variable password and execute the statements linked with the matched case(when password==000).

4. Otherwise, the switch case will trigger the default case and print the appropriate text regarding the program outline.

Why do we need a Switch case?

There is one potential problem with the if-else statement which is the complexity of the program increases whenever the number of alternative path increases. If you use multiple if-else constructs in the program, a program might become difficult to read and comprehend. Sometimes it may even confuse the developer who himself wrote the program.

The solution to this problem is the switch statement.

Rules for switch statement:

- An expression must always execute to a result.

- Case labels must be constants and unique.

- Case labels must end with a colon ( : ).

- A break keyword must be present in each case.

- There can be only one default label.

- We can nest multiple switch statements.

Summary

- A switch is a decision making construct in 'C.'

- A switch is used in a program where multiple decisions are involved.

- A switch must contain an executable test-expression.

- Each case must include a break keyword.

- Case label must be constants and unique.

- The default is optional.

- Multiple switch statements can be nested within one another.

Chapter 9: C Strings: Declare, Initialize, Read, Print with Example

What is a String?

A string is nothing but a collection of characters in a linear sequence. 'C' always treats a string a single data even though it contains whitespaces. A single character is defined using single quote representation. A string is represented using double quote marks.

Example, "Welcome to the world of programming!"

'C' provides standard library <string.h> that contains many functions which can be used to perform complicated string operations easily.

Declare and initialize a String

A string is a simple array with char as a data type. 'C' language does not directly support string as a data type. Hence, to display a string in 'C', you need to make use of a character array.

The general syntax for declaring a variable as a string is as follows,

char string_variable_name [array_size];

The classic string declaration can be done as follow:

char string_name[string_length] = "string";

The size of an array must be defined while declaring a string variable because it used to calculate how many characters are going to be stored inside the string variable. Some valid examples of string declaration are as follows,

char first_name[15]; //declaration of a string variable
char last_name[15];

The above example represents string variables with an array size of 15. This means that the given character array is capable of holding 15 characters at most. The indexing of array begins from 0 hence it will store characters from a 0-14 position. The C compiler automatically adds a NULL character '\0' to the character array created.

Let's study the initialization of a string variable. Following example demonstrates the initialization of a string variable,

char first_name[15] = "ANTHONY";
char first_name[15] = {'A','N','T','H','O','N','Y','\0'}; // NULL character '\0' is required at end in this declaration
char string1 [6] = "hello";/* string size = 'h'+'e'+'l'+'l'+'o'+"NULL" = 6 */
char string2 [ ] = "world"; /* string size = 'w'+'o'+'r'+'l'+'d'+"NULL" = 6 */
char string3[6] = {'h', 'e', 'l', 'l', 'o', '\0'} ; /*Declaration as set of characters ,Size 6*/

In string3, the NULL character must be added explicitly, and the characters are enclosed in single quotation marks.

'C' also allows us to initialize a string variable without defining the size of the character array. It can be done in the following way,

char first_name[ ] = "NATHAN";

The name of a string acts as a pointer because it is basically an array.

String Input: Read a String

When writing interactive programs which ask the user for input, C provides the scanf(), gets(), and fgets() functions to find a line of text entered from the user.

When we use scanf() to read, we use the "%s" format specifier without using the "&" to access the variable address because an array name acts as a pointer. For example:

#include <stdio.h>
int main() {
char name[10];
int age;
printf("Enter your first name and age: \n");
scanf("%s %d", name, &age); }
printf("You entered: %s %d",name,&age);

Output:

Enter your first name and age:
John_Smith 48

The problem with the scanf function is that it never reads an entire string. It will halt the reading process as soon as whitespace, form feed, vertical tab, newline or a carriage return occurs. Suppose we give input as "Guru99 Tutorials" then the scanf function will never read an entire string as a whitespace character occurs between the two names. The scanf function will only read Guru99.

In order to read a string contains spaces, we use the gets() function. Gets ignores the whitespaces. It stops reading when a newline is reached (the Enter key is pressed).For example:

#include <stdio.h>
int main() {
char full_name[25];
printf("Enter your full name: ");
gets(full_name);
printf("My full name is %s ",full_name);
return 0;
}

Output:

Enter your full name: Dennis Ritchie
My full name is Dennis Ritchie

Another safer alternative to gets() is fgets() function which reads a specified number of characters. For example:

#include <stdio.h>
int main() {
char name[10];
printf("Enter your name plz: ");
fgets(name, 10, stdin);
printf("My name is %s ",name);
return 0;}

Output:

Enter your name plz: Carlos
My name is Carlos

The fgets() arguments are :

- the string name,

- the number of characters to read,

- stdin means to read from the standard input which is the keyboard.

String Output: Print/Display a String

The standard printf function is used for printing or displaying a string on an output device. The format specifier used is %s

Example,

printf("%s", name);

String output is done with the fputs() and printf() functions.

fputs() function

The fputs() needs the name of the string and a pointer to where you want to display the text. We use stdout which refers to the standard output in order to print to the screen.For example:

#include <stdio.h>
int main()
{char town[40];
printf("Enter your town: ");
gets(town);
fputs(town, stdout);
return 0;}

Output:

Enter your town: New York
New York

puts function

The puts function prints the string on an output device and moves the cursor back to the first position. A puts function can be used in the following way,

#include <stdio.h>
int main() {
char name[15];
gets(name); //reads a string
puts(name); //displays a string
return 0;}

The syntax of this function is comparatively simple than other functions.

The string library

The standard 'C' library provides various functions to manipulate the strings within a program. These functions are also called as string handlers. All these handlers are present inside <string.h> header file.

Function

Purpose

strlen()

This function is used for finding a length of a string. It returns how many characters are present in a string excluding the NULL character.

strcat(str1, str2)

This function is used for combining two strings together to form a single string. It Appends or concatenates str2 to the end of str1 and returns a pointer to str1.

strcmp(str1, str2)

This function is used to compare two strings with each other. It returns 0 if str1 is equal to str2, less than 0 if str1 < str2, and greater than 0 if str1 > str2.

Lets consider the program below which demonstrates string library functions:

#include <stdio.h>
#include <string.h>
int main () {
//string initialization
char string1[15]="Hello";
char string2[15]=" World!";
char string3[15];
int val;

//string comparison
val= strcmp(string1,string2);
if(val==0){
printf("Strings are equal\n");
}
else{
printf("Strings are not equal\n");
}

//string concatenation
printf("Concatenated string:%s",strcat(string1,string2)); //string1 contains hello world!

//string length
printf("\nLength of first string:%d",strlen(string1));
printf("\nLength of second string:%d",strlen(string2));

//string copy
printf("\nCopied string is:%s\n",strcpy(string3,string1)); //string1 is copied into string3
return 0;
}

Output:

Strings are not equal
Concatenated string:Hello World!
Length of first string:12
Length of second string:7
Copied string is:Hello World!

Other important library functions are:

- strncmp(str1, str2, n) :it returns 0 if the first n characters of str1 is equal to the first n characters of str2, less than 0 if str1 < str2, and greater than 0 if str1 > str2.

- strncpy(str1, str2, n) This function is used to copy a string from another string. Copies the first n characters of str2 to str1

- strchr(str1, c): it returns a pointer to the first occurrence of char c in str1, or NULL if character not found.

- strrchr(str1, c): it searches str1 in reverse and returns a pointer to the position of char c in str1, or NULL if character not found.

- strstr(str1, str2): it returns a pointer to the first occurrence of str2 in str1, or NULL if str2 not found.

- strncat(str1, str2, n) Appends (concatenates) first n characters of str2 to the end of str1 and returns a pointer to str1.

- strlwr() :to convert string to lower case

- strupr() :to convert string to upper case

- strrev() : to reverse string

Converting a String to a Number

In C programming, we can convert a string of numeric characters to a numeric value to prevent a run-time error. The stdio.h library contains the following functions for converting a string to a number:

- int atoi(str) Stands for ASCII to integer; it converts str to the equivalent int value. 0 is returned if the first character is not a number or no numbers are encountered.

- double atof(str) Stands for ASCII to float, it converts str to the equivalent double value. 0.0 is returned if the first character is not a number or no numbers are encountered.

- long int atol(str) Stands for ASCII to long int, Converts str to the equivalent long integer value. 0 is returned if the first character is not a number or no numbers are encountered.

The following program demonstrates atoi() function:

#include <stdio.h>
int main()
{char *string_id[10];
int ID;
printf("Enter a number: ");
gets(string_id);
ID = atoi(string_id);
printf("you enter %d ",ID);
return 0;}

Output:

Enter a number: 221348
you enter 221348

- A string pointer declaration such as char *string = "language" is a constant and cannot be modified.

Summary

- A string is a sequence of characters stored in a character array.

- A string is a text enclosed in double quotation marks.

- A character such as 'd' is not a string and it is indicated by single quotation marks.

- 'C' provides standard library functions to manipulate strings in a program. String manipulators are stored in <string.h> header file.

- A string must be declared or initialized before using into a program.

- There are different input and output string functions, each one among them has its features.

- Don't forget to include the string library to work with its functions

- We can convert string to number through the atoi(), atof() and atol() which are very useful for coding and decoding processes.

- We can manipulate different strings by defining a string array.

Chapter 10: Storage Classes in C: auto, extern, static, register with Example

What is a Storage Class?

A storage class represents the visibility and a location of a variable. It tells from what part of code we can access a variable. A storage class is used to describe the following things:

- The variable scope.

- The location where the variable will be stored.

- The initialized value of a variable.

- A lifetime of a variable.

- Who can access a variable?

Thus a storage class is used to represent the information about a variable.

NOTE: A variable is not only associated with a data type, its value but also a storage class.

There are total four types of standard storage classes. The table below represents the storage classes in 'C'.

Storage class

Purpose

auto

It is a default storage class.

extern

It is a global variable.

static

It is a local variable which is capable of returning a value even when control is transferred to the function call.

register

It is a variable which is stored inside a Register.

Auto storage class

The variables defined using auto storage class are called as local variables. Auto stands for automatic storage class. A variable is in auto storage class by default if it is not explicitly specified.

The scope of an auto variable is limited with the particular block only. Once the control goes out of the block, the access is destroyed. This means only the block in which the auto variable is declared can access it.

A keyword auto is used to define an auto storage class. By default, an auto variable contains a garbage value.

Example, auto int age;

The program below defines a function with has two local variables

int add(void) {
int a=13;
auto int b=48;
return a+b;}

We take another program which shows the scope level "visibility level" for auto variables in each block code which are independently to each other:

#include <stdio.h>
int main( )
{
auto int j = 1;
{
auto int j= 2;
{
auto int j = 3;
printf ( " %d ", j);
}
printf ( "\t %d ",j);
}
printf( "%d\n", j);}

OUTPUT:

3 2 1

Extern storage class

Extern stands for external storage class. Extern storage class is used when we have global functions or variables which are shared between two or more files.

Keyword extern is used to declaring a global variable or function in another file to provide the reference of variable or function which have been already defined in the original file.

The variables defined using an extern keyword are called as global variables. These variables are accessible throughout the program. Notice that the extern variable cannot be initialized it has already been defined in the original file

Example, extern void display();

First File: main.c

#include <stdio.h>
extern i;
main() {
printf("value of the external integer is = %d\n", i);
return 0;}

Second File: original.c

#include <stdio.h>
i=48;

Result:

value of the external integer is = 48

In order to compile and run the above code, follow the below steps

Step 1) Create new project,

1. Select Console Application

2. Click Go

Step 2) Select C and click Next

Step 3) Click Next

Step 4) Enter details and click Next

Step 5) Click Finish

Step 6) Put the main code as shown in the previous program in the main.c file and save it

Step 7) Create a new C file [File -> new -> Empty File , save (as original.c ) and add it to the current project by clicking "OK" in the dialogue box .

Step 8) Put and save the C code of the original.c file shown in the previous example without the main() function.

Step 9) Build and run your project. The result is shown in the next figure

Static storage class

The static variables are used within function/ file as local static variables. They can also be used as a global variable

- Static local variable is a local variable that retains and stores its value between function calls or block and remains visible only to the function or block in which it is defined.

- Static global variables are global variables visible only to the file in which it is declared.

Example: static int count = 10;

Keep in mind that static variable has a default initial value zero and is initialized only once in its lifetime.

#include <stdio.h> /* function declaration */
void next(void);
static int counter = 7; /* global variable */
main() {
while(counter<10) {
next();
counter++; }
return 0;}
void next( void ) { /* function definition */
static int iteration = 13; /* local static variable */
iteration ++;
printf("iteration=%d and counter= %d\n", iteration, counter);}

Result:

iteration=14 and counter= 7
iteration=15 and counter= 8
iteration=16 and counter= 9

Global variables are accessible throughout the file whereas static variables are accessible only to the particular part of a code.

The lifespan of a static variable is in the entire program code. A variable which is declared or initialized using static keyword always contains zero as a default value.

Register storage class

You can use the register storage class when you want to store local variables within functions or blocks in CPU registers instead of RAM to have quick access to these variables. For example, "counters" are a good candidate to be stored in the register.

Example: register int age;

The keyword register is used to declare a register storage class. The variables declared using register storage class has lifespan throughout the program.

It is similar to the auto storage class. The variable is limited to the particular block. The only difference is that the variables declared using register storage class are stored inside CPU registers instead of a memory. Register has faster access than that of the main memory.

The variables declared using register storage class has no default value. These variables are often declared at the beginning of a program.

#include <stdio.h> /* function declaration */
main() {
{register int weight;
int *ptr=&weight ;/*it produces an error when the compilation occurs ,we cannot get a memory location when dealing with CPU register*/}
}

OUTPUT:

error: address of register variable 'weight' requested

The next table summarizes the principal features of each storage class which are commonly used in C programming

Storage Class

Declaration

Storage

Default Initial Value

Scope

Lifetime

auto

Inside a function/block

Memory

Unpredictable

Within the function/block

Within the function/block

register

Inside a function/block

CPU Registers

Garbage

Within the function/block

Within the function/block

extern

Outside all functions

Memory

Zero

Entire the file and other files where the variable is declared as extern

program runtime

Static (local)

Inside a function/block

Memory

Zero

Within the function/block

program runtime

Static (global)

Outside all functions

Memory

Zero

Global

program runtime

Summary

In this tutorial we have discussed storage classes in C, to sum up:

- A storage class is used to represent additional information about a variable.

- Storage class represents the scope and lifespan of a variable.

- It also tells who can access a variable and from where?

- Auto, extern, register, static are the four storage classes in 'C'.

- auto is used for a local variable defined within a block or function

- register is used to store the variable in CPU registers rather memory location for quick access.

- Static is used for both global and local variables. Each one has its use case within a C program.

- Extern is used for data sharing between C project files.

Chapter 11: C Files I/O: Create, Open, Read, Write and Close a File

C File management

A File can be used to store a large volume of persistent data. Like many other languages 'C' provides following file management functions,

1. Creation of a file

2. Opening a file

3. Reading a file

4. Writing to a file

5. Closing a file

Following are the most important file management functions available in 'C,'

function

purpose

fopen ()

Creating a file or opening an existing file

fclose ()

Closing a file

fprintf ()

Writing a block of data to a file

fscanf ()

Reading a block data from a file

getc ()

Reads a single character from a file

putc ()

Writes a single character to a file

getw ()

Reads an integer from a file

putw ()

Writing an integer to a file

fseek ()

Sets the position of a file pointer to a specified location

ftell ()

Returns the current position of a file pointer

rewind ()

Sets the file pointer at the beginning of a file

How to Create a File

Whenever you want to work with a file, the first step is to create a file. A file is nothing but space in a memory where data is stored.

To create a file in a 'C' program following syntax is used,

FILE *fp;
fp = fopen ("file_name", "mode");

In the above syntax, the file is a data structure which is defined in the standard library.

fopen is a standard function which is used to open a file.

- If the file is not present on the system, then it is created and then opened.

- If a file is already present on the system, then it is directly opened using this function.

fp is a file pointer which points to the type file.

Whenever you open or create a file, you have to specify what you are going to do with the file. A file in 'C' programming can be created or opened for reading/writing purposes. A mode is used to specify whether you want to open a file for any of the below-given purposes. Following are the different types of modes in 'C' programming which can be used while working with a file.

File Mode

Description

r

Open a file for reading. If a file is in reading mode, then no data is deleted if a file is already present on a system.

w

Open a file for writing. If a file is in writing mode, then a new file is created if a file doesn't exist at all. If a file is already present on a system, then all the data inside the file is truncated, and it is opened for writing purposes.

a

Open a file in append mode. If a file is in append mode, then the file is opened. The content within the file doesn't change.

r+

open for reading and writing from beginning

w+

open for reading and writing, overwriting a file

a+

open for reading and writing, appending to file

In the given syntax, the filename and the mode are specified as strings hence they must always be enclosed within double quotes.

Example:

#include <stdio.h>
int main() {
FILE *fp;
fp = fopen ("data.txt", "w");
}

Output:

File is created in the same folder where you have saved your code.

You can specify the path where you want to create your file

#include <stdio.h>
int main() {
FILE *fp;
fp = fopen ("D://data.txt", "w");
}

How to Close a file

One should always close a file whenever the operations on file are over. It means the contents and links to the file are terminated. This prevents accidental damage to the file.

'C' provides the fclose function to perform file closing operation. The syntax of fclose is as follows,

fclose (file_pointer);

Example:

FILE *fp;
fp = fopen ("data.txt", "r");
fclose (fp);

The fclose function takes a file pointer as an argument. The file associated with the file pointer is then closed with the help of fclose function. It returns 0 if close was successful and EOF (end of file) if there is an error has occurred while file closing.

After closing the file, the same file pointer can also be used with other files.

In 'C' programming, files are automatically close when the program is terminated. Closing a file manually by writing fclose function is a good programming practice.

Writing to a File

In C, when you write to a file, newline characters '\n' must be explicitly added.

The stdio library offers the necessary functions to write to a file:

- fputc(char, file_pointer): It writes a character to the file pointed to by file_pointer.

- fputs(str, file_pointer): It writes a string to the file pointed to by file_pointer.

- fprintf(file_pointer, str, variable_lists): It prints a string to the file pointed to by file_pointer. The string can optionally include format specifiers and a list of variables variable_lists.

The program below shows how to perform writing to a file:

fputc() Function:

#include <stdio.h>
int main() {
int i;
FILE * fptr;
char fn[50];
char str[] = "Guru99 Rocks\n";
fptr = fopen("fputc_test.txt", "w"); // "w" defines "writing mode"
for (i = 0; str[i] != '\n'; i++) {
/* write to file using fputc() function */
fputc(str[i], fptr);
}
fclose(fptr);
return 0;
}

Output:

The above program writes a single character into the fputc_test.txt file until it reaches the next line symbol "\n" which indicates that the sentence was successfully written. The process is to take each character of the array and write it into the file.

1. In the above program, we have created and opened a file called fputc_test.txt in a write mode and declare our string which will be written into the file.

2. We do a character by character write operation using for loop and put each character in our file until the "\n" character is encountered then the file is closed using the fclose function.

fputs () Function:

#include <stdio.h>
int main() {
FILE * fp;
fp = fopen("fputs_test.txt", "w+");
fputs("This is Guru99 Tutorial on fputs,", fp);
fputs("We don't need to use for loop\n", fp);
fputs("Easier than fputc function\n", fp);
fclose(fp);
return (0);
}

OUTPUT:

1. In the above program, we have created and opened a file called fputs_test.txt in a write mode.

2. After we do a write operation using fputs() function by writing three different strings

3. Then the file is closed using the fclose function.

fprintf()Function:

#include <stdio.h>
int main() {
FILE *fptr;
fptr = fopen("fprintf_test.txt", "w"); // "w" defines "writing mode"
/* write to file */
fprintf(fptr, "Learning C with Guru99\n");
fclose(fptr);
return 0;
}

OUTPUT:

1. In the above program we have created and opened a file called fprintf_test.txt in a write mode.

2. After a write operation is performed using fprintf() function by writing a string, then the file is closed using the fclose function.

Reading data from a File

There are three different functions dedicated to reading data from a file

- fgetc(file_pointer): It returns the next character from the file pointed to by the file pointer. When the end of the file has been reached, the EOF is sent back.

- fgets(buffer, n, file_pointer): It reads n-1 characters from the file and stores the string in a buffer in which the NULL character '\0' is appended as the last character.

- fscanf(file_pointer, conversion_specifiers, variable_adresses): It is used to parse and analyze data. It reads characters from the file and assigns the input to a list of variable pointers variable_adresses using conversion specifiers. Keep in mind that as with scanf, fscanf stops reading a string when space or newline is encountered.

The following program demonstrates reading from fputs_test.txt file using fgets(),fscanf() and fgetc () functions respectively :

#include <stdio.h>
int main() {
FILE * file_pointer;
char buffer[30], c;

file_pointer = fopen("fprintf_test.txt", "r");
printf("----read a line----\n");
fgets(buffer, 50, file_pointer);
printf("%s\n", buffer);

printf("----read and parse data----\n");
file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
char str1[10], str2[2], str3[20], str4[2];
fscanf(file_pointer, "%s %s %s %s", str1, str2, str3, str4);
printf("Read String1 |%s|\n", str1);
printf("Read String2 |%s|\n", str2);
printf("Read String3 |%s|\n", str3);
printf("Read String4 |%s|\n", str4);

printf("----read the entire file----\n");

file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
while ((c = getc(file_pointer)) != EOF) printf("%c", c);

fclose(file_pointer);
return 0;
}

Result:

----read a line----
Learning C with Guru99

----read and parse data----
Read String1 |Learning|
Read String2 |C|
Read String3 |with|
Read String4 |Guru99|
----read the entire file----
Learning C with Guru99

1. In the above program, we have opened the file called "fprintf_test.txt" which was previously written using fprintf() function, and it contains "Learning C with Guru99" string. We read it using the fgets() function which reads line by line where the buffer size must be enough to handle the entire line.

2. We reopen the file to reset the pointer file to point at the beginning of the file. Create various strings variables to handle each word separately. Print the variables to see their contents. The fscanf() is mainly used to extract and parse data from a file.

3. Reopen the file to reset the pointer file to point at the beginning of the file. Read data and print it from the file character by character using getc() function until the EOF statement is encountered

4. After performing a reading operation file using different variants, we again closed the file using the fclose function.

Interactive File Read and Write with getc and putc

These are the simplest file operations. Getc stands for get character, and putc stands for put character. These two functions are used to handle only a single character at a time.

Following program demonstrates the file handling functions in 'C' programming:

#include <stdio.h>
int main() {
FILE * fp;
char c;
printf("File Handling\n");
//open a file
fp = fopen("demo.txt", "w");
//writing operation
while ((c = getchar()) != EOF) {
putc(c, fp);
}
//close file
fclose(fp);
printf("Data Entered:\n");
//reading
fp = fopen("demo.txt", "r");
while ((c = getc(fp)) != EOF) {
printf("%c", c);
}
fclose(fp);
return 0;
}

Output:

1. In the above program we have created and opened a file called demo in a write mode.

2. After a write operation is performed, then the file is closed using the fclose function.

3. We have again opened a file which now contains data in a reading mode. A while loop will execute until the eof is found. Once the end of file is found the operation will be terminated and data will be displayed using printf function.

4. After performing a reading operation file is again closed using the fclose function.

Summary

- A file is a space in a memory where data is stored.

- 'C' programming provides various functions to deal with a file.

- A mechanism of manipulating with the files is called as file management.

- A file must be opened before performing operations on it.

- A file can be opened in a read, write or an append mode.

- Getc and putc functions are used to read and write a single character.

- The function fscanf() permits to read and parse data from a file

- We can read (using the getc function) an entire file by looping to cover all the file until the EOF is encountered

- We can write to a file after creating its name, by using the function fprintf() and it must have the newline character at the end of the string text.

Chapter 12: Functions in C Programming with Examples: Recursive, Inline

What is a Function?

A function in programming is a reusable block of code that makes a program easier to test, understand and can be modified easily without changing the calling program. Functions to divide the code and modularize the program for better and effective results. In short, a larger program is divided into various subprograms which are called as functions.

When you divide a large program into various functions, it becomes easy to manage each function individually. Whenever an error occurs in the program, you can easily investigate faulty functions and correct only those errors. You can easily call and use functions whenever they are required which automatically leads in saving time and space.

Library Vs. User-defined Functions

Every 'C' program has at least one function which is the main function, but a program can have any number of functions. The main () function is a starting point of a program.

In 'C' programming, functions are divided into two types:

1. Library functions

2. User-defined functions

The difference between the library and user-defined functions is that we do not need to write a code for a library function. It is already present inside the header file which we always include at the beginning of a program. You just have to type the name of a function and use it along with the proper syntax. Printf, scanf are the examples of a library function.

Whereas, a user-defined function is a type of function in which we have to write a body of a function and call the function whenever we require the function to perform some operation in our program.

A user-defined function is always written by the user, but later it can be a part of 'C' library. It is a major advantage of 'C' programming.

In 'C' programming functions are divided into three activities such as,

1. Function declaration

2. Function definition

3. Function call

Function Declaration

Function declaration means writing a name of a program. It is a compulsory part for using functions in code. In a function declaration, we just specify the name of a function that we are going to use in our program like a variable declaration. We cannot use a function unless it is declared in a program. A function declaration is also called "Function prototype."

The function declarations (called prototype) are usually done above the main () function and take the general form:

return_data_type function_name (data_type arguments);

- The return_data_type: is the data type of the value function returned back to the calling statement.

- The function_name: is followed by parentheses

- Arguments names with their data type declarations optionally are placed inside the parentheses.

We consider the following program that shows how to declare a cube function to calculate the cube value of an integer variable

#include <stdio.h>
/*Function declaration*/
int add(int a,b);
/*End of Function declaration*/
int main() {

Keep in mind that a function does not necessarily return a value. In this case, the keyword void is used.

For example, the output_message function declaration indicates that the function does not return a value: void output_message();

Function Definition

Function definition means just writing the body of a function. A body of a function consists of statements which are going to perform a specific task. A function body consists of a single or a block of statements. It is also a mandatory part of a function.

int add(int a,int b) //function body
{
int c;
c=a+b;
return c;
}

Function call

A function call means calling a function whenever it is required in a program. Whenever we call a function, it performs an operation for which it was designed. A function call is an optional part in a program.

result = add(4,5);

Here, is th complete code:

#include <stdio.h>
int add(int a, int b); //function declaration
int main()
{
int a=10,b=20;
int c=add(10,20); //function call
printf("Addition:%d\n",c);
getch();
}
int add(int a,int b) //function body
{
int c;
c=a+b;
return c;
}

Output:

Addition:30

Function Arguments

A function's arguments are used to receive the necessary values by the function call. They are matched by position; the first argument is passed to the first parameter, the second to the second parameter and so on.

By default, the arguments are passed by value in which a copy of data is given to the called function. The actually passed variable will not change.

We consider the following program which demonstrates parameters passed by value:

int add (int x, int y);
int main() {
int a, b, result;
a = 5;
b = 10;
result = add(a, b);
printf("%d + %d\ = %d\n", a, b, result);
return 0;}
int add (int x, int y) {
x += y;
return(x);}

The program output is:

5 + 10 = 15

Keep in mind that the values of a and b were passed to add function were not changed because only its value was passed into the parameter x.

Variable Scope

Variable scope means the visibility of variables within a code of the program.

In C, variables which are declared inside a function are local to that block of code and cannot be referred to outside the function. However, variables which are declared outside all functions are global and accessible from the entire program. Constants declared with a #define at the top of a program are accessible from the entire program. We consider the following program which prints the value of the global variable from both main and user defined function :

#include <stdio.h>
int global = 1348;
void test();
int main() {
printf("from the main function : global =%d \n", global);
test () ;
return 0;}

void test (){
printf("from user defined function : global =%d \n", global);}

Result:

from the main function : global =1348
from user defined function : global =1348

We discuss the program details:

1. We declare an integer globale variable with 1348 as initial value.

2. We declare and define a test() function which neither takes arguments nor returns a value. This function only prints the globale variable value to demonstrate that the global variables can be accessed anywhere in the program.

3. We print the global variable within the main function.

4. We call the test function in orde to print the global variable value.

In C, when arguments are passed to function parameters, the parameters act as local variables which will be destroyed when exiting the function.

When you use global variables, use them with caution because can lead to errors and they can change anywhere in a program. They should be initialized before using.

Static Variables

The static variables have a local scope. However, they are not destroyed when exiting the function. Therefore, a static variable retains its value forever and can be accessed when the function is re-entered. A static variable is initialized when declared and needs the prefix static.

The following program uses a static variable:

#include <stdio.h>
void say_hi();
int main() {
int i;
for (i = 0; i < 5; i++) { say_hello();}
return 0;}
void say_hi() {
static int calls_number = 1;
printf("Hi number %d\n", calls_number);
calls_number ++; }

The program displays :

Hi number 1
Hi number 2
Hi number 3
Hi number 4
Hi number 5

Recursive Functions

Consider the factorial of a number which is calculated as follow 6! =6* 5 * 4 * 3 * 2 * 1.

This calculation is done as repeatedly calculating fact * (fact -1) until fact equals 1.

A recursive function is a function which calls itself and includes an exit condition in order to finish the recursive calls. In the case of the factorial number calculation, the exit condition is fact equals to 1. Recursion works by "stacking" calls until the exiting condition is true.

For example:

#include <stdio.h>
int factorial(int number);
int main() {
int x = 6;
printf("The factorial of %d is %d\n", x, factorial(x));
return 0;}
int factorial(int number) {
if (number == 1) return (1); /* exiting condition */
else
return (number * factorial(number - 1));
}

The program displays:

The factorial of 6 is 720

Here,we discuss program details:

1. We declare our recursive factorial function which takes an integer parameter and returns the factorial of this parameter.This function will call itself and decrease the number until the exiting, or the base condition is reached. When the condition is true, the previously generated values will be multiplied by each other, and the final factorial value is returned.

2. We declare and initialize an integer variable with value"6" and then print its factorial value by calling our factorial function.

Consider the following chart to more understand the recursive mechanism which consists of calling the function its self until the base case or stopping condition is reached, and after that, we collect the previous values:

Inline Functions

Functions are used to store the most frequently used instructions. It is used for modularizing the program.

Whenever a function is called, the instruction pointer jumps to the function definition. After executing a function, instruction pointer falls back to the statement from where it jumped to the function definition.

Whenever we use functions, we require an extra pointer head to jump to the function definition and return to the statement. To eliminate the need of such pointer heads, we use inline functions.

In an inline function, a function call is directly replaced by an actual program code. It does not jump to any block because all the operations are performed inside the inline function.

Inline functions are mostly used for small computations. They are not suitable when large computing is involved.

An inline function is similar to the normal function except that keyword inline is place before the function name. Inline functions are created with the following syntax:

inline function_name ()
{
//function definition
}

Let us write a program to implement an inline function.

inline int add(int a, int b) //inline function declaration
{
return(a+b);
}
int main()
{
int c=add(10,20);
printf("Addition:%d\n",c);
getch();
}

Output:

Addition: 30

Above program demonstrates the use of an inline function for addition of two numbers. As we can see, we have returned the addition on two numbers within the inline function only without writing any extra lines. During function call we have just passed values on which we have to perform addition.

Summary

- A function is a mini-program or a subprogram.

- Functions are used to modularize the program.

- Library and user-defined are two types of functions.

- A function consists of a declaration, function body, and a function call part.

- Function declaration and body are mandatory.

- A function call can be optional in a program.

- C program has at least one function; it is the main function ().

- Each function has a name, data type of return value or a void, parameters.

- Each function must be defined and declared in your C program.

- Keep in mind that ordinary variables in a C function are destroyed as soon as we exit the function call.

- The arguments passed to a function will not be changed because they passed by value none by address.

- The variable scope is referred to as the visibility of variables within a program

- There are global and local variables in C programming

Chapter 13: Pointers in C Programming with Examples

What is a Pointer?

In simple words, a pointer is an address. It is a derived data type that stores the memory address. A pointer can also be used to refer another pointer, function. A pointer can be incremented/ decremented, i.e., to point to the next/ previous memory location.

How does Pointer Work?

If we declare a variable v of type int, v will actually store a value.

v is equal to zero now.

However, each variable, apart from value, also has its address (or, simply put, where it is located in the memory). The address can be retrieved by putting an ampersand (&) before the variable name.

If you print the address of a variable on the screen, it will look like a totally random number (moreover, it can be different from run to run).

Let's try this in practice.

The output of this program is -480613588.

Now, what is a pointer? Instead of storing a value, a pointer will y store the address of a variable.

Int *y = &v;

VARIABLE

POINTER

A value stored in a named storage/memory address

A variable that points to the storage/memory address of another variable

Declaring a pointer

Like variables, pointers have to be declared before they can be used in your program. Pointers can be named anything you want as long as they obey C's naming rules. A pointer declaration has the following form.

data_type * pointer_variable_name;

Here,

- data_type is the pointer's base type of C's variable types and indicates the type of the variable that the pointer points to.

- The asterisk (*: the same asterisk used for multiplication) which is indirection operator, declares a pointer.

Let's see some valid pointer declarations

int *ptr_thing; /* pointer to an integer */
int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */
double *ptr2; /* pointer to a double */
float *ptr3; /* pointer to a float */
char *ch1 ; /* pointer to a character */
float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */

Initialize a pointer

After declaring a pointer, we initialize it like standard variables with a variable address. If pointers are not uninitialized and used in the program, the results are unpredictable and potentially disastrous.

To get the address of a variable, we use the ampersand (&)operator, placed before the name of a variable whose address we need. Pointer initialization is done with the following syntax.

pointer = &variable;

A simple program for pointer illustration is given below:

#include <stdio.h>
int main()
{
int a=10; //variable declaration
int *p; //pointer variable declaration
p=&a; //store address of variable a in pointer p
printf("Address stored in a variable p is:%x\n",p); //accessing the address
printf("Value stored in a variable p is:%d\n",*p); //accessing the value
return 0;
}

Output:

Address stored in a variable p is:60ff08
Value stored in a variable p is:10

Operator

Meaning

*

Serves 2 purpose

1. Declaration of a pointer

2. Returns the value of the referenced variable

&

Serves only 1 purpose

- Returns the address of a variable

Types of a pointer

Null pointer

We can create a null pointer by assigning null value during the pointer declaration. This method is useful when you do not have any address assigned to the pointer. A null pointer always contains value 0.

Following program illustrates the use of a null pointer:

#include <stdio.h>
int main()
{
int *p = NULL; //null pointer
printf(“The value inside variable p is:\n%x”,p);
return 0;
}

Output:

The value inside variable p is:
0

Void Pointer

In C programming, a void pointer is also called as a generic pointer. It does not have any standard data type. A void pointer is created by using the keyword void. It can be used to store an address of any variable.

Following program illustrates the use of a void pointer:

#include <stdio.h>
int main()
{
void *p = NULL; //void pointer
printf("The size of pointer is:%d\n",sizeof(p));
return 0;
}

Output:

The size of pointer is:4

Wild pointer

A pointer is said to be a wild pointer if it is not being initialized to anything. These types of pointers are not efficient because they may point to some unknown memory location which may cause problems in our program and it may lead to crashing of the program. One should always be careful while working with wild pointers.

Following program illustrates the use of wild pointer:

#include <stdio.h>
int main()
{
int *p; //wild pointer
printf("\n%d",*p);
return 0;
}

Output

timeout: the monitored command dumped core
sh: line 1: 95298 Segmentation fault timeout 10s main

Other types of pointers in 'c' are as follows:

- Dangling pointer

- Complex pointer

- Near pointer

- Far pointer

- Huge pointer

Direct and Indirect Access Pointers

In C, there are two equivalent ways to access and manipulate a variable content

- Direct access: we use directly the variable name

- Indirect access: we use a pointer to the variable

Let's understand this with the help of program below

#include <stdio.h>
/* Declare and initialize an int variable */
int var = 1;
/* Declare a pointer to int */
int *ptr;
int main( void )
{
/* Initialize ptr to point to var */
ptr = &var;
/* Access var directly and indirectly */
printf("\nDirect access, var = %d", var);
printf("\nIndirect access, var = %d", *ptr);
/* Display the address of var two ways */
printf("\n\nThe address of var = %d", &var);
printf("\nThe address of var = %d\n", ptr);
/*change the content of var through the pointer*/
*ptr=48;
printf("\nIndirect access, var = %d", *ptr);
return 0;}

After compiling the program without any errors, the result is:

Direct access, var = 1
Indirect access, var = 1

The address of var = 4202496
The address of var = 4202496

Indirect access, var = 48

Pointers Arithmetic

The pointer operations are summarized in the following figure

Pointer Operations

Priority operation (precedence)

When working with pointers, we must observe the following priority rules:

- The operators * and & have the same priority as the unary operators (the negation!, the incrementation++, decrement--).

- In the same expression, the unary operators *, &,!, ++, - are evaluated from right to left.

If a P pointer points to an X variable, then * P can be used wherever X can be written.

The following expressions are equivalent:

int X =10

int *P = &Y;

For the above code, below expressions are true

Expression

Equivalent Expression

Y=*P+1

*P=*P+10

*P+=2

++*P

(*P)++

Y=X+1

X=X+10

X+=2

++X

X++

In the latter case, parentheses are needed: as the unary operators * and ++ are evaluated from right to left, without the parentheses the pointer P would be incremented, not the object on which P points.

Below table shows the arithmetic and basic operation that can be used when dealing with pointers

Operation

Explanation

Assignment

int *P1,*P2 P1=P2; P1 and P2 point to the same integer variable

Incrementation and decrementation

Int *P1; P1++;P1-- ;

Adding an offset (Constant)

This allows the pointer to move N elements in a table. The pointer will be increased or decreased by N times the number of byte (s) of the type of the variable. P1+5;

Pointers and Arrays

Traditionally, we access the array elements using its index, but this method can be eliminated by using pointers. Pointers make it easy to access each array element.

#include <stdio.h>
int main()
{
int a[5]={1,2,3,4,5}; //array initialization
int *p; //pointer declaration
/*the ptr points to the first element of the array*/

p=a; /*We can also type simply ptr==&a[0] */

printf("Printing the array elements using pointer\n");
for(int i=0;i<5;i++) //loop for traversing array elements
{
printf("\n%x",*p); //printing array elements
p++; //incrementing to the next element, you can also write p=p+1
}
return 0;
}

Output

1
2
3
4
5

Adding a particular number to a pointer will move the pointer location to the value obtained by an addition operation. Suppose p is a pointer that currently points to the memory location 0 if we perform following addition operation, p+1 then it will execute in this manner:

Pointer Addition/Increment

Since p currently points to the location 0 after adding 1, the value will become 1, and hence the pointer will point to the memory location 1.

Pointers and Strings

A string is an array of char objects, ending with a null character '\ 0'. We can manipulate strings using pointers. Here is an example that explains this section

#include <stdio.h>
#include <string.h>
int main()
{
char str[]="Hello Guru99!";
char *p;
p=str;
printf("First character is:%c\n",*p);
p =p+1;
printf("Next character is:%c\n",*p);
printf("Printing all the characters in a string\n");
p=str; //reset the pointer
for(int i=0;i<strlen(str);i++)
{
printf("%c\n",*p);
p++;
}
return 0;
}

Output

First character is:H
Next character is:e
Printing all the characters in a string
H
e
l
l
o

G
u
r
u
9
9
!

Another way to deal strings is with an array of pointers like in the following program:

#include <stdio.h>
int main(){
char *materials[ ] = { "iron", "copper", "gold"};
printf("Please remember these materials :\n");
int i ;
for (i = 0; i < 3; i++) {
printf("%s\n", materials[ i ]);}
return 0;}

Output:

Please remember these materials:
iron
copper
gold

Advantages of Pointers

- Pointers are useful for accessing memory locations.

- Pointers provide an efficient way for accessing the elements of an array structure.

- Pointers are used for dynamic memory allocation as well as deallocation.

- Pointers are used to form complex data structures such as linked list, graph, tree, etc.

Disadvantages of Pointers

- Pointers are a little complex to understand.

- Pointers can lead to various errors such as segmentation faults or can access a memory location which is not required at all.

- If an incorrect value is provided to a pointer, it may cause memory corruption.

- Pointers are also responsible for memory leakage.

- Pointers are comparatively slower than that of the variables.

- Programmers find it very difficult to work with the pointers; therefore it is programmer's responsibility to manipulate a pointer carefully.

Summary

- A pointer is nothing but a memory location where data is stored.

- A pointer is used to access the memory location.

- There are various types of pointers such as a null pointer, wild pointer, void pointer and other types of pointers.

- Pointers can be used with array and string to access elements more efficiently.

- We can create function pointers to invoke a function dynamically.

- Arithmetic operations can be done on a pointer which is known as pointer arithmetic.

- Pointers can also point to function which make it easy to call different functions in the case of defining an array of pointers.

- When you want to deal different variable data type, you can use a typecast void pointer.

Chapter 14: Functions Pointers in C Programming with Examples

Pointers give greatly possibilities to 'C' functions which we are limited to return one value. With pointer parameters, our functions now can process actual data rather than a copy of data.

In order to modify the actual values of variables, the calling statement passes addresses to pointer parameters in a function.

Functions Pointers Example

For example, the next program swaps two values of two:

void swap (int *a, int *b);
int main() {
int m = 25;
int n = 100;
printf("m is %d, n is %d\n", m, n);
swap(&m, &n);
printf("m is %d, n is %d\n", m, n);
return 0;}
void swap (int *a, int *b) {
int temp;
temp = *a;
*a = *b;
*b = temp;}
}

Output:

m is 25, n is 100
m is 100, n is 25

The program swaps the actual variables values because the function accesses them by address using pointers. Here we will discuss the program process:

1. We declare the function responsible for swapping the two variable values, which takes two integer pointers as parameters and returns any value when it is called.

2. In the main function, we declare and initialize two integer variables ('m' and 'n') then we print their values respectively.

3. We call the swap() function by passing the address of the two variables as arguments using the ampersand symbol. After that, we print the new swapped values of variables.

4. Here we define the swap() function content which takes two integer variable addresses as parameters and declare a temporary integer variable used as a third storage box to save one of the value variables which will be put to the second variable.

5. Save the content of the first variable pointed by 'a' in the temporary variable.

6. Store the second variable pointed by b in the first variable pointed by a.

7. Update the second variable (pointed by b) by the value of the first variable saved in the temporary variable.

Functions with Array Parameters

In C, we cannot pass an array by value to a function. Whereas, an array name is a pointer (address), so we just pass an array name to a function which means to pass a pointer to the array.

For example, we consider the following program:

int add_array (int *a, int num_elements);
int main() {
int Tab[5] = {100, 220, 37, 16, 98};
printf("Total summation is %d\n", add_array(Tab, 5));
return 0;}
int add_array (int *p, int size) {
int total = 0;
int k;
for (k = 0; k < size; k++) {
total += p[k]; /* it is equivalent to total +=*p ;p++; */}
return (total);}

Output:

Total summation is 471

Here, we will explain the program code with its details

1. We declare and define add_array() function which takes an array address( pointer) with its elements number as parameters and returns the total accumulated summation of these elements. The pointer is used to iterate the array elements (using the p[k] notation), and we accumulate the summation in a local variable which will be returned after iterating the entire element array.

2. We declare and initialize an integer array with five integer elements. We print the total summation by passing the array name (which acts as address) and array size to the add_array()called function as arguments.

Functions that Return an Array

In C, we can return a pointer to an array, as in the following program:

#include <stdio.h>
int * build_array();
int main() {
int *a;
a = build_array(); /* get first 5 even numbers */
for (k = 0; k < 5; k++)
printf("%d\n", a[k]);
return 0;}
int * build_array() {
static int Tab[5]={1,2,3,4,5};
return (Tab);}

Output:

1
2
3
4
5

And here, we will discuss the program details

1. We define and declare a function which returns an array address containing an integer value and didn't take any arguments.

2. We declare an integer pointer which receives the complete array built after the function is called and we print its contents by iterating the entire five element array.

Notice that a pointer, not an array, is defined to store the array address returned by the function. Also notice that when a local variable is being returned from a function, we have to declare it as static in the function.

Function Pointers

As we know by definition that pointers point to an address in any memory location, they can also point to at the beginning of executable code as functions in memory.

A pointer to function is declared with the * ,the general statement of its declaration is:

return_type (*function_name)(arguments)

You have to remember that the parentheses around (*function_name) are important because without them, the compiler will think the function_name is returning a pointer of return_type.

After defining the function pointer, we have to assign it to a function. For example, the next program declares an ordinary function, defines a function pointer, assigns the function pointer to the ordinary function and after that calls the function through the pointer:

#include <stdio.h>
void Hi_function (int times); /* function */
int main() {
void (*function_ptr)(int); /* function pointer Declaration */
function_ptr = Hi_function; /* pointer assignment */
function_ptr (3); /* function call */
return 0;}
void Hi_function (int times) {
int k;
for (k = 0; k < times; k++) printf("Hi\n");}

Output:

Hi
Hi
Hi

1. We define and declare a standard function which prints a Hi text k times indicated by the parameter times when the function is called

2. We define a pointer function (with its special declaration) which takes an integer parameter and doesn't return anything.

3. We initialize our pointer function with the Hi_function which means that the pointer points to the Hi_function().

4. Rather than the standard function calling by taping the function name with arguments, we call only the pointer function by passing the number 3 as arguments, and that's it!

Keep in mind that the function name points to the beginning address of the executable code like an array name which points to its first element. Therefore, instructions like function_ptr = &Hi_function and (*funptr)(3) are correct.

NOTE: It is not important to insert the address operator & and the indirection operator * during the function assignment and function call.

Array of Function Pointers

An array of function pointers can play a switch or an if statement role for making a decision, as in the next program:

#include <stdio.h>
int sum(int num1, int num2);
int sub(int num1, int num2);
int mult(int num1, int num2);
int div(int num1, int num2);

int main()
{ int x, y, choice, result;
int (*ope[4])(int, int);
ope[0] = sum;
ope[1] = sub;
ope[2] = mult;
ope[3] = div;
printf("Enter two integer numbers: ");
scanf("%d%d", &x, &y);
printf("Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: ");
scanf("%d", &choice);
result = ope[choice](x, y);
printf("%d", result);
return 0;}

int sum(int x, int y) {return(x + y);}
int sub(int x, int y) {return(x - y);}
int mult(int x, int y) {return(x * y);}
int div(int x, int y) {if (y != 0) return (x / y); else return 0;}

Enter two integer numbers: 13 48
Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: 2
624

Here, we discuss the program details:

1. We declare and define four functions which take two integer arguments and return an integer value. These functions add, subtract, multiply and divide the two arguments regarding which function is being called by the user.

2. We declare 4 integers to handle operands, operation type, and result respectively. Also, we declare an array of four function pointer. Each function pointer of array element takes two integers parameters and returns an integer value.

3. We assign and initialize each array element with the function already declared. For example, the third element which is the third function pointer will point to multiplication operation function.

4. We seek operands and type of operation from the user typed with the keyboard.

5. We called the appropriate array element (Function pointer) with arguments, and we store the result generated by the appropriate function.

The instruction int (*ope[4])(int, int); defines the array of function pointers. Each array element must have the same parameters and return type.

The statement result = ope[choice](x, y); runs the appropriate function according to the choice made by the user The two entered integers are the arguments passed to the function.

Functions Using void Pointers

Void pointers are used during function declarations. We use a void * return type permits to return any type. If we assume that our parameters do not change when passing to a function, we declare it as const.

For example:

void * cube (const void *);

Consider the following program:

#include <stdio.h>
void* cube (const void* num);
int main() {
int x, cube_int;
x = 4;
cube_int = cube (&x);
printf("%d cubed is %d\n", x, cube_int);
return 0;}

void* cube (const void *num) {
int result;
result = (*(int *)num) * (*(int *)num) * (*(int *)num);
return result;}

Result:

4 cubed is 64

Here, we will discuss the program details:

1. We define and declare a function that returns an integer value and takes an address of unchangeable variable without a specific data type. We calculate the cube value of the content variable (x) pointed by the num pointer, and as it is a void pointer, we have to type cast it to an integer data type using a specific notation (* datatype) pointer, and we return the cube value.

2. We declare the operand and the result variable. Also, we initialize our operand with value "4."

3. We call the cube function by passing the operand address, and we handle the returning value in the result variable

Function Pointers as Arguments

Another way to exploit a function pointer by passing it as an argument to another function sometimes called "callback function" because the receiving function "calls it back."

In the stdlib.h header file, the Quicksort "qsort()" function uses this technique which is an algorithm dedicated to sort an array.

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))

- void *base : void pointer to the array.

- size_t num : The array element number.

- size_t width The element size.

- int (*compare (const void *, const void *) : function pointer composed of two arguments and returns 0 when the arguments have the same value, <0 when arg1 comes before arg2, and >0 when arg1 comes after arg2.

The following program sorts an integers array from small to big number using qsort() function:

#include <stdio.h>
#include <stdlib.h>
int compare (const void *, const void *);
int main() {
int arr[5] = {52, 14, 50, 48, 13};
int num, width, i;
num = sizeof(arr)/sizeof(arr[0]);
width = sizeof(arr[0]);
qsort((void *)arr, num, width, compare);
for (i = 0; i < 5; i++)
printf("%d ", arr[ i ]);
return 0;}

int compare (const void *elem1, const void *elem2) {
if ((*(int *)elem1) == (*(int *)elem2)) return 0;
else if ((*(int *)elem1) < (*(int *)elem2)) return -1;
else return 1;}

Result:

13 14 48 50 52

Here, we will discuss the program details:

1. We define compare function composed of two arguments and returns 0 when the arguments have the same value, <0 when arg1 comes before arg2, and >0 when arg1 comes after arg2.The parameters are a void pointers type casted to the appropriate array data type (integer)

2. We define and initialize an integer array The array size is stored in the num variable and the size of each array element is stored in width variable using sizeof() predefined C operator.

3. We call the qsort function and pass the array name, size, width, and comparison function defined previously by the user in order to sort our array in ascending order.The comparison will be performed by taking in each iteration two array elements until the entire array will be sorted.

4. We print the array elements to be sure that our array is well sorted by iterating the entire array using for loop.

Chapter 15: C Bitwise Operators: AND, OR, XOR, Shift & Complement (with Example)

What are Bitwise Operators?

Bitwise operators are used for manipulating a data at the bit level, also called as bit level programming. Bit-level programming mainly consists of 0 and 1. They are used in numerical computations to make the calculation process faster.

Following is the list of bitwise operators provided by 'C' programming language:

Operator

Meaning

&

Bitwise AND operator

|

Bitwise OR operator

^

Bitwise exclusive OR operator

~

Binary One's Complement Operator is a unary operator

<<

Left shift operator

>>

Right shift operator

Bitwise operators cannot be directly applied to primitive data types such as float, double, etc. Always remember one thing that bitwise operators are mostly used with the integer data type because of its compatibility.

The bitwise logical operators work on the data bit by bit, starting from the least significant bit, i.e. LSB bit which is the rightmost bit, working towards the MSB (Most Significant Bit) which is the leftmost bit.

The result of the computation of bitwise logical operators is shown in the table given below.

x

y

x & y

x | y

x ^ y

0

0

0

0

0

0

1

0

1

1

1

0

0

1

1

1

1

1

1

0

Bitwise AND

This is one of the most commonly used logical bitwise operators. It is represented by a single ampersand sign (&). Two integer expressions are written on each side of the (&) operator.

The result of the bitwise AND operation is 1 if both the bits have the value as 1; otherwise, the result is always 0.

Let us consider that we have 2 variables op1 and op2 with values as follows:

Op1 = 0000 1101
Op2 = 0001 1001

The result of the AND operation on variables op1 and op2 will be

Result = 0000 1001

As we can see, two variables are compared bit by bit. Whenever the value of a bit in both the variables is 1, then the result will be 1 or else 0.

Bitwise OR

It is represented by a single vertical bar sign (|). Two integer expressions are written on each side of the (|) operator.

The result of the bitwise OR operation is 1 if at least one of the expression has the value as 1; otherwise, the result is always 0.

Let us consider that we have 2 variables op1 and op2 with values as follows:

Op1 = 0000 1101
Op2 = 0001 1001

The result of the OR operation on variables op1 and op2 will be

Result = 0001 1101

As we can see, two variables are compared bit by bit. Whenever the value of a bit in one of the variables is 1, then the result will be 1 or else 0.

Bitwise Exclusive OR

It is represented by a symbol (^). Two integer expressions are written on each side of the (^) operator.

The result of the bitwise Exclusive-OR operation is 1 if only one of the expression has the value as 1; otherwise, the result is always 0.

Let us consider that we have 2 variables op1 and op2 with values as follows:

Op1 = 0000 1101
Op2 = 0001 1001

The result of the OR operation on variables op1 and op2 will be

Result = 0001 0100

As we can see, two variables are compared bit by bit. Whenever only one variable holds the value 1 then the result is 0 else 0 will be the result.

Let us write a simple program that demonstrates bitwise logical operators.

#include <stdio.h>
int main()
{
int a = 20; /* 20 = 010100 */
int b = 21; /* 21 = 010101 */
int c = 0;

c = a & b; /* 20 = 010100 */
printf("AND - Value of c is %d\n", c );

c = a | b; /* 21 = 010101 */
printf("OR - Value of c is %d\n", c );

c = a ^ b; /* 1 = 0001 */
printf("Exclusive-OR - Value of c is %d\n", c );

getch();
}

Output:

AND - Value of c is 20
OR - Value of c is 21
Exclusive-OR - Value of c is 1

Bitwise shift operators

The bitwise shift operators are used to move/shift the bit patterns either to the left or right side. Left and right are two shift operators provided by 'C' which are represented as follows:

Operand << n (Left Shift)
Operand >> n (Right Shift)

Here,

- an operand is an integer expression on which we have to perform the shift operation.

- 'n' is the total number of bit positions that we have to shift in the integer expression.

The left shift operation will shift the 'n' number of bits to the left side. The leftmost bits in the expression will be popped out, and n bits with the value 0 will be filled on the right side.

The right shift operation will shift the 'n' number of bits to the right side. The rightmost 'n' bits in the expression will be popped out, and the value 0 will be filled on the left side.

Example: x is an integer expression with data 1111. After performing shift operation the result will be:

x << 2 (left shift) = 1111<<2 = 0011
x>>2 (right shift) = 1111>>2 = 1100

Shifts operators can be combined then it can be used to extract the data from the integer expression. Let us write a program to demonstrate the use of bitwise shift operators.

#include <stdio.h>
int main() {
int a = 20; /* 20 = 010100 */
int c = 0;

c = a << 2; /* 80 = 101000 */
printf("Left shift - Value of c is %d\n", c );

c = a >> 2; /*05 = 000101 */
printf("Right shift - Value of c is %d\n", c );
return 0;
}

Output:

Left shift - Value of c is 80
Right shift - Value of c is 5

After performing the left shift operation the value will become 80 whose binary equivalent is 101000.

After performing the right shift operation, the value will become 5 whose binary equivalent is 000101.

Bitwise complement operator

The bitwise complement is also called as one's complement operator since it always takes only one value or an operand. It is a unary operator.

When we perform complement on any bits, all the 1's become 0's and vice versa.

If we have an integer expression that contains 0000 1111 then after performing bitwise complement operation the value will become 1111 0000.

Bitwise complement operator is denoted by symbol tilde (~).

Let us write a program that demonstrates the implementation of bitwise complement operator.

#include <stdio.h>
int main() {
int a = 10; /* 10 = 1010 */
int c = 0;
c = ~(a);
printf("Complement - Value of c is %d\n", c );
return 0;
}

Output:

Complement - Value of c is -11

Here is another program, with an example of all the operatoes discussed so far:

#include <stdio.h>
main() {
unsigned int x = 48; /* 48 = 0011 0000 */
unsigned int y = 13; /* 13 = 0000 1101 */
int z = 0;

z =x & y; /* 0 = 0000 0000 */
printf("Bitwise AND Operator - x & y = %d\n", z );

z = x | y; /* 61 = 0011 1101 */
printf("Bitwise OR Operator - x | y = %d\n", z );

z= x^y; /* 61 = 0011 1101 */
printf("Bitwise XOR Operator- x^y= %d\n", z);

z = ~x; /*-61 = 1100 0011 */
printf("Bitwise One's Complement Operator - ~x = %d\n", z);

z = x << 2; /* 192 = 1100 0000 */
printf("Bitwise Left Shift Operator x << 2= %d\n", z );

z= x >> 2; /* 12 = 0000 1100 */
printf ("Bitwise Right Shift Operator x >> 2= %d\n", z );}

After we compile and run the program, it produces the following result:

Bitwise AND Operator - x & y = 0
Bitwise OR Operator - x | y = 61
Bitwise XOR Operator- x^y= 61
Bitwise One's Complement Operator - ~x = -49
Bitwise Left Shift Operator x << 2= 192
Bitwise Right Shift Operator x >> 2= 12

Summary

- Bitwise operators are special operator set provided by 'C.'

- They are used in bit level programming.

- These operators are used to manipulate bits of an integer expression.

- Logical, shift and complement are three types of bitwise operators.

- Bitwise complement operator is used to reverse the bits of an expression.

Chapter 16: C Dynamic Memory Allocation using malloc(), calloc(), realloc(), free()

Before you learn Dynamic Memory allocation, let's understand:

How Memory Management in C works?

When you declare a variable using a basic data type, the C compiler automatically allocates memory space for the variable in a pool of memory called the stack.

For example, a float variable takes typically 4 bytes (according to the platform) when it is declared. We can verify this information using the sizeof operator as shown in below example

#include <stdio.h>
int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}

The output will be:

The size of float is 4 bytes

Also, an array with a specified size is allocated in contiguous blocks of memory, each block has the size for one element:

#include <stdio.h>
int main() { float arr[10];
printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}

The result is:

The size of the float array with 10 element is 40

As learned so far, when declaring a basic data type or an array, the memory is automatically managed. However, there is a process for allocating memory which will permit you to implement a program in which the array size is undecided until you run your program (runtime). This process is called "Dynamic memory allocation."

Dynamic memory allocation

Dynamic memory allocation is an aspect of allocating and freeing memory according to your needs. Dynamic memory is managed and served with pointers that point to the newly allocated space of memory in an area which we call the heap. Now you can create and destroy an array of elements at runtime without any problems.

To sum up, the automatic memory management uses the stack, and the dynamic memory allocation uses the heap.

The <stdlib.h> library has functions responsible for dynamic memory management.

Function

Purpose

malloc

Allocates the memory of requested size and returns the pointer to the first byte of allocated space.

calloc

Allocates the space for elements of an array. Initializes the elements to zero and returns a pointer to the memory.

realloc

It is used to modify the size of previously allocated memory space.

Free

Frees or empties the previously allocated memory space.

Let's discuss the above functions with their application

The malloc Function

The malloc() function stands for memory allocation. It is a function which is used to allocate a block of memory dynamically. It reserves memory space of specified size and returns the null pointer pointing to the memory location. The pointer returned is usually of type void. It means that we can assign malloc function to any pointer.

Syntax

ptr = (cast_type *) malloc (byte_size);

Here,

- ptr is a pointer of cast_type.

- The malloc function returns a pointer to the allocated memory of byte_size.

Example: ptr = (int *) malloc (50)

When this statement is successfully executed, a memory space of 50 bytes is reserved. The address of the first byte of reserved space is assigned to the pointer ptr of type int.

Consider another example:

#include <stdlib.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */
if (ptr != NULL) {
*(ptr + 5) = 480; /* assign 480 to sixth integer */
printf("Value of the 6th integer is %d",*(ptr + 5));
}
}

Output:

Value of the 6th integer is 480

1. Notice that sizeof(*ptr) was used instead of sizeof(int) in order to make the code more robust when *ptr declaration is typecasted to a different data type later.

2. The allocation may fail if the memory is not sufficient. In this case, it returns a NULL pointer. So, you should include code to check for a NULL pointer.

3. Keep in mind that the allocated memory is contiguous and it can be treated as an array. We can use pointer arithmetic to access the array elements rather than using brackets [ ]. We advise to use + to refer to array elements because using incrementation ++ or += changes the address stored by the pointer.

Malloc function can also be used with the character data type as well as complex data types such as structures.

The free Function

The memory for variables is automatically deallocated at compile time. In dynamic memory allocation, you have to deallocate memory explicitly. If not done, you may encounter out of memory error.

The free() function is called to release/deallocate memory. By freeing memory in your program, you make more available for use later.

For example:

#include <stdio.h>
int main() {
int* ptr = malloc(10 * sizeof(*ptr));
if (ptr != NULL){
*(ptr + 2) = 50;
printf("Value of the 2nd integer is %d",*(ptr + 2));
}
free(ptr);
}

Output

Value of the 2nd integer is 50

The calloc Function

The calloc function stands for contiguous allocation. This function is used to allocate multiple blocks of memory. It is a dynamic memory allocation function which is used to allocate the memory to complex data structures such as arrays and structures.

Malloc function is used to allocate a single block of memory space while the calloc function is used to allocate multiple blocks of memory space. Each block allocated by the calloc function is of the same size.

Syntax:

ptr = (cast_type *) calloc (n, size);

- The above statement is used to allocate n memory blocks of the same size.

- After the memory space is allocated, then all the bytes are initialized to zero.

- The pointer which is currently at the first byte of the allocated memory space is returned.

Whenever there is an error allocating memory space such as the shortage of memory, then a null pointer is returned.

The program below calculates the sum of an arithmetic sequence.

#include <stdio.h>
int main() {
int i, * ptr, sum = 0;
ptr = calloc(10, sizeof(int));
if (ptr == NULL) {
printf("Error! memory not allocated.");
exit(0);
}
printf("Building and calculating the sequence sum of the first 10 terms \ n ");
for (i = 0; i < 10; ++i) { * (ptr + i) = i;
sum += * (ptr + i);
}
printf("Sum = %d", sum);
free(ptr);
return 0;
}

Result:

Building and calculating the sequence sum of the first 10 terms
Sum = 45

calloc vs. malloc: Key Differences

The calloc function is generally more suitable and efficient than that of the malloc function. While both the functions are used to allocate memory space, calloc can allocate multiple blocks at a single time. You don't have to request for a memory block every time. The calloc function is used in complex data structures which require larger memory space.

The memory block allocated by a calloc function is always initialized to zero while in malloc it always contains a garbage value.

The realloc Function

Using the realloc() function, you can add more memory size to already allocated memory. It expands the current block while leaving the original content as it is. realloc stands for reallocation of memory.

realloc can also be used to reduce the size of the previously allocated memory.

Syntax

ptr = realloc (ptr,newsize);

The above statement allocates a new memory space with a specified size in the variable newsize. After executing the function, the pointer will be returned to the first byte of the memory block. The new size can be larger or smaller than the previous memory. We cannot be sure that if the newly allocated block will point to the same location as that of the previous memory block. This function will copy all the previous data in the new region. It makes sure that data will remain safe.

For example:

#include <stdio.h>
int main () {
char *ptr;
ptr = (char *) malloc(10);
strcpy(ptr, "Programming");
printf(" %s, Address = %u\n", ptr, ptr);

ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new size
strcat(ptr, " In 'C'");
printf(" %s, Address = %u\n", ptr, ptr);
free(ptr);
return 0;
}

Whenever the realloc results in an unsuccessful operation, it returns a null pointer, and the previous data is also freed.

Dynamic Arrays

A Dynamic array allows the number of elements to grow as needed. They are widely used in Computer science algorithms.

in the following program, we create and resize an array dynamically

#include <stdio.h>
int main() {
int * arr_dynamic = NULL;
int elements = 2, i;
arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks
for (i = 0; i < elements; i++) arr_dynamic[i] = i;
for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
elements = 4;
arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements
printf("After realloc\n");
for (i = 2; i < elements; i++) arr_dynamic[i] = i;
for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
free(arr_dynamic);
}

Result at the screen:

arr_dynamic[0]=0
arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0
arr_dynamic[1]=1
arr_dynamic[2]=2
arr_dynamic[3]=3

Summary

- We can dynamically manage memory by creating memory blocks as needed in the heap

- In dynamic memory allocation, memory is allocated at a run time.

- Dynamic memory allocation permits to manipulate strings and arrays whose size is flexible and can be changed anytime in your program.

- It is required when you have no idea how much memory a particular structure is going to occupy.

- Malloc is a dynamic memory allocation function which stands for memory allocation that blocks of memory with the specific size initialized to a garbage value

- Calloc is a contiguous memory allocation function that allocates multiple memory blocks at a time initialized to 0

- Realloc is used to reallocate memory according to the specified size.

- Free function is used to clear the dynamically allocated memory.

Chapter 17: TypeCasting in C: Implicit, Explicit with Example

What is Typecasting in C?

Typecasting is converting one data type into another one. It is also called as data conversion or type conversion. It is one of the important concepts introduced in 'C' programming.

'C' programming provides two types of type casting operations:

1. Implicit type casting

2. Explicit type casting

Implicit type casting

Implicit type casting means conversion of data types without losing its original meaning. This type of typecasting is essential when you want to change data types without changing the significance of the values stored inside the variable.

Implicit type conversion happens automatically when a value is copied to its compatible data type. During conversion, strict rules for type conversion are applied. If the operands are of two different data types, then an operand having lower data type is automatically converted into a higher data type. This type of type conversion can be seen in the following example.

#include<stdio.h>
int main(){
short a=10; //initializing variable of short data type
int b; //declaring int variable
b=a; //implicit type casting
printf("%d\n",a);
printf("%d\n",b);
}

Output

10
10

1. In the given example, we have declared a variable of short data type with value initialized as 10.

2. On the second line, we have declared a variable of an int data type.

3. On the third line, we have assigned the value of variable s to the variable a. On third line implicit type conversion is performed as the value from variable s which is of short data type is copied into the variable a which is of an int data type.

Converting Character to Int

Consider the example of adding a character decoded in ASCII with an integer:

#include <stdio.h>
main() {
int number = 1;
char character = 'k'; /*ASCII value is 107 */
int sum;
sum = number + character;
printf("Value of sum : %d\n", sum );
}

Output:

Value of sum : 108

Here, compiler has done an integer promotion by converting the value of 'k' to ASCII before performing the actual addition operation.

Arithmetic Conversion Hierarchy

The compiler first proceeds with promoting a character to an integer. If the operands still have different data types, then they are converted to the highest data type that appears in the following hierarchy chart:

Consider the following example to understand the concept:

#include <stdio.h>
main() {
int num = 13;
char c = 'k'; /* ASCII value is 107 */
float sum;
sum = num + c;
printf("sum = %f\n", sum );}

Output:

sum = 120.000000

First of all, the c variable gets converted to integer, but the compiler converts num and c into "float" and adds them to produce a 'float' result.

Important Points about Implicit Conversions

- Implicit type of type conversion is also called as standard type conversion. We do not require any keyword or special statements in implicit type casting.

- Converting from smaller data type into larger data type is also called as type promotion. In the above example, we can also say that the value of s is promoted to type integer.

- The implicit type conversion always happens with the compatible data types.

We cannot perform implicit type casting on the data types which are not compatible with each other such as:

1. Converting float to an int will truncate the fraction part hence losing the meaning of the value.

2. Converting double to float will round up the digits.

3. Converting long int to int will cause dropping of excess high order bits.

In all the above cases, when we convert the data types, the value will lose its meaning. Generally, the loss of meaning of the value is warned by the compiler.

'C' programming provides another way of typecasting which is explicit type casting.

Explicit type casting

In implicit type conversion, the data type is converted automatically. There are some scenarios in which we may have to force type conversion. Suppose we have a variable div that stores the division of two operands which are declared as an int data type.

int result, var1=10, var2=3;
result=var1/var2;

In this case, after the division performed on variables var1 and var2 the result stored in the variable "result" will be in an integer format. Whenever this happens, the value stored in the variable "result" loses its meaning because it does not consider the fraction part which is normally obtained in the division of two numbers.

To force the type conversion in such situations, we use explicit type casting.

It requires a type casting operator. The general syntax for type casting operations is as follows:

(type-name) expression

Here,

- The type name is the standard 'C' language data type.

- An expression can be a constant, a variable or an actual expression.

Let us write a program to demonstrate implementation of explicit type-casting in 'C'.

#include<stdio.h>
int main()
{
float a = 1.2;
//int b = a; //Compiler will throw an error for this
int b = (int)a + 1;
printf("Value of a is %f\n", a);
printf("Value of b is %d\n",b);
return 0;
}

Output:

Value of a is 1.200000
Value of b is 2

1. We have initialized a variable 'a' of type float.

2. Next, we have another variable 'b' of integer data type. Since the variable 'a' and 'b' are of different data types, 'C' won't allow the use of such expression and it will raise an error. In some versions of 'C,' the expression will be evaluated but the result will not be desired.

3. To avoid such situations, we have typecast the variable 'a' of type float. By using explicit type casting methods, we have successfully converted float into data type integer.

4. We have printed value of 'a' which is still a float

5. After typecasting, the result will always be an integer 'b.'

In this way, we can implement explicit type casting in 'C' programming.

Summary

- Typecasting is also called as type conversion

- It means converting one data type into another.

- Converting smaller data type into a larger one is also called as type promotion.

- 'C' provides an implicit and explicit way of type conversion.

- Implicit type conversion operates automatically when the compatible data type is found.

- Explicit type conversion requires a type casting operator.

Keep in mind the following rules for programming practice when dealing with different data type to prevent from data loss :

- Integers types should be converted to float.

- Float types should be converted to double.

- Character types should be converted to integer.

One Last Thing….

DID YOU ENJOY THE BOOK?

IF SO, THEN LET ME KNOW LEAVING A REVIEW ON AMAZON! Reviews are lifeblood of independent authors. I would appreciate even a few words and rating if that’s all you have time for

IF YOU DID NOT LIKE THIS BOOK, THEN PLEASE TELL ME! EMAIL me and Let me know what you didn’t like! Perphase I can change it. In today’s world a book doesn’t have to be stagnant, it can improve with time and feedback from readers like you. You can impact this book, and I welcome your feedback. Help make this book better for everyone!

More Books -

Learn Java in 1 Day: Complete Beginners Guide

BUY NOW

Learn Python in 1 Day: Complete Python Guide with Examples

BUY NOW

Learn JSP in 1 Day: Definitive Guide to Learn JSP for Beginners

BUY NOW