C Programming
C Programming
• Not long after Unix first ran on the PDP-7 in 1969, Doug
McIlroy created the system’s first high-level language, an
implementation of McClure’s TMG (TransMoGrifiers).
• The type int means that the variables listed are integers. The
range of both int and float depends on the machine you are
using; 16-bits ints, which lie between -32768 and +32767, are
common, as are 32-bit ints.
• Floating point variables on the other hand, are those that have a
decimal part. A float number is typically a 32-bit quantity, with
at least six significant digits, and magnitude between about 10-38
and 1038.
• The definition:
char var;
defines a memory location of size one byte, of character type,
referred to as var.
• The definition:
• char var; defines a variable location called var, which is one
byte in size, and can therefore hold only one character.
• #include <conio.h>
• #include <stdio.h>
• main( )
• {
• char ch;
• ch = getch( );
• fflush(stdin);
• putch(ch);
• }
• #include <stdio.h>
• main( )
• {
• char ch;
• ch = getchar( );
• fflush(stdin);
• putchar(ch);
• }
• #include <stdio.h>
• #include <conio.h>
• main( )
• {
• char str[11];
• puts("Enter a string of maximum 10 characters");
• gets(str);
• fflush(stdin);
• puts(str);
• }
• Relational Operators:
Operator Meaning
== Equal to
!= Not equal to
stop
• #include <stdio.h>
• main( )
• {
• char chr;
• chr = getchar( );
• if (chr == '0')
• puts("You entered the number 0");
• else if (chr == '1')
• puts("You entered the number 1");
• else if (chr == '2')
puts("You entered the number 2");
• A nested if statement is
encountered if the statement to be
executed after a condition
evaluates to true is another if
statement.
no
• Both the outer if statement and the ye
”
s
inner if statement have to evaluate
ye
to true for the statement following s
no
• #include< stdio.h>
• main( )
• {
• char ch;
• ch = getchar( );
• fflush(stdin);
• if (ch >= ‘A’)
• {
• if (ch <= ‘Z’)
• puts (Its an Uppercase alphabet”);
• else if (ch >= ‘a’)
• {
• if (inp <= ‘z’)
• puts (“It’s a lowercase alphabet”);
• else
• puts (“Input character > z”);
• }
• else
• puts (“Input character greater than Z but less than a”);
• }
• else
• puts (“Input character less than A”);
• }
• switch ( chr)
• {
• case '0' : puts( "you entered 0");
• break;
• case '1' : puts( "you entered 1");
• break;
• case '2' : puts( "you entered 2");
• break;
• case '3' : puts( "you entered 3");
• break;
• case '4' : puts( "you entered 4");
• break;
• case '5' : puts( "you entered 5");
• break;
• case '6' : puts( "you entered 6");
• break;
• #include <stdio.h>
• /* function to accept a string and display it 10 times */
• main( )
• {
• int counter=0;
• char message[10];
• gets( message);
• fflush( stdin);
• while (counter <= 9)
• {
• puts( message);
• putchar ('\r');
• counter = counter + 1;
• gets( message);
• fflush (stdin); } }
false
• The loop is entered into straightaway, and after Evaluate Condition
the first execution of the loop body, the loop
condition is evaluated. true
• #include <stdio.h>
• /* this function displays a message 10 times */
• main( )
• {
• int i;
• char message[10];
• gets (message);
• fflush(stdin);
• for( i = 0; i <= 9; i = i + 1)
• {
• puts( message);
• }
• }
• Control passes back to the top of the loop where the loop
condition is evaluated again.
Operator Notation
NOT !
AND &&
OR ||
• a && b;
a b a && b a || b
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1
• An example:
• printf(“%c\n”, var);
• The conversion characters and their meanings are:
• Between the % character and the conversion character, there may be:
•
A minus sign Implying left adjustment of data
A digit Implying the minimum width in which the data is to be output. If
the data has larger number of characters than the specified width,
the width occupied by the output is larger. If the data consists of
fewer characters than the specified width, it is padded to the
right (if minus sign is specified), or to the left (if no minus sign
is specified). If the digit is prefixed with a zero, the padding is
done with zeroes instead of blanks
A period Separates the width from the next digit.
A digit Specifying the precision, or the maximum number of characters
to be output
l To signify that the data item is a long integer, and not an integer.
• #include<stdio.h>
• main( )
• {
• int number = 97;
• printf("Value of num is %d\n", number);
• printf("The Character equivalent of %d is %c\n", number, number);
• }
• #include<stdio.h>
• main( )
• {
• char name[10];
• int age = 0;
• char gender = ' ';
• scanf ("%7s %c %2d", name, &gender, &age);
• fflush(stdin);
• printf( "% s %c %d", name, gender, age);
• }
• #include<stdio.h>
• main( )
• {
• char string[40];
• printf("Enter a string of maximum 39 characters");
• scanf("%s", string);
• fflush(stdin);
• printf("%s", string);
• }
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]
name
a b c d e f g h i j \0
name[0] name[1] name[2] name[3] name[4] name[5] name[6] name[7] name[8] name[9] name[10]
• #include<stdio.h>
• main( )
• {
• char array1[ ] = {‘A’, ‘R’, ‘R’, ‘A’, ‘Y’, ‘\0’};
• char array2[ ] = {“ARRAY”};
• char dayofweek[ ] = {‘M’, ‘T’, ‘W’, ‘T’, ‘F’, ‘S’, ‘S’, ‘\0’};
• float values[ ] = {100.56, 200.33, 220.44, 400.22, 0};
• }
• #include<stdio.h>
• main( )
• {
• char array1[ ] = {‘A’, ‘R’, ‘R’, ‘A’, ‘Y’, ‘\0’};
• char array2[ ] = {“ARRAY”};
• char dayofweek[ ] = {‘M’, ‘T’, ‘W’, ‘T’, ‘F’, ‘S’, ‘S’, ‘\0’};
• float values[ ] = {100.56, 200.33, 220.44, 400.22, 0};
• int i = 0;
• printf( “String 1 is %s\n”, array1);
• printf( “String 2 is %s\n”, array2);
• for( i = 0; dayofweek[i] != ‘\0’; i = i +1)
• printf ( “The Day %d in a week is %c\n”, i + 1, dayofweek[i];
• for( i = 0; values[i] != 0; i = i +1)
• printf ( “The amount %d in a week is %f\n”, i + 1, values[i];
• }
• #include<stdio.h>
• main( )
• {
• int i, num[50];
• for (i = 0; i < 50; i = i + 1)
• {
• num[i] = 0;
• num[i] = i + 1;
• printf("%d\n",i);
• }
• }
• #include<stdio.h>
• /* displays each element of the array on a new line */
• main( )
• {
• int i;
• char array[11];
• printf( "enter a string of maximum 10 characters\n");
• gets(array);
• fflush(stdin);
• for (i = 0; array[i] != '\0'; i = i +1)
• printf("Element %d is %c\n", i +1, array[i]);
• }
• In the declaration:
• char string[11);
• the name of the array refers to the starting address of the
area that gets allocated for storing the elements of the array.
string
100
100 101 102 103 104 105 106 107 108 109 110
a b c d e f g h i j \0
0 1 2 3 4 5 6 7 8 9 10
• In the aforesaid assignment, the data type on the right (char) is converted
to the data type on the left (int), which is the type of the result.
if (a > b)
z = a;
else
z = b;
• x = x * y; can be written as x *= y;
• x = x / y; can be written as x /= y;
row 0
row 1
row 2
reg A
reg B
reg C
• int rp_array[3][3];
• /* this array would have nine elements starting at rp_array[0][0],
rp_array[1][1]…….and going on till rp_array[2,2] */
• /* Program for converting these sales figures into percentages of total sales. */
• main( )
• {
• int r_counter, p_counter, rp_array[3][3], total_sales = 0;
• float rp_array_perc[3][3];
• /* initialization of rp_array using the for loop */
• for (r_counter = 0; r_counter < 3; r_counter ++)
• {
• for (p_counter = 0; p_counter < 3; p_counter ++)
• {
• rp_array[r_counter][p_counter] = 0;
• }
• }
• main( )
• {
• char team_india [11][30] = { “Akash Chopra”,
• “Virendra Sehwag”,
• “Rahul Dravid”
• “Sachin Tendulkar”,
• “V.V.S. Laxman”,
• “Yuvraj Singh”,
• “Ajit Agarkar”,
• “Parthiv Patel”,
• “Anil Kumble”,
• “L. Balaji”,
• “Irfan Pathan”
• };
• int i;
• for( i = 0; i < 11; i ++)
• {
• printf(“%s”, team_india[i]);
• }
• }
22 value
1000 address
• int i, *pointer_to_an_integer;
• i = 22;
• pointer_to_an_integer = &i; /* initializing the integer
pointer variable (pointer_to_an_integer) with the address of
the integer variable i. */
• It is obvious from the preceding code snippet that the ‘&’ operator is
used to return the address of a variable. The returned address is stored
into a pointer variable of the appropriate type.
i variable name
• #include<stdio.h>
• main( )
• {
• int x, y, *pointer;
• x = 22;
• pointer = &x;
• y = *pointer; /* obtain whatever pointer is pointing to */
• }
pointer2
1000
1000 22
p2 y
2000 44
1000 44
pointer2
y
1000 44
• In the declaration:
• char string[11];
• the name of the array refers to the starting address of
the area that gets allocated for storing the elements of
the array.
• char *string; /* string is now a explicit pointer variable that can point
to a character */
• char *string = “Hello”;
• printf(“%s”, string);
100
100 101 102 103 104 105 106 107 108 109 110
S h e r l o c k H \0
0 1 2 3 4 5 6 7 8 9 10
101
100 101 102 103 104 105 106 107 108 109 110
S h e r l o c k H \0
0 1 2 3 4 5 6 7 8 9 10
100
100 104 108
4 8 12
p
104
100 104 108
4 8 12
p
100
• The format string, and the variable name can be called the
parameters to the function printf( ) in our example.
void swap(int,int );
main()
{ int a=10, b=20;
swap(a, b);
printf(“ %d %d \n”,a,b);
}
void swap (int x, int y)
{ int temp = x;
x= y;
y=temp;
}
• The parameters of a function are local to that function, and hence, any
changes made by the called function to its parameters affect only the
copy received by the called function, and do not affect the value of
the variables in the called function. This is the call by value
mechanism.
C Programming ver 2.0 Page 186
Call by Reference
• fn(int num_list[10]); or
• fn(int *num_list)
• In the aforesaid example, the function add( ) sends back the value of
the expression (a + b) to the function main( ). The value returned to
main( ) from add( ) is stored in the variable value which appears on the
left hand side of the statement in which the function add( ) is called.
• #include <stdio.h>
• main( )
• {
• void add( float, float);
• float i, j, value;
• scanf(“%f %f”, &i, &j);
• fflush(stdin);
• add(i, j);
• printf( “the total is %d\n”, value);
• }
• It is important to know how the CPU manages all this, i.e., knowing
where to look for when a function call is encountered, and having
executed the function, to also know where it has to return to.
Memory
Register Area
Code Area
RAM
Data Area
code area
global/static area
stack
free
free space
space
heap
• int z;
fn_a( int m ) fn_b( int n )
• main( )
• { { {
• int x; int y; int b;
• fn_a( );
• ….. . fn_b( ); …..
return instruction
• . ….. return instruction .
• .
. .
• .
• } . .
• . }
}
z
S Global static area
t Activation record of main
x
a
m
c
y
k
control link Activation record of call to fn_a( )
G return address
r n
o control link Activation record of call to fn_b( )
w return address
t fp b
sp
h Free Store (Heap)
• Two examples:
– The number of arguments in a call may vary from call to call.
– The size of an array parameter or a local array variable may vary
from call to call.
• Nested declarations can be treated in a similar way to temporary expressions, allocating them
on the stack as the block is entered and deleting them on exit.
• The strings are the words that make up the command line
arguments.
argv
argc = 3
100
argv[0]
200
u p p e r c a s e \0
argv[1] 300
S h e r l o c k H o l m e s \0
/* A sample C program */
# include <stdio.h>
int sum( ); /* function prototype */
int a=10, b=20; /* a and b are global variables, visible to main( ) as well as to sum( ) */
main()
{
int c;
c = sum();
printf(“%d+%d = %d \n”,a,b,c);
}
int sum()
{
return(a+b);
}
• #include<stdio.h>
• main( )
• {
• char var;
• while ((var = getchar( )) != ‘*’)
• {
• if ((var >= ‘A’) && (var <= ‘Z’))
• {
• uppercase_count( );
• }
• }
• }
• uppercase_count( )
• {
• static int counter = 0;
• counter ++;
• }
• When opening a file using fopen( ), one also needs to mention the
mode in which the file is to be operated on. C allows a number of
modes in which a file can be opened.
“w” Write only mode The “w” mode creates an empty file
for output. If a file by the name
already exists, it is deleted. Data can
only be written to the file, and not
read from it
• #include<stdio.h>
• main( )
• {
• FILE *fp1, *fp2;
• fp1 = fopen( “source.dat”, “r”);
• fp2 = fopen( “target.dat”, “w”);
• char ch;
• while ( (ch = fgetc( fp1)) != EOF)
• {
• fputc (ch, fp2);
• }
• fclose(fp1);
• fclose(fp2);
• }
• #include<stdio.h>
• main( )
• {
• char ch;
• while ( (ch = fgetc( stdin)) != EOF)
• {
• fputc (ch, stdout);
• }
• }
• If, after opening the file, the first input operation results in
ten bytes being read from the file, the current position in
the file from which the next input operation will take place
is from the eleventh byte position.
• If, after opening the file, the first input operation results in
ten bytes being read from the file, the current position in the
file from which the next input operation will take place is
from the eleventh byte position.
• The function fseek( ) is used for repositioning the current position in a file
opened by the function fopen( ).
• fp = fopen(“employee.dat”, r)
employee.dat
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
current offset
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
current offset
• fgets(string, 7, fp);
employee.dat
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
current offset
• fseek(fp, -10L, 2)
employee.dat
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
current offset
Structure of SALARY.DAT
employee number salary
• struct empdata {
• int empno;
• char name[10];
• char job[10];
• float salary;
• };
• struct empdata {
• int empno;
• char name[10];
• char job[10];
• float salary;
• } emprec; /* emprec is a variable of structure type empdata */
• Even for fundamental data types, the compiler does not allocate
memory for types. Rather, it allocates memory for implementations
of fundamental data types, in short, memory is allocated only for a
variable declaration.
• #include<stdio.h>
• struct salesdata
• {
• int transaction_number;
• int salesman_number;
• int product_number;
• int units_sold;
• float value_of_sale;
• };
• main( )
• {
• struct salesdata salesvar;
• compute(&salesvar);
• .
• .
• .
• }
• compute( salesdata *salesptr)
• {
• static float product_unit_price = {10.0, 20.0, 30.0, 40.0};
• /*product unit price for products numbered 1 through 4 */
• salesptr-> value_of_sale = (float)salesptr-> units_sold *
• product_unit_price[salesptr->product_number – 1]
• }
• fread( ) will return the actual number of records read from the file. This
feature can be checked for a successful read.
• An odd feature of the fread( ) function is that it does not return any
special character on encountering end of file.
• Therefore, after every read using fread( ), care must be taken to check
for end of file, for which the standard C library provides the feof( )
function. It can be used thus:
• if(feof(fp))
Byte 0 Byte 1
ch
• While you can write any type of data to a file using fwrite( ),
using fwrite( ) incurs excessive overhead for such a simple
operation.
Copyright C Programming ver 2.0 Page 316
Unions
• The following example assumes that short integers are 2 bytes long.
First, create a union consisting of one short integer and a 2-byte
character array:
• union pw
• {
• short int i;
• char ch[2];
• };
• For the same reason, you cannot use this code to achieve
the desired results:
• /* this code is wrong */
• strcpy (money, “dime”);
• For example, you need the following code to display, in words, the kind of
coins that money contains:
• switch (money)
• {
• case penny : printf( “penny”);
• break;
• case nickel : printf( “nickel”);
• break;
• case dime : printf( “dime”);
• break;
• case quarter : printf( “quarter”);
• break;
• case half_dollar : printf( “half_dollar”);
• break;
• case dollar : printf( “dollar”);
• break;
• }
• The dots are really a shorthand notation for all the numbers
between (n – 3) and (n – 2) multiplied together.
• 0! = 1
• 1! = 1
• 2! = 2 * 1
• 3! = 3 * 2 * 1
• 4! = 4 * 3 * 2 * 1
• It is cumbersome for you to list the formula for the factorial of each
integer.
prod = 1
for (x = n; x > 0; x--)
{
prod *= x;
return (prod)
}
• Using the mathematical notation used earlier, you can write the
factorial of any number as:
• n! = 1 if n = = 0
• n! = n * (n – 1)! If n > 0
• Thus, before you can evaluate 5!, you must first evaluate
4!. Using the definition once more, you find that 4! = 4 *
3!. Therefore, you must evaluate 3!.
• This produces:
• 0! = 1
• 1! = 1 * 0! = 1 * 1 = 1
• 2! = 2 * 1! = 2 * 1 = 2
• 3! = 3 * 2! = 3 * 2 = 6
• 4! = 4 * 3! = 4 * 6 = 24
• 5! = 5 * 4! = 5 * 24 = 120
• int fact(n)
• int n;
• {
• int x, y;
• if ( n == 0)
• return (1);
• else
• {
• x = n-1;
• y = fact(x);
• return ( n * y);
• }
• }
• Since execution has not yet left the first call of fact( ), the
first allocation of these variables remains.
• This previous copy is the one that was allocated upon the
original entry to the previous call and is local to that call.
2 * *
3 * *
3 2 *
4 * * 4 3 * 4 3 *
n x y n x y n x y n x y
0 * *
1 * * 1 0 *
1 0 1
2 1 * 2 1 *
2 1 * 2 1 1
3 2 * 3 2 *
3 2 * 3 2 *
4 3 * 4 3 *
4 3 * 4 3 *
n x y n x y n x y n x y
3 2 2
4 3 * 4 3 6
n x y n x y n x y
The stack at various times during execution. An asterisk indicates an uninitialized value.
• Then you compile your code, and every time your program
comes to that point, your function is called.
• But what can you do, if you don't know at build-time which
function has got to be called? Or, invoke functions at runtime.
Copyright C Programming ver 2.0 Page 366
Function Pointers
• How are function pointers used? As stated above they are typically
used so one function can take in other functions as a parameter.
• x = compute( 5, &tripleIt );
• printf("The result is: %i\n", x );
• return 0;
• }