C Programming
C Programming
2 . Portability :
C Programs are portable i.e they can be run on any Compiler with Little or
no Modification
Compiler and Preprocessor make it Possible for C Program to run it on
Different PC
3 . Powerful
Provides Wide verity of Data Types
Provides Wide verity of Functions
Provides useful Control & Loop Control Statements
4 . Bit Manipulation
C Programs can be manipulated using bits. We can perform different
operations at bit level. We can manage memry representation at bit level.
[Eg. We can use Structure to manage Memory at Bit Level]
It provides wide verity of bit manipulation Operators. We have bitwise
operators to manage Data at bit level.
6 . Modular Programming
8 . More Efficient
C - Program Structure
AC
#include <stdio.h>
int main()
{
/* My first program */
printf("Hello, World! \n");
return 0;
}
Variables: are used to hold numbers, strings and complex data for
manipulation. You will learn in detail about variables in C Variable Types.
C Tokens
In a passage of text, individual words and punctuation marks are called
tokens or lexical units. Similarly, the smallest individual unit in a c program is
known as a token or a lexical unit. C tokens can be classified as follows:
Keywords
Identifiers
Constants
Strings
Special Symbols
Operators
C Keywords
C keywords are the words that convey a special meaning to the c compiler.
keywords cannot be used as variable names because by doing so, we are
trying to assign a new meaning to the keyword which is not allowed.
The list of C keywords is given below:
auto
break
case
char
continue
default
do
double
enum
extern
float
for
if
int
long
register
short
signed
sizeof
static
switch
typedef
union
unsigned
volatile
while
The
const
else
goto
return
struct
void
C Identifiers
Identifiers are used as the general terminology for the names of variables,
functions and arrays. These are user defined names consisting of arbitrarily
long sequence of letters and digits with either a letter or the underscore(_)
as a first character.
There are certain rules that should be followed while naming c identifiers:
They must begin with a letter or underscore(_).
They must consist of only letters, digits, or underscore. No other special
character is allowed.
It should not be a keyword.
It must not contain white space.
It should be up to 31 characters long as only first 31 characters are
significant.
Some examples of c identifiers:
Name
Remark
_A9
Valid
Temp.var Invalid as it contains special character other than the underscore
void
Invalid as it is a keyword
C Constants
C constants refer to the data items that do not change their value during the
program execution. Several types of C constants that are allowed in C are:
1. Integer Constants
Integer constants are whole numbers without any fractional part. It must
have at least one digit and may contain either + or sign. A number with no
sign is assumed to be positive.
There are three types of integer constants:
1.1. Decimal Integer Constants
Integer constants consisting of a set of digits, 0 through 9, preceded by an
optional or + sign.
Example of valid decimal integer constants
341, -341, 0, 8972
1.2. Octal Integer Constants
Integer constants consisting of sequence of digits from the set 0 through 7
starting with 0 is said to be octal integer constants.
Example of valid octal integer constants
010, 0424, 0, 0540
1.3. Hexadecimal Integer Constants
Hexadecimal integer constants are integer constants having sequence of
digits preceded by 0x or 0X. They may also include alphabets from A to F
representing numbers 10 to 15.
Example of valid hexadecimal integer constants
0xD, 0X8d, 0X, 0xbD
It should be noted that, octal and hexadecimal integer constants are rarely
used in programming.
2. Real Constants
The numbers having fractional parts are called real or floating point
constants. These may be represented in one of the two forms called
fractional form or the exponent form and may also have either + or sign
preceding it.
Example of valid real constants in fractional form or decimal notation
0.05, -0.905, 562.05, 0.015
3. Character Constants
A character constant contains one single character enclosed within single
quotes.
Examples of valid character constants
a , Z, 5
It should be noted that character constants have numerical values known as
ASCII values, for example, the value of A is 65 which is its ASCII value.
Escape Characters/ Escape Sequences
C allows us to have certain non graphic characters in character constants.
Non graphic characters are those characters that cannot be typed directly
from keyboard, for example, tabs, carriage return, etc.
These non graphic characters can be represented by using escape sequences
represented by a backslash() followed by one or more characters.
NOTE: An escape sequence consumes only one byte of space as it represents
a single character.
Escape Sequence
a
b
f
n
r
t
v
\
Description
Audible alert(bell)
Backspace
Form feed
New line
Carriage return
Horizontal tab
Vertical tab
Backslash
Double quotation mark
Single quotation mark
Question mark
Null
String Constants
String constants are sequence of characters enclosed within double quotes.
For example,
hello
abc
hello911
Every sting constant is automatically terminated with a special character
called the null character which represents the end of the string.
For example, hello will represent hello in the memory.
Thus, the size of the string is the total number of characters plus one for the
null character.
Special Symbols
The following special symbols are used in C having some special meaning and
thus, cannot be used for some other purpose.
[] () {} , ; : * = #
Braces {}: These opening and ending curly braces marks the start and end of
a block of code containing more than one executable statement.
Parentheses (): These special symbols are used to indicate function calls and
function parameters.
Brackets []: Opening and closing brackets are used as array element
reference. These indicate single and multidimensional subscripts.
C Operators
C operators are symbols that triggers an action when applied to C variables
and other objects. The data items on which operators act upon are called
operands.
Depending on the number of operands that an operator can act upon,
operators can be classified as follows:
Unary Operators: Those operators that require only single operand to act
upon are known as unary operators.
Binary Operators: Those operators that require two operands to act upon
are called binary operators.
Ternary Operators: These operators requires three operands to act upon.
Storage Class
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
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.
When the above code is compiled and executed, it produces the following
result
i
i
i
i
i
is
is
is
is
is
6 and count is 4
7 and count is 3
8 and count is 2
9 and count is 1
10 and count is 0
count = 5;
write_extern();
Here, extern is being used to declare count in the second file, where as it has
its definition in the first file, main.c. Now, compile these two files as follows
It will produce the executable program a.out. When this program is executed,
it produces the following result
if statement
1
C - Loops
You may encounter situations, when a block of code needs to be executed
several number of 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. Given below is the general form of a loop statement in most
of the programming languages
S.
Loop Type & Description
N.
while loop
1
It is more like a while statement, except that it tests the condition at the
end of the loop body.
nested loops
You can use one or more loops inside any other while, for, or do..while
loop.
Causes the loop to skip the remainder of its body and immediately retest
its condition prior to reiterating.
goto statement
3
Transfers control to the labeled statement.
int main () {
for( ; ; ) {
printf("This loop will run forever.\n");
}
return 0;
}
When the conditional expression is absent, it is assumed to be true. You may
have an initialization and increment expression, but C programmers more
commonly use the for(;;) construct to signify an infinite loop.
NOTE You can terminate an infinite loop by pressing Ctrl + C keys.
C - Arrays
Arrays a kind of data structure that can store a fixed-size sequential
collection of elements of the same type. An array is used to store a collection
of data, but it is often more useful to think of an array as a collection of
variables of the same type.
Instead of declaring individual variables, such as number0, number1, ..., and
number99, you declare one array variable such as numbers and use
Declaring Arrays
To declare an array in C, a programmer specifies the type of the elements
and the number of elements required by an array as follows
type arrayName [ arraySize ];
Initializing Arrays
You can initialize an array in C either one by one or using a single statement
as follows
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
The number of values between braces { } cannot be larger than the number
of elements that we declare for the array between square brackets [ ].
If you omit the size of the array, an array just big enough to hold the
initialization is created. Therefore, if you write
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
You will create exactly the same array as you did in the previous example.
Following is an example to assign a single element of the array
balance[4] = 50.0;
The above statement assigns the 5th element in the array with a value of
50.0. All arrays have 0 as the index of their first element which is also called
the base index and the last index of an array will be total size of the array
minus 1. Shown below is the pictorial representation of the array we
discussed above
The above statement will take the 10th element from the array and assign
the value to salary variable. The following example Shows how to use all the
three above mentioned concepts viz. declaration, assignment, and accessing
arrays
#include <stdio.h>
int main () {
int n[ 10 ]; /* n is an array of 10 integers */
int i,j;
/* initialize elements of array n to 0 */
for ( i = 0; i < 10; i++ ) {
n[ i ] = i + 100; /* set element at location i to i + 100 */
}
/* output each array element's value */
for (j = 0; j < 10; j++ ) {
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
When the above code is compiled and executed, it produces the following
result
Element[0]
Element[1]
Element[2]
Element[3]
Element[4]
Element[5]
Element[6]
Element[7]
Element[8]
Element[9]
=
=
=
=
=
=
=
=
=
=
100
101
102
103
104
105
106
107
108
109
Arrays in Detail
Arrays are important to C and should need a lot more attention. The
following important concepts related to array should be clear to a C
programmer
S.
Concept & Description
N.
Multi-dimensional arrays
1
3
C allows a function to return an array.
Pointer to an array
4
1. Multi-dimensional Arrays in C
C programming language allows multidimensional arrays. Here is the general
form of a multidimensional array declaration
type name[size1][size2]...[sizeN];
Two-dimensional Arrays
The simplest form of multidimensional array is the two-dimensional array. A
two-dimensional array is, in essence, a list of one-dimensional arrays. To
declare a two-dimensional integer array of size [x][y], you would write
something as follows
type arrayName [ x ][ y ];
Where type can be any valid C data type and arrayName will be a valid C
identifier. A two-dimensional array can be considered as a table which will
have x number of rows and y number of columns. A two-dimensional array a,
which contains three rows and four columns can be shown as follows
/*
/*
/*
The nested braces, which indicate the intended row, are optional. The
following initialization is equivalent to the previous example
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
The above statement will take the 4th element from the 3rd row of the array.
You can verify it in the above figure. Let us check the following program
where we have used a nested loop to handle a two-dimensional array
#include <stdio.h>
int main () {
/* an array with 5 rows and 2 columns*/
int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
int i, j;
/* output each array element's value */
for ( i = 0; i < 5; i++ ) {
for ( j = 0; j < 2; j++ ) {
printf("a[%d][%d] = %d\n", i,j, a[i][j] );
}
}
}
return 0;
When the above code is compiled and executed, it produces the following
result
a[0][0]:
a[0][1]:
a[1][0]:
a[1][1]:
a[2][0]:
a[2][1]:
a[3][0]:
a[3][1]:
a[4][0]:
a[4][1]:
0
0
1
2
2
4
3
6
4
8
As explained above, you can have arrays with any number of dimensions,
although it is likely that most of the arrays you create will be of one or two
dimensions.
Way-1
Formal parameters as a pointer
void myFunction(int *param) {
.
.
.
}
Way-2
Formal parameters as a sized array
void myFunction(int param[10]) {
.
.
.
}
Way-3
Formal parameters as an unsized array
void myFunction(int param[]) {
.
.
.
}
Example
Now, consider the following function, which takes an array as an argument
along with another argument and based on the passed arguments, it returns
the average of the numbers passed through the array as follows
double getAverage(int arr[], int size) {
int i;
double avg;
double sum;
for (i = 0; i < size; ++i) {
sum += arr[i];
}
avg = sum / size;
return avg;
}
return 0;
When the above code is compiled together and executed, it produces the
following result
Average value is: 214.400000
As you can see, the length of the array doesn't matter as far as the function
is concerned because C performs no bounds checking for formal parameters.
Second point to remember is that C does not advocate to return the address
of a local variable to outside of the function, so you would have to define the
local variable as static variable.
Now, consider the following function which will generate 10 random numbers
and return them using an array and call this function as follows
#include <stdio.h>
/* function to generate and return random numbers */
int * getRandom( ) {
static int
int i;
r[10];
return r;
return 0;
When the above code is compiled together and executed, it produces the
following result
r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*(p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*(p + 5) : 167288147
*(p
*(p
*(p
*(p
+
+
+
+
6)
7)
8)
9)
:
:
:
:
1827471542
834791014
1901409888
1990469526
4. Pointer to an Array in C
It is most likely that you would not understand this section until you are
through with the chapter 'Pointers'.
Assuming you have some understanding of pointers in C, let us start: An
array name is a constant pointer to the first element of the array. Therefore,
in the declaration
double balance[50];
It is legal to use array names as constant pointers, and vice versa. Therefore,
*(balance + 4) is a legitimate way of accessing the data at balance[4].
Once you store the address of the first element in 'p', you can access the
array elements using *p, *(p+1), *(p+2) and so on. Given below is the
example to show all the concepts discussed above
#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) );
return 0;
i, *(balance + i) );
When the above code is compiled and executed, it produces the following
result
Array values using pointer
*(p + 0) : 1000.000000
*(p + 1) : 2.000000
*(p + 2) : 3.400000
*(p + 3) : 17.000000
*(p + 4) : 50.000000
Array values using balance as address
*(balance + 0) : 1000.000000
*(balance + 1) : 2.000000
*(balance + 2) : 3.400000
*(balance + 3) : 17.000000
*(balance + 4) : 50.000000
In the above example, p is a pointer to double, which means it can store the
address of a variable of double type. Once we have the address in p, *p will
give us the value available at the address stored in p, as we have shown in
the above example.
C - Pointers
Pointers in C are easy and fun to learn. Some C programming tasks are
performed more easily with pointers, and other tasks, such as dynamic
memory allocation, cannot be performed without using pointers. So it
becomes necessary to learn pointers to become a perfect C programmer.
Let's start learning them in simple and easy steps.
As you know, every variable is a memory location and every memory location
has its address defined which can be accessed using ampersand (&) operator,
which denotes an address in memory. Consider the following example, which
prints the address of the variables defined
#include <stdio.h>
int main () {
int var1;
char var2[10];
printf("Address of var1 variable: %x\n", &var1
printf("Address of var2 variable: %x\n", &var2
}
);
);
return 0;
When the above code is compiled and executed, it produces the following
result
Address of var1 variable: bff5a400
Address of var2 variable: bff5a3f6
Here, type is the pointer's base type; it must be a valid C data type and varname is the name of the pointer variable. The asterisk * used to declare a
pointer is the same asterisk used for multiplication. However, in this
statement the asterisk is being used to designate a variable as a pointer.
Take a look at some of the valid pointer declarations
int
double
float
char
*ip;
*dp;
*fp;
*ch
/*
/*
/*
/*
pointer
pointer
pointer
pointer
to
to
to
to
an integer */
a double */
a float */
a character */
The actual data type of the value of all pointers, whether integer, float,
character, or otherwise, is the same, a long hexadecimal number that
represents a memory address. The only difference between pointers of
different data types is the data type of the variable or constant that the
pointer points to.
var = 20;
*ip;
ip = &var;
);
return 0;
When the above code is compiled and executed, it produces the following
result
NULL Pointers
It is always a good practice to assign a NULL value to a pointer variable in
case you do not have an exact address to be assigned. This is done at the
time of variable declaration. A pointer that is assigned NULL is called a null
pointer.
The NULL pointer is a constant with a value of zero defined in several
standard libraries. Consider the following program
#include <stdio.h>
int main () {
int
*ptr = NULL;
);
return 0;
}
When the above code is compiled and executed, it produces the following
result
The value of ptr is 0
Pointers in Detail
Pointers have many but easy concepts and they are very important to C
programming. The following important pointer concepts should be clear to
any C programmer
S.
N.
Pointer arithmetic
1
There are four arithmetic operators that can be used in pointers: ++, --,
+, -
Array of pointers
2
3
C allows you to have pointer on a pointer and so on.
Passing pointers to functions in C
4
1. C - Pointer arithmetic
A pointer in c is an address, which is a numeric value. Therefore, you can
perform arithmetic operations on a pointer just as you can on a numeric
value. There are four arithmetic operators that can be used on pointers: ++,
--, +, and To understand pointer arithmetic, let us consider that ptr is an integer
pointer which points to the address 1000. Assuming 32-bit integers, let us
perform the following arithmetic operation on the pointer
ptr++
After the above operation, the ptr will point to the location 1004 because
each time ptr is incremented, it will point to the next integer location which
is 4 bytes next to the current location. This operation will move the pointer
to the next memory location without impacting the actual value at the
memory location. If ptr points to a character whose address is 1000, then the
above operation will point to the location 1001 because the next character
will be available at 1001.
Incrementing a Pointer
We prefer using a pointer in our program instead of an array because the
variable pointer can be incremented, unlike the array name which cannot be
incremented because it is a constant pointer. The following program
increments the variable pointer to access each succeeding element of the
array
#include <stdio.h>
const int MAX = 3;
int main () {
int
int
return 0;
When the above code is compiled and executed, it produces the following
result
Address of var[0]
Value of var[0] =
Address of var[1]
Value of var[1] =
Address of var[2]
Value of var[2] =
= bf882b30
10
= bf882b34
100
= bf882b38
200
Decrementing a Pointer
The same considerations apply to decrementing a pointer, which decreases
its value by the number of bytes of its data type as shown below
#include <stdio.h>
const int MAX = 3;
int main () {
int
int
return 0;
}
When the above code is compiled and executed, it produces the following
result
Address of var[3]
Value of var[3] =
Address of var[2]
Value of var[2] =
Address of var[1]
Value of var[1] =
= bfedbcd8
200
= bfedbcd4
100
= bfedbcd0
10
Pointer Comparisons
Pointers may be compared by using relational operators, such as ==, <, and
>. If p1 and p2 point to variables that are related to each other, such as
elements of the same array, then p1 and p2 can be meaningfully compared.
The following program modifies the previous example one by incrementing
the variable pointer so long as the address to which it points is either less
than or equal to the address of the last element of the array, which is
&var[MAX - 1]
#include <stdio.h>
const int MAX = 3;
int main () {
int
int
return 0;
}
When the above code is compiled and executed, it produces the following
result
Address of var[0]
Value of var[0] =
Address of var[1]
Value of var[1] =
Address of var[2]
Value of var[2] =
= bfdbcb20
10
= bfdbcb24
100
= bfdbcb28
200
2. C - Array of pointers
Before we understand the concept of arrays of pointers, let us consider the
following example, which uses an array of 3 integers
#include <stdio.h>
const int MAX = 3;
int main () {
int var[] = {10, 100, 200};
int i;
for (i = 0; i < MAX; i++) {
printf("Value of var[%d] = %d\n", i, var[i] );
}
return 0;
}
When the above code is compiled and executed, it produces the following
result
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
There may be a situation when we want to maintain an array, which can store
pointers to an int or char or any other data type available. Following is the
declaration of an array of pointers to an integer
int *ptr[MAX];
It declares ptr as an array of MAX integer pointers. Thus, each element in ptr,
holds a pointer to an int value. The following example uses three integers,
which are stored in an array of pointers, as follows
#include <stdio.h>
const int MAX = 3;
int main () {
int var[] = {10, 100, 200};
int i, *ptr[MAX];
for ( i = 0; i < MAX; i++) {
ptr[i] = &var[i]; /* assign the address of integer. */
}
for ( i = 0; i < MAX; i++) {
printf("Value of var[%d] = %d\n", i, *ptr[i] );
}
}
return 0;
When the above code is compiled and executed, it produces the following
result
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
You can also use an array of pointers to character to store a list of strings as
follows
#include <stdio.h>
const int MAX = 4;
int main () {
char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
int i = 0;
for ( i = 0; i < MAX; i++) {
printf("Value of names[%d] = %s\n", i, names[i] );
}
return 0;
}
When the above code is compiled and executed, it produces the following
result
Value
Value
Value
Value
of
of
of
of
names[0]
names[1]
names[2]
names[3]
=
=
=
=
Zara
Hina
Nuha
Sara
Ali
Ali
Ali
Ali
3. C - Pointer to Pointer
A pointer to a pointer is a form of multiple indirection, or a chain of pointers.
Normally, a pointer contains the address of a variable. When we define a
pointer to a pointer, the first pointer contains the address of the second
pointer, which points to the location that contains the actual value as shown
below.
int
int
int
var;
*ptr;
**pptr;
var = 3000;
/* take the address of var */
ptr = &var;
/* take the address of ptr using address of operator & */
pptr = &ptr;
/* take the value using pptr */
printf("Value of var = %d\n", var );
printf("Value available at *ptr = %d\n", *ptr );
printf("Value available at **pptr = %d\n", **pptr);
return 0;
}
When the above code is compiled and executed, it produces the following
result
Value of var = 3000
Value available at *ptr = 3000
Value available at **pptr = 3000
When the above code is compiled and executed, it produces the following
result
The function, which can accept a pointer, can also accept an array as shown
in the following example
#include <stdio.h>
/* function declaration */
double getAverage(int *arr, int size);
int main () {
/* an int array with 5 elements */
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
/* pass pointer to the array as an argument */
avg = getAverage( balance, 5 ) ;
/* output the returned value */
printf("Average value is: %f\n", avg );
return 0;
}
double getAverage(int *arr, int size) {
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i) {
sum += arr[i];
}
When the above code is compiled together and executed, it produces the
following result
Average value is: 214.40000
Second point to remember is that, it is not a good idea to return the address
of a local variable outside the function, so you would have to define the local
variable as static variable.
Now, consider the following function which will generate 10 random numbers
and return them using an array name which represents a pointer, i.e.,
address of first array element.
#include <stdio.h>
#include <time.h>
/* function to generate and retrun random numbers. */
int * getRandom( ) {
static int
int i;
r[10];
When the above code is compiled together and executed, it produces the
following result
1523198053
1187214107
1108300978
430494959
1421301276
930971084
123250484
106932140
1604461820
149169022
*(p + [0])
*(p + [1])
*(p + [2])
*(p + [3])
*(p + [4])
*(p + [5])
*(p + [6])
*(p + [7])
*(p + [8])
:
:
:
:
:
:
:
:
:
1523198053
1187214107
1108300978
430494959
1421301276
930971084
123250484
106932140
1604461820
C - Strings
Strings are actually one-dimensional array of characters terminated by a null
character '\0'. Thus a null-terminated string contains the characters that
comprise the string followed by a null.
The following declaration and initialization create a string consisting of the
word "Hello". To hold the null character at the end of the array, the size of
the character array containing the string is one more than the number of
characters in the word "Hello."
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
If you follow the rule of array initialization then you can write the above
statement as follows
char greeting[] = "Hello";
Actually, you do not place the null character at the end of a string constant.
The C compiler automatically places the '\0' at the end of the string when it
initializes the array. Let us try to print the above mentioned string
#include <stdio.h>
int main () {
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
printf("Greeting message: %s\n", greeting );
return 0;
}
When the above code is compiled and executed, it produces the following
result
Greeting message: Hello
S.N
Function & Purpose
.
strcpy(s1, s2);
1
Copies string s2 into string s1.
strcat(s1, s2);
2
Concatenates string s2 onto the end of string s1.
strlen(s1);
3
Returns the length of string s1.
strcmp(s1, s2);
4
Returns 0 if s1 and s2 are the same; less than 0 if s1<s2; greater than 0
if s1>s2.
strchr(s1, ch);
5
Returns a pointer to the first occurrence of character ch in string s1.
strstr(s1, s2);
6
Returns a pointer to the first occurrence of string s2 in string s1.
The following example uses some of the above-mentioned functions
#include <stdio.h>
#include <string.h>
int main () {
char
char
char
int
str1[12] = "Hello";
str2[12] = "World";
str3[12];
len ;
%s\n", str3 );
return 0;
When the above code is compiled and executed, it produces the following
result
strcpy( str3, str1) :
strcat( str1, str2):
strlen(str1) : 10
Hello
HelloWorld
C - Structures
Arrays allow to define type of variables that can hold several data items of
the same kind. Similarly structure is another user defined data type available
in C that allows 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
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
member
...
member
} [one or
definition;
definition;
definition;
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;
/* 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;
}
When the above code is compiled and executed, it produces the following
result
Book
Book
Book
Book
Book
Book
Book
Book
1
1
1
1
2
2
2
2
title : C Programming
author : Nuha Ali
subject : C Programming Tutorial
book_id : 6495407
title : Telecom Billing
author : Zara Ali
subject : Telecom Billing Tutorial
book_id : 6495700
/* 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;
printf(
printf(
printf(
printf(
"Book
"Book
"Book
"Book
When the above code is compiled and executed, it produces the following
result
Book
Book
Book
Book
Book
Book
Book
Book
title : C Programming
author : Nuha Ali
subject : C Programming Tutorial
book_id : 6495407
title : Telecom Billing
author : Zara Ali
subject : Telecom Billing Tutorial
book_id : 6495700
Pointers to Structures
You can define pointers to structures in the same way as you define pointer
to any other variable
struct Books *struct_pointer;
Now, you can store the address of a structure variable in the above defined
pointer variable. To find the address of a structure variable, place the '&';
operator before the structure's name as follows
struct_pointer = &Book1;
/* 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 by passing address of Book1 */
printBook( &Book1 );
/* print Book2 info by passing address of Book2 */
printBook( &Book2 );
}
return 0;
When the above code is compiled and executed, it produces the following
result
Book
Book
Book
Book
Book
Book
Book
Book
title : C Programming
author : Nuha Ali
subject : C Programming Tutorial
book_id : 6495407
title : Telecom Billing
author : Zara Ali
subject : Telecom Billing Tutorial
book_id : 6495700
Bit Fields
Bit Fields allow the packing of data in a structure. This is especially useful
when memory or data storage is at a premium. Typical examples include
Packing several objects into a machine word. e.g. 1 bit flags can be
compacted.
Reading external file formats -- non-standard file formats could be read in,
e.g., 9-bit integers.
C allows us to do this in a structure definition by putting :bit length after the
variable. For example
struct packed_struct {
unsigned int f1:1;
unsigned int f2:1;
unsigned int f3:1;
unsigned int f4:1;
unsigned int type:4;
unsigned int my_int:9;
} pack;
Here, the packed_struct contains 6 members: Four 1 bit flags f1..f3, a 4-bit
type and a 9-bit my_int.
C automatically packs the above bit fields as compactly as possible, provided
that the maximum length of the field is less than or equal to the integer word
length of the computer. If this is not the case, then some compilers may allow
memory overlap for the fields while others would store the next field in the
next word.
C - Unions
A union is a special data type available in C that allows to store different
data types in the same memory location. You can define a union with many
members, but only one member can contain a value at any given time.
Unions provide an efficient way of using the same memory location for
multiple-purpose.
Defining a Union
To define a union, you must use the union statement in the same way as you
did while defining a structure. The union statement defines a new data type
with more than one member for your program. The format of the union
statement is as follows
union [union tag] {
member definition;
member definition;
...
member definition;
} [one or more union variables];
The union tag is optional and each member definition is a normal variable
definition, such as int i; or float f; or any other valid variable definition. At
the end of the union's definition, before the final semicolon, you can specify
one or more union variables but it is optional. Here is the way you would
define a union type named Data having three members i, f, and str
union Data {
int i;
float f;
char str[20];
} data;
return 0;
When the above code is compiled and executed, it produces the following
result
return 0;
When the above code is compiled and executed, it produces the following
result
data.i : 1917853763
data.f : 4122360580327794860452759994368.000000
data.str : C Programming
Here, we can see that the values of i and f members of union got corrupted
because the final value assigned to the variable has occupied the memory
location and this is the reason that the value of str member is getting printed
very well.
Now let's look into the same example once again where we will use one
variable at a time which is the main purpose of having unions
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main( ) {
When the above code is compiled and executed, it produces the following
result
data.i : 10
data.f : 220.500000
data.str : C Programming
Here, all the members are getting printed very well because one member is
being used at a time.
C - File I/O
The last chapter explained the standard input and output devices handled by
C programming language. This chapter cover how C programmers can create,
open, close text or binary files for their data storage.
A file represents a sequence of bytes, regardless of it being a text file or a
binary file. C programming language provides access on high level functions
as well as low level (OS level) calls to handle file on your storage devices.
This chapter will take you through the important calls for file management.
Opening Files
You can use the fopen( ) function to create a new file or to open an existing
file. This call will initialize an object of the type FILE, which contains all the
information necessary to control the stream. The prototype of this function
call is as follows
FILE *fopen( const char * filename, const char * mode );
Here, filename is a string literal, which you will use to name your file, and
access mode can have one of the following values
Mod
Description
e
r
Opens a text file for writing. If it does not exist, then a new file is
created. Here your program will start writing content from the
beginning of the file.
Opens a text file for writing in appending mode. If it does not exist, then
a new file is created. Here your program will start appending content in
the existing file content.
r+
w+
Opens a text file for both reading and writing. It first truncates the file
to zero length if it exists, otherwise creates a file if it does not exist.
a+
Opens a text file for both reading and writing. It creates the file if it
does not exist. The reading will start from the beginning but writing can
only be appended.
If you are going to handle binary files, then you will use following access
modes instead of the above mentioned ones
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
Closing a File
To close a file, use the fclose( ) function. The prototype of this function is
int fclose( FILE *fp );
Writing a File
Following is the simplest function to write individual characters to a stream
int fputc( int c, FILE *fp );
The function fputc() writes the character value of the argument c to the
output stream referenced by fp. It returns the written character written on
success otherwise EOF if there is an error. You can use the following
functions to write a null-terminated string to a stream
int fputs( const char *s, FILE *fp );
The function fputs() writes the string s to the output stream referenced by
fp. It returns a non-negative value on success, otherwise EOF is returned in
case of any error. You can use int fprintf(FILE *fp,const char *format, ...)
function as well to write a string into a file. Try the following example.
Make sure you have /tmp directory available. If it is not, then before
proceeding, you must create this directory on your machine.
#include <stdio.h>
main() {
FILE *fp;
fp = fopen("/tmp/test.txt", "w+");
fprintf(fp, "This is testing for fprintf...\n");
fputs("This is testing for fputs...\n", fp);
fclose(fp);
When the above code is compiled and executed, it creates a new file test.txt
in /tmp directory and writes two lines using two different functions. Let us
read this file in the next section.
Reading a File
Given below is the simplest function to read a single character from a file
int fgetc( FILE * fp );
The fgetc() function reads a character from the input file referenced by fp.
The return value is the character read, or in case of any error, it returns EOF.
The following function allows to read a string from a stream
char *fgets( char *buf, int n, FILE *fp );
The functions fgets() reads up to n-1 characters from the input stream
referenced by fp. It copies the read string into the buffer buf, appending a
null character to terminate the string.
If this function encounters a newline character '\n' or the end of the file EOF
before they have read the maximum number of characters, then it returns
only the characters read up to that point including the new line character.
You can also use int fscanf(FILE *fp, const char *format, ...) function to read
strings from a file, but it stops reading after encountering the first space
character.
#include <stdio.h>
main() {
FILE *fp;
char buff[255];
fp = fopen("/tmp/test.txt", "r");
fscanf(fp, "%s", buff);
printf("1 : %s\n", buff );
fgets(buff, 255, (FILE*)fp);
printf("2: %s\n", buff );
fgets(buff, 255, (FILE*)fp);
printf("3: %s\n", buff );
fclose(fp);
When the above code is compiled and executed, it reads the file created in
the previous section and produces the following result
1: This
2: is testing for fprintf...
3: This is testing for fputs...
Let's see a little more in detail about what happened here. First, fscanf()
read just This because after that, it encountered a space, second call is for
fgets() which reads the remaining line till it encountered end of line. Finally,
the last call fgets() reads the second line completely.
Both of these functions should be used to read or write blocks of memories usually arrays or structures.