What is C?
C is a general-purpose, high-level language that was originally developed by Dennis M. Ritchie to develop the UNIX operating system at Bell Labs. C was originally first implemented on the DEC PDP-11 computer in 1972.
The PDP-11 is a series of 16-bit minicomputers sold by Digital Equipment Corporation (DEC) from 1970 to the 1990s, one of a succession of products in the PDP series.
In 1978, Brian Kernighan and Dennis Ritchie produced the first publicly available description of C, now known as the K&R standard.
The UNIX operating system, the C compiler, and essentially all UNIX application programs have been written in C.
Facts about C
1. C was invented to write an operating system called UNIX.
2. C is a successor of B language which was introduced around the early 1970s.
3. The language was formalized in 1988 by the American National Standard Institute (ANSI).
4. The UNIX OS was totally written in C.
5. Today C is the most widely used and popular System Programming Language.
6. Most of the state-of-the-art software have been implemented using C.
7. Today's most popular Linux OS and RDBMS MySQL have been written in C.
Dennis Ritchie is known as the founder of c language.
It was developed to overcome the problems of previous languages such as B, BCPL, etc.
Initially, the C language was developed to be used in a UNIX operating system. It inherits many features of previous languages such as B and BCPL.
Let's see the programming languages that were developed before the C language.
Language |
Year |
Developed By |
Algol |
1960 |
International Group |
BCPL |
1967 |
Martin Richard |
B |
1970 |
Ken Thompson |
Traditional C |
1972 |
Dennis Ritchie |
K & R C |
1978 |
Kernighan & Dennis Ritchie |
ANSI C |
1989 |
ANSI Committee |
ANSI/ISO C |
1990 |
ISO Committee |
C99 |
1999 |
Standardization Committee |
Why use C?
C was initially used for system development work, particularly the programs that make-up the operating system. C was adopted as a system development language because it produces code that runs nearly as fast as the code written in assembly language.
Some examples of the use of C might be −
1. Operating Systems
2. Language Compilers
3. Assemblers
4. Text Editors
5. Print Spoolers
6. Network Drivers
7. Modern Programs
8. Databases
9. Language Interpreters
10. Utilities
C as a mother language
C language is considered as the mother language of all the modern languages because most of the compilers, JVMs, Kernals, etc. are written in C language and most of the languages follow c syntax e.g. C++, Java, etc.
It provides the core concepts like an array, functions, file handling, etc. that are being used in many languages like C++, Java, C#, etc.
C as a system programming language
A system programming language is used to create system software. C language is a system programming language because it can be used to do low-level programming (e.g. driver and kernel). It is generally used to create hardware devices, OS, drivers, kernels, etc. For example, the Linux kernel is written in C.
It can't be used in internet programming like java, .net, PHP, etc.
C as a procedural language
A procedure is known as function, method, routine, subroutine, etc. A procedural language specifies a series of steps or procedures for the program to solve the problem.
A procedural language breaks the program into functions, data structures, etc.
C is a procedural language. In C, variables and function prototypes must be declared before being used.
C as a structured programming language
A structured programming language is a subset of procedural language. Structure means to break a program into parts or blocks so that it may be easy to understand.
In C language, we break the program into parts using functions. It makes the program easier to understand and modify.
C as a mid-level programming language
C is considered as a middle-level language because it supports the feature of both low- level and high-level language. C language program is converted into assembly code, supports pointer arithmetic (low level), but it is machine independent (a feature of high level).
Low-level language is specific to one machine i.e. machine-dependent. It is machine-dependent, fast to run. But it is not easy to understand.
A high-Level language is not specific to one machine i.e. machine-independent. It is easy to understand.
Features of C Language
1. Simple
2. Machine Independent or Portable
3. Mid-level programming language
4. structured programming language
5. Rich Library
6. Memory Management
7. Fast Speed
8. Pointers
9. Recursion
10. Extensible
How to Install C?
There are many compilers available for c and c++. You need to download anyone. Here, we are going to use Turbo C++. It will work for both C and C++. To install the Turbo C software, you need to follow the following steps.
1. Download Turbo C++.
2. Create a turboc directory inside c drive and extract the tc3.zip inside c:\turboc.
3. Double click on install.exe file.
4. Click on the TC application file located inside c:\TC\BIN to write the c program.
1. Download Turbo C++ software
You can download turbo c++ from many sites. download Turbo c++
2. Create turboc directory in c drive and extract the tc3.zip
Now, you need to create a new directory turboc inside the c: drive. Now extract the tc3.zip file in c:\truboc directory.
3. Double click on the install.exe file and follow steps
Now, click on the install icon located inside the c:\turboc
It will ask you to install c or not, press enter to install.
Change your drive to c, press c.
Press enter, it will look inside the c:\turboc directory for the required files.
Select Start installation by the down arrow key then press enter.
Now C is installed, press enter to read documentation or close the Software
1. Click on the tc application located inside c:\TC\BIN
Now double click on the tc icon located in c:\TC\BIN directory to write the c program.
In windows 7 or window 8, it will show a dialog block to ignore and close the application because the fullscreen mode is not supported. Click on the Ignore button.
Now it will show the following console.
Installation of Code Blocks
Step 1: Download the Software::
In order to install the Code::Blocks IDE as well as the MinGW compiler, you must download it. You can download it for Windows from here: http://sourceforge.net/projects/codeblocks/files/Binaries/16.01/Windows/codeblocks-
16.01mingw-setup.exe Save the file to your hard disk and remember its location.
Proceed to the next page in order to continue the installation.
Step 2: Install Code::Blocks
-
- Double click the installer.
- Hit next several times. Other setup tutorials will assume you have installed in C:\Program Files\CodeBlocks (the default install location), but you may install elsewhere if you like
-
- Do a Full Installation
- Launch Code::Blocks
Step 3: Running in Code::Blocks
You will be prompted with a Compilers auto-detection window:
When you get the compiler auto-detection window, just hit OK. Code::Blocks may ask if you want to associate it as the default viewer for C/C++ files--I'd suggest you do. Click on the File menu, and under "New", select "Project..."
The following window will come up:
Click on "Console Application" and hit the "Go" button. Click next until you get to the Language Selection Dialog:
You'll be asked to choose whether you want to use C or C++. If you're not sure, use C++. Otherwise, choose based on the language you are learning. (You can find tutorials here on both C and C++.)
After clicking "Next", Code::Blocks will then prompt you with where you'd like to save the console application:
I'd recommend you put it in its own folder, as it may create several files (this is especially true if you create other types of projects). You will need to give your project a name, anything will be fine.
Clicking "Next" again will prompt you to set up your compiler:
You don't need to do anything here. Just accept the defaults by hitting "Finish". You can now open the main.cpp file on the left:
(You may need to expand the contents of the "Sources" folder if you don't see main.cpp.)
At this point, you will have your main.cpp file, which you can modify if you like. For now, it just says "Hello World!", so we can run it as is. Hit F9, which will first compile it and then run it.
You now have a running program! You can simply edit main.cpp and then hit F9 to compile it and run it again.
//We will learn CodeBlock IDE later classes.
First C Program
A 'C' program basically consists of the following parts -
1. Preprocessor Commands
2. Functions
3. Variables
4. Statements & Expressions
5. Comments
Syntax/Format of the program is:-
<Preprocessor commands>
[<UDF Prototype>]
int main() {
….. <variables and statements>
….
}
[<UDF definitions> ]
Note: comments can be placed anywhere inside the program.
For a sample program, we will use the output statement/function of c – printf()
printf() is used to show formatted output. It is the part of standard input/output (stdio.h) library of c.
Syntax-
printf(“Msg/Text”);
printf(“<formate string>”, <list of variables/Constants>);
Sample Program :
Let us look at a simple code that would print the words "Hello World" −
#include <stdio.h>
int main()
{
/* my first program in C */
printf("Hello, World! ");
return 0;
}
Let us take a look at the various parts of the above program -
The first line of the program #include <stdio.h> is a preprocessor command, which tells a C compiler to include stdio.h file before going to actual compilation.
The next line int main() is the main function where the program execution begins.
The next line /*...*/ will be ignored by the compiler and it has been put to add additional comments in the program. So such lines are called comments in the program. In C, we can write comments on two types :
1. Multi Line Comment :
/*
....
.....
....
*/
2. single-line comment
//.........
The next line printf(...) is another function available in C which causes the message "Hello, World!" to be displayed on the screen.
The next line return 0; terminates the main() function and returns the value 0.
Compile and Execute C Program
There are 2 ways to compile and run the c program, by menu and by shortcut.
By menu
Now click on the compile menu then compile sub-menu to compile the c program. Then click on the run menu then run sub-menu to run the c program.
By shortcut
Or, press ctrl+f9 keys compile and run the program directly. You will see the following output on the user screen.
You can view the user screen any time by pressing the alt+f5 keys. Now press Esc to return to the turbo c++ console.
Managing Console I/O (conio.h)
clear screen by clrscr() function
If you run the c program many times, it will append the output in the previous output. But, you can call clrscr() function to clear the screen. So it will be better for you to call clrscr() function after the main method. This function is the part of conio.h header file.
Example :
#include <conio.h>
void main() {
clrscr();
printf("Hello C Language");
}
//Press ctrl+f9 to run
// prss alt + f5 to view output
Hold output screen by getch() function
As we run the program, output is displayed for a part of second, so we have to press ctrl+f5 key to view the output.
We can use the function- getch() to hold the console prompt while user does not press any key.
Basically getch() is a character input function that comes from conio.h header file and it wait for input of a single character.
Example 1:
#include <stdio.h>
#include <conio.h>
void main() {
clrscr();
printf("Hello C Language");
getch();
}
Example 2: show message one after one (show msg when user press any key )
#include <stdio.h>
#include <conio.h>
void main() {
clrscr();
printf("Hello C Language");
getch();
printf(“This is testing of getch()”);
getch();
printf(“Press any key to goback to the source code”);
getch();
}
Example 3: show message one after one after clearing console.
#include <stdio.h>
#include <conio.h>
void main() {
clrscr();
printf("Hello C Language");
getch();
printf(“This is testing of getch()”);
getch();
printf(“Press any key to goback to the source code”);
getch();
}
Set cursor to specific location on console : gotoxy()
When we Execute the program and show any message on console it will be displayed at top left (0,0) corner of the screen.
We can change the postion of message by using the function – gotoxy()
This function is also the part of <conio.h>
It works on Turbo compiler but not on CodeBlock( there is another method for code block)
Syntax is –
gotoxy(<x-coordinate>, <y-coordinate>);
like-
gotoxy(20,5);
printf(“Hello World”);
Note that we can put 80 characters in x coordinatin (left to right) and upto 25 characters in y-coordination (top to bottom)
Example 1: show following output on console – Ram
Ram
Ram
Ram Ram
Solution : -
#include <stdio.h>
#include <conio.h>
void main() {
clrscr();
gotoxy(10,5);
printf(“Ram”);
gotoxy(15,7);
printf(“Ram”);
gotoxy(20,9);
printf(“Ram”);
gotoxy(15,11);
printf(“Ram”);
gotoxy(10,9);
printf(“Ram”);
printf(“\n\n Press Any Key to Exit”);
getch();
}
Making Time Delay in between two statements: delay()
We can put delay() function anywhere inside the program where we want to wait for a specific time period.
This function comes from DOS.H.
We have to specify the time amount in a millisecond, ie- 1 second = 1000 milliseconds.
Example – The following example will move your name on the console.
#include <stdio.h>
#include <conio.h>
void main() {
clrscr();
gotoxy(10,5);
printf(“Ram”);
delay(1000);
clrscr();
gotoxy(15,5);
printf(“Ram”);
delay(1000);
clrscr();
gotoxy(20,5);
printf(“Ram”);
delay(1000);
clrscr();
gotoxy(25,5);
printf(“Ram”);
delay(1000);
clrscr();
printf(“\n\n Press Any Key to Exit”);
getch();
}
Note that delay() and gotoxy() functions can not be used in codeblocks directly.
For delay() we use the Sleep() function which is the part of window.h header file.
Method of using gotoxy() in codeblock will be discussed later.
Example – The following example will print 5 names. Each name will be printed after 1-second delay. (in CODE::BLOCKS)
#include <stdio.h>
#include <windows.h>
void main() {
Sleep(1000);
printf(" Ram");
Sleep(1000);
printf("\n Mohan");
Sleep(1000);
printf("\n Ramesh");
Sleep(1000);
printf("\n Umesh");
Sleep(1000);
printf("\n Kamlesh");
printf(“\n\n Press Any Key to Exit”); getch();
}
Flow of C Program
The C program follows many steps in execution. To understand the flow of C program well, let us see a simple program first.
#include <stdio.h>
void main() {
printf("Hello C Language");
}
Let's try to understand the flow of the above program by the figure given below.
1. C program (source code) is sent to the preprocessor first. The preprocessor is responsible to convert preprocessor directives into their respective values. The preprocessor generates expanded source code.
2. Expanded source code is sent to the compiler which compiles the code and converts it into assembly code.
3. The assembly code is sent to the assembler which assembles the code and converts it into object code. Now a simple.obj file is generated.
4. The object code is sent to the linker which links it to the library such as header files. Then it is converted into executable code. A simple.exe file is generated.
5. The executable code is sent to loader which loads it into memory and then it is executed. After execution, the output is sent to the console.
Here is the Sequence of Execution of C Program :
Execution Characters/
Escape Sequences
Characters are printed on the screen through the keyboard but some characters such as newline, tab. backspace cannot be printed like other normal characters. C supports the combination of backslash (\)and some characters from the C character set to print these characters.
These character combinations are known as escape sequences and are represented by two characters.
The first character is "\" and second character is from the C character set. Some escape sequences are given below-
Escape |
Meaning |
ASCII |
Purpose |
\b |
Backspace |
008 |
Moves cursor to the previous character of the current line |
\a |
Bell alert |
007 |
Produces beep sound for alert |
\r |
Carriage return |
013 |
Moves the cursor at be beginning of the current line. |
\n |
Newline |
010 |
Moves the cursor to be beginning of the next line. |
\f |
Form feed |
012 |
Moves the cursor to the initial position of the next logical page |
\0 |
NULL |
000 |
NULL |
\v |
Vertical Tab |
011 |
Moves the cursor to next vertical position |
\t |
Horizontal tab |
009 |
Moves the cursor to the next horizontal tab position |
\\ |
Backslash |
092 |
Print the \ (backslash) |
\“ |
Double quote |
034 |
Prints “ on console. |
Note:-
Common ASCII values:
A-Z : 65-90
a-z : 97-122
0-9 : 48-57
Trick:
HOW TO show ASCII of any character –
printf(“%d”, „<character>‟);
How to show Character from ASCII value-
printf(“%c”,<ASCII/Number>); //range -128 to 127
Some Example of Escape characters :
Example 1:
#include
#include
void main() {
clrscr();
printf("Hello C Language");
getch();
printf(“\n This Text is written in New Line ”);
printf(“\t this is Horizontal Tab”);
printf(“\n My Name is : \”Manish\” ”);
getch();
}
Output :
Hello C Language
This Text is written in New Line this is Horizontal Tab
My Name is : “Manish”
Trigraph Characters There is a possibility that the keyboard doesn't print some characters. C supports the facility of "trigraph sequence" to print these characters. These trigraph sequences have three characters.. First two are '??' and third character is any character from C character set. Some trigraph sequences are as given below-
Trigraph |
Sequence Symbol |
??< |
{ left brace |
??> |
} right brace |
??( |
[ left bracket |
??) |
] right bracket |
??! |
I vertical bar |
??/ |
\ backslash |
??= |
# hash slgn |
??- |
~ tilde |
??' |
/\ caret |
Digraph Characters
They are made of two character instead of 3. They are introduced in C99 Standard.
They are –
Digraph |
Equivalent |
<: |
[ |
:> |
] |
<% |
{ |
%> |
} |
%: |
# |
// Example of Digraph :
%: include
void main() <%
printf("Hello C Language");
getch();
%>
Do the assignment 1 , before moving to next topic.
C character Set:
A character denotes any alphabet, digit or special symbol used to represent information. Figure shows the valid alphabets, numbers and special symbols allowed in C.
Alphabets A … Z a … z
Digits 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Special symbols ~ „ ! @ # % ^ & * ( ) _ - + = | \ { } [ ] : ; " ' < > , . ? /
Tokens in C The alphabets, numbers and special symbols when properly combined become a Token. A C program consists of various tokens and a token is a keyword, an identifier, a constant, a string literal, or a symbol. For example, the following C statement consists of five tokens −
printf("Hello, World! \n");
The individual tokens are −
printf (
"Hello, World! \n"
)
;
Tokens can be categorized as –
1. Keywords /Reserve Words
2. Constants / Literals / Values
3. Data Types
4. Identifier/Variables
5. Operators
6. Delimiters / Separators
Keywords:
There are certain words that are reserved for doing specific tasks. These words are known as keywords and they have standard, predefined meaning in C. They are always written in lowercase.
There are only 32 keywords available in C which are given below-
auto |
break |
case |
char |
const |
continue |
default |
do |
double |
else |
enum |
extern |
float |
for |
goto |
if |
int |
long |
register |
return |
short |
signed |
sizeof |
static |
struct |
switch |
typedef |
union |
unsigned |
void |
volatile |
while |
Additional Keywords in C99
inline restrict
_Bool
_Complex
_Imaginary
Notes:
In older version of c variable declaration is only possible at the very first line of the function, but now we can declare variable any time/any where we want.
Constants / Literals:
The values that are assigned to any memory area (like variables) are known as constants. Constants cannot be altered. They are also known as Literals.
Numeric Constants-
numeric constants consist of numeric digits; they may or may not have decimal point. These are the rules for defining numeric constants-
1. Numeric constant should have at least one digit.
2. No comma or space is allowed within the numeric constant.
3. Numeric constants can either be positive or negative but default sign is always positive.
Note: Only String can be printed directly by printf() function, to print other values/Variables we have to use proper control character / format specifier within printf().
i.e.-
printf (“Hello”); //ok
char name[]= “GIST”;
printf(name); //ok
printf (220); //Error
Syntax to print constatnts-
printf(“<format specifier>”,<constant>);
There are two types of numeric constants-
Integer constant
Integer constants are whole numbers that have no decimal point (.). There are three types of integer Constants based on different number of systems. The permissible characters that can be used in these constants are –
Decimal constants - 0,1,2,3,4,5,6,7,8,9
Octal "constants - 0, 1,2,3,4,5,6,7
Hex decimal constants - 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,a,b,c,d,e,f
Some valid decimal integer constants are-
0
123
3705
23759
3705
23759
Invalid decimal integers are :
Invalid Remark
2.5 Illegal character ( . )
3#5 illegal character ( # )
98 5 No blank. space allowed
0925 First digit can not be zero
8,354 Comma is not allowed'
# A hexadecimal constant should begin with 0X or 0x. Ex: 0x65F or 0X7A
# An octal constant should begin with digit 0. It can take any digits from 0 through 7.
There is no binary integer constant in C by default. This means, you can’t give a binary number directly to program by writing like:- 0b11001011 – which is meaningless and result in an error. However, programmer can add a preprocessor (which we will learn later) to accept binary numbers in a program.
How to print Integers:
printf(“<format character>”,<integer constant>);
format specifier :
%d for decimal (base 10) integers
%x for hexadecimal integers
%o for octal integers
%i for all types of integers (decimal,octal,hexadecimal)
%u for unsigned integers
//Here goes some examples :
By default the type of an integer constant is int. But if the value of integer constant exceeds the range of values represented by int type, the type is taken to be unsigned int or long int. We can also explicitly mention the type of the constant by suffixing it with k or L( for long), u or U (for unsigned), ul or UL (for unsigned long).
For example-
6453 Integer constant of type int
45238722UL or 45238722ul Integer constant of type unsigned long int
6655U or 6655u Integer constant of type unsigned int
Here are some examples of integer literals −
212 /* Legal */
215u /* Legal */
0xFeeL /* Legal */
078 /* Illegal: 8 is not an octal digit */
032UU /* Illegal: cannot repeat a suffix */
Following are other examples of various types of integer literals −
85 /* decimal */
0213 /* octal */
0x4b /* hexadecimal */
30 /* int */
30u /* unsigned int */
30l /* long */
30ul /* unsigned long */
Real (floating point) Constants
Floating point constants are numeric constants that contain decimal point. Some valid floating point constants are-
0.5
5.3
4000.0
0.0073
5597.
39.0807
For expressing very large or very small real constants, exponential (scientific) form is used. Here the Number is written in the mantissa and exponent form, which are separated by e or E. The mantissa can be an integer or real number. While the exponent can be only the integer(Positive or negative).
For example the number : 1800000 can be written as f 1.8E6. Here 1.8 is Mantissa and 6 is the exponent.
Some More Examples are :
Number |
Exponential form |
Scientific form |
2500000000 |
2.5*109 |
2.5e9 |
0.0000076 |
7.6*10-6 |
7.6e-6 |
-670000 |
-6.7*105 |
-6.7e5 |
By default the type of a floating point constant is double. We can explicitly mention the type of constant by suffixing it by f or F for float type or l or L for long double.
For ex-
2.3e5 floating point constant of type double 2.4e-9l or 2.4e-9L floating point constant of type long double
3.52f or 3.52F floating point constant of type float
Format specifier for float, double or long double-
%f For Float
%lf for Double
%e For Float (Scientific / Exponential representation)
%g For Float |
//Some Examples .....
Character Constants-
A character constant is a single alphabet, a single digit or a single special symbol enclosed within single inverted commas.
Both the inverted commas should point to the left.
For example,
‟A‟ is a valid character constant whereas „A‟ is not. The maximum length of a character constant can be 1 character.
Ex.:
'A'
'I'
'5'
'='
Format specifier for character is –
%c |
//Some Examples :
String Constants
A string constant is enclosed within double quotes (“”).
At the end of string, \0 is 'automatically placed by the compiler. some examples of string constants are-
"Kumar" "593"
"8"
"A"
Format specifier for character is – %s Note that we can directly print the string in printf() without using format specifier |
Delimiters-
Delimiters are used for syntatic meaning in C. these are as given below
: |
colon |
used for Label |
; |
semicolon |
Statement End of |
( ) |
parentheses |
Used in expression and function |
[ ] |
Square Brackets |
Used for Array |
{ } |
Curly Braces |
Used for block of statements |
# |
Hash |
Pre-processor Directive |
, |
comma |
variable delimiter |
Data Types
Data types are the predefine keywords of C library which are used to declare the memory location(variables/identifiers) inside the program to hold some value/constant during the execution of the program.
For all types of constants we have learned before, C provides one or more data type(based on range/size).
C also provides the facility to modify /change the structure of basic data types to create Derived or user-defined data type.
C Qualifiers
Qualifiers alter the meaning of base data types to yield a new data type.
Size qualifiers
Size qualifiers alter the size of a basic type. There are two size qualifiers, long and short. For example:
Sign qualifiers
Integers and floating-point variables can hold both negative and positive values. However, if a variable needs to hold positive value only, unsigned data types are used.
For example:
unsigned variables cannot hold negative value unsigned int; // positiveInteger;
There is another qualifier signed which can hold both negative and positive only. However, it is not necessary to define a variable signed since a variable is signed by default.
Constant qualifiers
An identifier can be declared as a constant. To do so the const keyword is used.
const int cost = 20;
The value of cost cannot be changed in the program.
Volatile qualifiers
A variable should be declared volatile whenever its value can be changed by some external sources outside the program.
Keyword volatile is used for creating volatile variables.
Integer Types
The following table provides the details of standard integer types with their storage sizes and value ranges −
Type |
Storage size |
Value range |
char |
1 byte |
-128 to 127 or 0 to 255 |
unsigned char |
1 byte |
0 to 255 |
signed char |
1 byte |
-128 to 127 |
int |
2 or 4 bytes |
-32,768 to 32,767 or -2,147,483,648 to 2,147,483,647 |
unsigned int |
2 or 4 bytes |
0 to 65,535 or 0 to 4,294,967,295 |
short short int short signed int |
2 bytes |
-32,768 to 32,767 |
unsigned short unsigned short int |
2 bytes |
0 to 65,535 |
long long int signed long int |
4 bytes |
-2,147,483,648 to 2,147,483,647 |
unsigned long unsigned long int |
4 bytes |
0 to 4,294,967,295 |
To get the exact size of a type or a variable on a particular platform, you can use the sizeof() operator. The expressions sizeof(type) yields the storage size of the object or type in bytes. Given below is an example to get the size of int type on any machine −
#include <stdio.h>
#include <limits.h> //in case error in sizeof()
int main() {
printf("Storage size for int : %d \n", sizeof(int));
return 0;
}
How to find range of integer data types:
Put the 2 exponet number of bits
Like-
printf(“Range of negative integer -%d”, pow(2,15));
printf(“Range of Positive integer %d”, pow(2,15)-1);
Floating-Point Types
The following table provides the details of standard floating-point types with storage sizes and value ranges and their precision −
Type |
Storage size |
Value range |
Precision |
float |
4 byte |
1.2E-38 to 3.4E+38 |
6 decimal places |
double |
8 byte |
2.3E-308 to 1.7E+308 |
15 decimal places |
long double |
10 byte |
3.4E-4932 to 1.1E+4932 |
19 decimal places |
The header file float.h defines macros that allow you to use these values and other details about the binary representation of real numbers in your programs. The following example prints the storage space taken by a float type and its range values −
#include
#include
int main() {
printf("Storage size for float : %d \n", sizeof(float));
printf("Minimum float positive value: %E\n", FLT_MIN );
printf("Maximum float positive value: %E\n", FLT_MAX );
printf("Precision value: %d\n", FLT_DIG );
return 0;
}
When you compile and execute the above program, it produces the following result on Linux −
Storage size for float : 4
Minimum float positive value: 1.175494E-38
Maximum float positive value: 3.402823E+38
Precision value: 6
The void Type-
The void type specifies that no value is available. It is used in three kinds of
situations −
S.N.:- |
Types & Description |
1 |
Function returns as void There are various functions in C which do not return any value or you can say they return void. A function with no return value has the return type as void. For example, void exit (int status); |
2 |
Function arguments as void There are various functions in C which do not accept any parameter. A function with no parameter can accept a void. For example, int rand(void); |
3 |
Pointers to void A pointer of type void * represents the address of an object, but not its type. For example, a memory allocation function void *malloc( size_t size ); returns a pointer to void which can be casted to any data type. |
Examples :
void main()
or
void main(void)
or
int main(void)
or
int main(<command line arguments>)
Variables :
A variable is nothing but a name given to a storage area that our programs can manipulate. Each variable in C has a specific type, which determines the size and layout of the variable's memory; the range of values that can be stored within that memory; and the set of operations that can be applied to the variable.
syntax to declare a variable:
<data type> <variable_list>; Like-
int a;
float b,c; char gender;
We can also provide values while declaring the variables as given below:
int a=10,b=20;//declaring 2 variable of integer type float f=20.8;
char c='A';
Rules for defining variables
# A variable can have alphabets, digits, and underscore.
# A variable name can start with alphabet and underscore only. It can't start with a digit.
# No white space is allowed within a variable name.
# A variable name must not be any reserved word or keyword eg. int, float, etc.
# The length of the name can be 1 to 31 characters long. C99 permits 63 identical characters in the name. Some compilers allow name to be 247 characters long.
# Name must be unique in it's scope.
Examples of variables-
Assigning value to variable- (use = ) int a=1030;
printf(“the value of a = %d”,a); int b=5;
printf(“the square of %d = %d”,b ,b*b);
#include<stdio.h>
#include<float.h>
int main() {
int c=20;
int b=30;
int a=b=c;
printf("%d",a);
printf("\n%d",b);
a=b=c=0;
printf("\n%d\n%d\n%d",a,b,c);
getting input from console-
writing expressions in printf-
Scope and Life Cycle of Variable –
Storage classes –
Types of Variables in C
There are many types of variables in c:
1. local variable
2. global variable
3. static variable
4. automatic variable
5. external variable
Lvalues and Rvalues in C
There are two kinds of expressions in C −
# lvalue − Expressions that refer to a memory location are called "lvalue" expressions. An lvalue may appear as either the left-hand or right-hand side of an assignment.
# rvalue − The term rvalue refers to a data value that is stored at some address in memory. An rvalue is an expression that cannot have a value assigned to it which means an rvalue may appear on the right- hand side but not on the left-hand side of an assignment.
Variables are lvalues and so they may appear on the left-hand side of an assignment. Numeric literals are rvalues and so they may not be assigned and cannot appear on the left-hand side. Take a look at the following valid and invalid statements −
int g = 20; // valid statement
10 = 20; // invalid statement; would generate compile-time error |
"lvalue" and "rvalue" are so named because of where each of them can appear in an assignment operation. An lvalue can appear on the left side of an assignment operator, whereas an rvalue can appear on the right side.
As an example:
1. int a;
2. a = 3;
In the second line, "a" is the lvalue, and "3" is the rvalue.
And in this example:
1. int a, b;
2. a = 4;
3. b = a;
In the third line of that example, "b" is the lvalue, and "a" is the rvalue, whereas it was the lvalue in line 2. This illustrates an important point: An lvalue can also be an rvalue, but an rvalue can never be an lvalue.
Another definition of lvalue is "a place where a value can be stored."
Creating String variable:
String is a set of characters like – name –“Amit kumar Shukla” String is written inside the “”
We can use string to show messages inside printf()
C does not provide any data type for string.
We can derive the string data type from character by putting size,
like-
char name[20];
1. basically this concept is called array
2. we will discuss much about array in following classes.
How to assign value to string ?
char name[] = “Gist Technosolutions”;
Note:-
We do not need to specify the size of string in case of assignment along with the declaration.
if you want to get string value from the keyboard. then specify the size at the time of declaration.
char name[20];
we can not assign the string directly anywhere else inside the program .
char nm[20];
nm= “Suresh”; //Error
to show the string value on console we use conversion specification character -%s
ex-
char name[]=”AMITHES KUMAR”;
char address [] = “d-20, Nehru nagar,Bhopal”;
printf(“Name is : %s”,name);
printf(“\nAddress is :%s”,address);
another way of creating string variable- char *name;
name= “Mukesh Kumar”;
when we use *<variable>, we can assign it again in program
Defining Variable as Constant:
# There are two mechanism if defining symbolic constants
Method 1:-
Use the keyword ‘const’ for variable declaration. This type of variable behaves like constant and the value can not be further altered or changed inside the program.
Ex-
const int totalMarks=500;
int a,b;
a=20;
b=a;
totalMarks=a+b; //Error
totalMarks =0; //Error
const float PI = 3.14;
float redius=5.0;
float areaOfCircle = redius * PI;
C says that anyone should declare constant in upper case. this is a convension for a good programming habit.
Method 2:-
Use the Pre-Processor - #define
ex-
#define PI 3.14
void main() {
clrscr();
float redius = 5.55;
float area = redius * PI;
printf(“Area of Circle = %f”area);
getch();
}
Getting input from console-
scanf() function :
This function comes from <stdio.h> header file.
This function is used to read different types of data from console (keyboard at run time)
Syntax
scanf(“<format character>”, &<variable>);
scanf(“<list of format chars>”, &<var1>,&<var2>,…);
Note:
In case of reading string(group of characters) we don’t need to use & operator.
It reads the value upto white space or new line (when user press Enter Key)
So we can provide more than one values at same line with white spaces.
Ex-
Read two numbers through keyboard and show their sum.
…
..
int main() {
int a,b,c;
printf(“Enter First no : “);
scanf(“%d”,&a);
printf(“Enter second no :”);
scanf(“%d”,&b);
c=a+b;
printf(“sum = %d”,c);
}
We can use single scanf() for reading both numbers :
…
printf( “enter two numbers”);
scanf(“%d%d”,&a,&b);
…
…
Converting methmetical expressions into C-statements:
1. a=x2+y2+2xy
2. x= a + b(c+d)
3. x = x-1+x-2
4. area = ∏r2
Solutions: (do not use any type of additional header files)
1. a= x*x +y*y +2*x*y;
2. x= a + b * (c+b);
OR
X = a + b*c + b*d;
3. x = 1/x + 1/(x*x);
4. area = 3.14 * r * r;
Some Questions for Practice:
WAP to input 3 numbers and swap their values without using 4th Variable.
A,B,C
A = B
B = C
C = A
WAP to input item-code, item-name, the price per unit, and quantity of an item. Calculate total cost of the items apply a 10% discount.
Now show the total cost, discounts, and net amount on console.
WAP to calculate the Simple interest.
WAP to input temperature in Degree Celcius and convert it into a degree far.
volatile and restrict (c99) qualifier : Will be discussed further ….. |
User-Defined Type Declaration :
C supports a feature known as “type definition” that allows user to define an identifier that would represent an existing data type.
Syntax is –
typedef <data type> <user-define-identifier>; |
ex-
typedef int Integer; typedef floa tmarks; |
Ex ## int main() { typedef int Integer; typedef float marks;
Integer rollno; marks phy,che,math,eng,hindi,total; printf(“Enter rollno:”); scanf(“%d”,&rollno); printf(“Enter marks of Physics,Chemistry,Math,English and Hindi : \n”); scanf(“%f%f%f%f%f”,&phy,&che,&math,&eng,&hindi); total = phy+che+math+eng+hindi; printf(“the rollno %d Has got %f marks!!”,rollno,total); getch(); return 0; }
|
Scope and Life Cycle of Variable –
A scope in any programming is a region of the program where a defined variable can have its existence and beyond that variable, it cannot be accessed. There are 2 types of scopes in C programming language −
1. Local Scope
2. Global scope
Local Scope /Local Variable :
Variables that are declared inside a function or block are called local variables. They can be used only by statements that are inside that function or block of code. Local variables are not known to functions outside their own. The following example shows how local variables are used. Here all the variables a, b, and c are local to main() function.
#include<stdio.h> int main () { /* local variable declaration */ int a, b; /* actual initialization */ a = 10; |
Global Variables-
Global variables are defined outside a function, usually on top of the program. Global variables hold their values throughout the lifetime of your program and they can be accessed inside any of the functions defined for the program.
A global variable can be accessed by any function. That is, a global variable is available for use throughout your entire program after its declaration. The following program show how global variables are used in a program.
#include <stdio.h>
/* global variable declaration */ int g; int main () { /* local variable declaration */ int a, b; /* actual initialization */ a = 10; b = 20; g = a + b; printf ("value of a = %d, b = %d and g = %d\n", a, b, g); return 0; } |
A program can have same name for local and global variables but the value of local variable inside a function will take preference. Here is an example −
#include <stdio.h> /* global variable declaration */ int g = 20; int main () { /* local variable declaration */ int g = 10; printf ("value of g = %d\n", g); return 0; } |
When the above code is compiled and executed, it produces the following result −
value of g = 10
Default values of variables:-
(Initializing Local and Global Variables)
When a local variable is defined, it is not initialized by the system, you must initialize it yourself. These uninitialized variables will take some garbage value already available at their memory location.
Global variables are initialized automatically by the system when you define them as follows −
Data Type |
Initial Default Value |
int |
0 |
char |
'\0' |
float |
0 |
double |
0 |
pointer |
NULL |
It is a good programming practice to initialize variables properly, otherwise your program may produce unexpected results.
What is the output of following code? #include<stdio.h> int a=10; int main() { int a=20; { int a=30; |
|
printf(“a = %d”,a); |
//30 |
} printf(“a = %d”,a); |
//20 |
} |
|
What is the output of following code?
#include<stdio.h>
int a=10; int main() { { int a=30;
printf(“a = %d”,a); } printf(“a = %d”,a); }
What is the output of following code? #include<stdio.h> int a; int main() { a=20; { a=30; printf(“a = %d”,a); //30 } printf(“a = %d”,a); //30 }
What is the output of following code? #include<stdio.h> int a; int main() { { int a=30; printf(“a = %d”,a); //30 } printf(“a = %d”,a); //0 } |
Storage classes –
A storage class defines the scope (visibility) and life-time of variables and/or functions within a C Program. They precede the type that they modify. We have four different storage classes in a C program −
auto
register
static
extern
The auto Storage Class
The auto storage class is the default storage class for all local variables.
{ int mount; auto int month; } |
The example above defines two variables with in the same storage class. 'auto' can only be used within functions, i.e., local variables.
The register Storage Class-
The register storage class is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and can't have the unary '&' operator applied to it (as it does not have a memory location).
{ register int miles; } |
The register should only be used for variables that require quick access such as counters. It should also be noted that defining 'register' does not mean that the variable will be stored in a register. It means that it MIGHT be stored in a register depending on hardware and implementation restrictions.
The static Storage Class-
The static storage class instructs the compiler to keep a local variable in existence during the life-time of the program instead of creating and destroying it each time it comes into and goes out of scope. Therefore, making local variables static allows them to maintain their values between function calls.
The static modifier may also be applied to global variables. When this is done, it causes that variable's scope to be restricted to the file in which it is declared.
In C programming, when static is used on a global variable, it causes only one copy of that member to be shared by all the objects of its class.
#include <stdio.h>
/* function declaration */ void func(void);
static int count = 5; /* global variable */ main() { while(count--) {
func(); }
return 0; }
/* function definition */ void func( void ) {
static int i = 5; /* local static variable */ i++;
printf("i is %d and count is %d\n", i, count); }
|
When the above code is compiled and executed, it produces the following result −
i is 6 and count is 4 i is 7 and count is 3 i is 8 and count is 2 i is 9 and count is 1 i is 10 and count is 0 |
The extern Storage Class-
The extern storage class is used to give a reference of a global variable that is visible to ALL the program files. When you use 'extern', the variable cannot be initialized however, it points the variable name at a storage location that has been previously defined.
When you have multiple files and you define a global variable or function, which will also be used in other files, then extern will be used in another file to provide the reference of defined variable or function. Just for understanding, extern is used to declare a global variable or function in another file.
The extern modifier is most commonly used when there are two or more files sharing the same global variables or functions as explained below.
First File: main.c
#include <stdio.h> int count ; extern void write_extern(); main() { count = 5; write_extern(); } |
Second File: support.c
#include <stdio.h> extern int count; void write_extern(void) { printf("count is %d\n", count); } |
Here, extern is being used to declare count in the second file, whereas it has its definition in the first file, main.c. Now, compile these two files as follows −
$gcc main.c support.c |
It will produce the executable program a.out. When this program is executed, it produces the following result −
count is 5 |
Types of Variables in C
According to the scope and storage classes as we discussed above, there are following types of variables in c:
1. local variable
2. global variable
3. static variable
4. automatic variable
5. external variable
Some More Secretes of C:
printf() returns the integer value to main function. So we can write it like this also-
printf(“%d”, printf(“Hello”));
output:
Hello 5
We can write the Assignment statements like this also –
what will the output of following code?
#include <stdio.h> #include <stdlib.h> void main(){ int x; int a,b; x=10,20,30; a=30, b=40; printf("%d %d %d",x,a,b); //10,30,40 |
Operators in C
An operator is a symbol that tells the compiler to perform specific mathematical or logical functions. C language is rich in built-in operators and provides the following types of operators −
# Arithmetic Operators
# Relational Operators
# Logical Operators
# Assignment Operator
# Compound Assignment Operator / Shorthand Operator
# Increment and Decrement Operators (Unary Operators)
# Bitwise Operators
# Conditional Operators
# Misc Operators
Categories of Operators :
# Unary Operators (- , ++, --)
# Binary Operators
# Ternary Operators
Arithmetic Operators-
An arithmetic operator performs mathematical operations such as addition, subtraction, and multiplication on numerical values (constants and variables).
Operator |
Meaning of Operator |
+ |
addition (or unary plus) |
- |
subtraction (or unary minus) |
* |
multiplication |
/ |
Division |
% |
remainder after division( modulo division) |
Example:
Arithmetic Operators-
// C Program to demonstrate the working of arithmetic operators #include <stdio.h> int main() { int a = 9, b = 4, c; c = a+b; printf("a+b = %d \n",c); //13 c = a-b; printf("a-b = %d \n",c); //5 c = a*b; printf("a*b = %d \n",c); //36 c=a/b; printf("a/b = %d \n",c); //2
c=a%b; printf("Remainder when a divided by b = %d \n",c); //1 return 0; }
Output a+b = 13
a-b = 5
a*b = 36
a/b = 2
Remainder when a divided by b=1 |
Example 2 : // C Program to demonstrate the working of arithmetic operators #include <stdio.h> int main() { int a = 9, b = 4, c; c = a+b; printf("%d + %d = %d \n",a,b,c); c = a-b; printf("%d - %d = %d \n",a,b,c);
c = a*b; printf("%d * %d = %d \n",a,b,c); c=a/b; printf("%d / %d = %d \n",a,b,c); c=a%b; printf("%d % %d = %d \n",a,b,c); return 0; }
Output - 9 + 4 = 13 9 – 4 = 5 … .. |
C Relational Operators-
A relational operator checks the relationship between two operands. If the relation is true, it returns 1; if the relation is false, it returns value 0.
Relational operators are used in decision making and loops.
Operator |
Meaning of Operator |
Example |
== |
Equal to |
5 == 3 returns 0 |
> |
Greater than |
5 > 3 returns 1 |
< |
Less than |
5 < 3 returns 0 |
!= |
Not equal to |
5 != 3 returns 1 |
>= |
Greater than or equal to |
5 >= 3 returns 1 |
<= |
Less than or equal to |
5 <= 3 return 0 |
#include<stdio.h> int main() { int a = 5, b = 5, c = 10; printf("%d == %d = %d \n", a, b, a == b); // true printf("%d == %d = %d \n", a, c, a == c); // false
printf("%d > %d = %d \n", a, b, a > b); //false printf("%d > %d = %d \n", a, c, a > c); //false
printf("%d < %d = %d \n", a, b, a < b); //false printf("%d < %d = %d \n", a, c, a < c); //true printf("%d != %d = %d \n", a, b, a != b); //false printf("%d != %d = %d \n", a, c, a != c); //true
printf("%d >= %d = %d \n", a, b, a >= b); //true printf("%d >= %d = %d \n", a, c, a >= c); //false
printf("%d <= %d = %d \n", a, b, a <= b); //true printf("%d <= %d = %d \n", a, c, a <= c); //true return0; }
Output: 5 == 5 = 1 5 == 10 = 0 5 > 5 = 0 5 > 10 = 0 5 < 5 = 0 5 < 10 = 1 5 != 5 = 0 5 != 10 = 1 5 >= 5 = 1 5 >= 10 = 0 5 <= 5 = 1 5 <= 10 = 1 |
C Logical Operators:
An expression containing a logical operator returns either 0 or 1 depending upon whether expression results true or false. Logical operators are commonly used in decision making in C programming.
Operator |
Meaning of Operator |
Example |
&& |
Logial AND. True only if all operands are true |
If c = 5 and d = 2 then, expression ((c == 5) && (d > 5)) equals to 0. |
|| |
Logical OR. True only if either one operand is true |
If c = 5 and d = 2 then, expression ((c == 5) || (d > 5)) equals to 1. |
! |
Logical NOT. True only if the operand is 0 |
If c = 5 then, expression ! (c == 5) equals to 0. |
Example :
Logical Operators
// C Program to demonstrate the working of logical operators #include <stdio.h> int main() { int a = 5, b = 5, c = 10, result;
result = (a == b) && (c > b); printf("(a == b) && (c > b) equals to %d \n", result);
result = (a == b) && (c < b); printf("(a == b) && (c < b) equals to %d \n", result);
result = (a == b) || (c < b); printf("(a == b) || (c < b) equals to %d \n", result);
result = (a != b) || (c < b); printf("(a != b) || (c < b) equals to %d \n", result);
result = !(a != b); printf("!(a == b) equals to %d \n", result);
result = !(a == b); printf("!(a == b) equals to %d \n", result);
return 0; }
Output:
(a == b) && (c > b) equals to 1 (a == b) && (c < b) equals to 0 (a == b) || (c < b) equals to 1 (a != b) || (c < b) equals to 0 !(a != b) equals to 1 !(a == b) equals to 0 |
C Assignment and Compound Assignment Operators-An assignment operator is used for assigning a value to a variable. The most common assignment operator is =
Compound Assignment Operators also assign value/result to the variable but they do not overlap the variable’s value, instead, they update the variable's value after doing a specific operation on It.
Operator |
Example |
Same as |
= |
a = b |
a = b |
+= |
a += b |
a = a+b |
-= |
a -= b |
a = a-b |
*= |
a *= b |
a = a*b |
/= |
a /= b |
a = a/b |
%= |
a %= b |
a = a%b |
Example :
Assignment Operators-
// C Program to demonstrate the working of assignment operators #include<stdio.h> int main() { int a =5, c; c = a; printf("c = %d \n", c); c += a;// c = c+a printf("c = %d \n", c);
c -= a;// c = c-a printf("c = %d \n", c);
c *= a;// c = c*a printf("c = %d \n", c);
c /= a;// c = c/a printf("c = %d \n", c);
c %= a;// c = c%a printf("c = %d \n", c);
return0; }
Outputs: c = 5 c = 10 c = 5 c = 25 c = 5 c = 0 |
Increment and decrement operators:
++ , --
C programming has two operators increment ++ and decrement
-- to change the value of an operand (constant or variable) by 1.
Increment ++ increases the value by 1 whereas decrement -- decreases the value by 1. These two operators are unary operators, meaning they only operate on a single operand.
Example:
Increment and Decrement Operators
// C Program to demonstrate the working of increment and decrement operators
#include <stdio.h> int main() { int a = 10, b = 100; float c = 10.5, d = 100.5;
printf("++a = %d \n", ++a);
printf("--b = %d \n", --b);
printf("++c = %f \n", ++c);
printf("--d = %f \n", --d);
return 0; }
Outputs:
++a = 11 --b = 99 ++c = 11.500000 ++d = 99.500000 |
Note : -
Here, the operators ++ and -- are used as prefix. These two operators can also be used as postfix like a++ and a--.
Suppose you use ++ operator as prefix like: ++var. The value of var is incremented by 1 then, it returns the value.
Suppose you use ++ operator as postfix like: var++. The original value of var is returned first then, var is incremented by 1.
Example:1 #include<stdio.h> int main() { intvar=5;
// 5 is displayed then, var is increased to 6. printf("%d\n",var++); //output : 5
// Initially, var = 6. It is increased to 7 then, it is displayed. printf("%d",++var); //Ouput : 7
return0; }
Example:2 #include <stdio.h> int main() { int a,b; a=5,b=0; b= a++; printf("b = %d\n",b); //b=5 printf("a = %d\n",a); //a=6 return 0; }
Example:3 #include <stdio.h> int main() { int a,b; a=5,b=0; b = ++a; printf("b = %d\n",b); //b=6 printf("a = %d\n",a); //a=6 return 0; } |
What is the output of the following?
int a=30; printf(“%d”,a++) |
int a=0; a=a+; printf(“%d”,a) |
int a=0,b=0; b = a++ + a; printf(“%d\n”,b); //1 printf(“%d”,a); //1 |
int a=0,b=0; b = a++ + a++; printf(“%d\n”,b); //1 printf(“%d”,a); //2 |
int a=0,b=0; b = a++ + a--; printf(“%d\n”,b); printf(“%d”,a); |
int a=0,b=0; b = a++ + --a; printf(“%d\n”,b); printf(“%d”,a); |
Bitwise Operators-
Operators |
Meaning of operators |
& |
Bitwise AND |
| |
Bitwise OR |
^ |
Bitwise exclusive OR |
~ |
Bitwise complement |
<< |
Shift left |
>> |
Shift right |
The truth tables for &, |, and ^ is as follows −
P |
q |
p & q |
p | q |
p ^ q |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
Assume A = 60 and B = 13 in binary format, they will be as follows −
A = 0011 1100
B = 0000 1101
------------------------------------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
Bitwise AND operator &-
The output of bitwise AND is 1 if the corresponding bits of two operands is 1. If either bit of an operand is 0, the result of the corresponding bit is evaluated to 0.
Let us suppose the bitwise AND operation of two integers 12 and 25.
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)
Bit Operation of 12 and 25
00001100 & 00011001 ----------------------------------- 00001000 = 8 (In decimal) |
Example #1: Bitwise AND #include <stdio.h> int main() { int a = 12, b = 25; printf("Output = %d", a&b); return 0; }
Output: 8 |
Bitwise OR operator |
The output of bitwise OR is 1 if at least one corresponding bit of two operands is 1. In C Programming, bitwise OR operator is denoted by |.
12 = 00001100 (In Binary) 25 = 00011001 (In Binary)
Bitwise OR Operation of 12 and 25 00001100 | 00011001 ------------------------------------------------------- 00011101 = 29 (In decimal) |
Example #2: Bitwise OR #include<stdio.h> int main() { int a = 12, b =25; printf("Output = %d",a|b); return 0; } Output: 29 |
Bitwise XOR (exclusive OR) operator ^
The result of bitwise XOR operator is 1 if the corresponding bits of two operands are opposite. It is denoted by ^.
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)
Bitwise XOR Operation of 12 and 25 00001100 | 00011001 ------------------------------------------------------------------------------------- 00010101 = 21 (In decimal) |
Example #3: Bitwise XOR
#include <stdio.h> int main() { int a = 12, b = 25; printf("Output = %d", a^b); return 0; }
Output 21 |
Bitwise complement operator ~
Bitwise compliment operator is an unary operator (works on only one operand). It changes 1 to 0 and 0 to 1. It is denoted by ~.
Bitwise complement of any number N is -(N+1).
#include <stdio.h> int main() { printf("complement = %d\n",~35); printf("complement = %d\n",~-12); return 0; }
output: complement = -36 complement = 11 |
Shift Operators in C programming
There are two shift operators in C programming:
# Right shift operator
# Left shift operator.
Right Shift Operator
Right shift operator shifts all bits towards right by certain number of specified bits. It is denoted by >>.
212 = 11010100 (In binary)
212>>2 = 00110101 (In binary) [Right shift by two bits] 212>>7 = 00000001 (In binary) 212>>8 = 00000000
212>>0 = 11010100 (No Shift) |
Left Shift Operator
Left shift operator shifts all bits towards left by certain number of specified bits. It is denoted by <<.
212 = 11010100 (In binary)
212<<1 = 110101000 (In binary) [Left shift by one bit] 212<<0 =11010100 (Shift by 0) 212<<4 = 110101000000 (In binary) =3392(In decimal) |
Example #5:
Shift Operators
#include <stdio.h> int main() { int num=15, i; i=num>>2; printf(“I = %d”,i); i=i<<2; printf(“Now I = %d”,i); return 0; } |
Conditional Operator / Ternary Operator :
?:
A conditional operator is a ternary operator, that is, it works on 3 operands.
Conditional Operator Syntax
<conditionalExpression>?<expression1> : <expression2> |
The conditional operator works as follows:
1. The first expression conditional Expression is evaluated first. This expression evaluates to 1 if it's true and evaluates to 0 if it's false.
2. If conditional Expression is true, expression1 is evaluated.
3. If conditional Expression is false, expression2 is evaluated.
Example 1: /* Input a number and show it’s unsigned (absolute) value on console. i.e. if number is negative then show it’s positive value.*/
#include<stdio.h> int main() { int a,b; printf(“enter no :”); scanf(“%d”,&a); b = a<0 ? –a : a; printf(“Unsigned(absolute) a = %d” ,a); return 0; } |
Example 2:
/* Input two numbers and show big number between them */
#include<stdio.h> int main() { int a,b; printf(“enter 2 numbers:”); scanf(“%d%d”,&a,&b); a>b?printf(“Big no %d”,a) : printf(“Big no %d”,b); /*OR c = a>b : a : b; printf(“Big number = %d” ,c); */ return 0; } |
Nesting of ternary operator (condition) ? (- ? - ;) : ( - ? - : - ) ;
Example 3: /* Input 3 numbers and show big number between them */
#include<stdio.h> int main() { int a,b,c,big; printf(“enter 3 numbers:”); scanf(“%d%d%d”,&a,&b,&c); big= a>b?(a>c?a:c) : (b>c?b:c) ; printf(“Big number = %d” ,big); return 0; } |
Example 4: /* Input marks of 5 subjects, calculate total marks and percentage. Show the division of student. */ #include<stdio.h> int main() { float p,c,m,e,h,total,per; printf("enter marks of phy,che,math,eng,hindi :"); scanf("%f%f%f%f%f",&p,&c,&m,&e,&h); total=p+c+m+e+h; per = total*100/500.0; printf("Total =%f \n Percentage = %f",total,per); per>=60?printf("First"): per>=45?printf("second"):per>=33? printf("third"):printf("Fail"); return 0; } |
Operators Precedence in C
Operator precedence determines the grouping of terms in an expression and decides how an expression is evaluated. Certain operators have higher precedence than others; for example, the multiplication operator has a higher precedence than the addition operator.
For example, x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has higher precedence than +, so it first gets multiplied with 3*2 and then adds into 7.
Here, operators with the highest precedence appear at the top of the table, those with the lowest appear at the bottom. Within an expression, higher precedence operators will be evaluated first.
Category |
Operator |
Associativity |
Postfix |
() [] -> . ++ - - |
Left to right |
Unary |
+ - ! ~ ++ - - (type)* & sizeof |
Right to left |
Multiplicative |
* / % |
Left to right |
Additive |
+ - |
Left to right |
Shift |
<<>> |
Left to right |
Relational |
<<= >>= |
Left to right |
Equality |
== != |
Left to right |
Bitwise AND |
& |
Left to right |
Bitwise XOR |
^ |
Left to right |
Bitwise OR |
| |
Left to right |
Logical AND |
&& |
Left to right |
Logical OR |
|| |
Left to right |
Conditional |
?: |
Right to left |
Assignment |
= += -= *= /= %=>>= <<= &=^= |= |
Right to left |
Comma |
, |
Left to right |
Types of I/O Functions in C
In turbo C- getch() ,getche() and putch() comes from conio.h This header file is depricated in many of the modern compilers – codeblock, visual c++, and linux based (gcc) compilers, …. all required input output functions has been integrated in <stdio.h |
When we say Input, it means to feed some data into a program. An input can be given in the form of a file or from the command line. C programming provides a set of built-in functions to read the given input and feed it to the program as per requirement.
When we say Output, it means to display some data on-screen, printer, or in any file. C programming provides a set of built-in functions to output the data on the computer screen as well as to save it in text or binary files.
The Standard Files
C programming treats all the devices as files. So devices such as the display are addressed in the same way as files and the following three files are automatically opened when a program executes to provide access to the keyboard and screen.
Standard File |
File Pointer |
Device |
Standard input |
stdin |
Keyboard |
Standard output |
stdout |
Screen |
Standard error |
stderr |
Your screen |
The file pointers are the means to access the file for reading and writing purpose. This section explains how to read values from the screen and how to print the result on the screen.
Unformatted Functions
# These are the functions which can work with specific type of data only.
# C has three types of Unformatted I/O functions:
1. Character I/O : getchar(),putchar(),getch(),putch(),getche()
2. String I/O : gets() , puts()
3. File I/O : fgets(),fputs(), getc(), putc(), …..
Note-
File I/O functions will be discussed in File Handling Class.
getchar() , putchar() and putch()
This function reads a character-type data from standard input. It reads one character at a time till the user presses the enter key.
The int getchar(void) function reads the next available character from the screen and returns it as an integer. This function reads only single character at a time. You can use this method in the loop in case you want to read more than one character from the screen.
#include <stdio.h> int main() {
char c; //we can also write - int c; printf(“enter a character”); c=getchar(); printf(“c = %c ”,c); return 0; } Output: Enter a character k c = k |
The int putchar(int c) function puts the passed character on the screen and returns the same character. This function puts only single character at a time. You can use this method in the loop in case you want to display more than one character on the screen.
putch() function works same as putchar()
Check the following example −
#include<stdio.h> int main( ) { int c; printf( "Enter a value :"); c = getchar( ); printf( "\nYou have Typed : "); putchar( c ); return 0; } |
When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then the program proceeds and reads only a single character and displays it as follows −
Enter a value : this is test You have typed : t |
The getch() and getche()
# These functions read any alphanumeric character from the standard input device.
# The getche() accepts and displays the character and forwards the control to the next line of the program.
# The getch() accepts but does not display the character and forwards the control to the next line of the program.
#include<stdio.h> void main() { char a,b; printf(“Enter two alphabets:”); a=getche(); b=getch(); printf(“\n\nThe entered characters are :”); putch(a); putch(b); }
Output: Enter two alphabets : a (try to type ab)
The entered characters are : ab |
The gets() and puts
The char *gets(char *s) function reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF (End of File).
The int puts(const char *s) function writes the string 's' and 'a' trailing newline to stdout.
Ex-1 //Input String using scanf(“%s”)
#include<stdio.h> int main( ) { char str1[100]; printf( "Enter String :"); scanf(“%s”,str1); printf( "\nYou entered: %s",str1); return 0; } Output: Enter String : pybron.com You entered : pybron |
Ex-2 //Input String using gets()
#include<stdio.h> int main( ) { char str[100]; printf( "Enter first string :"); gets(str); printf( "\nYou entered: %s",str); return 0; }
Output: Enter String : pybron You entered : pybron |
What will be the output of follwing program ?
#include<stdio.h> int main( ) { char str1[100]str2[100]; printf( "Enter first string :"); scanf(“%s”,str1); printf(“enter second string:”); gets(str2); printf( "\nYou entered:\n %s \n %s",str1,str2); return 0; }
Output:
Enter First String : Gist Technosolutions Enter Second String : You have entered : pybron
2nd Run Outupt : Enter First String : pybron bhopal Enter Second String : You have entered : pybron Bhopal |
puts
#include<stdio.h> void main() { char str1[100],str2[100]; printf("enter string 1 :"); gets(str1); printf("enter string 2 "); gets(str2); puts ("Strings are :"); puts(str1); puts(str2); } |
Formatted I/O:
printf () and scanf ()scanf()
C library contains several input functions, and scanf() is the most general of them, because it can read a variety of formats. Of course, input from the keyboard is text because the keys generate text characters: letters, digits, and punctuation. When you want to enter, say, the integer 2004, you type the characters 2 0 0 and 4. If you want to store that as a numerical value rather than as a string, your program has to convert the string character-by-character to a numerical value; that is what scanf() does! It converts string input into various forms: integers, floating-point numbers, characters, and C strings. It is the inverse of printf(), which converts integers, floating-point numbers, characters, and C strings to text that is to be displayed onscreen.
scanf() uses a control string followed by a list of arguments. The control string indicates the destination data types for the input stream of characters. The chief difference is in the argument list. The printf() function uses variable names, constants, and expressions. The scanf() function uses pointers to variables. Fortunately, you don't have to know anything about pointers to use the function. Just remember these simple rules:
# If you use scanf() to read a value for one of the basic variable types, precede the variable name with an &.
# If you use scanf() to read a string into a character array, don't use an &.
// input.c -- when to use & #include<stdio.h> int main(void) { int age; //variable float assets; //variable char pet[30]; //string
printf("Enter your age, assets, and favorite pet.\n");
scanf("%d %f", &age, &assets); // use the & here scanf("%s", pet); // no & for char array
printf("%d $%.2f %s\n", age, assets, pet); return 0; }
|
The scanf() function uses whitespace (newlines, tabs, and spaces) to decide how to divide the input into separate fields. It matches up consecutive conversion specifications to consecutive fields, skipping over the whitespace in between. Note how the input is spread over two lines. You could just as well have used one or five lines, as long as you had at least one newline, space, or tab between each entry. The only exception to this is the %c specification, which reads the very next character, even if that character is whitespace.
Conversion Specifier |
Meaning |
%c |
Interpret input as a character. |
%d |
Interpret input as a signed decimal integer. |
%e, %f, %g, %a |
Interpret input as a floating-point number (%a is C99). |
%E, %F, %G, %A |
Interpret input as a floating-point number (%A is C99). |
%i |
Interpret input as a signed decimal integer. |
%o |
Interpret input as a signed octal integer. |
%p |
Interpret input as a pointer (an address). |
%s |
Interpret input as a string. Input begins with the first non-whitespace character and includes everything up to the next whitespace character. |
%u |
Interpret input as an unsigned decimal integer. |
%x, %X |
Interpret input as a signed hexadecimal integer. |
You also can use modifiers in the conversion specifiers.
Modifiers go between the percent sign and the conversion letter. If you use more than one in a specifier, they should appear in the same order as shown in below Table.
Modifier |
Meaning |
* |
Suppress assignment (see text). Example: "%*d" |
Modifier |
Meaning |
digit(s) |
Maximum field width. Input stops when the maximum field width is reached or when the first whitespace character is encountered, whichever comes first. Example: "%10s" |
hh |
Read an integer as a signed char or unsigned char. Examples: "%hhd" "%hhu" |
ll |
Read an integer as a long long or unsigned long long (C99). Examples: "%lld" "%llu" |
h, l, or L |
"%hd" and "%hi" indicate that the value will be stored in a short int. "%ho", "%hx", and "%hu" indicate that the value will be stored in an unsigned short int. "%ld" and "%li" indicate that the value will be stored in a long. "%lo", "%lx", and "%lu" indicate that the value will be stored in unsigned long. "%le", "%lf", and "%lg" indicate that the value will be stored in type double. Using L instead of l with e, f, and g indicates that the value will be stored in type long double. In the absence of these modifiers, d, i, o, and x indicate type int, and e, f, and g indicate type float. |
user define character |
to get input along with given character – ex- printf(“Enter time in HH:MM:SS”); scanf(“%d:%d:%d”,&h,&m,&s);
printf(“Enter DOB”); scanf(“%d/%d/%d”,&d,&m,&y); |
The scanf() Return Value
The scanf() function returns the number of items that it successfully reads. If it reads no items, which happens if you type a nonnumeric string when it expects a number, scanf() returns the value 0. It returns EOF when it detects the condition known as "end of file.
Inuting Integer values :
%wd |
W is an integer number that specifies the field width to be read.
Ex-
|
%*d
An input field may be skipped by specifying * in place of field width.
Ex-
scanf(“%d %*d %d”,&a,&b);
If Input is : 123 456 789
Then, a = 123 and b = 789
#include<stdio.h> int main(void) { int n; printf("Please enter three integers:\n"); scanf("%*d %*d %d", &n); printf("The last integer was %d\n", n); return 0; } |
Using Non – white space character:
scanf(“%d-%d”,&a,&b); Now input like this> 20-40 a=20 and b=40 |
Ex-
#include<stdio.h>
|
Inputting real numbers :
Unlike integer numbers, the field width of real number is not to be specified. But if we specify the width, it is not any error. It works little much same as working with integer. The digits inputed after the given length can be skipped.
If the number to be read is of double type, then the specification should be %lf instead of simle %f.
Inputting character String :
Specification are –
|
When we use %wc for reading a string , the system will wait until the wth character is keyed in Even after the Enter key/ white space. Note that %s, terminates reading at the encounter of blank space.
Ex:-
#include<stdio.h> void main() { char addr[20]; printf("enter address :"); scanf("%15s",addr); printf("Address is : %s"); }
Output : enter address : saket nagar Bhopal Address is : saket nagar Bhopal |
#include<stdio.h> void main() { char addr[40]; printf("enter address :"); scanf("%35c",addr); printf("Address is : %s"); }
Output :
enter address : saket nagar bhopal Pin-462023
Address is : bhopal Pin-462023 |
Another Specification, for string input,is – %[pattern] – accepts only the characters specified within [] . if the input stirng contains any other character,the string will be terminated at the first encounter of such a character. Or %[^pattern] - wors exactly reverse of %[..] |
#include<stdio.h> void main() { char name[10]; printf("enter name(a-z only) "); scanf("%[a-z]",fname); printf("%s",fname); }
Output : enter name : pybron p123 enter name : manish singh |
Ex-2 : // trick : Reading white space with scanf()
#include<stdio.h> void main() { char name[20]; printf("enter name "); scanf("%[^\n]",fname); //this will read until user press Enter printf("%s",fname); }
Output : enter name : pybron p123 |
Point to Notice .. scanf() also returns integer like printf it returns number of values read successfully we can also use it within printf() to see how many number have been inputed successfully. Like-
Ex:- 1
#include<stdio.h> void main() { int a,b; printf("enter two integers :"); printf("Total Input = %d",scanf("%d%d",&a,&b)); }
Output: Enter two integers : 20 43 Total Input = 2 ================== Enter two integers : 12 Hello Total input = 1
Ex:-2 Detecting Error in Input
#include<stdio.h> void main() { int a; printf(“enter no :”); scanf(“%d”,&a)==1?printf(“square is :%d”,a*a):printf(“Error in Input”); }
Output: Enter no : 20 Square is 400 ================== Enter no : five Error in inpu |
Working with printf() :
Conversion Specification output
%a Floating-point number, hexadecimal digits and p-notation (C99).
%A Floating-point number, hexadecimal digits and P-notation (C99).
%c Single character.
%d Signed decimal integer.
%e Floating-point number, e-notation.
%E Floating-point number, e-notation.
%f Floating-point number, decimal notation.
%g Use %f or %e, depending on the value. The %e style is used if the exponent is less than –4 or greater than or equal to the precision.
%G Use %f or %E, depending on the value. The %E style is used if the exponent is less than –4 or greater than or equal to the precision.
%i Signed decimal integer (same as %d).
%o Unsigned octal integer.
%p A pointer.
%s Character string.
%u Unsigned decimal integer.
%x Unsigned hexadecimal integer, using hex digits 0f.
%X Unsigned hexadecimal integer, using hex digits 0F.
%% Prints a percent sign.
Decision Making
Decision making structures require that the programmer specifies one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.
C programming language assumes any non-zero and non- null values as true, and if it is either zero or null, then it is assumed as false value.
C programming language provides the following types of decision-making statements.
S.N.:- |
Statement & Description |
1 |
if statement An if statement consists of a boolean expression followed by one or more statements. |
2 |
if...else statement An if... else statement can be followed by an optional else statement, which executes when the Boolean expression is false. |
3 |
If else-if ladder The if else-if statement is used to execute one code from multiple conditions. |
4 |
nested if statements You can use one if or else if statement inside another if or else if statement(s). |
5 |
switch statement A switch statement allows a variable to be tested for equality against a list of values. |
6 |
nested switch statements You can use one switch statement inside another switch statement(s). |
7 |
Ternary Operator? : This is an alternative of If-else statement. We can also use it as – else if , nested if. It has only single statement body. |
if-else statement
Simple if statement
An if statement consists of a Boolean expression followed by one or more statements.
The syntax of an 'if' statement in C programming language is −
if(<boolean_expression>) { /* statement(s) will execute if the boolean expression is true */ } |
If the Boolean expression evaluates to true, then the block of code inside the 'if' statement will be executed. If the Boolean expression evaluates to false, then the first set of code after the end of the 'if' statement (after the closing curly brace) will be executed.
C programming language assumes any non-zero and non- null values as true and if it is either zero or null, then it is assumed as false value.
#include<stdio.h> int main () { /* local variable definition */ int a = 10; /* check the boolean condition using if statement */ if( a < 20 ) { printf("a is less than 20\n" ); } printf("value of a is : %d\n", a); return 0; } |
Note: We can skip the { } in case of a single statement block.
If there are multiple if statements are placed inside the program then all of them are evaluated one by one and true conditions are executed. |
More Examples :
Input any number and show it’s Unsigned (Positive) Only Value. #include<stdio.h> #include<conio.h>
void main() { int a; clrscr(); printf(“enter any number : “); scanf(“%d”,&a); if(a<0)
a=a*-1;
printf(“Unsigend a = %d”,a); getch(); } |
Input Any two number and show the big number between them using simple if statement.
#include <stdio.h> #include <stdlib.h> int main() { int a,b; printf("enter any 2 number : "); scanf("%d%d",&a,&b); if(b>a) a=b; printf("\nbig no %d",a); }
Input Any 3 numbers and show the big number among them using simple if statement. #include <stdio.h> #include <stdlib.h> int main() { int a,b,c,big; printf("enter any 3 number : "); scanf("%d%d%d",&a,&b,&c); big=a; if(b>big) big=b; if(c>big) big=c; printf("\nbig no %d",big); } |
If-else Statement
An if statement can be followed by an optional else statement, which executes when the Boolean expression is false.
Syntax
The syntax of an if...else statement in C programming language is −
if(<boolean_expression>) { /* statement(s) will execute if the boolean expression is true */ } else { /* statement(s) will execute if the boolean expression is false */ } |
Example:1
#include<stdio.h> int main (){ int a =100; /* check the boolean condition */ if( a <20){ printf("a is less than 20\n"); } else{ printf("a is not less than 20\n"); }
printf("value of a is : %d\n", a); return0; } |
Example:2 find big b/w two numbers
#include<stdio.h> int main (){ int a,b; printf(“enter two numbers :”); scanf(“%d%d”,&a,&b); if(a>b) printf(“big no =%d”,a); else printf(“big no =%d”,b); return 0; } |
If...else if...else Statement
else if ladder :
An if statement can be followed by an optional else if...else statement, which is very useful to test various conditions using single if...else if statement.
When using if...else if..else statements, there are few points to keep in mind −
# An if can have zero or one else's and it must come after any else if's.
# An if can have zero to many else if's and they must come before the else.
# Once an else if succeeds, none of the remaining else if's or else's will be tested.
Syntax
The syntax of an if...else if...else statement in C programming language is −
if(<boolean_expression 1>) { ... } else if( <boolean_expression 2>) { ... } else if( <boolean_expression 3>) { ... } else { /* executes when the none of the above condition is true */ } |
Example : Input the percentage of student and show division.
#include <stdio.h> #include <stdlib.h>
int main() { float per; printf("enter percentage of student :") ; scanf("%f",&per);
if(per>=60) printf("First "); else if(per>=45) printf("Second");
else if(per>=33) printf("Third"); else printf("Faild");
} |
Nested if Statement
It is always legal in C programming to nest if-else statements, which means you can use one if or else if statement inside another if or else if statement(s).
Syntax
The syntax for a nested if statement is as follows −
if( boolean_expression 1) { if(boolean_expression 2) { /* Executes when the boolean expression 1 and 2 is true */ } } |
We can also put the if – statements or if-else statement inside the else block or else-if ladder block also.
Some more syntax:
if(<condition>) { if(<condition>) { …. } else { … .. } } else { if(<condion> ) { … } else { … } } |
Find big number among 3 numbers:
#include <stdio.h> int main() {
int a,b,c,big=0; printf("enter 3 numbers :"); scanf("%d%d%d",&a,&b,&c); if(a>b){ if(a>c) big =a; else big = c;
} else { if (b>c) big=b; else big=c; } printf("Big no = %d",big); }
Method – 2 :
#include <stdio.h> #include <stdlib.h> int main() { int a,b,c,big=0; printf("enter 3 numbers :"); scanf("%d%d%d",&a,&b,&c); if(a>b && a>c) big=a; else if(b>c) big=b; else big =c; printf("Big no = %d",big); } |
Loops
You may encounter situations when a block of code needs to be executed several times. In general, statements are executed sequentially: The first statement in a function is executed first, followed by the second, and so on.
Programming languages provide various control structures that allow for more complicated execution paths.
A loop statement allows us to execute a statement or group of statements multiple times. The process of repetition of a block, statement(s) is called looping.
Given below is the general form of a loop statement in most of the programming languages.
Advantage of loops in C
1. It saves code.
2. It helps to traverse the elements of array (which is covered in next pages).
C programming language provides the following types of loops to handle looping requirements.
S.N. |
Loop Type & Description |
1 |
do...while loop It is more like a while statement, except that it tests the condition at the end of the loop body. |
2 |
while loop Repeats a statement or group of statements while a given condition is true. It tests the condition before executing the loop body. |
3 |
for loop Executes a sequence of statements multiple times and abbreviates the code that manages the loop variable. |
4 |
nested loops You can use one or more loops inside any other while, for, or do..while loop. |
Loop Control Statements
Loop control statements change execution from its normal sequence. When execution leaves a scope, all automatic objects that were created in that scope are destroyed.
C supports the following control statements.
S.N. |
Control Statement & Description |
1 |
break statement Terminates the loop or switch statement and transfers execution to the statement immediately following the loop or switch. |
2 |
continue statement Causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating. |
3 |
goto statement Transfers control to the labeled statement. |
Basic needs/elements of Loop :
1. We need a variable that counts the repetition, called counter. The counter should be any integer variable. like – int cn;
2. We need to set the initial value to counter, for example – int cn=0;
3. Write a test condition for the repetition of block. Basically condition is set over the counter (most of the cases, but it is not compulsory)
4. Updation of the counter after each repeat of the loop. We either increase or decrease the value of the counter.
Note: loop may go infinite if we do not update counter
5. Set of statements to be executed.
Do...while
this is an exit control loop.
It always starts the loop without testing any condition As the condition is placed after the block. But it is repeated again only if the given condition is true. Otherwise, it exits from the loop.
It continues the loop till the condition is true, and stops when the condition becomes false.
In do while loop, the statement is given before the condition, so statement or code will be executed at least one time. In other words, we can say it is executed 1 or more times.
It is better if you have to execute the code at least once.
Syntax
<set counter> do { …. Statement(s) <counter updation> } while (<condition>) ; |
Example1 :
Show your name 10 times on console.
#include <stdio.h> int main () { int cn=1; do{ printf("XYZ\n"); //printf("%d . XYZ”,cn); cn=cn+1; //cn++, cn+=1; } while(cn<=10); printf("now cn = %d",cn); } |
Example 2: condition within loop
Write a program to input some even numbers from the console. Stop reading numbers when user put any odd number. Count how many times the user has put the even numbers.
#include <stdio.h> int main () { int n,cn=0; do{ printf("enter even no :"); scanf("%d",&n); if(n%2==0) cn++; } while(n%2!=1); printf("now cn = %d",cn); } |
Example 3: Loop within condition
Input a number and show its’ multiplication table if the number is even.
#include <stdio.h> int main () { int n,cn; printf("enter no :"); scanf("%d",&n); if(n%2==0) { cn=1; do { printf("%d\n", n*cn); cn++; } while(cn<=10); } } |
To do yourself : - Show the output in formate of – M * N = T Like- 5 * 1 = 5 5 * 2 = 10 |
Example 4:
Write a program that reads some numbers (one by one ) from the keyboard until the user does not input any odd number. In the end, show how many numbers have been given by the user, how many numbers are even and how many numbers are odd.
Hint: Here we will input number first only then we can check that it is even or not if the number is even then again repeat the process(loop) otherwise exit from the loop. Here we have to use the do loop (not while loop)
#include<stdio.h> void main() { int n,cn=0; //n, for number and cn for counting the inputed numbers do { printf(“enter any even number : “); scanf(“%d”,&n); cn++; }while(n%2==0); // or -> while (n%2 != 1);
printf(“OOPs!! You put the Odd number \n\n”); printf(“Total number give by user : %d\n\n”,cn); printf(“Total Even no = %d \n total Odd no = %d”, cn-1, 1); } |
Some more points to remember
If we do not update the counter inside the loop, it may cause an infinite loop. Another way of making loop infinite is to put the constant ‘1’ as condition. |
Example1 : Making infinite loop #include<stdio.h> void main() { int cn=1; do{ printf(“%d \t “ ,cn); cn++; } while(1); } |
Nested - Loops
When a loop is written inside the body of another loop, then it is known as the nesting of loops. Any type of loop can be nested inside any other type of loop. For example, a for loop may be nested inside another for loop or inside a while or do while loop. Similarly while and do while loops can be nested.
The nested loop works as iteration of loop. In other words we use nested loop the repeat the loop itself.
There is one outer and at least one inner loop. Whenever the outer loop is executed, the inner loop is repeated again.
Syntax :
for ( init; condition; increment ) { //outer loop for ( init; condition; increment ) { //inner loop statement(s); } statement(s); } |
if the outer loop is repeated form times and inner for n times then the total repetition of the inner loop will be m*n times.
Uses of nested loop :
=> To work with matrix (double dimensional array)
=> To work with repetitive series.
=> To Display row and columns on console.
Example1:
Show the table of the numbers 1 to 10
#include<stdio.h> void main(){ int i,j; for(i=1;i<=10;i++){ for( j=1;j<=10;j++){ printf("%d\t",i*j); } printf("\n"); } } |
Output:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
2 |
4 |
6 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
3 |
6 |
9 |
12 |
15 |
18 |
21 |
24 |
27 |
30 |
4 |
8 |
12 |
16 |
20 |
24 |
28 |
32 |
36 |
40 |
5 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
6 |
12 |
18 |
24 |
30 |
36 |
42 |
48 |
54 |
60 |
7 |
14 |
21 |
28 |
35 |
42 |
49 |
56 |
63 |
70 |
8 |
16 |
24 |
32 |
40 |
48 |
56 |
64 |
72 |
80 |
9 |
18 |
27 |
36 |
45 |
54 |
63 |
72 |
81 |
90 |
10 |
20 |
30 |
40 |
50 |
60 |
70 |
80 |
90 |
100 |
Example2:
Show the Matrix of stars(*)
#include<stdio.h> void main(){ int i,j; for(i=1;i<=5;i++){ for( j=1;j<=5;j++){ printf("*"); } printf("\n"); } } Output : * * * * * * * * * * * * * * * * * * * * * * * * * |
Example3:
changing the number of columns in each row
We can show the variable(changeable) number of columns in each row by putting any variable(in condition) in place of constant (that value is going to be updated in each repetition). Like this -
#include<stdio.h>
Output:* * * * * * * * * * * * * * * |
Example4:
Triangle of numbers
#include<stdio.h> printf("\n"); Output: 1 12 123 1234 12345 |
Q. Write a program to show the following output :
*
**
***
****
*****
(hint: Show decreasing space before printing of starts)
Jumps In Loops
break –
break statement is used to jump outside of the loop. It terminates the loop body.
the break is also used with a switch statement to terminate the block after the successful execution of any case statement once we break the loop it is terminated and can not be resumed( can be started again at some point)
ex-
...
break;
output: 1 2 3 4 5 6 7 8 9 10 Final value of if I = 11 |
Note :
Break only terminate the loop body in which it is written (in case of a nested loop)
break;
Output : 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
|
The final value of I and J: 11, 4
Ex-2 for(i=1; i<=10; i++ ) { Output :
|
Final value of I and J: 11, 1
Ex-3
Output : 1 2 3 4 5 6 7 8 9 10 |
Final value of I and J:1, 11
Ex-3 for(i=1; i<=10; i++ ) {
Outputs:
|
Continue :
This statement is used to skip the loop body and continues the empty loop.
The statements written after the continue will not be executed more but loop will continue to the end.
Ex- #include <stdio.h> #include <float.h> void main() { int i; for(i=1;i<=100;i++){ if(i>10 && i<90) continue; printf("%d\t",i); } }
Output: 1 2 3 4 5 6 7 8 9 10 90 91 92 93 94 95 96 97 98 99 100 |
Ex-2 #include <stdio.h> #include <float.h> void main() { int i; for(i=1;i<=100;i++){ continue; printf("%d\t",i); } printf("\nFinal value of i %d",i); } Output: Final value of I : 101 |
Ex-
Write a program to show all the even numbers between 1 to 50 with the help of continue statement.
#include <stdio.h> #include <float.h> void main() { int i; for(i=1;i<=50;i++){ if(i%2!=0) continue; // also write if(i%2) printf("%d\t",i); } printf("\nFinal value of i %d",i); } |
goto :
This is a control tranfer statement.
We can move the contorl of program (change the sequence of execution) using goto statement.
We have to decalre the lables (any text followed by colon : ) to transter the control at that line.
We simple use the name of label with goto.
goto <label>;
Ex- #include <stdio.h> #include <float.h> void main() { int i; xx: printf("enter any postive no : "); scanf("%d",&i); if(i<0) { printf("Not a valid no !! \n"); goto xx; } } |
Note: we can also transfer the control forward. (for skipping )
Ex- #include <stdio.h> #include <float.h> void main() { int n; printf("enter no : "); scanf("%d",&n); if(n%2==0) goto even; else goto odd; even: printf("THE NUMBER IS EVEN NO "); goto stop; odd: printf("THE NUMBER IS ODD NO"); stop: printf("\nProgram finished"); } |
Write a program to input any number and show it’s multiplicaiton table using goto.
#include <stdio.h> #include <float.h> void main() { int n,i=1,t; printf("enter no : "); scanf("%d",&n); table: t = n*i; printf("%d\t",t); i++; if(i<=10) goto table; } |
exit–
This statement is used to transter the control outside of program. It is used to jump outside of program (to source code). In other word exit statement is used to terminate the execution of the program.
Syntax:
exit(0);
Ex- #include <stdio.h> #include <float.h> void main() { int a,choice; printf("enter no :"); scanf("%d",&a); while(1) { printf("Press\n1 for Square \n2 for Cube \n 3 for exit :"); scanf("%d",&choice); switch(choice){ case 1: printf("square = %d",a*a); break; case 2: printf("cube =%d",a*a*a); break; case 3: exit(0); default : printf("Not a valid choice! Try Again \n\n"); } } } |
Array
An array is a collection of similar types of data items and each data item is called an element of the array. The data type of the elements may be any valid data type like char, int, or float, double. The elements of array share the same variable name but each element has a different index number known as a subscript. An array is a collection of items stored at continuous memory locations. The idea is to declare multiple items of the same type together.
Instead of declaring individual variables, such as number0, number1, ..., and number99, you declare one array variable such as numbers and use numbers[0], numbers[1], and ..., numbers[99] to represent individual variables. A specific element in an array is accessed by an index.
All arrays consist of contiguous memory locations. The lowest address, 0, corresponds to the first element and the highest address,size-1, to the last element.
The size and type of arrays cannot be changed after its declaration.
Types of Array:
One Dimensional Array
Two Dimensional Array
Multi-Dimensional Array
One Dimensional Array (1-D Array):
The one-dimensional array or single dimensional array in C is the simplest type of array that contains only one row for storing data. It has a single set of a square bracket (“[]”). To declare a single dimensional array in C, you can write the following code –
<data_type><arrayname>[<size>]; |
Here array_name denotes the name of the array and it can be any valid C identifier (Variable Name), data type of the elements of array. The size of the array specifies the number of elements that be stored in the array. It may be a positive
integer constant or constant integer expression.
Here are some examples of array declarations-
int age[100];
float sal[15];
char grade[20];
Tips : - When the array is declared, the compiler allocates space in memory sufficient to hold all the elements of the array, so the compiler should know the size of array at the compile time. Hence we can't use variables for specifying the size of array in the declaration. The symbolic constants can be used to specify the size of array. For example- |
#include<stdio.h> #define SIZE 10 void main() { int size=10;
int a[SIZE]; //valid int b[size]; //not valid int c[2+2]; //valid } |
Memory allocation for 1-D array –
Compiler allocates a continuous memory block of any 1 D array and makes the index for each element from 0 to size-1.
Ex-
int a[5]
1 |
2 |
3 |
4 |
5 |
a[0] a[1] a[2] a[3] a[4]
How to store Values (Initialize array)?
Method1 :
We can initialize array at declaration Time – int a[5] = {10,40,50,20,60};
No need to declare size if we want to initialize array at declaration time-
int a[] = {10,20,40,60,50,20,50};
Note –
# if we put the size of an array at the declaration time then we have to assign only the same number of values as specified size but if we don’t have specified the size then we can take any number of values.
# No Index Out of bound Checking:
There is no index out of bounds checking in C, for example, the following program compiles fine but may produce unexpected output when run.
// This C program compiles fine as an index out of //bound is not checked in C. int main() { int arr[2];
printf("%d ", arr[3]); printf("%d ", arr[-2]);
return 0; } |
What happen – int a[5] = {10,20,30,40,50,60,70}; //Not valid in C++ but valid in C The program won’t compile in C++. If we save the above program as a .cpp, the program generates compiler error “error: too many initializers for ‘int [2]'”
|
We can put any duplicate data in an array.
The size of array is depended over the memory stack available in that particular computer where the program is running.
As the Array is also a type of variable so the values (elements ) of the array can be changed/updated/altered any time.
If we allocate any blank element block to the array( { } ) at declaration time, the array is initalized by 0.
Like-
int a[5] ={}; //all the 5 elements are initalized by 0, Error in TC
int[5]={100}; // values – {100,0,0,0,0} (fine for TC)
sizeof() can be used to get the total number of bytes allocated to array.
How values are allocated in array -
int a[] = {10,20,40,60,50,20,50};
10 |
20 |
40 |
60 |
50 |
20 |
50 |
a[0] a[1] a[2] a[3] a[4] a[5] a[6]
int a[5] = {}; // This may cause Error in Turbo C
0 |
0 |
0 |
0 |
0 |
a[0] a[1] a[2] a[3] a[4]
int a[5] = {0}; // This will also work Turbo C
0 |
0 |
0 |
0 |
0 |
a[0] a[1] a[2] a[3] a[4]
int a[7] = {10,20,40,60,50};
10 |
20 |
40 |
60 |
50 |
0 |
0 |
a[0] a[1] a[2] a[3] a[4] a[5] a[6]
How to show data-
printf(“first element : %d”,a[0]);
printf(“second element : %d”,a[1]);
…
..
Using loop is the best practice to show the array elements,
like this-
... int i; for(i=0; i<7; i++) printf(“a[%d] = %d”, i,a[i]); ...
Output : a[0] = 10 a[1] = 20 a[2] = 40 a[3] = 60 a[4] = 50 a[5] = 20 a[6] = 50 |
Method 2: Getting Input from keyboard at run time.
We can input the values inside the array at rum time using scanf() function.
scanf(”<formate char.”, &array[index]);
ex-
printf(“enter 7 numbers :”);
scanf(“%d%d%d%d%d%d%d”,&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6]);
we can also use loop for input ,like this –
for(i=0; i<7; i++){
printf(“enter no : “);
scanf(“%d”,&a[i]);
}
Befinits of array :
- All the data are saved in RAM while program is running.
- We can pass the set of elements to the array for processing (like- sorting, searching,…)
- We can read the records from files.
- TO work with Linear Data Structures (Stacks and Ques)
- To Work with memory buffers
Complete Example of Array:
#include <stdio.h> #define SIZE 10 void main() { int a[SIZE],i,n,found=0; for(i=0; i<SIZE; i++) { printf("Enter Number: "); scanf("%d",&a[i]); } //printing of all numbers : for(i=0; i<SIZE ; i++) printf("\na[%d] : %d",i,a[i]); //show all evan numers from array printf("\nOnly the Even number :"); for(i=0; i<SIZE; i++) if(a[i]%2==0) printf("\n%d",a[i]);
printf("\nLast 5 numbers : "); for(i=5; i<SIZE; i++) printf("\na[%d] : %d",i,a[i]);
//Searching Inside Array : do{ found=0; printf("\n\n Enter number you want to search :"); scanf("%d",&n);
for(i=0; i<SIZE; i++){ if(a[i]==n){ found=1; //break; printf("Num found at index :%d",i); } } if(found==0) printf("Number not found");
printf("\nPress 1 to continue Searching "); }while(getch()=='1'); } |
Sorting of Array: {learn methods before programming)
Method 1 – Selection Sort
Method 2 – Bubble Sort
Method 3 – Insertion Sort
Selection Sort :
#include<stdio.h> void main() { int a[] = {20,30,40,10,22,24,21}, i,j ,k; //sorting using Selection sort for(i=0; i<7; i++) { for(j=i+1; j<7; j++) { if(a[i]>a[j]){ k=a[i]; a[i]=a[j]; a[j]=k; } } } //Printing the sorted Array : printf(“List in Ascending order : \n”); for(i=0; i<7; i++ ) printf(“%d\n”,a[i]); } |
Bubble Sort:
#include<stdio.h> void main() { int a[] = {20,30,40,10,22,24,21}, i,j ,k; //sorting using Selection sort for(i=6; i>0; i--) { for(j=0; j<i; j++) { if(a[j]>a[j+1]){ k=a[j]; a[j]=a[j+1]; a[j+1]=k; } } } //Printing the sorted Array : printf(“List in Ascending order : \n”); for(i=0; i<7; i++ ) printf(“%d\n”,a[i]); } |
Some More Points About Array 1. In C, array and pointer are different. They seem similar because array name gives the address of first element and array elements are accessed using pointer arithmetic. See array vs pointer in C for details.
2. Arrays are always passed as a pointer to functions. We will do it in the chapter of function.
3. A character array initialized with double-quoted string has the last element as ‘\0’.
4. Like other variables, arrays can be allocated memory in any of the three segments, data, heap, and stack (Memory Management topic for details). Dynamically allocated arrays are allocated memory on the heap, static or global arrays are allocated memory on data segment and local arrays are allocated memory on the stack segment. |
if we create array as global variable , the default values for each element of array will be 0
#include<stdio.h> int a[5]; void main() { int i; for(i=0; i<5; i++) printf("%d\n",a[i]); //0 0 0 0 0 } |
if we declare array as local variable then it will take garbage.
#include<stdio.h> void main() { int a[5]; int i; for(i=0; i<5; i++) printf("%d\n",a[i]); //five garbage values } |
If we initialize array at declaration time (even single element or blank {})
then the remaining elements are initialized by 0 automatically
#include<stdio.h> void main() { int a[5]={10,20}; int i; for(i=0; i<5; i++) printf("%d\n",a[i]); //10 20 0 0 0 } |
#include<stdio.h> void main() { int a[5]={ }; int i; for(i=0; i<5; i++) printf("%d\n",a[i]); //0 0 0 0 0 } |
Working with Double Dimensional Array :
- In 2-D array values or elements are organized in matrix order ( in rows and columns)
- Each element of array need at two indices for idenfiying it- Row Index and colums index.
Syntax:
<data type> <arrayName> [rows] [cols];
Ex-
int a[3][4];
How to Initialized 2 – D array -
int a[3][4] = { {10,20,30,40},{11,22,33,44},{22,44,66,88} };
int a[3][4] = { {10,20,30,40}, {11,22,33,44},{22,44,66,88} };
How to show value?
Use Nested Loop to print the rows and columns in Matrix order Outer loop responsible for printing rows
The inner loop is used to print columns
#include<stdio.h> void main() { int a[3][4] = { {10,20,30,40},{11,22,33,44},{22,44,66,88} }; int i,j; for(i=0; i<3; i++) { for(j=0; j<4; j++) { printf("%d ",a[i][j]); } printf("\n"); } } |
Getting input from user :
Use nested loop.
#include<stdio.h> void main() {
int a[3][4]; int i,j; for(i=0;i<3; i++){ printf("enter 4 values for row %d:",i+1); for(j=0;j<4;j++){ // printf("enter number :"); scanf("%d",&a[i][j]); } }
for(i=0; i<3; i++) { for(j=0; j<4; j++) { printf("%d ",a[i][j]); } printf("\n"); } } |
Input any 9 numbers in a 3*3 matrix and find the sum of each column
Like-
10 |
20 |
30 |
11 |
22 |
33 |
30 |
20 |
10 |
Functions in C
A function is a self-contained subprogram that is meant to do some specific, well-defined task. A program may consist of one or more functions. If a program has only one function then it must be the Main() function.
6.1 Advantages Of Using_Functions
1. Generally, a difficult problem is divided into subproblems and then solved. This divide and conquer technique are implemented in C through functions. A program can be divided into functions, each of which performs some specific task. So the use of C functions modularizes and divides the word of a program.
2. When some specific code is to be used more than once and at different places in the program the use of functions avoids repetition of that code.
3. The program becomes easily understandable, modifiable, and easy to debug and test. It becomes simple to write the program and understand what work is done by each part of the program
4. Functions can be stored in a library and reusability can be achieved.
C programs have two types' of functions-
1. Library functions ...
2. User-defined functions
Library Functions :
These are the part of standard c library.they are also called pre-defined functions.
They are available in all the computer(where we install the c compiler)
They are defined in header files, so we need to link the required header file to use them inside our program. Example of Library Functions-
...... .. many more |
Example1 – Program to find Square root of any number, using sqrt() function.
#include<stdio.h> #include<math.h> main() { double n, s; printf ("Enter a number ") ; scanf (''%lf'', &n) ; s=sqrt(n); printf ("The square root of %. 2lf is %.2lf\n" ,n, s ); }
Output: Enter a number:16 The square root of 16.00 is: 4.00 |
User-defined functions :
These are the functions defined by the user, so they are only available in the user's computer. To create and use these functions, we should know about these three things-
1. Function definition
2. Function declaration
3. Function call
{ we will discuss UDF after Libray Functions }
Functions of STRING.H
The string.h header defines one variable type, one macro, and various functions for manipulating arrays of characters.
Library Variables
Following is the variable type defined in the header string.h:
S.N. |
Variable & Description |
1 |
size_t This is the unsigned integral type and is the result of the size of keyword. |
Library Macros
Following is the macro defined in the header string.h:
S.N. |
Macro & Description |
1 |
NULL This macro is the value of a null pointer constant. |
Following are the functions defined in the header string.h:
strlen()
strcpy()
strcmp()
strcat()
strrev()
strupr()
strlwr()
..
strlen():
returns the length of string (char array)
length includes the number of character includeing white spacebut excluding '\0'
return type is integer.
prototype/signature is -
int strlen(<string>)
syntax-
<int-var> = strlen(<string>);
#include<stdio.h> #include<string.h> void main(){ int n; char name[]="Ramesh kumar"; n = strlen(name); printf("length of name :%d",n); printf("\n size using strlen: %d",strlen(name)); printf("\n size of name : %d",sizeof(name)); /* FINDING THE LENGTH USING COSOTOME CODE*/ int cn=0; int i=0; while(name[i]!='\0'){ cn++; i++; } printf("\n LENGTH USING LOOP :%d",cn); } |
strupr() :
it converts the string to upper case
strlwr():
it converts the string into lower case.
Signature / Stynatx-
char *strupr(<string>);
char *strlwr(<string>); |
Example -
#include<stdio.h> #include<string.h> void main(){ char name[] = "Ramesh"; puts(name); strupr(name); puts(name); printf("now name is %s",name); strlwr(name); printf("\n Now Lower case :%s",name); } |
strcpy() :
used to copy one string to another char array.
in c, we can not use = operator to assign any string to another. like-
char name[20];
name="Ram";//Error
Or -
char name1[] = "Ram";
char name2[10];
name1 = name1; //Error
for this purpose, we use the strcpy().
signature:
char *strcpy(<target-string>, <source-string>); |
Ex-1 .... char name[20],name1[20]; strcpy(name,"Ramesh"); strcpy(name1,name); printf("%s",name); //Ramesh printf("\n%s",name1); //Ramesh ... |
Ex-2
#include<stdio.h> #include<string.h> void main(){ char name[] = "Ramesh"; char name1[20]; /* Using loop */ int i=0; while(name[i]!='\0'){ name1[i]=name[i]; i++; } puts(name); puts(name1); } |
strcmp() :
used to compare any two string.
if the both strings are equal, then it returns 0
if first string is greter than secod then it returns positive value if first is smaller than second the it returns negative value.
so signature is -
int strcmp(<string1>,<string2>); |
Ex-
#include<stdio.h> #include<string.h> void main(){ char name1[10],name2[10]; printf("enter first name : "); gets(name1); printf("enter second name :"); gets(name2);
if(strcmp(name1,name2)==0) printf("Both names are equal"); else if (strcmp(name1,name2)>0) printf("first name is bigger than second"); else printf("first name is smaller than second "); } |
strrev() :
this function is used to reverse the string.
char *strrev(<string>);
Ex-
#include<stdio.h> #include<string.h> void main(){ char name[] ="RAM"; strrev(name); puts(name); //MAR } |
Program to check that the given stirng is palindrome or not –
Ex-
#include<stdio.h> #include<conio.h> void main(){ char txt[20];
printf(“input any text/word”); gets(txt); if(strcmp(txt,strrev(txt))==0) printf(“Text is palindrome”); else printf(“Text is not palindrome”); } |
strcat()
This function is used to append any string at the end of another string variable.
Syntax:
char*strcat(<str1>,<str2>); str2 will be appended at the end of str1 |
Ex-
#include <stdio.h> #include <string.h> int main () { char src[50], dest[50]; strcpy(src, "This is source"); strcpy(dest, "This is destination"); strcat(dest, src); printf("Final destination string : |%s|", dest); return(0); } |
Sample Program -
Ex-
#include <stdio.h> int main( ) { charnm[]="nitin"; charpwd[] = "nitin"; if(strlen(pwd)<8) printf("Password is too short"); else printf("strong password");
if(strcmp(pwd,nm)==0) printf("\n name and password can not be same"); else printf("\n ok valid password");
if(strcmp(nm,strrev(nm))==0) printf("\n name is palindrome"); } |
memcmp() :(Compare Memory Blocks)
The C library function int memcmp()compares the first n bytes of memory area str1 and memory area str2.
Declaration
Following is the declaration for memcmp() function.
int memcmp(<str1>, <str2> , size_t n)
Parameters
str1 − This is the pointer to a block of memory.
str2 − This is the pointer to a block of memory.
n − This is the number of bytes to be compared.
Return Value
if Return value < 0 then it indicates str1 is less than str2.
if Return value > 0 then it indicates str2 is less than str1.
if Return value = 0 then it indicates str1 is equal to str2.
Ex-
#include <stdio.h> #include <string.h> int main () { char str1[15]; char str2[15]; int ret; memcpy(str1, "Abcdef", 6); memcpy(str2, "ABCDEF", 6); ret = memcmp(str1, str2, 1); if(ret > 0) { printf("str2 is less than str1"); } else if(ret < 0) { printf("str1 is less than str2"); } else { printf("str1 is equal to str2"); } return(0); } |
void *memchr(const void *str, int c, size_t n)
Searches for the first occurrence of the character c (an unsigned char) in the first n bytes of the string pointed to, by the argument str.
This function returns a pointer to the matching byte or NULL if the character does not occur in the given memory area.
Ex-
#include<stdio.h> #include<string.h> int main (){ constchar str[]="http://www.pybron.com"; constchar ch ='.'; char*ret; ret= memchr(str, ch, strlen(str)); printf("String after |%c| is - |%s|\n", ch, ret); return(0); } |
Let us compile and run the above program that will produce the following result −
String after |.| is - |.pybron.com|
void *memcpy(void *dest, const void *src, size_t n)
Copies n characters from src to dest.
This function returns a pointer to a destination, which is str1.
Ex-
#include <stdio.h> #include <string.h>
int main () { const char src[50] = "Welcome to PyBron"; char dest[50];
printf("Before memcpy dest = %s\n", dest); //no input memcpy(dest, src, 6);
printf("After memcpy dest = %s\n", dest); //weclom return(0); } |
char *strncpy(char *dest, const char *src, size_t n)
Copies up to n characters from the string pointed to, by src to dest.
Ex-
#include <stdio.h> #include <string.h> int main () { char src[40]; char dest[12]; strcpy(src, "This is PyBron"); strncpy(dest, src, 10); printf("Final copied string : %s\n", dest); return(0); } |
char *strstr(const char *s1, const char *s2)
In the C Programming Language, the strstr function searches within the string pointed to by s1 for the string pointed to by s2. It returns a pointer to the first occurrence in s1 of s2. If no match found then it returns null.
Ex-
#include <stdio.h> #include <string.h> int main () { const char s1[20] = "PyBron"; const char s2[10] = "Techno"; char *ret; ret = strstr(s1,s2); printf("The substring is: %s\n", ret); //Techno ret = strstr(s1,”Hello”); printf(“%s”,ret); //(null) return(0); } |
To-Do yourSelf !!
Write a program to read the password and confirm the password from console. if the given password is less than 8 character then show - "week password" and ask again for a password( using goto )
if the password is strong(more than 8 characters) then ask for confirm password/ retype password. If the confirm password is matched to the previous password then show a message- registered successfully.
if the confirm password is not matched with the previous password then show msg- "password and confirm password are not matched, Try again", and again input the confirm password. if the user makes 3 unsuccessfully attempts then exit from the program.
Write a program to input name of 10 students. now create a table to show how many times the name is entered.
like this-
Name Repeated
amit 2
mohit 1
suresh 3
...
Write a program to input any 10 names and re-arrange them in Descending order (alphabetic reverse order)
Character Functions : <ctype.h>
- This header file provides the functions to work with the single character. Main functions are :
toupper()
tolower()
isupper()
islower()
isalpha()
isdigit()
isspace()
..
toupper() : it returns the upper case of given character.
tolower() : It returns the lower case of the given character.
Syntax –
int toupper(<char>)
int tolower(<char>)
Ex-
#include <stdio.h> int main( ) { char ch='a'; char ch2; ch2 = toupper(ch); printf("%c",toupper(ch)); printf("\n%c",ch); printf("\n%c",ch2); } |
Finding out the character type :
all following functions return 1(true) if the character belongs to the particular class otherwise returns 0.
1 |
int isalnum(int c) This function checks whether the passed character is alphanumeric. |
2 |
int isalpha(int c) This function checks whether the passed character is alphabetic. |
3 |
int iscntrl(int c) This function checks whether the passed character is control character |
4 |
int isdigit(int c) This function checks whether the passed character is decimal digit. |
5 |
int isgraph(int c) This function checks whether the passed character has graphical representation using locale. |
6 |
int islower(int c) This function checks whether the passed character is lowercase letter. |
7 |
int isprint(int c) This function checks whether the passed character is printable. |
8 |
int ispunct(int c) This function checks whether the passed character is a punctuation character |
9 |
int isspace(int c) This function checks whether the passed character is whitespace. |
10 |
int isupper(int c) This function checks whether the passed character is an uppercase letter. |
11 |
int isxdigit(int c) This function checks whether the passed character is a hexadecimal digit |
Ex-
#include <stdio.h> int main( ) { char ch = 'A'; if(isupper(ch)) printf("Char in upper case"); if (islower(ch)) printf("char in lower case"); if(isdigit(ch)) printf("char is a digit"); if(isalpha(ch)) printf("char is alphabet"); if(isspace(ch)) printf("char is a space"); } |
1. Write a program to read any string and convert it into a toggle case.
2. Write a program to read a line of text. convert all the words in proper case.
3. Write a program to read multiple lines of text. now convert the text into a sentence case. (the first char of line in upper case).
4. write a program to input any line of text. count all the digits, vowels, consonants, special characters, and spaces.
Math.h
The math.h header defines various mathematical functions and one macro. All the functions available in this library take double as an argument and return double as the result.
Sr.No. |
Function & Description {Press Ctrl+Click over the heading to view detials and programs) |
1 |
double acos(double x) Returns the arc cosine of x in radians. |
2 |
double asin(double x) Returns the arc sine of x in radians. |
3 |
double atan(double x) Returns the arc tangent of x in radians. |
4 |
double atan2(double y, double x) Returns the arc tangent in radians of y/x based on the signs of both values to determine the correct quadrant. |
5 |
double cos(double x) Returns the cosine of a radian angle x. |
6 |
double cosh(double x) Returns the hyperbolic cosine of x. |
7 |
double sin(double x) Returns the sine of a radian angle x. |
8 |
double sinh(double x) Returns the hyperbolic sine of x. |
9 |
double tanh(double x) Returns the hyperbolic tangent of x. |
10 |
double exp(double x) Returns the value of e raised to the xth power. |
11 |
double frexp(double x, int *exponent) The returned value is the mantissa and the integer pointed to by exponent is the exponent. The resultant value is x = mantissa * 2 ^ exponent. |
12 |
double ldexp(double x, int exponent) Returns x multiplied by 2 raised to the power of exponent. |
13 |
double log(double x) Returns the natural logarithm (base-e logarithm) of x. |
14 |
double log10(double x) Returns the common logarithm (base-10 logarithm) of x. |
15 |
double modf(double x, double *integer) The returned value is the fraction component (part after the decimal) and sets integer to the integer component. |
16 |
double pow(double x, double y) Returns x raised to the power of y. |
17 |
double sqrt(double x) Returns the square root of x. |
18 |
double ceil(double x) Returns the smallest integer value greater than or equal to x. |
19 |
double fabs(double x) Returns the absolute value of x. |
20 |
double floor(double x) Returns the largest integer value less than or equal to x. |
21 |
double fmod(double x, double y) Returns the remainder of x divided by y. |
Some Examples:
Squrt()-
#include <stdio.h> #include<math.h> void main() { double n=121; double sqt = sqrt(n); printf("square root = %lf",sqt); }
pow()-
#include <stdio.h> #include<math.h> void main() { double a,b,c; a=10; b=3; c=pow(a,b); printf("%lf to pow %lf = %lf",a,b,c); } |
Square-
#include <stdio.h> #include<math.h>
void main() { double a,b; printf("enter number :"); scanf("%lf",&a); b = pow(a,2); printf("square of %lf = %lf",a,b); } |
abs()
find the absolute value of give number
#include <stdio.h> #include<math.h> void main() { int a=-20; printf("%d",abs(a)); } |
Floor and ceil():
#include <stdio.h> #include<math.h> void main() { float a=45.12; printf("%f",ceil(a)); printf("\n%f",floor(a)); } |
Limit.h
The limits.h header determines various properties of the various variable types. The macros defined in this header, limits the values of various variable types like char, int and long.
These limits specify that a variable cannot store any value beyond these limits, for example, an unsigned character can store up to a maximum value of 255.
Library Macros
The following values are implementation-specific and defined with the #define directive, but these values may not be any lower than what is given here.
Macro |
Value |
Description |
CHAR_BIT |
8 |
Defines the number of bits in a byte. |
SCHAR_MIN |
-128 |
Defines the minimum value for a signed char. |
SCHAR_MAX |
+127 |
Defines the maximum value for a signed char. |
UCHAR_MAX |
255 |
Defines the maximum value for an unsigned char. |
CHAR_MIN |
-128 |
Defines the minimum value for type char and its value will be equal to SCHAR_MIN if char represents negative values, otherwise zero. |
CHAR_MAX |
+127 |
Defines the value for type char and its value will be equal to SCHAR_MAX if char represents negative values, otherwise UCHAR_MAX. |
MB_LEN_MAX |
16 |
Defines the maximum number of bytes in a multi-byte character. |
SHRT_MIN |
-32768 |
Defines the minimum value for a short int. |
SHRT_MAX |
+32767 |
Defines the maximum value for a short int. |
USHRT_MAX |
65535 |
Defines the maximum value for an unsigned short int. |
INT_MIN |
-2147483648 |
Defines the minimum value for an int. |
INT_MAX |
+2147483647 |
Defines the maximum value for an int. |
Example
The following example shows the usage of few of the constants defined in limits.h file.
#include <stdio.h> #include <limits.h>
int main() {
printf("The number of bits in a byte %d\n", CHAR_BIT);
printf("The minimum value of SIGNED CHAR = %d\n", SCHAR_MIN); printf("The maximum value of SIGNED CHAR = %d\n", SCHAR_MAX); printf("The maximum value of UNSIGNED CHAR = %d\n", UCHAR_MAX); printf("The minimum value of SHORT INT = %d\n", SHRT_MIN); printf("The maximum value of SHORT INT = %d\n", SHRT_MAX);
printf("The minimum value of INT = %d\n", INT_MIN); printf("The maximum value of INT = %d\n", INT_MAX);
printf("The minimum value of CHAR = %d\n", CHAR_MIN); printf("The maximum value of CHAR = %d\n", CHAR_MAX);
printf("The minimum value of LONG = %ld\n", LONG_MIN); printf("The maximum value of LONG = %ld\n", LONG_MAX);
return(0); } |
User Define Functions Part-I
A Function is a self-contained block of code that performs a particular task. Once a function has been designed and packed, it can be treated as a ‘black box’ that takes some data from the main program and returns a value.
The function in C language is also known as procedure or subroutine in other programming languages.
To perform any task, we can create function. A function can be called many times. It provides modularity and code reusability.
int a,b,c; printf(“enter two numbers:”); scanf(“%d%d”,&a,&b); c=a+b; printf(“sum = %d”,c); |
Now we make the grouping of above code, like this-
{ int a,b,c; printf(“enter two numbers:”); scanf(“%d%d”,&a,&b); c=a+b; printf(“sum = %d”,c); } |
Now think a name that can be given to identify this code block, assume the name will be ‘addition’, now write this name along with () just before the block-
addition() { int a,b,c; printf(“enter two numbers :”); scanf(“%d%d”,&a,&b); c=a+b; printf(“sum = %d”,c); } |
Here we named the block – addition, that is given by user/ programmer. It may be any other name also.
This block is now formed in function, called addition(), and we can call(reuse) this code block in our main program any time whenever we want,
like this-
#include<stdio.h> addition() { //this is function definition int a,b,c; printf(“enter two numbers :”); scanf(“%d%d”,&a,&b); c=a+b; printf(“sum = %d”,c); } void main() { addition(); //this is function call , we can call many time } |
Above code is the sample program of UDF (User Define Function)
Elements of UDF
In order to make use of a user-define function, we need to establish three elements that are related to functions-
- Function Definition.
- Function Call.
- Function Declaration.
The function Definition is an independent program module that is specially written to implement the requirement of the function. In order to use this function, we need to invoke it at a required place in the program. This is known as a function call. The Program (or function) that calls the function is referred to as the calling program or calling function. The calling program should declare any function (like a declaration of a variable) that is to be used later int the program. This is known as the function declaration or function prototype. Function Declaration and Function calls can be done multiple times but function can be defined only once in a file |
Defining a Function
A Function Definition shall include the following elements-
1. Function type or Return type
2. Function Name
3. List of parameters
4. Local variable declaration
5. Function statements and
6. A return statement
The general form of a function definition in C programming language is as follows −
<return_type><function_name>(<parameter list> ) { /* <body of the function> */ <local variables> <statements> return [<statement/expression/value>]; } |
A function definition in C programming consists of a function header and a function body. Here are all the parts of a function −
=> Return Type − A function may return a value.
The return_type is the data type of the value the function returns. Some functions perform the desired operations without returning a value. In this case, the return_type is the keyword void.
=> Function Name –
- This is the actual name of the function.
- Function name is the identifier of the code block created to perform any specific operation.
- Function name is used to invoke (call) the code block inside another program/function/main() function
​​​​​​​- Function name must follow the rules of variable name.
​​​​​​​- The function name and the parameter list together constitute the function signature.
=> Parameters −
A parameter is like a placeholder. When a function is invoked, you pass a value to the parameter. This value is referred to as an actual parameter or argument. The parameter list refers to the type, order, and a number of the parameters of a function. Parameters are optional; that is, a function may contain no parameters.
=> Function Body −
The function body contains a collection of statements that define what the function does.
Note- Inside the function body, we should use the return statement at the end of body. In case of void type, it is not necessory.
When we use ‘return’ statement, the result/value is sent back to the main() function or to the program where we invoke/call the function.
Function can be defined anywhere in the file,either before main() or after the main() function, but not inside main() or other function. Function can be placed in any order. A called function can be placed either before or after the calling function. However , it is the usual practice to define all the called functions at the end of main(). |
Ex 1- void print() { printf(“welcome to PyBron”); return; //optional for void type function }
Ex 2- int getValue() { return 10; //required for returing any value/expression } |
Function Call :
A Function can be called by simply using the funciton name followed by a list of actual parameters(in case of parametrized functions) enclosed in parentheses. Like-
<function_Name> (<argument_List>);
Or
<function_Name>() ; //if there are not arguments
Note- The function does not work until we call it inside our main program(inside main())
If function doesnot retur any value (void tpe function) then it can be called directly inside the main(), like- <function_name>(<actual_arguments>);
If function has a return type Or it returns any value then we should assign the function to the appropriate type of variable and the value will be put to the variable.like- <variable> = <function_name>(<actual_arguments>);
Any Function can call any other function. In fact, it can call itself. A ‘called function’ can also call another function. A function can be called more than once. In fact, this is one of the main features of using functions. |
Complete Example 1:-
void print() { printf(“welcome to PyBron”); return; //optional for void type function } void main() { print(); //calling of function } |
Complete Example 2:-
void main() { int n = getValue(); //calling of function printf(“Value given by function : %d”,n); /* we can also write- printf(“value given by function :%d”,getValue()); */ } int getValue() { |
The mechanism behind function call-
When the compiler encounters a function call, the control is transferred to the function. This function is then executed line by line as described and a value is returned when a return statement is encountered.
Function Declaration:
In ANSI C standard, we follow the Top-Down Programming approch, where the main unit of the program(which is main() function) is created first then we should create/define it’s subunits i.e. other functions(UDFs).
All the UDF is called inside the main() but they are defined outside of the main(), usually after main().
This approach some time may cause an Error – Function should have a prototype, as the main does not find the function definition when it calls the UDF.
So there is a mechanism to avoid such type of error. That is – Function Declaration or Function Prototyping.
Functions can be declared anywhere (also multiple times) either inside the main() or other function before it’s call.
Usually, we should declare the function before the main(), at the global section, so that it will be available for all other functions of the source file. We can also declare the function inside another file(header file).
A function declaration is similar to the function definition except that it is terminated by a semicolon(;) in place of {}
Syntax:- <type><name>(<arguments>); Ex-
void show(void); //takes nothing returns nothing void show(); //same as above void showTable(int n); //takes something returns nothing int square(int x); //take something returns something |
Steps of Invoking function-
1. function declaration/prototyping : before main() 2. function calling: inside main() 3. function definition : after the main() Like- <function declaration> main() { <function calling> } <function definition> |
Some More Examples:
#include<stdio.h> void showTable(); //function prototype(declaration) /* or void showTable(void); */ void main(){ showTable();//function call } void showTable(){ //function defintion int n,i; printf("enter number :"); scanf("%d",&n); ' for(i=1;i<=10;i++) printf("\n%d",n*i); } |
Passing Parameters/arguments to function :
âž” Parameters are the additional arguments which are declared along with the functions
âž” They are used to receive the values from the calling function or calling program.
âž” Each parameter which are declared within the parenthesis of the function are known as a formal parameter and the values which are passed (given) by the calling function are known as actual parameter.
âž” Each parameter is a variable which is declared separated by a comma.
Parameters are used to share the data/values among multiple functions. Another way to share the values among multiple functions is to declare them in the global section, but in this case, variables become accessible for all of the functions defined in that source file. We can not prevent any function not to access them. Also, there is no control of the calling function over the values. Using the parameter we can achieve both goals- * Sharing the values among desired functions * Controlling the data before passing/giving to function |
Syntax:
1. Declaration (Before main() function) – <type><Func_Name> (<type><arg1>, <type><arg2>, ..) ; 2. Calling (Inside main() function ) :- <Func_Name> (<list of actual arguments> ) ; 3. Definition (After main() function ) :- <type><Func_Name> (<type><arg1>, <type><arg2>, ..) { …… } |
When a function receive the value in the form of a parameter, then we need not read the value from a console inside the function instead we work with the argument.
Example1:
#include<stdio.h> void drawLine(int); void main() { printf(“this is the example of parametrized funtion \n”); drawLine(40);//call1 printf(“\n Thanx for watching\n”); drawLine(20); //call2 printf(“\n”); drawLine(10); //call3 printf(“Vizit Again”); drawLine(10); //call4 } void drawLine(int x) { int i; for(i=1;i<=x;i++) printf(“=”); } outputs: ?? |
Example2:
#include<stdio.h> void drawLine(char,int); void main() { printf(“this is the example of parametrized funtion \n”); drawLine(‘=‘,40); //call1 printf(“\n Thanx for watching\n”); drawLine(‘-‘,20); //call2 printf(“\n”); drawLine(‘*’,10); //call3 printf(“Vizit Again”); drawLine(‘*’,10); //call4 } void drawLine(char ch,int x) { int i; for(i=1;i<=x;i++) printf(“%c”,ch); } outputs: ?? |
Note : 1. If the actual parameters are more than the formal parameters, the extra actual arguments will be discarded
2. On the other hand, if the actual parameters are less than the formal parameters the unmatched formal arguments will be initialized to some garbage.
But, if we declare the function before the calling, then both above mechanism will produce a compile-time error.
3. Any mismatch in data type may also result in some garbage value.
4. The parameter list must be separated by comma(,)
5. The parameter name does not need to be the same in the prototype declaration and the function definition.
6. The type must match the type of parameters in the function definition in number and order.
7. Use of parameter names in the declaration in optional
8. If the function has no formal parameters, the list is written as void
9. The return type is optional when the function returns the int type data.
10. The type must be void if no value is returned.
11. When the declared type does not match with the type in the function definition, the compiler will produce an error.
12. We can not declare the same variable name inside the function body as we have taken in a parameter list |
Some More Examples :
Pass any two numbers to the function and show their sum
Ex1- #include<stdio.h> void main() { sum(10,30,450); //Call1, Ok, no Compilation Error sum(10); //call2, Ok, No Compilation error, not desired output sum(); //call3, Ok, No Compilation Error, not desired output sum(20,20.0); //Call4,Ok,No Error, not desired output } void sum(int x,int y){ printf(“%d + %d = %d”,x,y,x+y); }
Ex2- #include<stdio.h> void sum(int,int); //Function Declaration void main() { sum(10,30,450); //Call1, Compilation Error sum(10); //call2 , Compilation error sum(); //call3, Compilation Error sum(20,20.0); //Call4,Ok } void sum(int x,int y){ printf(“%d + %d = %d”,x,y,x+y); } |
Create a function that takes a number from main(), and show it’s a multiplication table
#include<stdio.h> void showTable(int); //declaration //void showTable(int x); void main() { //showTable(5); int a; printf("enter any number : "); showTable(a); } /* Function Definition */ void showTable(int x) { int i; printf("\nTable of %d\n",x); for(i=1;i<=10;i++) printf("\n%d",x*i); } |
How to determine the declaration, calling and defintion–
If the function has code block {} then it denotes the definition of a function. If the function has an only actual parameter, or values or constants (without any data type declaration) then it is calling. Calling always done inside another function or the main function. If there is at least one declarative statement (like variable declaration or return type declaration ) then it is a function declaration. |
Examples –
void addtion(); //declaration void addtion() { //definition ... } void addtion(int,int ) ; //declaration addtion(a,b); //calling addtion(int a,int b); //declaration addtion(int a,int b){ //defintion } addition(3,4); //calling addtion(a,3); //calling addtion(int x,int y,int z); //declaration
void sum(int x,int y,int z) { //defintion } sum(){ //defintion } |
Returning value from Function –
A Function may or may not send back any value to the calling function. If it does, it is done through the return statement. While it is possible to pass to the called function any number of values, the called function can only return one value per call, at the most.
The return statement can take one of the following forms-
return; OR return (expression); |
If we are going to return some value or expression from the function, then the type of function can never be void.
The return type of the function must be matched with the type of expression/value returning from the function.
Like-
If the function returns integer value-
int <Function>(<arguments>) { .. return (<int type data/expression>); } |
Note that the returned value is sent back to the calling function. We can use such functions as expressions inside the calling function. like inside printf, if, arithmetical expressions.. etc.
Ex –
Create a function that takes an integer argument and returns the square of the given number.
#include<stdio.h> //Declaration- int square(int x); void main(){ int a,s; printf(“enter any number :”); scanf(“%d”,&a); s = square(a); //calling printf(“Square = %d”,s); //or we can write smply inside printf- Printf("Square of %d = %d”, a,square(a)); //or we can use the function in expression- s =square(2) + square(3); printf(“Result = %d”,s); } // Function Definition : - int square(int x){ return x*x; } |
Creating Function to check any condition-
If we want to create such a function that check any condition and returns true(1) or false(0), then we should use some facts in mind-
i. The return type should be int
ii. The name should like- is XXXX() (not compulsory, but it is suggested)
iii. We should return 1 in case of true condition and 0 otherwise
iv. We can use this type of function inside if statement in the main program
Ex- Create a function that checks the even and odd number.
addtion(2,3); //calling #include<stdio.h> int isEven(int x); //Declaration void main() { int a; printf("enter any number : "); scanf("%d",&a); if(isEven(a)) //Calling of function inside if( ) printf("Number is Even "); else printf("Number is odd"); } /* Function Definition */ int isEven(int x){ /*if(x%2==0) return 1; else return 0; */ return !(x%2); } |
We can also write-
return (x%2==0?1:0); |
Note that, the return statement can not be used as expression inside the conditional operator.
So this is Invalid-
x%2==0?return (1) : return (0); |
Try it yourself-
• Create a function that returns the m to the power n Prototype is –
int power(int x,int y);
• Create a function that counts the total number of digits in a number.
Prototype is –
int countDigit(int x) ;
Write Driver Program(main function) to implement above functions
Categories of Functions :
On the Basis of the return type and parameter, the function can be divided into 4 categories :
1. Function with no arguments and no return value
// Takes Nothing Returns Nothing
For Example : clrscr()
Declaration:- [ Above Main() ] void <functionName>( ) ;
Definition:- [ Below Main() ] void <functionName>( ) { //Statements }
Calling:- [ within any function ] <functionName>();
|
# void square(); //declaration : void square(void); void main() { square(); //calling } void square() { //definition int a; printf(“enter any number :”); scanf(“%d”,&a); printf(“Square of %d = %d” , a, a*a); } |
2. Function with arguments and no return value
// Takes Something Returns Nothing
For Example : fopen(<file>,<mode>), strupr(<string>), strrev(<str>), ....
Declaration:- void <functionName>(<Type> <Var1>,<Type> <Var2>,... ); Definition:- void <functionName>(<Type> <Var1>,<Type> <Var2>,... ){ //Statements } Calling:- <functionName>(<value1>,<value2>,.. ); |
Ex- # void square(int x); //declaration: void square(int); void main() { square(5); //calling } void square(int x) { //definition printf(“Square of %d = %d” , x , x*x); } |
Wap to create a function "Table" that accepts a number and print its Table
#include<stdio.h> #include<conio.h> void table(int n); void main() { clrscr(); table(6); table(7); getch(); } void table(int n) |
Create a function that accepts a number and print its Factorial.
#include<stdio.h> #include<conio.h> void fact(long int x); void main() { clrscr(); fact(8); getch(); } void fact(long int x) { long int i,f=1; for(i=1;i<=x;i++) f = f * i; printf("\n Factorial of %ld is %ld ",x,f); } |
3. Function with no arguments but returns a value
// Takes Nothing Returns Something
For Example : getch(), getchar(), getche()
Declaration:- <data-type> <functionName>(void); Definition:- <data-type> <functionName>() { //Statements } Calling:- <varaible/> = <functionName>();
|
Ex- Create a function that reads an integer from keyboard and returns to a variable.
#include<stdio.h> int getint(void);
void main() { int a; printf("Enter a number : "); a =getint(); printf("Number is : %d",a); } int getint(void) { int n; scanf("%d",&n); return n; } |
4. Function with arguments and one return value
// Takes Something, Returns Something
Example : strlen(<string>), toupper(<char>), sqrt(n), pow(m,n)
Declaration:- <data-type> <functionName>(<formal parameter list>); Definition:- <data-type> <functionName>(<formal parameter list>) { ......... //Statements ......... Calling:- <varaible/> = <functionName>(<actual parameter list>); |
Ex-
Write a function power that computes x raised to the power y for integers x and y, and returns double type value.
#include<stdio.h> double power(int,int); //declaration
void main() { int x,y; double p; printf("enter x, y : "); scanf("%d %d",&x,&y); p=power(x,y); //calling printf("%d to power %d = %lf",x,y,p); } double power(int x,int y) { //definition of function double p; p=1.0; // for x to poer zero if(y>=0) while(y--) // compute positive power p *= x; else while(y++) //compute Negative power p /= x; return(p); //returns double type } |
Do Yourself !!
Create a function that accepts a number and return Number of digits
Create a function that accepts a number and return Number of even digits.
Create a function that accepts two numbers "x and y" and returns the value of x to the power y.
Create a function that accepts two numbers "x and y" and returns their LCM
Create a function that accepts a binary number and returns its Decimal Equivalent
User Define Functions : Part II
A Mechanism to Return multiple Values from Function !!
[Call By Value & Call By Reference]
Usually, a function can return only one value using a return statement.
If we want to get more information from a function, then we have to use the pointers as formal arguments and we have to pass the address of the actual variables into the function.
This type of formal arguments are called as ‘output parameters'
Output parameters(formal parameters) are declared with indirection operator(*) and actual parameters are followed by address of operator(&).
Inside the function body simply use the Indirection(*) Operator to access the value of the parameters. These output parameters directly work over the values of the actual parameter.
This type of function calling is known as Call By Reference.
Look at this Example:
#include<stdio.h> void math_operations(int x,int y,int *sum,int *diff);
void main() { int a,b,s,d; a=10; b=5; math_operations(a,b,&s,&d); printf("sum = %d \n diff = %d",s,d); } void math_operations(int x,int y,int *sum,int *diff) { *sum = x+y; *diff=x-y; } Output:
|
Note that :
- The actual arguments a and b are the input arguments, s and d are output arguments
- We have passed the momory location(address) of s and d the operator * in the function declaration, indicates these variables(*sum and *diff) are the pointer variables that stores the address instead of value of the actual arguments.
- Inside the function body we use indirection (*) Operator (also read as Content of ) that gives an indirect reference to a variable thourgh it’s address.
- Thus making any changes in the contents of output arguments(pointer variables) is directly effect the values of the actual arguments.
- This mechanism is called as Function call by Reference
Call by value in C
In call by value, original value (actual argument) is not modified.
In call by value, value being passed to the function is locally stored by the function parameter in stack memory location. In other word values of actual parameters are copied to the formal parameters of the called function. The called function works on the copy and not on the original values of passing parameters. If you change the value of function parameter, it is changed for the current function only. It will not change the value of variable inside the caller method such as main().
Let's try to understand the concept of call by value in c language by the example given below:
#include <stdio.h> #include <conio.h> void change(int);
void main() { int x=100; clrscr();
printf("Before function call x=%d \n", x); change(x);//passing value in function
printf("After function call x=%d \n", x); getch(); }
void change(int num) { printf("Before adding value inside function num=%d \n",num); num=num+100; printf("After adding value inside function num=%d \n", num); }
Output: Before function call x=100 Before adding value inside function num=100 After adding value inside function num=200 After function call x=100 |
Call by reference in C
In call by reference, the original value is modified because we pass a reference (address).
Here, the address of the value is passed in the function, so actual and formal arguments share the same address space. Hence, value changed inside the function is reflected inside as well as outside the function.
Note:
To understand the call by reference, you must have the basic knowledge of pointers.
Let's try to understand the concept of call by reference in c language by the example given below:
#include <stdio.h> #include <conio.h> void change(int *num); void main() { int x=100; clrscr(); printf("Before function call x=%d \n", x); change(&x); //passing reference in function printf("After function call x=%d \n", x); getch(); } void change(int *num) { printf("Before adding value inside function num=%d \n",*num); (*num) += 100; printf("After adding value inside function num=%d \n", *num); }
Output: Before function call x=100 Before adding value inside function num=100 After adding value inside function num=200 After function call x=200 |
To Do –
Create a function swap_number(int*,int*) , that exchanges the values of the given variables with each other.
Create a function that rounds off the value of the given float variable up to 2 decimal points.
void round_value(float *x)
Difference between call by value and call by reference
No. |
Call by value |
Call by reference |
1 |
A copy of value is passed to the function |
An address of value is passed to the function |
2 |
Changes made inside the function is not reflected on other functions |
Changes made inside the function is reflected outside the function also |
3 |
Actual and formal arguments will be created in different memory location |
Actual and formal arguments will be created in same memory location |
Note:
We do not use the indirection operator (*)with the pointer variable where we want to access address instead of value. Like – to use the pointer argument in scanf()
Like-
#include<stdio.h> void readNumber(int*); void main() { int a; readNumber(&a); printf(“Number = %d”,a); } void readNumber(int *x) { printf(“enter number :”); scanf(“%d”,x); //Not – scanf(“%d”,&x); } |
Here want to store the value over the Address of ‘a’ not the address of ‘x’. and the address of a is stored as the value of x. when we use indirection operator (*) with x, it denotes that the content of memory address hold by x, that is value of a.
Calling Function as Function argument :
we can also pass the function as the passing argument into another function. Like-
char nm[]= “ram”; char nm1[10];
strcpy(nm1,strrev(nm));
- We can only the function into another function if it returns any value
Ex-
#include<stdio.h> int sum(int,int); void main() { int a,b,c,d,s=0; a=20,b=30,c=10,d=50; /* Finding sum of all above 4 variables using Function */ s= sum(a,b); s = s + sum(c,d);
/* or we can simply write :- s = sum(a,b) + sum(c,d); */ /* Or we can also write - s = sum( sum(a,b) , sum(c,d)); */ printf(“ %d + %d + %d + %d = %d”,a,b,c,d,s); } int sum(int x,int y) { return (x+y); } |
Passing Array to Function: Array As Function Arguments :
One-Dimensional Array :
To pass a single-dimensional array to any function, we should follow some specific rules.
- In the Function declaration and definition, I must declare an array argument.
- The size of the array (as formal argument) does not need to be specified.
Like –
void showElements(int x[]);
- It is suggested to declare an additional integer variable to receive the number of elements to be accessed. As we don’t have any function to get the length of the array inside the function body.
Like-
void showElements(int size, int x[]) ;
or
void showElements(int x[] ,int size);
- The Function must be called by passing only the name of the array. Like-
main() { int a[] = {10,30,50,60}; int size = sizeof(a)/sizeof(a[0]); showElements(size,a); } |
Note that the sizeof(<array-name>) does not properly work on the array variable declared as function argument. It returns only the size of specified data type not the size of whole array.
Like- void showElements(int x[]) { int s = sizeof(x); //returns only 2 or 4 , depending on compiler int s1 = sizeof(x[0]); // same as above int a[] ={10,40,50}; int s2 = sizeof(a); //size of whole array : 6 or 12 int s3 = sizeof(a[0]); //size of single element : 2 or 4 } |
Let’s See Practical Implementation :
#include<stdio.h> void showElements(int size,int x[]); void main() { int a[] = {2,4,6,3,20}; int size = sizeof(a)/sizeof(a[0]); showElements(size,a); } void showElements(int size, int x[]) { int i; for(i=0;i<size;i++) printf("%d\n",x[i]); } |
Do Yourself !!
Create a function that takes an integer array as arguments and returns the sum of its elements. [ int get_sum(<array> ,<size>);]
Create a function that takes an array, size and element to be searched. The function should Return 1 if the element is found in array otherwise it will return return 0.
Prototype – int isFound(<array>, <key> , <size>) ; //key is a value which is to be searched
Create a function to pass any character array to the function and return the length of text/string passed to the function.
Ptototype :- int string_length(char[]);
Major Fact About Array-Arguments- In C, the name of array represents the address of its first element. By passing the array name, we are, in fact, passing the address of the aray to the called function. The array argument in the called function now refers to the same array stored in the memory. Therefore, any changes in the array in the called function will be refleceted in the original array. |
Example:
#include<stdio.h> void sort(int x[],int size); void show(int x[],int size);
void main(){ int a[]={3,5,1,6,8,9}; int i; sort(a, 6); show(a,6);
int b[] ={2,3,4,1,5,6,2,7,8,6,7,10,7,12}; int size=sizeof(b)/sizeof(b[0]); printf("\nUnsorted Array : "); show(b,size); sort(b,size); printf("\n List after sorting : \n"); show(b,size); } void show(int x[],int size){ int i; for(i=0;i<size;i++) printf("\n%d",x[i]); }
void sort(int x[],int size) { int i,j,k; for(i=0;i<size;i++) {
for(j=i+1;j<size;j++) { if(x[i]>x[j]){ k=x[i]; x[i]=x[j]; x[j]=k; } } } } |
Double-Dimensional Array :
To pass double dimensional array to any function, we should follow some specifi rules.
- In the function declaration and definition, we must indicate two dimensions by including two sets of brackets.
- The size of the second dimension must be specified.
- The function must be called by passing only the array name.
#include<stdio.h> void showMatrix(int r, int c, int a[][c]); void main() { int a[][3] = { {1,3,5} , {6,7,8} } ; show(2,3,a); } void showMatrix(int rows,int cols,int a[][cols]) { int i,j; for(i=0;i<rows;i++) { for(j=0;j<cols;j++) printf("%d ",a[i][j]); printf("\n"); } } |
Passing String to function : The strings are treated as a character array in C and therefore the rules for passing string to the functions are very similar to those passing array to function. Only the difference is that we can declare character array as well as character pointer in the function argument. Like- int string_length(char txt[]) ; or int string_length(char *txt); |
Nesting of Function:
When we call any UDF inside another UDF then it is called as Nesting of Function. C permits nesting of functions freely. We can call any function inside main() function as same way one function also calls another function.
Example:
#include<stdio.h>
int is_equal(char[],char[]); void string_reverse(char[]);
void main() { char nm1[] = "nitin", nm2[] = "amit"; if(is_equal(nm1,nm2)) printf("Both strings are equal"); else printf("Strings are different ");
//checking palindrome string:
char txt[20]; string_copy(txt,nm1); //printf("\n txt = %s",txt); string_reverse(txt); //printf("\ntxt = %s",txt); if(is_equal(txt,nm1)) printf("\nPalindrome string"); else printf("\n Not Palindrome string"); }
int is_equal(char x[], char y[]) { int i=0; int compare=1; while(1){ if(x[i]!=y[i]) { compare=0; break; }
if(x[i]=='\0' || y[i]=='\0') break; i++; } return compare; } void string_reverse(char x[]) { int i=strlen(x)-1; int j=0; char dx[20]; while(i>=0){ dx[j++]=x[i--]; } dx[j]='\0'; //terminating the string by \0 at end. string_copy(x,dx); //nesting of function } void string_copy (char x[],char y[]) { int i; for(i=0;y[i]!='\0';i++) x[i]=y[i];
x[i]='\0'; } |
Recursion :
Recursion is a special process of chaining. When a function calls itself, this is known as Recursion. Rersion works similar to the loop.
Ex- main() { printf(“\n Welcome pybron”); mian(); } |
Above program will produce output like-
Welcome pybron
Welcome pybron
..... //indefinitely
- It is used to solve such a problem where solution is expressed in terms of applying same solution to subsets of the problem.
- While Writing the recursive functions, we must have an if statement somewhere to force the function to return. Otherwise, the function will never return (cause infinite loop)
The recursion continues until some condition is met to prevent it.
Eample of finding factorial of given number without using loop (using recursion) :
#include<stdio.h> #include<conio.h> int factorial (int n) ;
void main () { int fact = 0; clrscr(); fact=factorial(5); printf("\n factorial of 5 is %d",fact); getch(); } int factorial (int n) { if ( n < 0) return -1; /*Wrong value*/ else if (n == 0) return 1; /*Terminating condition*/ else return (n * factorial (n -1)); }
Output: factorial of 5 is 120 |
We can understand the above program of the recursive method call by the figure given below.
Example: Sum of first n Natural Numbers Using Recursion
#include <stdio.h> int sum(int n); int main() { int number, result;
printf("Enter a positive integer: "); scanf("%d", &number); result = sum(number); printf("sum=%d", result); } int sum(int num) { if (num!=0) return num + sum(num-1); // sum() function calls itself else return num; } Output
Enter a positive integer: 3 6 |
Ex- Print Nth Term of Fibonacci Series :{1 1 2 3 5 8 ..}
Like-
1st Term : 1
2nd Term : 1
3rd Term : 2
4th Term : 3, and so on ...
Note that: 1st and 2nd terms are predefine and they are 1. All the next Nth term is calculated by adding term N-1 + N-2
Fib(N) =Fib(N-1) + fib(N-2)
For Example :
fib(3) = fib(2) + fib(1) => 1 + 1 = 2 {3rd term }
fib(4) = fib(3) + fib(2) => (fib(2) + fib(1) ) + fib(2) => (1 + 1 ) + 1 => 3 {4th term}
fib(5) => fib(4) + fib(3)
⇨ (fib(3)+fib(2)) + ( fib(2) + fib(1))
⇨ (fib(2)+fib(1)+ 1) + (1 + 1)
⇨ (1 + 1 + 1 ) + (1 + 1 )
⇨ 5 { 5th term}
fib(6) => fib(5) + fib(4)
⇨ .......
⇨ .......
⇨ 5 + 3 => 8 (6th term)
Program:
#include<stdio.h> int fib(int); void main() { int n=4; printf("%d",fib(n)); } int fib(int x) { if(x==1||x==2) return 1; else return fib(x-1) + fib(x-2); } |
Program: print the first 10 terms of the Fibonacci series.
#include<stdio.h> int fib(int); void main() { int i; for(i=1; i<=10; i++) printf("%d\t", fib(i)) ; }
int fib(int x) { if(x==1 || x==2) return 1; else return fib(x-1) + fib(x-2); } |
Program: GDC of two numbers without using a loop.
{using recursion}
#include <stdio.h> int hcf(int n1, int n2); int main() { int n1, n2; printf("Enter two positive integers: "); scanf("%d %d", &n1, &n2);
printf("G.C.D of %d and %d is %d.", n1, n2, hcf(n1,n2)); return 0; }
int hcf(int n1, int n2) { if (n2 != 0) return hcf(n2, n1%n2); else return n1; } |
Do Yourself !! ⇨ Calculate the power using recursion ⇨ Write a recursive function to sort an array ⇨ Write a recursive function to print first N natural numbers ⇨ Write a recursive function to print first N natural numbers in reverse order ⇨ Write a recursive function to calculate sum of digits of a number ⇨ Write a recursive function to calculate sum of squares of digits of a number ⇨ Write a recursive function to calculate sum of cubes of first N natural numbers ⇨ Write a recursive function to calculate the determinant of any order |
Storage Classes in C: Scope of variables
A storage class defines the scope (visibility) and life-time of variables and/or functions within a C Program. Basically storage class specifies four attributes of variable/function :
1. Storage location
2. Default value
3. Life time
4. Scope in program
There are four storage classes in C programming.
- auto
- extern
- static
- register
Here is the Brief Description about attributes/properties of each class :
Storage Classes |
Storage Place |
Default Value |
Scope |
Life-time |
auto |
RAM |
Garbage Value |
Local |
Within function |
extern |
RAM |
Zero |
Globa l |
Till the end of main program, Maybe declared anywhere in the program |
static |
RAM |
Zero |
Local |
Till the end of main program, Retains value between multiple functions call |
register |
Register |
Garbage Value |
Local |
Within function |
The auto Storage Class
The auto storage class is the default storage class for all local variables.
{ int mount; auto int month; } |
The example above defines two variables with in the same storage class. 'auto' can only be used within functions, i.e., local variables.
We can not access the automatic variables outside of their function.
We can also not declare any global variable as auto, all global variables are belong to external class by default.
We can also make a nested block, each block may contain the automatic variables which are not accessible outside of their block.
int a; //ok, it is not ‘auto’. It is global and belongs to external class auto int b; //Error -> we can not declare global variable as auto void show() { int a=10,b=20; //local to function show() , created each time when // the function will be called. printf("%d\n",a); //local value will be printed a++; //local value will be changed } main() { show(); //call1 show(); //call2 show(); //call2 { //nested block, only to test auto class int a=100; //again this is auto variable , limited only inside this block a=a+100; } //end of nested block, local values will be lost outside printf(“a = %d”,a); //the global a will be printed here /* printf(“b = %d”,b); // Error we can not access the local variable of function show(), inside another function. */ }
output: 10 10 10 a = 0 |
The register Storage Class
The register storage class is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and can't have the unary '&' operator applied to it (as it does not have a memory location).
{ register int miles; } |
The register should only be used for variables that require quick access such as counters. It should also be noted that defining 'register' does not mean that the variable will be stored in a register. It means that it MIGHT be stored in a register depending on hardware and implementation restrictions.
Usually, C put only the char or int type of variables in register. Other type variables are not supported by register class. They are indirectly transferred to RAM.
We can not declare any global variable in register storage class As it works for local scope.
void change(int *x) { *x= *x+10; } register int a; //Error, register can not be global void main() { int a=10; register int b=0; change(&a); printf("a = %d",a); //output : 20 b=b+10; //ok printf(“b = %d”,b); //output : 10 change(&b); //Error } |
The static Storage Class
The static storage class instructs the compiler to keep a local variable in existence during the life-time of the program instead of creating and destroying it each time it comes into and goes out of scope. Therefore, making local variables static allows them to maintain their values between function calls.
The static modifier may also be applied to global variables. When this is done, it causes that variable's scope to be restricted to the file in which it is declared.
void show() { static int a=10; //variable 'a' is created only once printf("%d\n",a); a++; } void main() { show(); //function call 1 show(); // function call 2 show(); // function call 3 }
Output: 10 11 12 |
In C programming, when static is used on a global variable, it causes only one copy of that member to be shared by all the functions of that file. Like this-
#include <stdio.h> void func(void); //function declaration static int count = 5; //global variable, can be accessed at anywhere main() { while(count--) { func(); } } /* function definition */ void func( void ) { static int i = 5; /* local static variable */ i++; printf("i is %d and count is %d\n", i, count); //i is local, count is global } |
When the above code is compiled and executed, it produces the following result −
i is 6 and count is 4 i is 10 and count is 0 |
Sum using Recursion and Static variable:
#include <stdio.h> int sum(int, int) ; //declarion of function void main() { int a,b; scanf("%d%d",&a,&b); printf("%d",sum(a,b)); } int sum(int a,int b) { static int s=0; if(b > 0){ s++; sum(a,b-1); } else if(a>0){ s++; sum(a-1,b); } return s; } |
The extern Storage Class
The extern storage class is used to give a reference of a global variable that is visible to ALL the program files. When you use 'extern', the variable cannot be initialized however, it points the variable name at a storage location that has been previously defined.
When you have multiple files and you define a global variable or function, which will also be used in other files, then extern will be used in another file to provide the reference of defined variable or function. Just for understanding, extern is used to declaring a global variable or function in another file.
- Extern is used to declaring a variable inside the function to make preference of the global variable that is declared/ defined after the function definition or anywhere inside the global section of same file or other files. If we use the variable inside function that is declared in the global section but after the function body, then it will generate an error.
Like-
main() { printf(“%d”,a); //Error } int a; |
we can rewrite this code this way-
main() { extern int a; printf(“%d”,a); //ok, output is 0 , default value of global a } int a; |
Ex-2
void show() {
|
the external declaration of 'a' inside the functions informs the compiler that 'a' is an integer type defined somewhere else in the program. Note that extern declaration does not allocate storage space for the variable.
We can not assign the value inside the function in the line of declaration extern variable.
We can assign the value in outside extern declaration.
The first time declaration must not be extern (it may be extern if you assign the value in global scope either with a declaration of after declaration, But we can not assign these global external variables inside the function)
void main() {
|
void main() {
extern int a; a=10; */ |
void main() { extern int a=20; //Error ,we can not initialize extern variable // very 1st time inside function printf("%d",a); } extern int a; |
void main() { extern int a; a=20; //Error, first time initalization not permitted inside function printf("%d",a); } extern int a; |
void main() { extern int a; a=20; //ok, not the first time intialization printf("%d",a); } int a; //ok , a is global and intialize with 0 |
The extern modifier is most commonly used when there are two or more files sharing the same global variables or functions as explained below.
First File: main.c
#include <stdio.h>
|
Second File: support.c
#include<stdio.h> extern int count; void write_extern(void) { printf("count is %d\n", count); } |
Here, extern is being used to declare count in the second file, whereas it has its definition in the first file, main.c.
count is 5 |
Command Line Arguments
Command Line arguments are the parameters suplied to a program when the program is invoked. This parameter may represent a file name (to be accessed) or other values (like- numbers, characters, strings...)
These arguments are handled by main() function.
To support command line argument, you need to change the structure of main() function is given below.
int main(int argc, char *argv[] ) |
Here, argc counts the number of arguments. It counts the file name as the first argument.
The argv[] contains the total number of arguments. The first argument is the file name always.
Example Let's see the example of command line arguments where we are passing one argument with file name.
#include <stdio.h> void main(int argc, char *argv[] ) { printf("Program name is: %s\n", argv[0]); if(argc < 2){ printf("No argument passed through command line.\n"); } else{ printf("First argument is: %s\n", argv[1]); } } |
It should be noted that argv[0] holds the name of the program itself and argv[1] is a pointer to the first command line argument supplied, and *argv[n] is the last argument. If no arguments are supplied, argc will be one, and if you pass one argument then argc is set at 2.
You pass all the command line arguments separated by a space, but if the argument itself has space then you can pass such arguments by putting them inside double quotes " ", or single quotes ''.
How to Run Above Program?
In Turbo C :
File | Dos Shell | Type : <program Name>.exe<argument list>
Ex- Program1.exe Hello Or Program1 Hello
Output: Program name is: program1 //You may also get the file name with path First argument is: hello |
If you pass many arguments, it will print only one. C:\Tc\Bin>program1 hello c how r u
Outputs: Program name is: program1 First argument is: hello
But if you pass many arguments within double quote, all arguments will be treated as a single argument only. C:\Tc\Bin>program1 "hello c how r u"
Output: Program name is: program1 First argument is: hello c how r u
You can write your program to print all the arguments. In this program, we are printing only argv[1], that is why it is printing only one argument |
Write a program that will show all the arguments provided through command line.
Write a program to add two numbers using command line arguments. If the name of file is ‘Sum.c’ then, command will be like this-
C:tc\bin>Sum 20 40
#include<stdio.h> #include<conio.h> int getInt(char *x);
void main(int argc,char *argv[]) { int a,b,c; clrscr(); if(argc<3) { printf("Please put 2 numbers "); return; } a= getInt(argv[1]); b= getInt(argv[2]); c = a+b; printf("%d",c); getch(); } int getInt(char *x) { int i=0,num=0;
while(x[i]!='\0'){ num = num*10 + (x[i]-48); i++; } return num; } |
C – Variable length argument
Variable length arguments are an advanced concept in C language offered by c99 standard. In c89 standard, fixed arguments only can be passed to the functions.
When a function gets a number of arguments that change at run time, we can go for variable length arguments.
It is denoted as … (3 dots) stdarg.h header file should be included to make use of variable length argument functions. |
Steps −
- Define a function with its last parameter as ellipses and the one just before the ellipses is always an int which will represent the number of arguments.
- Create a va_list type variable in the function definition. This type is defined in stdarg.h header file.
- Use int parameter and va_start macro to initialize the va_list variable to an argument list. The macro va_start is defined in stdarg.h header file.
- Use the va_arg macro and va_list variable to access each item in the argument list.
- Use a macro va_end to clean up the memory assigned to the va_list variable.
- Now let us follow the above steps and write down a simple function which can take the variable number of parameters and return their average −
#include <stdio.h> #include <stdarg.h> int add(int num,...); int main() { printf("The value from first function call = %d\n", add(2,2,3)); printf("The value from second function call=%d \n", add(4,2,3,4,5));
/*Note - In function add(2,2,3), first 2 is total number of arguments 2,3 are variable length arguments In function add(4,2,3,4,5), 4 is total number of arguments 2,3,4,5 are variable length arguments */ return 0; }
int add(int num,...) { va_list valist; int sum = 0; int i; va_start(valist, num); for (i = 0; i < num; i++) sum += va_arg(valist, int); va_end(valist); return sum; } |
Structures
The structure is a user-defined data type available in C that allows us to combine data items of different kinds.
Structures are used to represent a record. Suppose you want to keep track of your books in a library. You might want to track the following attributes about each book −
# Title
# Author
# Subject
# Book ID
More examples of such structure/records are :
Time: seconds, minutes, hours
Date: day, month, year
City : name,country,population
Address: name, house-no, street,city
Customer : name,telephone,city,category
....
Structure helps us to organize complex data in a more meaningful way.
Defining a Structure
To define a structure, you must use the struct statement. The struct statement defines a new data type, with more than one member. The format of the struct statement is as follows –
struct <structure tag> { member definition; member definition; ... member definition; } [one or more structure variables]; |
The structure tag is optional and each member definition is a normal variable definition, such as int i; or float f; or any other valid variable definition. At the end of the structure's definition, before the final semicolon, you can specify one or more structure variables but it is optional. Here is the way you would declare the Book structure −
struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } book; |
Common Rules:
- The Template is terminated by semicolon.
- Each memeber is declared separately
- We can not assign the value to any member inside the template
Declaring Structure Variable:
After defining structure format we can declare variables of that type. A structure variable declaration is similar to the declaration of other variable declaration. It includes the following elements –
- The keyword struct
- The Structure tag name
- List of variable names separated by commas.
- A terminating semicolon.
Example –
struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } ; struct Books book1, book2, book3; |
We can declare a structure variable inside any functions also.
It is also allowed to combine both the structure definition and variable declaration in one statement. Like this-
struct Books { char title[50]; char author[50]; char subject[100]; int book_id; }book1, book2, book3; |
- We do not need to specify the name of the structure for such type of variable declaration. The use of tag name is optional here. But further, we can not declare more structure type variables inside the main program. - A structure can also be defined inside the main() function. |
Example –
struct { char title[50]; char author[50]; char subject[100]; int book_id; } book1, book2, book3; |
Type-Defined Structures :
We can also provide a user define data type for newly defined memory. The keyword typedef is used to create a new name for any data type such as- int, float, char As well as for structure template.
struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } ; typedef struct Books book; //type defined book b1,b2,b3; //variable declaration |
Accessing Structure Members
To access any member of a structure, we use the member access operator (.). The member access operator is coded as a period between the structure variable name and the structure member that we wish to access.
#include <stdio.h> #include <string.h> struct Books { char title[50]; char author[50]; char subject[100]; int book_id; };
int main( ) { struct Books Book1; /* Declare Book1 of type Book */ struct Books Book2; /* Declare Book2 of type Book */ /* book 1 specification */ strcpy( Book1.title, "C Programming"); strcpy( Book1.author, "Nuha Ali"); strcpy( Book1.subject, "C Programming Tutorial"); Book1.book_id = 6495407;
/* book 2 specification */ strcpy( Book2.title, "Telecom Billing"); strcpy( Book2.author, "Zara Ali"); strcpy( Book2.subject, "Telecom Billing Tutorial"); Book2.book_id = 6495700;
/* print Book1 info */ printf( "Book 1 title : %s\n", Book1.title); printf( "Book 1 author : %s\n", Book1.author); printf( "Book 1 subject : %s\n", Book1.subject); printf( "Book 1 book_id : %d\n", Book1.book_id);
/* print Book2 info */ printf( "Book 2 title : %s\n", Book2.title); printf( "Book 2 author : %s\n", Book2.author); printf( "Book 2 subject : %s\n", Book2.subject); printf( "Book 2 book_id : %d\n", Book2.book_id); return 0; } |
Note that, in Dos Base compilers there may be problem to input any float type data into structure. If the floating type data is not liked then put the following code inside main() function – float f,*fp; fp = &f;
EX- #include<stdio.h> #include<conio.h> #include<string.h>
struct Record { int rollno; char name[20]; int age; float total_marks; } s; void main() { float f,*fp; fp = &f; //Not required for CodeBlock IDE clrscr(); printf(“Etner rollno :”); scanf(“%d”,&s.rollno); printf(“Enter name of student :”); scanf(“%s”,s.name); //or- gets(s.name); printf(“enter Total Marks Obtained outof 500 :”); scanf(“%f”,&s.total_marks); printf(“===== The Details are ========\n”); printf("Rollno : %d",s.rollno); printf("\nName : %s",s.name); printf("\nAge : %d",s.age); printf("\nMarks : %f",s.total_marks); getch(); } |
Three ways to access Members :We have used dot(.) operator to access the members of the structre variable. In fact, there are two other ways, which are used when use the pointer to structure. We will discuss this topic in details in the topic of pointers. Consider the following structure – typedef struct { int x; int y; } VECTOR; VECTOR v,*ptr; ptr = &v; Now the members can be accessed in three ways: 1. Using dot(.) notation : v.x, v.y 2. Using indirection notation : (*ptr).x, (*ptr).y 3. Using selection notation : ptr -> x, ptr -> y; |
Structure Initialization -
Like other data type structure, a variable can be initialized at compile time along with structure definition –
struct student{ int rollno; char name[20]; float per; } s= {101,"ram",67.34};
main(){ printf("%d %s %f",s.rollno,s.name,s.per); } /*OR*/ struct { int rollno; char name[20]; float per; } student1 = {101,"ram",67.34}, student2 ={102,"mohit",65.55};
void main(){ printf("%d %s %f",student1.rollno,student1.name,student1.per); printf("\n%d%s%f",student2.rollno,student2.name,student2.per); } |
There is a one to one correspondence between the members and their initialization. We can also initialize the structure variable inside the function also void main() { struct student s = {101,”amit”, 67.44}; ..... } |
Structure members cannot be initialized with a declaration. For example, the following C program fails in a compilation.
struct Point { int x = 0; // COMPILER ERROR: cannot initialize members here int y = 0; // COMPILER ERROR: cannot initialize members here };
The reason for the above error is simple, when a data type is declared, no memory is allocated for it. Memory is allocated only when variables are created. |
Partial Initialization It is permitted to have partial initialization. We can initialize the first few members and leave the remaining blank. The remaining members will be assigned by default values like- All numbers(int and floats) by 0 Characters and strings by ‘\0’.... .... void main() { struct students s= {101}; printf(“%d %s %f”, s.rollno,s.name,s.per); }
Output :-101 <space> 0.000000 |
designated Initialization Designated Initialization allows structure members to be initialized in any order. This feature has been added in C99 standard. struct Point { int x, y, z; }; int main() { // Examples of initializtion using designated initialization struct Point p1 = {.y = 0, .z = 1, .x = 2}; struct Point p2 = {.x = 20}; //or struct Point p2={20} printf ("x = %d, y = %d, z = %d\n", p1.x, p1.y, p1.z); printf ("x = %d, y = %d, z = %d\n", p2.x,p2.y,p2.z); return 0; } |
Copying and Comparing Structure Variable :
- Two variables of the same structure type can be copied the same way as an ordinary variables. struct students s1={101,”ram”,45.44};
struct students s2; s2=s1; //valid
- C does not permits any logical operation (comparision/relational) on structure variables. In this case we need to copare members individualy. s1==s2; //Not permitted s1 !=s2; //Not permitted
We can do like this- s1.rollno == s2.rollno; strcmp(s1.name,s2.name); .... |
Structure and Functions :
# Passing structure to function
# Returning structure from function
Structures as Function Arguments
You can pass a structure as a function argument in the same way as you pass any other variable or pointer.
#include <stdio.h> #include <string.h> struct Books { char title[50]; char author[50]; char subject[100]; int book_id; }; /* function declaration */ void printBook( struct Books book ); int main( ) { struct Books Book1; /* Declare Book1 of type Book */ struct Books Book2; /* Declare Book2 of type Book */ /* book 1 specification */ strcpy( Book1.title, "C Programming"); strcpy( Book1.author, "Nuha Ali"); strcpy( Book1.subject, "C Programming Tutorial"); Book1.book_id = 6495407;
/* book 2 specification */ strcpy( Book2.title, "Telecom Billing"); strcpy( Book2.author, "Zara Ali"); strcpy( Book2.subject, "Telecom Billing Tutorial"); Book2.book_id = 6495700;
/* print Book1 info */ printBook( Book1 ); /* Print Book2 info */ printBook( Book2 ); return 0; }
void printBook( struct Books book ) {
printf( "Book title : %s\n", book.title); printf( "Book author : %s\n", book.author); printf( "Book subject : %s\n", book.subject); printf( "Book book_id : %d\n", book.book_id); } |
Returning Structure from Function :
#include <stdio.h> #include <stdlib.h> struct Number{ int integer; float real; }; // passing structure to function void sum(struct Number p, struct Number q); void show(struct Number x);
// returning structure from function struct Number add(struct Number p, struct Number q);
//comparing structure int isEqual(struct Number x, struct Number y);
void main() { struct Number x ={12,23.2}; struct Number y ={10,22.22}; //sum(x,y); struct Number z = add(x,y); show(x); show(y); show(z);
if(isEqual(x,y)) printf("Both records are equal"); else printf("Both records are different "); }
void sum(struct Number p, struct Number q){ //int sum=0; printf("%d",p.integer+q.integer); printf(" : %f",p.real+q.real); }
struct Number add(struct Number p, struct Number q){
struct Number r; r.integer = p.integer+q.integer; r.real = p.real+q.real; return r; };
void show(struct Number x){ printf("%d : %g\n",x.integer,x.real); }
int isEqual(struct Number x,struct Number y ){ if(x.integer==y.integer && x.real==y.real) return 1; else return 0; } |
Basics of Pointers
Pointer is a derived data type in C. Pointer contains memory address as there value. Pointers can be used to access and manipulate data stored in the memory.
Pointer offers a number of benefits to the programmers, like- 1. Pointers are more efficient in handling arrays and data tables. 2. The pointer can be used to return multiple values from the function 3. They can be used for better management of character array (string) 4. Pointer allows the Dynamic Memory Allocation 5. Pointers provide an efficient tool for manipulating dynamic data structures such as - structures, linked list, queues, stacks, and trees. |
Accessing the Address of a variable [Reference (&) and Dereference (*) Operators]
# & (also called as Address Of) is the Reference operator.
# It is an Unary Operator
# Operand must be name of variable
# & operator gives address of variable.
Likewise, there is another operator that gets you the value from the address, it is called a dereference operator (*).
# * operator is also called in directional operator
# It is also a unary operator
# takes address as an argument
# * operator returns the contents of the given address (also read as content of)
Note:
The address is an unsigned numeric data that is represented by %u, No matter it is the address of int or char or long or float or double. A computer system having 64K memory will have its last address as 65535 [0 to 65535]
Example 1:
void main() { int a = 200; printf("%d",a); //200 printf("\n %u",&a); //Numeric Address Number of a printf("\n %d",*&a); //200 } |
Note:-
# The & operator can be used only with a simple variable or an array element (not with array name). Following are the illegal use of address operator :
# &125 (Pointing at constants)
# int x[10]; &x (pointing at array name)
# &(x+y) (Pointing at expression)
If x is an array then expression cab be –
&x[0]
&x[i+3]
# The name of array itself indicates the base address of the array.
Example 2 :
void main() { int a[10]; printf("%u",a); //base address of a printf("\n %u",&a[0]); //same as above statement } |
Under Laying concept of pointers:
Pointer constant
Pointer values
Pointer Variables
Memory addresses within a computer are referred to as pointer constant. We can not change them; we can only obtain the value through the address of operator(&). The value thus obtained is known as pointer value. The variable that contains a pointer value (Address of a variable) is called a pointer variable.
Declaring Pointer Variables :
Syntax:-
<data type> <pointer_variable>;
Example:
int *p; /* integer pointer */
float *x; /*float pointer*/
pointer variables contain garbage until we assign the address of other variable into them. We can also declare pointer like this- int* p; float* x; |
Initialization of Pointer Variables:
We can initialize the pointer by the address of any other variable of same data type.
Ex-
int x,*p;
p=&x;
we can also combine the initialization with the declaration, this is –
int x;
int *p = &x;
we can also write like this-
int x, *p = &x;
But this is an Error – int *p=&x, x;
The target variable ‘x’ must be declared first.
We could also define a pointer varibale with an initial value of NULL or 0 (zero).
int *p = NULL;
int *q = 0;
With the Exception of NULL and 0, no other constant value can be assigned to a pointer variale,following is the wrong initialization –
int *p = 1230;
Accessing Variable through Pointer :
The pointer holds the address of variable, so we use the %u specifier to show pointer’s value. Pointers value is the address of other variable.
int x,*p = &x;
printf(“Address of x = %u”,p); the above like is same as- printf(“Address of x = %u”,&x);
We can get the value of the variable (which is pointed by pointer) by using the Deferencing Operator (*) that is also read as ‘Content of’
int x,*p = &x;
printf(“Address of x = %u”,p);
printf(“\nValue of x = %d”, *p); //content of address hold by pointer p
Follwoings expressions are equivalent- *&x => x *p => x &*p => &x |
Examples based on Basics of Pointer:
Ex1-
void main() { int x,*p=&x; x=300; /*Fetching Value of variable */ printf("value of x : %d", x); printf("\n Value using pointer :%d ", *p); printf("\n value using Address :%d", *&x); /*Fetching Address of variable x */ printf("\nAddress of x : %u",&x); printf("\nAddress using pointer : %u",p); printf("\nAddress using De-ref. : %u",&*p); } |
Ex2 : -
#include<stdlib.h> void main() { int *p = NULL; int *q = 0; int *r = 200; //ERROR IN TURUBO C, only Null, Zero, and Address printf("%u",p); printf("\n%u",q); // printf("\n%u",r); } |
The pointer is also a variable, So it also takes some address in memory.
We can find the address of the pointer by using the AddressOf operator - &
Ex3-
void main() { int a = 200; int *p; char ch =’A’, *cp; cp = &ch; p = &a; printf("%d",a); //200 printf("\n %u",p); //Address of a printf("\n %d",*p); //value of a : 200 printf("\nAddress of Pointer %u",&p); //address of pointer:p printf("\nch=%c",ch); //value of ch :A printf(“\n content of *cp = %c”, *cp); //value of ch : A printf("\naddress of ch = %u",cp); //Address of ch printf("\naddress of cp =%u",&cp); //Address of pointer cp } |
We can also change the value of any variable with the help of pointer by using the De-referencing operator (*).
void main() { int a=10,*p; p=&a; *p = *p + 10; printf("Value of a : %d",a); } |
Pointers are flexible. We can make the same pointer to point to different variables in a different statement.
Ex-
void main() { int a=10,b=20,*p; p=&a; printf("the value of a = %d",*p); printf("Address of a = %u",p); p = &b; printf("\n the value of b = %d",*p); printf("\n address of b = %u",p); } |
Printing Address using- %u %p %d
For correct address output, you should use %p bcoz %d, %u will try to cast the address value to int and uint type respectively,
What if your computer is having an 8-byte address, in which case %d and %u will give the wrong output due to their memory limits.
% p will use the exact amount of storage needed for the address value.
% d and %u may give correct output on some systems if the address size fits into the respective data size of the specifier.
%p will give correct output irrespective of the address size.
Pointers to pointer: / Chain of Pointers -
It is possible to make a pointer point to another pointer. A variable that is a pointer to a pointer must be declared using an additional indirection operator symbol.
ex-
int *p1, **p2 , ***p3;
void main(){ int a,*p,**p1,***p2; a=30; p=&a; p1=&p; p2=&p1; printf("value of a Using Pointer : %d",*p); printf("\nValue of a Using p1 : %d",**p1); printf("\nValue of a Using p2 : %d",***p2); printf("\nAddress of a : %u",p); printf("\nAddress of p : %u \t %p \t %d", &p, p1, p1); printf("\nAddress of p1: %u \ t %p \t %d", &p1, p2, p2); printf("\nAddress of p2: %u \t %p \t %d",&p2, &p2, &p2); printf("\nAddress of Using all pointer : %u \t %u \t %u",p,*p1,**p2); } |
Note-
we can assign the pointer to another pointer of the same type. In this case, both pointers point to the same variable.
Ex-
void main() { int a=100,*p,*q; p=&a; q=p; *q = *q + 100; printf("Now Value of A : %d \t %d \t %d ",*p,*q,a); } |
Pointer Arithmetic:
- we can perform all the arithmetical operations over the Contents (values). But the only limited set of operations can be formed over the pointer variable or between pointers.
For example, if p1 and p2 are properly declared and initialized pointers, then the following statements are valid-
y = *p1 * p2; sum = sum + *p;
z= *p1/ *p2; //Note that there must be space between / and *
Rules of Pointer’s arithmetic :
- We can not make addition, Multiplication, and Division between two pointers. Following are invalid operations-
p1 / p2 p1 * p2 p1 + p2
- We can subtract one pointer from another like- p1-p2 is allowed
- Integers can be added to ( + or += ) and subtracted from ( – or -= ) pointers.
Like- p1+4 p1-2 are allowed.
- Pointer can be Incremented(++) and Decremented(--)
- Pointers can be compared using Relational operators (==, <, >, != etc.) if they point the object of same data type.
Note : Pointer arithmetic is meaningless unless performed on an array.
When the pointer is increased or decreased, by one, it will point the next/previous memory location of same type. If the pointer is integer then it will increase(++) by 4 Byte(next integer location) , If the Pointer is character then it will increase(++) by 1 byte(next character location) and so on... If the pointer is integer with initial value 2800, then after operation p1=p1+1 Or p1++, the value of p1 will be 2802 / 2804, and not 2801. That is, when we increment a pointer, its values is increased by the ‘length’ of the data type that it points to. |
Applications of Pointers Pointers and Array Pointers and String Pointers and Function Pointers and Structure Pointers and DMA |
Pointer to Array :
An array name acts like a pointer constant. The value of this pointer constant is the address of the first element.
For example, if we have an array named val then val and &val[0] can be used interchangeably.
So if we create a pointer to point any Array we need only to assign the name of array to it . Like-
int val[10];
int *p;
p = val; // or - p = &val[0];
printf(“Base address of Array : %u %u”, p, val);
Once we store the base address of array to a pointer, we can access the elements of an array using pointer also, like following ways-
*p, *(p+1), *(p+2) and so on.
We can also increase the pointer to move/set it to next buffer/index of the array.
*p : first element p++,
*p : next elements
...
....
Some More Examples :
#include <stdio.h> int main () {
/* an array with 5 elements */ double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0}; double *p; int i;
p = balance;
/* output each array element's value */ printf( "Array values using pointer\n");
for ( i = 0; i < 5; i++ ) { printf("*(p + %d) : %f\n", i, *(p + i) ); } printf( "Array values using balance as address\n"); for ( i = 0; i < 5; i++ ) { printf("*(balance + %d) : %f\n", i, *(balance + i) ); } printf( "Array values By Increasing Pointer \n"); for ( i = 1; i <=5; i++ ) { printf("%f\n", *p); p++; } return 0; } |
Pointer and 2-D Array :
- Any pointer created for a double dimensional array Basically points the base address of it’s first row
- When we increase the pointer by 1, it will start pointing to the next row of Array. That means it increases by the size of the row of the array. Like-
int a[][3]={{1,2,3},{4,5,6},{7,8,9}};
int *p = a;
p: pointer to first row
p+1: pointer to 2nd row of the array
p + i: pointer to ith row
*(p+i): pointer to first element of the ith row
*(p+i)+j: pointer to jth Element of the ith row
*(*(p+i)+j) : value stored in cell (i,j)
Example :
void main() { int a[][3]={{1,2,3},{4,5,6},{7,8,9}}; int *p; int i,j; printf("Address of First row :%u",a); printf("\nAddress of 2nd Row :%u",a+1); printf("\nAddress of 3rd Row :%u",a+2); /* value using pointer */ printf("\nValues :\n"); for(i=0;i<3;i++){ for(j=0;j<3;j++) printf("%d ", *(*(a+i)+j)); printf("\n"); } /* Accessing Value using pointer */ printf("\n Value of 2-D Array \n"); for(i=0;i<3;i++){ p=a+i; for(j=1;j<=3;j++) { printf("%d ", *p); p++; } printf("\n"); } } |
Another Explanation of Pointer and 2D Array :
Consider pointer notation for the two-dimensional numeric arrays. consider the following declaration
int nums[2][3] = { {16, 18, 20}, {25, 26, 27} }; |
In general, nums[i][j] is equivalent to *(*(nums+i)+j)
Pointer and String :
Pointer is used to create a dynamic length string variable. As we know that the C does not permit string type data by default. We can derive the string with the help of the character Array.
- We can declare the character pointer instead of character array
- A character pointer can point any string (base address)
- We can also print the string using character pointer using formate specifier %s
- We can also get the individual character from character pointer.
void main() { char *name="Amit Kumar"; char *n = name ; //copying base address to n printf("%s",name); printf("\n printing character by character \n"); while(*name !='\0'){ printf("%u : %c\n",name,*name); name++; } printf("Length of string : %d", name-n); } |
Pointer and 2D Strings:
void main() { char *name[]={"Amit Kumar","keshav","mahesh" ,"mukesh"}; int i; for(i=0;i<4;i++) printf("%s\n",*(name+i)); } |
Array Of Pointer :
We can create an array of a pointer. Pointer Array is used to store the address of multiple variables. It is also used to store a table string (as we have seen in the previous example).
Array of integer pointer:
Ex- 1
void main() { /* array of pointer */ int a,b,c,d,e; int *p[] = {&a,&b,&c,&d,&e};
int i; for(i=0;i<5;i++){ printf("enter number : %d : ",i+1); scanf("%d",p[i]); }
printf("values are : \n"); for(i=0;i<5;i++) printf("%d \t",*(p[i]));
/* it will also print same */ printf("\n%d %d %d %d %d",a,b,c,d,e); } |
Ex-2 (Method 2)
void main() { /* array of pointer */ int a,b,c,d,e; int *p[] = {&a,&b,&c,&d,&e}; int **q=p; //same as q=&p[i] int i; for(i=0;i<5;i++) { printf("enter number : %d : ",i+1); scanf("%d",*q); q++; }
q=p; printf("values are : \n"); for(i=0;i<5;i++) printf("%d \t",**(q+i));
printf("\n%d\t%d\t%d\t%d\t%d",a,b,c,d,e); } |
Example 3:
void main() { int a,b,c,d,e; int *p[] = {&a,&b,&c,&d,&e}; int **q=p; int i; for(i=0;i<5;i++){ printf("enter number : %d : ",i+1); scanf("%d",*(q+i)); } printf("values are : \n"); printf("Addr P\t Addr var\t Value of var\n"); for(i=0;i<5;i++) printf("\n%u : %u : %d",q+i,*(q+i),**(q+i)); //printf("\n%d\t%d\t%d\t%d\t%d",a,b,c,d,e); }
Ragged Array : |
Difference between ++*p, *p++ and *++p
simple rules about postfix ++, prefix ++ and * (dereference) operators
1. Precedence of prefix ++ and * is same. Associativity of both is right to left.
2. Precedence of postfix ++ is higher than both * and prefix ++. Associativity of postfix ++ is left to right.
Look At Following Examples:
Ex-1
// PROGRAM 1 #include <stdio.h> int main(void) { int arr[] = {10, 20}; int *p = arr; ++*p; printf("arr[0] = %d, arr[1] = %d, *p = %d", arr[0], arr[1], *p); return 0; } |
The expression ++*p has two operators of same precedence, so compiler looks for associativity. Associativity of operators is right to left. Therefore the expression is treated as ++(*p). Therefore the output is –
arr[0] = 11, arr[1] = 20, *p = 11 |
Ex-2
// PROGRAM 2 #include <stdio.h> int main(void) { int arr[] = {10, 20}; int *p = arr; *p++; printf("arr[0] = %d, arr[1] = %d, *p = %d", arr[0], arr[1], *p); return 0; } |
The expression *p++ is treated as *(p++) as the precedence of postfix ++ is higher than *. Therefore the output of second program is -
arr[0] = 10, arr[1] = 20, *p = 20 |
Ex 3:-
// PROGRAM 3 #include <stdio.h> int main(void) { int arr[] = {10, 20}; int *p = arr; *++p; printf("arr[0] = %d, arr[1] = %d, *p = %d", arr[0], arr[1], *p); return 0; } |
The expression *++p has two operators of same precedence, so compiler looks for associativity. Associativity of operators is right to left. Therefore the expression is treated as *(++p). Therefore the output of second program is
arr[0] = 10, arr[1] = 20, *p = 20 |
Pointers and Functions:
- Passing Pointer to Function
- Returning Pointer from function
- Pointer to function
Passing Pointer to Function / Pointer as Function Arguments
C programming allows passing a pointer to a function. To do so, simply declare the function parameter as a pointer type. And pass the address of the variables to the function. These types of passing arguments are also called Output Parameter and if we change the content of these arguments inside the function, the change is also reflected back to the actual argument. This concept is also known as Call By Reference
Like-
Program to Swap Elements Using Call by Reference
#include<stdio.h> void cyclicSwap(int *a,int *b,int *c); int main() { int a, b, c; printf("Enter a, b and c respectively: "); scanf("%d %d %d",&a,&b,&c); printf("Value before swapping:\n"); printf("a = %d \nb = %d \nc = %d\n",a,b,c); cyclicSwap(&a, &b, &c); printf("Value after swapping:\n"); printf("a = %d \nb = %d \nc = %d",a, b, c); return 0; }
void cyclicSwap(int *a,int *b,int *c) {
int temp; // swapping in cyclic order temp = *b; *b = *a; *a = *c; *c = temp; }
Output Enter a, b and c respectively: 1 |
Example 2: Exchanging the values of two variable using Pointer
# void main() { } |
Functions returning Pointer variables
A function can also return a pointer to the calling function. In this case, you must be careful, because local variables of function don't live outside the function. They have scope only inside the function. Hence if you return a pointer connected to a local variable, that pointer will be pointing to nothing when the function ends.
#include <stdio.h> int* larger(int*, int*); void main() { int a = 15; int b = 92; int *p; p = larger(&a, &b); printf("%d is larger",*p); }
int* larger(int *x, int *y) { if(*x > *y) return x; else return y; } |
Pointer to functions
It is possible to declare a pointer pointing to a function that can then be used as an argument in another function. A pointer to a function is declared as follows,
type (*pointer-name)(parameter);
Here is an example :
int (*sum)(); //legal declaration of pointer to function
int *sum(); //This is not a declaration of pointer to function
A function pointer can point to a specific function when it is assigned the name of that function.
int sum(int, int); int (*s)(int, int);
s = sum;
Here s is a pointer to a function sum. Now sum can be called using function pointer s along with providing the required argument values.
s (10, 20);
Example of Pointer to Function
#include <stdio.h> int sum(int x, int y) { return x+y; }
int main( ) { int (*fp)(int, int); fp = sum; int s = fp(10, 15); printf("Sum is %d", s);
return 0; } |
Example 2:
void sum(int ,int); void multiply(int ,int); int sqr(int); void print() { printf("\nHello world !!"); }
void main() { int result; void (*fun1) (int,int); int (*fun2) (int); void (*fun3) (); fun1 = sum; fun2 = sqr;
fun1(20,40); result=fun2(5); fun1 = multiply; fun1(20,40); printf("\n sqr = %d",result);
fun3 = print; fun3(); } |
void sum(int x,int y) { printf("\n%d + %d = %d",x,y,x+y); }
int sqr(int x) { return x*x; }
void multiply(int x,int y){ printf("\n%d * %d = %d",x,y,x*y); } |
Function returning Pointer:
int *fun() { static int a=30; return &a; } void main() { int *p = fun(); printf(“ %u %d”,p,*p) } |
Dangling, Void, Null and Wild Pointers
Dangling pointer
A pointer pointing to a memory location that has been deleted (or freed) is called dangling pointer. There are three different ways where Pointer acts as dangling pointer
Sample Program :
int *fun(){ int a=30; return &a; }
void main() { int *p = fun(); printf("%u , %d",p,*p); *p = *p + 10; printf("\n%u , %d",p,*p); } |
De-allocation of memory
// Deallocating a memory pointed by ptr causes // dangling pointer #include <stdlib.h> #include <stdio.h> int main() { int *ptr = (int *) malloc (sizeof(int));
// After below free call, ptr becomes a // dangling pointer free(ptr);
// No more a dangling pointer ptr = NULL; } |
Function Call
// The pointer pointing to local variable becomes // dangling when local variable is static. #include<stdio.h> int *fun() { // x is local variable and goes out of // scope after an execution of fun() is // over. int x = 5; return &x; }
// Driver Code
int main() { int *p = fun(); fflush(stdin);
// p points to something which is not // valid anymore printf("%d", *p); return 0; }
Output: A garbage Address |
The above problem doesn’t appear (or p doesn’t become dangling) if x is a static variable.
// The pointer pointing to local variable doesn't
// become dangling when local variable is static.
#include<stdio.h>
int *fun() { // x now has scope throughout the program static int x = 5;
return &x; } int main() { int *p = fun(); fflush(stdin);
// Not a dangling pointer as it points // to static variable. printf("%d",*p); }
Output: 5 |
Variable goes out of scope void main() { int *ptr; ..... ..... { int ch; ptr = &ch; } ..... // Here ptr is dangling pointer } |
Void pointer
Void pointer is a specific pointer type – void * – a pointer that points to some data location in storage, which doesn’t have any specific type. Void refers to the type. Basically the type of data that it points to is can be any. If we assign the address of char data type to void pointer it will become char Pointer, if int data type then int pointer and so on. Any pointer type is convertible to a void pointer hence it can point to any value.
Important Points
void pointers cannot be dereferenced. It can however be done using typecasting the void pointer Pointer arithmetic is not possible on pointers of void due to lack of concrete value and thus size.
Example:
#include<stdlib.h> int main() { int x = 4; float y = 5.5; //A void pointer void *ptr; ptr = &x;
// (int*)ptr - does type casting of void // *((int*)ptr) dereferences the typecasted // void pointer variable. printf("Integer variable is = %d", *( (int*) ptr) );
// void pointer is now float
ptr = &y; printf("\nFloat variable is= %f", *( (float*) ptr) );
return 0; } Output: |
NULL Pointer
NULL Pointer is a pointer which is pointing to nothing. In case, if we don’t have address to be assigned to a pointer, then we can simply use NULL.
#include <stdio.h> int main() { // Null Pointer int *ptr = NULL; printf("The value of ptr is %u", ptr); return 0; } Output : |
Important Points
NULL vs Uninitialized pointer – An uninitialized pointer stores an undefined value. A null pointer stores a defined value, but one that is defined by the environment to not be a valid address for any member or object. NULL vs Void Pointer – Null pointer is a value, while void pointer is a type |
Wild pointer
A pointer which has not been initialized to anything (not even NULL) is known as wild pointer. The pointer may be initialized to a non-NULL garbage value that may not be a valid address.
int main() { int *p; /* wild pointer */ int x = 10; // p is not a wild pointer now p = &x; return 0; } |
Pointers and Constants:
- Pointer to constant
- Constant pointer
constant variables are the one whose values cannot be changed. For example:
const int a = 10;
The above line declares a constant variable 'a' with value 10. Now, since its a constant variable so any attempt to change the value of a will be disregarded by compiler.
Lets try :
#include<stdio.h> int main(void) { const int a = 10; a++; //error return 0; } |
The above program tries to change the value of constant variable 'a'. Lets see what the compiler has to say :
error: increment of read-only variable ‘a’
We see that the compiler clearly says that we cannot change value of a read- only(const) variable 'a'.
Now, ther interesting part. Can we have a mechanism through which we can change the value of 'a' without the compiler complaining???
Hmmmmm...lets try pointers. Have a look at the following code :
#include<stdio.h> int main(void) { const int a = 10; int* ptr = &a;
printf("\n value at ptr is : [%d]\n",*ptr); printf("\n Address pointed by ptr : [%p]\n",(unsigned int*)ptr);
*ptr = 11; printf("\n value at ptr is : [%d]\n",*ptr);
return 0; } |
Now, this is left as an exercise to the readers to see if the above program actually works?? If yes, then whats the reason??
Conclusion
To conclude, pointers are a powerful mechanism in 'C' to manipulate memory locations and values present at these locations. 'C' provides the concept of constant pointers and pointer to constants to have control on how pointers are being manipulated.
Constant Pointers :
These type of pointers are the one which cannot change address they are pointing to. This means that suppose there is a pointer which points to a variable (or stores the address of that variable). Now if we try to point the pointer to some other variable (or try to make the pointer store address of some other variable), then constant pointers are incapable of this.
A constant pointer is declared as : int *const ptr; ( the location of 'const' make the pointer 'ptr' as constant pointer) |
Pointer to Constant :
These type of pointers are the one which cannot change the value they are pointing to. This means they cannot change the value of the variable whose address they are holding.
A pointer to a constant is declared as :
const int *ptr; (the location of 'const' makes the pointer 'ptr' as a pointer to constant.) |
Examples:
Constant Pointer :
#include<stdio.h> main() { int a[] = {10,11}; int* const ptr = a; *ptr = 20; //Ok, No error printf("\n value at ptr is : %d\n",*ptr); printf("\n Address pointed by ptr : %p\n",ptr); ptr++; //This will Make Error , We can not update pointer printf("\n Address pointed by ptr : [%p]\n",(unsigned int*)ptr); } |
Ex 2: Pointer to Constat:
#include<stdio.h> int main(void) { int a[] = {10,20}; const int* ptr = a; printf("\n value at ptr is : [%d]\n",*ptr); printf("\n Address pointed by ptr : [%p]\n",(unsigned int*)ptr); ptr++; //OK *ptr = 11; //Error , we can not change Content printf("\n value at ptr is : [%d]\n",*ptr); printf("\n Address pointed by ptr : [%p]\n",(unsigned int*)ptr); return 0; } |
Write a Program Difference between const char *p, char * const p and const char * const p
There is a lot of confusion when char, const, *, p are all used in different permutaions and meanings change according to which is placed where. Following article focus on differentiation and usage of all of these.
The qualifier const can be applied to the declaration of any variable to specify that its value will not be changed. const keyword applies to whatever is immediately to its left. If there is nothing to its left, it applies to whatever is immediately to its right.
const char *ptr : This is a pointer to a constant character. You cannot change the value pointed by ptr, but you can change the pointer itself. “const char *” is a (non-const) pointer to a const char. // C program to illustrate // char const *p #include<stdio.h> #include<stdlib.h>
int main() {
char a ='A', b ='B'; const char *ptr = &a;
//*ptr = b; illegal statement (assignment of read-only location *ptr)
// ptr can be changed printf( "value pointed to by ptr: %c\n", *ptr); ptr = &b; printf( "value pointed to by ptr: %c\n", *ptr); }
Run on IDE
Output:
value pointed to by ptr:A value pointed to by ptr:B
NOTE: There is no difference between const char *p and char const *p as both are pointer to a const char and position of ‘*'(asterik) is also same.
const * char ptr : This is a constant pointer to non-constant character. You cannot change the pointer p, but can change the value pointed by ptr.
// C program to illustrate // char* const p #include<stdio.h> #include<stdlib.h>
int main() {
char a ='A', b ='B'; char *const ptr = &a; printf( "Value pointed to by ptr: %c\n", *ptr); printf( "Address ptr is pointing to: %d\n\n", ptr);
//ptr = &b; illegal statement (assignment of read-only variable ptr)
// changing the value at the address ptr is pointing to *ptr = b; printf( "Value pointed to by ptr: %c\n", *ptr); printf( "Address ptr is pointing to: %d\n", ptr); }
Run on IDE Output:
Value pointed to by ptr: A Address ptr is pointing to: -1443150762 Value pointed to by ptr: B Address ptr is pointing to: -1443150762 NOTE: Pointer always points to same address, only the value at the location is changed.
const char * const ptr : This is a constant pointer to constant character. You can neither change the value pointed by ptr nor the pointer ptr. // C program to illustrate //const char * const ptr #include<stdio.h> #include<stdlib.h>
int main() {
char a ='A', b ='B'; const char *const ptr = &a; printf( "Value pointed to by ptr: %c\n", *ptr); printf( "Address ptr is pointing to: %d\n\n", ptr);
// ptr = &b; illegal statement (assignment of read-only variable ptr) // *ptr = b; illegal statement (assignment of read-only location *ptr)
} Run on IDE Output:
Value pointed to by ptr: A Address ptr is pointing to: -255095482
NOTE: char const* *const ptr is same as const char *const ptr |
Near Pointer , far Pointer, Huge Pointer These are the Old types of pointer , Designed to work with 16 Bit(DOS) based C compiler |
Pointer and Structure :
We have already learned that a pointer is a variable which points to the address of another variable of any data type like int, char, float etc. Similarly, we can have a pointer to structures, where a pointer variable can point to the address of a structure variable. Here is how we can declare a pointer to a structure variable.
struct dog { char name[10]; char breed[10]; int age; char color[10]; }; struct dog spike; // declaring a pointer to a structure of type struct dog struct dog *ptr_dog
This declares a pointer ptr_dog that can store the address of the variable of type struct dog. We can now assign the address of variable spike to ptr_dog using & operator. ptr_dog = &spike; Now ptr_dog points to the structure variable spike. |
Accessing members using Pointer
There are two ways of accessing members of structure using pointer:
- 1. Using indirection (*) operator and dot(.) operator.
- 2. Using arrow (->) operator or membership operator.
Using Indirection (*) Operator and Dot(.) Operator
At this point ptr_dog points to the structure variable spike, so by dereferencing it we will get the contents of the spike.This means spike and *ptr_dog are functionally equivalent.To access a member of structure write *ptr_dog followed by a dot(.) operator, followed by the name of the member. For example:
(*ptr_dog).name - refers to the name of dog
(*ptr_dog).breed - refers to the breed of dog
and so on.
Parentheses around *ptr_dog are necessary because the precedence of dot(.) operator is greater than that of indirection (*) operator.
Using arrow operator (->)
The above method of accessing members of the structure using pointers is slightly confusing and less readable, that's why C provides another way to access members using the arrow (->) operator.To access members using arrow (->) operator write pointer variable followed by -> operator, followed by name of the member.
ptr_dog->name - refers to the name of dog
ptr_dog->breed - refers to the breed of dogand so on.
Here we don't need parentheses, asterisk(*) and dot(.) operator.This method is much more readable and intuitive.
We can also modify the value of members using pointer notation.
strcpy(ptr_dog->name, "new_name");
Here we know that the name of the array (ptr_dog->name) is a constant pointer and points to the 0th element of the array. So we can't assign a new string to it using assignment operator(=), that's why strcpy() function is used.
--ptr_dog -> age;
In the above expression precedence of arrow operator (->) is greater than that of prefix decrement operator (--), so first -> operator is applied in the expression then its value is decremented by 1.
The following program demonstrates how we can use a pointer to structure.
#include<stdio.h>
struct dog { char name[10]; char breed[10]; int age; char color[10]; };
int main() { struct dog my_dog = {"tyke", "Bulldog", 5, "white"}; struct dog *ptr_dog; ptr_dog = &my_dog;
printf("Dog's name: %s\n", ptr_dog->name); printf("Dog's breed: %s\n", ptr_dog->breed); printf("Dog's age: %d\n", ptr_dog->age); printf("Dog's color: %s\n", ptr_dog->color);
// changing the name of dog from tyke to jack strcpy(ptr_dog->name, "jack");
// increasing age of dog by 1 year ptr_dog->age++;
printf("Dog's new name is: %s\n", ptr_dog->name); printf("Dog's age is: %d\n", ptr_dog->age);
// signal to operating system program ran fine return 0; } |
Expected Output: Dog's name: tyke Dog's breed: Bulldog Dog's age: 5 Dog's color: white After changes Dog's new name is: jack Dog's age is: 6 |
Pointers as Structure Member in C
We can also have a pointer as a member of the structure. For example:
struct test { char name[20]; int *ptr_mem; }; struct test t1, *str_ptr = &t1; |
Here ptr_mem is a pointer to int and a member of structure test.
There are two ways in which we can access the value (i.e address) of ptr_mem:
1. Using structure variable - t1.ptr_mem
2. Using pointer variable - str_ptr->ptr_mem
Similarly, there are two ways in which we can access the value pointed to by ptr_mem.
1. Using structure variable - *t1.ptr_mem
2. Using pointer variable - *str_ptr->ptr_mem
Since the precedence of dot(.) operator is greater than that of indirection(*) operator, so in the expression *t1.ptr_mem the dot(.) is applied before the indirection(*) operator. Similarly in the expression *str_ptr->ptr_mem, the arrow (->) operator is applied followed by indirection(*) operator.
The following program demonstrates everything we have learned so far in this lesson.
#include<stdio.h> struct student { char *name; int age; char *program; char *subjects[5]; }; int main() { struct student stu = { "Lucy", 25, "CS", {"CS-01", "CS-02", "CS-03", "CS-04", "CS-05" } }; struct student *ptr_stu = &stu; int i; printf("Accessing members using structure variable: \n\n"); printf("Name: %s\n", stu.name); printf("Age: %d\n", stu.age); printf("Program enrolled: %s\n", stu.program); for(i = 0; i < 5; i++) { printf("Subject : %s \n", stu.subjects[i]); } printf("\n\nAccessing members using pointer variable: \n\n"); printf("Name: %s\n", ptr_stu->name); printf("Age: %d\n", ptr_stu->age); printf("Program enrolled: %s\n", ptr_stu->program); for(i = 0; i < 5; i++) { printf("Subject : %s \n", ptr_stu->subjects[i]); } // signal to operating system program ran fine return 0; }
Expected Output: Accessing members using structure variable: Subject : CS-02 |
Dynamic Memory Allocation
The malloc() Function in C
Up until now in our programs, we have been using static memory allocation. In static memory allocation the size of the program is fixed, we can not increase or decrease size while the program is running. So why would we actually want to increase or decrease the size of the program while the program is running?
Consider the following situation.
Let's say we are creating a program to calculate the average marks of students in a class. Here is one way to approach the problem.
#include<stdio.h> #define STUDENT 100 int main() { float marks[STUDENT], sum = 0; int i; for(i = 0; i < STUDENT; i++) { printf("Enter marks for %d student: ", i+1); scanf("%f", &marks[i]); } // calculate sum for(i = 0; i < STUDENT; i++) { sum += marks[i]; } printf("\nAverage marks = %.2f\n", sum/STUDENT ); // signal to operating system everything works fine return 0; } |
The important thing to notice about the program is the size of the student is fixed which is 100.
At this point, two types of problems may arise. Let's say 20 more students joined the class? Since our program can only handle 100 students, one way to solve this problem is to change the size of the student, recompile, and run the program again. What if after some time 50 more students joined the class, then we have to modify the program and recompile again. Certainly, this is not the ideal way.
Let's face another side of the coin. What if 40 students left the class. In this case number of values to be stored is less than the size of the array, so (40*4 = 160 bytes) memory would be wasted.
As you can see our program due to the fixed size of the array facing two major shortcomings.
So what's the solution?
The solution is to use dynamic memory allocation. It simply means that we can allocate/release memory whenever we need it while the program is running.
The allocation/release of memory is done with the help of three functions defined in header file stdlib.h.
Whenever you call these functions they take memory from a memory area called heap and release the memory whenever not required, so it can be reused.
The malloc() function #
It is used to allocate memory at run time. The syntax of the function is:
Syntax: void *malloc(size_t size);
This function accepts a single argument called size which is of type size_t. The size_t is defined as an unsigned int in stdlib.h, for now, you can think of it as an alias to unsigned int.
If successful, malloc() returns a void pointer to the first allocated byte of memory. Before you can use the pointer you must cast it to the appropriate type. So malloc() function is generally used as follows:
p = (datatype *)malloc(size);
where the p is a pointer of type (datatype *) and size is memory space in bytes you want to allocate.
Let's take a simple example:
Suppose we want to allocate 20 bytes(for storing 5 integers, where the size of each integer is 4 bytes) dynamically using malloc(). Here is how we can do it:
int *p; // p is pointer to int or (int*)
p = (int*)malloc(20); // allocate 20 bytes
This statement allocates 20 contiguous bytes of memory from the heap and assigns the address of the first byte to variable p. Notice how void pointer returned from the malloc() function is typecasted and then assigned to p. Memory allocated contains garbage value so do not try to dereference it before assigning proper values to it.
As we know the size of data types in C vary from system to system, that's why malloc() function is used in conjunction with the size of operator.
int *p; // p is pointer to int or (int*)
p = (int*)malloc(5*sizeof(int)); // allocate sufficient memory for 5 integers
We are still allocating 20 bytes of memory but now our program is portable (i.e it can be run on the various operating system without any modification.) and certainly more readable.
Now we have p pointing to the first byte of allocated memory, we can easily access subsequent bytes using pointer arithmetic.
When the heap runs out of free space, malloc() function returns NULL. So before using the pointer variable in any way, we must first always check the value returned by malloc() function.
if(p == NULL) {
printf("Memory allocation failed"); exit(1); // exit the program } |
Let's rewrite the program to calculate the average marks of students in a class using the malloc() function.
#include<stdio.h> #include<stdlib.h>
int main() {
float *p, sum = 0; int i, n;
printf("Enter the number of students: "); scanf("%d", &n);
// allocate memory to store n variables of type float p = (float*)malloc(n*sizeof(float));
// if dynamic allocation failed exit the program if(p==NULL) {
printf("Memory allocation failed"); exit(1); // exit the program } // ask the student to enter marks for(i = 0; i < n; i++) {
printf("Enter marks for %d student: ", i+1); scanf("%f", p+i); }
// calculate sum for(i = 0; i < n; i++) { sum += *(p+i); }
printf("\nAverage marks = %.2f\n", sum/n);
// signal to operating system program ran fine return 0; }
Expected Output:
1st run:
Enter the number of students: 4 Enter marks for 1 student: 12.12 Enter marks for 2 student: 34.14 Enter marks for 3 student: 43.1 Enter marks for 4 student: 45.87
Average marks = 33.81 2nd run:
Enter the number of students: 2 Enter marks for 1 student: 13.41 Enter marks for 2 student: 56.31
Average marks = 34.86 |
The calloc() Function in C
C provides another function to dynamically allocate memory which sometimes better than the malloc() function. Its syntax is:
Syntax: void *calloc(size_t n, size_t size);
It accepts two arguments the first argument is the number of the element, and the second argument is the size of elements. Let's say we want to allocate memory for 5 integers, in this case, 5 is the number of elements i.e n and the size of each element is 4 bytes (may vary from system to system). Here is how you can allocate memory for 5 integers using calloc().
int *p;
p = (int*)calloc(5, 4);
This allocates 20 bytes of contiguous memory space from the heap and assigns the address of first allocated byte to pointer variable p.
Here is how you can achieve the same thing using malloc() function:
int *p;
p = (int*)malloc(5 * 4);
To make our program portable and more readable sizeof() operator is used in conjunction with calloc().
int *p;
p = (int*)calloc(5, sizeof(int));
So apart from the number of arguments is there any other difference between calloc() and malloc() ?
The difference between calloc() and malloc() function is that memory allocated by malloc() contains garbage value while memory allocated by calloc() is always initialized to 0.
The following program uses calloc() to create dynamic (it can vary in size at runtime) 1-D array.
#include<stdio.h> #include<stdlib.h> int main() {
int *p, i, n;
printf("Enter the size of the array: "); scanf("%d", &n);
p = (int*)calloc(n, sizeof(int));
if(p==NULL) {
printf("Memory allocation failed"); exit(1); // exit the program }
for(i = 0; i < n; i++) { printf("Enter %d element: ", i); scanf("%d", p+i); }
printf("\nprinting array of %d integers\n\n", n);
// calculate sum
for(i = 0; i < n; i++) { printf("%d ", *(p+i)); } // signal to operating system program ran fine return 0; }
Expected Output: 1st run:
Enter the size of the array: 5 Enter 0 element: 13 Enter 1 element: 24 Enter 2 element: 45 Enter 3 element: 67 Enter 4 element: 89
printing array of 5 integers 13 24 45 67 89
2nd run:
Enter the size of the array: 2 Enter 0 element: 11 Enter 1 element: 34
printing array of 2 integers 11 34 |
The realloc() Function in C
Let's say we have allocated some memory using malloc() and calloc(), but later we find that memory is too large or too small. The realloc() function is used to resize allocated memory without losing old data. It's syntax is:
Syntax: void *realloc(void *ptr, size_t newsize);
realloc() function accepts two arguments, the first argument ptr is a pointer to the first byte of memory that was previously allocated using malloc() or calloc() function.The newsize parameter specifies the new size of the block in bytes, which may be smaller or larger than the original size. And size_t is just an alias of unsigned int defined inside stdlib.h header file.
Let's take an example:
int *p;
p = (int*)malloc(5*sizeof(int)); // allocate memory for 5 integers
Suppose that sometimes later we want to increase the size of the allocated memory to store 6 more integers. To do that, we have to allocate an additional 6 x sizeof(int) bytes of memory. Here is how you will call realloc() function to allocate 6 x sizeof(int) bytes of memory.
// allocate memory for 6 more integers i.e a total of 11 integers
p = (int*)realloc(p, 11*sizeof(int));
If sufficient memory (in this case 6 * sizeof(int) bytes) is available following already used bytes then realloc() function allocates only allocates 6 * sizeof(int) bytes next to already used bytes. In this case, the memory pointed to by ptr doesn't change. It is important to note that in doing so old data is not lost but newly allocated bytes are uninitialized.
On the hand, if sufficient memory (in this case 6 * sizeof(int) bytes ) is not available following already used bytes then realloc() re-allocates entire 11 * sizeof(int) bytes of memory somewhere else in the heap and copies the content from the old memory block to the new memory block. In this case, the address pointed to by ptr changes.
realloc-function
If realloc() failed to expand memory as requested then it returns NULL, the data in the old memory remains unaffected.
The following program demonstrates the realloc() function.
#include<stdio.h> #include<stdlib.h> int main() { int *p, i, n;
printf("Initial size of the array is 4\n\n"); p = (int*)calloc(4, sizeof(int));
if(p==NULL) { printf("Memory allocation failed"); exit(1); // exit the program }
for(i = 0; i < 4; i++) { printf("Enter element at index %d: ", i); scanf("%d", p+i); }
printf("\nIncreasing the size of the array by 5 elements ...\n ");
p = (int*)realloc(p, 9 * sizeof(int));
if(p==NULL) { printf("Memory allocation failed"); exit(1); // exit the program }
printf("\nEnter 5 more integers\n\n");
for(i = 4; i < 9; i++) { printf("Enter element at index %d: ", i); scanf("%d", p+i); } printf("\nFinal array: \n\n");
for(i = 0; i < 9; i++) { printf("%d ", *(p+i) ); } // signal to operating system program ran fine return 0; }
Expected Output:
Initial size of the array is 4
Enter element at index 0: 11 Enter element at index 1: 22 Enter element at index 2: 33 Enter element at index 3: 44
Increasing the size of the array by 5 elements ...
Enter 5 more integers
Enter element at index 4: 1
Enter element at index 5: 2 Enter element at index 6: 3 Enter element at index 7: 4 Enter element at index 8: 5
Final array: 11 22 33 44 1 2 3 4 5 |
Free() function in C
Linked List in C
The sprintf() and sscanf() Function in C
The sprintf() Function in C
The sprintf() works just like printf() but instead of sending output to console it returns the formatted string.
Syntax: int sprintf(char *str, const char *control_string, [ arg_1, arg_2, ... ]);
The first argument to sprintf() function is a pointer to the target string. The rest of the arguments are the same as for printf() function.
The function writes the data in the string pointed to by str and returns the number of characters written to str, excluding the null character. The return value is generally discarded. If an error occurs during the operation it returns -1.
The following program demonstrates how to use sprintf() function.
#include<stdio.h> #include<string.h> int factorial(int );
int main() { int sal; char name[30], designation[30], info[60];
printf("Enter your name: "); gets(name);
printf("Enter your designation: "); gets(designation);
printf("Enter your salary: "); scanf("%d", &sal);
sprintf(info, "Welcome %s !\nName: %s \nDesignation: %s\nSalary: %d", name, name, designation, sal);
printf("\n%s", info);
// signal to operating system program ran fine return 0; }
Expected Output:
Enter your name: Sim Enter your designation: Developer Enter your salary: 230000
Welcome Sim ! Name: Sim Designation: Developer Salary: 230000 |
Another important use of sprintf() function is to convert integer and float values to strings.
#include<stdio.h> #include<string.h> int factorial(int );
int main() { char s1[20]; char s2[20];
int x = 100; float y = 300;
sprintf(s1, "%d", x); sprintf(s2, "%f", y);
printf("s1 = %s\n", s1); printf("s2 = %s\n", s2);
// signal to operating system program ran fine return 0; }
Expected Output:
s1 = 100 s2 = 300.000000 |
The sscanf() Function in C
The sscanf() function allows us to read formatted data from a string rather than standard input or keyboard. Its syntax is as follows:
Syntax: int sscanf(const char *str, const char * control_string [ arg_1, arg_2, ... ]);
The first argument is a pointer to the string from where we want to read the data. The rest of the arguments of sscanf() is the same as that of scanf(). It returns the number of items read from the string and -1 if an error is encountered.
The following program demonstrates how sscanf() works:
#include<stdio.h> #include<string.h> int main() { char *str = "Tom Manager 28"; char name[10], designation[10]; int age, ret;
ret = sscanf(str, "%s %s %d", name, designation, &age);
printf("Name: %s\n", name); printf("Designation: %s\n", designation); printf("Age: %d\n", age);
// signal to operating system program ran fine return 0; }
Expected Output:
Name: Tom Designation: Manager Age: 28 |
How it works?
In line 6, we have declared and initialized variable str of type pointer to char.
In line 7, we have declared two arrays of character name and designation of size 10 characters.
In line 8, we have declared variable age of type int.
In line 10, sscanf() function is called to read the data from the string pointed to by str. Notice that the string literal "Tom Manager 28" contains three pieces of information name, designation, and age separated by space. To read all the three items we need to supply three variables of the appropriate type to the scanf() function. Then variable ret is assigned the number of items read by sscanf() function. In this case, we are reading three items from the string str, so 3 will be assigned to ret.
We are not obliged to read all the items in the string literal, if we want we can also read one or two items from it.
ret = sscanf(str, "%s %s", name, designation);
Here we are only reading and name and designation that's why only two variables are provided to sscanf().
At last printf() statements are used to display name, designation, age, and ret.
Binary Input and Output
Up to this point, we have been using text mode to read and write data to and from the file. In this chapter, we will learn how we can read and write data to and from the file using the binary mode. Recall that in binary mode data is stored in the file in the same way as in the memory, so no transformation of data takes place in binary mode. As no transformation takes place binary mode is significantly faster than text mode.
fread() and fwrite() functions are commonly used to read and write binary data to and from the file respectively. Although we can also use them with text mode too. |
fwrite() function
Syntax: size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp); |
fwrite() function writes the data specified by the void pointer ptr to the file.
ptr: it points to the block of memory which contains the data items to be written.
size: It specifies the number of bytes of each item to be written.
n: It is the number of items to be written.
fp: It is a pointer to the file where data items will be written.
On success, it returns the count of the number of items successfully written to the file. On error, it returns a number less than n. Notice that two arguments (size and n) and return value of fwrite() are of type size_t which on the most system is unsigned int.
Ex-
float f = 100.13; fwrite(&f, sizeof(f), 1, fp); |
Example 2: Writing an array
int arr[3] = {101, 203, 303}; fwrite(arr, sizeof(arr), 1, fp); |
Example 3: Writing some elements of array
int arr[3] = {101, 203, 303}; fwrite(arr, sizeof(int), 2, fp); |
Example 4: Writing structure
struct student { char name[10]; int roll; float marks; };
struct student student_1 = {"Tina", 12, 88.123}; fwrite(&student_1, sizeof(student_1), 1, fp); |
struct student { char name[10]; int roll; float marks; };
struct student students[3] = { {"Tina", 12, 88.123}, {"Jack", 34, 71.182}, {"May", 12, 93.713} };
fwrite(students, sizeof(students), 1, fp); .... |
This writes the whole array students into the file.
Let's say we don't' want to write all elements of the array into the file, instead, we want is to write only 0th and 1st element of the array into the file.
fwrite(students, sizeof(struct student), 2, fp);
Complete Example :
#include<stdio.h> #include<stdlib.h>
struct employee { char name[50]; char designation[50]; int age; float salary } employee;
int main() { int n, i, chars; FILE *fp;
fp = fopen("employee.txt", "wb");
if(fp == NULL) { printf("Error opening file\n"); exit(1); }
printf("Testing fwrite() function: \n\n");
printf("Enter the number of records you want to enter: "); scanf("%d", &n);
for(i = 0; i < n; i++) { printf("\nEnter details of employee %d \n", i + 1);
fflush(stdin);
printf("Name: "); gets(employee.name);
printf("Designation: "); gets(employee.designation);
printf("Age: "); scanf("%d", &employee.age);
printf("Salary: "); scanf("%f", &employee.salary);
chars = fwrite(&employee, sizeof(employee), 1, fp); printf("Number of items written to the file: %d\n", chars); }
fclose(fp); return 0; } |
fread() Function in C
fread() function is the complementary of fwrite() function. fread() function is commonly used to read binary data. It accepts the same arguments as fwrite() function does.
Syntax:
int fread(void *ptr, size_t size, size_t n, FILE *fp);
The ptr is the starting address of the memory block where data will be stored after reading from the file. The function reads n items from the file where each item occupies the number of bytes specified in the second argument. On success, it reads n items from the file and returns n. On error or end of the file, it returns a number less than n.
Example 1: Reading a float value from the file
int val; fread(&val, sizeof(int), 1, fp); |
Example 2: Reading an array from the file
int arr[10]; fread(arr, sizeof(arr), 1, fp); |
Example 3: Reading the first 5 elements of an array
int arr[10]; fread(arr, sizeof(int), 5, fp); |
Example 4: Reading the first 5 elements of an array
int arr[10]; fread(arr, sizeof(int), 5, fp); |
Example 5: Reading the structure variable
struct student { char name[10]; int roll; float marks; };
struct student student_1;
fread(&student_1, sizeof(student_1), 1, fp); |
Example 6: Reading an array of structure
struct student { char name[10]; int roll; float marks; };
struct student arr_student[100];
fread(&arr_student, sizeof(struct student), 10, fp); |
This reads first 10 elements of type struct student from the file and stores them in the variable arr_student.
The following program demonstrates how we can use fread() function.
#include<stdio.h> #include<stdlib.h>
struct employee { char name[50]; char designation[50]; int age; float salary } emp;
int main() { FILE *fp; fp = fopen("employee.txt", "rb"); if(fp == NULL) { printf("Error opening file\n"); exit(1); } printf("Testing fread() function: \n\n");
while( fread(&emp, sizeof(emp), 1, fp) == 1 ) { printf("Name: %s \n", emp.name); printf("Designation: %s \n", emp.designation); printf("Age: %d \n", emp.age); printf("Salary: %.2f \n\n", emp.salary); } fclose(fp); return 0; } |
sprintf() and sscanf() function in C
The sprintf() works just like printf() but instead of sending output to console it returns the formatted string.
Syntax:
int sprintf(char *str, const char *control_string, [ arg_1, arg_2, ... ]);
The first argument to sprintf() function is a pointer to the target string. The rest of the arguments are the same as for printf() function.
The function writes the data in the string pointed to by str and returns the number of characters written to str, excluding the null character. The return value is generally discarded. If an error occurs during the operation it returns -1.
Ex-
#include<stdio.h> #include<string.h> int factorial(int ); int main() { int sal; char name[30], designation[30], info[60];
printf("Enter your name: "); gets(name);
printf("Enter your designation: "); gets(designation); printf("Enter your salary: "); scanf("%d", &sal);
sprintf(info, "Welcome %s !\nName: %s \nDesignation: %s\nSalary: %d", name, name, designation, sal);
printf("\n%s", info);
// signal to operating system program ran fine return 0; }
Expected Output: Enter your name: Sim Enter your designation: Developer Enter your salary: 230000
Welcome Sim ! Name: Sim Designation: Developer Salary: 230000 |
Another important use of sprintf() function is to convert integer and float values to strings.
#include<stdio.h> #include<string.h> int factorial(int ); int main() { char s1[20]; char s2[20];
int x = 100; float y = 300;
sprintf(s1, "%d", x); sprintf(s2, "%f", y); printf("s1 = %s\n", s1); printf("s2 = %s\n", s2); // signal to operating system program ran fine return 0; }
Expected Output:
s1 = 100 s2 = 300.000000 |
The sscanf() Function in C
The sscanf() function allows us to read formatted data from a string rather than standard input or keyboard. Its syntax is as follows:
Syntax:
int sscanf(const char *str, const char * control_string [ arg_1, arg_2, ... ]);
The first argument is a pointer to the string from where we want to read the data.The rest of the arguments of sscanf() is the same as that of scanf(). It returns the number of items read from the string and -1 if an error is encountered.
Example :
#include<stdio.h> #include<string.h> int main() { char *str = "Tom Manager 28"; char name[10], designation[10]; int age, ret;
ret = sscanf(str, "%s %s %d", name, designation, &age);
printf("Name: %s\n", name); printf("Designation: %s\n", designation); printf("Age: %d\n", age);
// signal to operating system program ran fine return 0; }
Expected Output:
|