C Programming
C Programming
• C is a structured language.
tcc pgm.c
Preprocessor
Compiler
Program Object Code File pgm.obj
Other Object Code Files (if any)
Linker
int main ( )
{
statement(s)
return 0 ;
}
1/12/2007 School of Computer Science [email protected] 21
Program Header Comment
• A comment is descriptive text used to help a
reader of the program understand its
content.
• All comments must begin with the characters
/* and end with the characters */
• These are called comment delimiters
• The program header comment always
comes first.
x=a+b
z + 2 = 3(y - 5)
• Remember that variables in algebra are
represented by a single alphabetic
character.
1/12/2007 School of Computer Science [email protected] 40
Naming Variables
• Variables in C may be given representations
containing multiple characters. But there are
rules for these representations.
• Variable names (identifiers) in C
– May only consist of letters, digits, and
underscores
– May be as long as you like, but only the first 31
characters are significant
– May not begin with a digit
– May not be a C reserved word (keyword)
1/12/2007 School of Computer Science [email protected] 41
Reserved Words (Keywords) in
C
FE07 int
1/12/2007 School of Computer Science [email protected] 48
Notes About Variables
diameter
float diameter = 5.9 ; 5.9
initial
char initial = ‘A’ ; ‘A’
return 0 ;
}
#define FEET_PER_FATHOM 6
#define INCHES_PER_FOOT 12
#define PI 3.14159
answer++ = value-- / 3 ;
++a * b - c--
++b / c + a * d++
Expression Value
i += j + k
j *= k = m + 5
k -= m /= j * 2
() left to right/inside-out
++ -- ! + (unary) - (unary) (type) right to left
* / % left to right
+ (addition) - (subtraction) left to right
< <= > >= left to right
== != left to right
&& left to right
|| left to right
= += -= *= /= %= right to left
, (comma) right to left
1/12/2007 School of Computer Science [email protected] 98
Review: Structured
Programming
• All programs can be written in terms of
only three control structures
– The sequence structure
• Unless otherwise directed, the statements are
executed in the order in which they are written.
– The selection structure
• Used to choose among alternative courses of
action.
– The repetition structure
• Allows an action to be repeated while some
condition remains true.
1/12/2007 School of Computer Science [email protected] 99
Selection: the if statement
if ( condition )
{
statement(s) /* body of the if statement */
}
if ( value == 0 )
{
printf (“The value you entered was zero.\n”) ;
printf (“Please try again.\n”) ;
}
1/12/2007 School of Computer Science [email protected] 101
Good Programming Practice
if ( value == 0 )
{
printf (“The value you entered was zero.\n”) ;
printf(“Please try again.\n”) ;
}
else
{
printf (“Value = %d.\n”, value) ;
}
1/12/2007 School of Computer Science [email protected] 105
Good Programming Practice
• Always place braces around the bodies of
the if and else clauses of an if-else
statement.
• Advantages:
– Easier to read
– Will not forget to add the braces if you go back
and add a second statement to the clause
– Less likely to make a semantic error
• Indent the bodies of the if and else clauses
3 to 5 spaces -- be consistent!
1/12/2007 School of Computer Science [email protected] 106
The Conditional Operator
expr1 ? expr2 : expr3
OR
0 0 0
0 nonzero 0
nonzero 0 0
nonzero nonzero 1
0 0 0
0 nonzero 1
nonzero 0 1
nonzero nonzero 1
if ( ! (x == 2) ) /* same as (x != 2) */
{
printf(“x is not equal to 2.\n”) ;
}
Expression ! Expression
0 1
nonzero 0
125
Simple While Loop
OUTPUT:
Index: 1
126
Example
while ( children > 0 )
{
children = children - 1 ;
cookies = cookies * 2 ;
}
/* Initializations */
total = 0 ;
counter = 1 ;
printf(“Enter a grade: “) ;
scanf(“%d”, &grade) ;
while (grade != -1) {
total = total + grade ;
counter = counter + 1 ;
printf(“Enter another grade: “) ;
scanf(“%d”, &grade) ;
}
return 0 ;
}
1/12/2007 School of Computer Science [email protected] 141
Using a while Loop to Check
#include <stdio.h>
User Input
int main ( )
{
int number ;
printf (“Enter a positive integer : “) ;
scanf (“%d”, &number) ;
while ( number <= 0 )
{
printf (“\nThat’s incorrect. Try again.\n”) ;
printf (“Enter a positive integer: “) ;
scanf (“%d”, &number) ;
}
printf (“You entered: %d\n”, number) ;
return 0 ;
}
while ( x != y )
{
printf(“x = %d”, x) ;
x=x+2;
}
for ( i = 9; i >= 0; i = i - 1 )
{
printf (“%d\n”, i) ;
}
{ Index: 3
...
default:
statement(s)
break ;
}
return 0;
}
printf (“\nprincipal = %f, rate = %f, years = %d\n”, principal, rate, years ) ;
printf (“amount = %f, interest = %f\n”);
return 0 ;
}
printf (“\nprincipal = %f, rate = %f, years = %d\n”, principal, rate, years ) ;
printf (“amount = %f, interest = %f\n”);
return 0 ;
}
printf (“\nprincipal = %f, rate = %f, years = %d\n”, principal, rate, years ) ;
printf (“amount = %f, interest = %f\n”);
return 0 ;
}
return 0 ;
}
Main
Main
Draw Draw
Door Frame Knob
Main
Draw Draw
Outline . . . Windows
Main
Draw Draw
Outline . . . Windows
Draw a
Window
int main ( )
{
printMessage ( ) ;
return 0 ;
}
int main ( )
{
printMessage ( ) ; function call
return 0 ;
}
function definition
1/12/2007 School of Computer Science [email protected] 229
The Function Prototype
• Informs the compiler that there will be a function
defined later that:
returns this type
has this name
takes these arguments
int main ( )
{
int num ; /* number of times to print message */
return 0 ;
}
5 8
5 8
int int float int int float
1/12/2007 School of Computer Science [email protected] 244
Changes to Local Variables Do NOT
Change Other Variables with the
#include <stdio.h> Same Name
void addOne (int number) ; void addOne (int num1)
{
int main ( ) num1++ ;
{ printf (“In addOne: “) ;
int num1 = 5 ; printf (“num1 = %d\n”, num1) ;
addOne (num1) ; }
printf (“In main: “) ;
printf (“num1 = %d\n”, num1) ; num1
return 0 ;
} int
num1
5 OUTPUT
int In addOne: num1 = 6
In main: num1 = 5
1/12/2007 School of Computer Science [email protected] 245
Call by Value and Call by Reference
By Default the function calling is by Value i.e. there is no
relation between actual and formal parameter. Change in
formal parameter doesn't affect actual parameter.
/* somewhere in code */
int k = contrived_example(42, 3.3);
• What does this look like on the stack?
(more frames)
return value 52
function i = 42
arguments f = 3.3
j = 10 stack frame
local d = 3.14
variables
arr[10] =
<garbage>
• Another example:
int factorial(int i)
{
if (i == 0) {
return 1;
} else {
return i * factorial (i - 1);
}
}
return value ?
factorial(3) stack frame
i = 3
return value ?
factorial(2) stack frame
i = 2
return value ?
factorial(3) stack frame
i = 3
return value ?
factorial(1) stack frame
i = 1
return value ?
factorial(2) stack frame
i = 2
return value ?
factorial(3) stack frame
i = 3
return value ?
factorial(0) stack frame
i = 0
return value ?
factorial(1) stack frame
i = 1
return value ?
factorial(2) stack frame
i = 2
return value ?
factorial(3) stack frame
i = 3
return value 1
factorial(0) stack frame
i = 0
return value ?
factorial(1) stack frame
i = 1
return value ?
factorial(2) stack frame
i = 2
return value ?
factorial(3) stack frame
i = 3
return value 1
factorial(1) stack frame
i = 1
return value ?
factorial(2) stack frame
i = 2
return value ?
factorial(3) stack frame
i = 3
return value 2
factorial(2) stack frame
i = 2
return value ?
factorial(3) stack frame
i = 3
return value 6
factorial(3) stack frame
i = 3
factorial(3)
result: 6
void foo() {
int arr[10]; /* local (on stack) */
/* do something with arr */
} /* arr is deallocated */
• Local variables sometimes called "automatic"
variables; deallocation is automatic
foo
local arr[10] =
stack frame
variables <whatever>
void foo2() {
int *arr;
/* allocate memory on the heap: */
arr = (int *)calloc(10, sizeof(int));
/* do something with arr */
} /* arr is NOT deallocated */
void foo3() {
int *arr;
/* allocate memory on the heap: */
arr = (int *)calloc(10, sizeof(int));
/* do something with arr */
free(arr);
}
heap
local arr =
stack frame
variables 0x1234
stack
1/12/2007 School of Computer Science [email protected] 271
The stack and the heap
0x1234
arr[0]
arr[1]
(after foo2
exits, arr[2]
without arr[3]
freeing memory
leak arr[4]
memory)
(etc.)
heap
stack
1/12/2007 School of Computer Science [email protected] 272
The stack and the heap
0x1234 arr[0]
arr[1]
(after foo3
exits, with arr[2]
freeing arr[3]
memory) arr[4]
(etc.)
heap
stack
[email protected] 1
Recursive Thinking
• A recursive definition is one which uses the word
or concept being defined in the definition itself
[email protected] 2
Recursive Definitions
• Consider the following list of numbers:
A LIST is a: number
or a: number comma LIST
[email protected] 3
Recursive Definitions
• The recursive part of the LIST definition is
used several times, terminating with the
non-recursive part:
number comma LIST
24 , 88, 40, 37
number
37
[email protected] 4
Infinite Recursion
• All recursive definitions have to have a non-
recursive part
[email protected] 5
Recursive Definitions
• N!, for any positive integer N, is defined to be the
product of all integers between 1 and N inclusive
[email protected] 6
Recursive Definitions
5!
120
5 * 4!
24
4 * 3!
6
3 * 2!
2
2 * 1!
1
[email protected] 7
Recursive Programming
• A Function can invoke itself; if set up that way, it
is called a recursive function
[email protected] 8
Recursive Programming
• Consider the problem of computing the sum of all
the numbers between 1 and any positive integer N
N N −1 N −2
∑i
i =1
= N + ∑i
i =1
= N + N −1 + ∑i
i =1
N −3
= N + N −1 + N − 2 + ∑i
i =1
o
[email protected] 9
Recursive Programming
// This function returns the sum of 1 to num
int sum (int num)
{
int result;
if (num == 1)
result = 1;
else
result = num + sum (n-1);
return result;
}
[email protected] 10
Recursive Programming
result = 6
main
sum(3)
result = 3
sum
sum(2)
result = 1
sum
sum(1)
sum
[email protected] 11
Recursive Programming
• Note that just because we can use recursion to
solve a problem, doesn't mean we should
[email protected] 12
Indirect Recursion
• A function invoking itself is considered to be
direct recursion
[email protected] 13
Indirect Recursion
m1 m2 m3
m1 m2 m3
m1 m2 m3
[email protected] 14
Towers of Hanoi
• The Towers of Hanoi is a puzzle made up of three
vertical pegs and several disks that slide on the
pegs
[email protected] 15
Towers of Hanoi
Move 2 Move 3
[email protected] 16
Towers of Hanoi
Move 4 Move 5
[email protected] 17
Towers of Hanoi
• An iterative solution to the Towers of Hanoi is
quite complex
[email protected] 18
Towers of Hanoi
#include <stdio.h>
#include <conio.h>
void transfer(int,char,char,char);
int main()
{
int n;
printf("Recursive Solution to Towe of Hanoi Problem\n");
printf("enter the number of Disks");
scanf("%d",&n);
transfer(n,'L','R','C');
getch();
return 0;
}
void transfer(int n,char from,char to,char temp)
{
if (n>0)
{
transfer(n-1,from,temp,to); /* Move n-1 disk from origin to temporary */
printf("Move Disk %d from %c to %c\n",n,from,to);
transfer(n-1,temp,to,from); /* Move n-1 disk from temporary to origin */
}
return;
}
[email protected] 19
Drawbacks of Recursion
Regardless of the algorithm used, recursion has two
important drawbacks:
Function-Call Overhead
Memory-Management Issues
[email protected] 20
Eliminating Recursion — Tail
Recursion
A special kind of recursion is tail recursion.
Tail recursion is when a recursive call is the last thing a
function does.
Tail recursion is important because it makes the
recursion → iteration conversion very easy.
That is, we like tail recursion because it is easy to
eliminate.
In fact, tail recursion is such an obvious thing to optimize
that some compilers automatically convert it to iteration.
[email protected] 21
Eliminating Recursion — Tail
Recursion
For a void function, tail recursion looks like this:
[email protected] 22
A tail-recursive Factorial Function
We will use an auxiliary function to rewrite factorial as tail-
recursive:
[email protected] 23
Devi Ahilya Vishwavidyalaya
Programming With C
[email protected]
Arrays
A sequential collection
Arrays
An array is a collection of variables of the same type that are referred to
through a common name.
A specific element in an array is accessed by an index. In C, all arrays
consist of contiguous memory locations.
The lowest address corresponds to the first element and the highest
address to the last element.
Arrays can have from one to several dimensions.
3 [email protected]
DAVV
SCS
Single-Dimensional Arrays
Generic declaration:
typename variablename[size]
typename is any type
variablename is any legal variable name
size is a constant number
To define an array of ints with subscripts ranging from 0 to 9, use:
int a[10];
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]
4 [email protected]
DAVV
SCS
Single-Dimensional Arrays
Array declared using int a[10]; requires 10*sizeof(int) bytes of
memory
To access individual array elements, use indexing: a[0]=10; x=a[2];
a[3]=a[2]; a[i]=a[i+1]+10; etc.
To read a value into an array location, use scanf("%d",&a[3]);
Accessing an individual array element is a fast operation
5 [email protected]
DAVV
SCS
6 [email protected]
DAVV
SCS
7 [email protected]
DAVV
SCS
Array-Bounds Checking
C, unlike many languages, DOES NOT check array bounds subscripts
during:
Compilation
Runtime
Programmer must take responsibility for ensuring that array indices are
within the declared bounds
8 [email protected]
DAVV
SCS
Array-Bounds Checking
If you access beyond the end of an array:
C calculates the address as usual
Attempts to treat the location as part of the array
Program may continue to run,OR may crash with a memory
access violation error (segmentation fault, core dump error)
It’s better if the program crashes right away – easier to debug
9 [email protected]
DAVV
SCS
Initializing Arrays
Initialization of arrays can be done by a comma separated list following
its definition.
Example: int array [4] = { 100, 200, 300, 400 };
is equivalent to:
int array [4];
array[0] = 100;
array[1] = 200;
array[2] = 300;
array[3] = 400;
Or, you can let the compiler compute the array size: int array[ ] = { 100, 200,
300, 400};
10 [email protected]
DAVV
SCS
Example
#include <stdio.h>
int main( ) {
float expenses[12]={10.3, 9, 7.5, 4.3, 10.5, 7.5, 7.5, 8, 9.9,
10.2, 11.5, 7.8};
int count,month;
float total;
for (month=0, total=0.0; month < 12; month++)
{
total+=expenses[month];
}
for (count=0; count < 12; count++)
printf ("Month %d = %.2f \n", count+1, expenses[count]);
printf("Total = %.2f, Average = %.2f\n", total, total/12);
return 0;
}
11 [email protected]
DAVV
SCS
Multidimensional Arrays
Arrays in C can have virtually as many dimensions as you want unlike
coordinate geometry.
Definition is accomplished by adding additional subscripts:
int a [4] [3] ;
defines a two dimensional array with 4 rows and 3 columns
a can be thought of as a 1-dimensional array of 4 elements, where
each element is of type int[3]
12 [email protected]
DAVV
SCS
Multidimensional Arrays
13 [email protected]
DAVV
SCS
Multidimensional Arrays
14 [email protected]
DAVV
SCS
15 [email protected]
DAVV
SCS
#include <stdio.h>
#include <stdlib.h> Example
int main () {
int random1[8][8]; The function
int a, b; int rand( );
for (a = 0; a < 8; a++)
from <stdlib.h>
for (b = 0; b < 8; b++)
returns a random
random1[a][b] = rand( )%2;
int between 0 and
for (a = 0; a < 8; a++)
RAND_MAX, a
{ constant defined
for (b = 0; b < 8; b++) in the same
printf ("%c " , random1[a][b] ? 'x' : 'o'); library.
printf("\n");
}
return 0;
}
16 [email protected]
DAVV
SCS
17 [email protected]
DAVV
SCS
18 [email protected]
DAVV
SCS
Example
Actual parameter
void bubbleSort(int a[ ],int size) corresponding to formal
{ parameter a[ ] can be
any array of int values;
int i, j, x; its declared size does not
for(i=0; i < size; i++) matter
for(j=i; j > 0; j--)
if(a[ j ] < a[ j-1])
{ /* Switch a[ j ] and a[ j-1] */
x=a[ j ]; a[ j ]=a[ j-1]; a[j-1]=x;
} Function bubbleSort( ) sorts
the first size elements of
}
array a into ascending order
19 [email protected]
Devi Ahilya Vishwavidyalaya
Pointers
Pointer Variables
Pointers are often referred to as references
The value in a pointer variable is interpreted as a memory address
Usually, pointer variables hold references to specific kinds of data (e.g.:
address of an int, address of a char, etc)
21 [email protected]
DAVV
SCS
Dereferencing Operator
22 [email protected]
DAVV
SCS
int x, *p;
x ? p ?
p = &x;
x ? p Value of x has
*p = 4; been changed
by *p = 4;
x 4 p
23 [email protected]
DAVV
SCS
NULL •
24 [email protected]
DAVV
SCS
Pointer Example
int *p, x, y, *q = NULL;
p = &x;
*p = 4;
p x 4 y ? q .
(or *p)
p = &y;
p x 4 y ? q .
*p is now another
name for y
25 [email protected]
DAVV
SCS
Pointer Example
*p = 8;
p x 4 y 8 . q
*p
q = p;
p x 4 y 8 q
*p or *q
26 [email protected]
DAVV
SCS
Pointer Example
p = &x;
p x 4 y 8 q
*p *q
*p = *q;
p x 8 y 8 q
*q
*p
27 [email protected]
DAVV
SCS
Arrays of Pointers
It’s possible to have arrays of pointers
The array name is a pointer to an array of pointers:
6 j 4 k ? ? ? ?
arrayOfPtr 0 1 2 3
28 [email protected]
DAVV
SCS
Arrays of Pointers
arrayOfPtr[0] = &k;
arrayOfPtr[2]=&j;
6 4
? ?
j k arrayOfPtr 0 1 2 3
29 [email protected]
DAVV
SCS
30 [email protected]
DAVV
SCS
31 [email protected]
DAVV
SCS
Generic Pointers
Sometimes we need to use pointer variables that aren’t associated with
a specific data type
In C, these generic pointers simply hold memory addresses, and are
referred to as pointers to void:
void* ptr;
32 [email protected]
DAVV
SCS
Generic Pointers
Any kind of pointer can be stored in a variable whose type is void*
If we know that a value in a pointer p of type void* is really of a specific
pointer type x, and we want to treat the value p points to as a value of
type x, we have to cast the pointer to type x
33 [email protected]
DAVV
SCS
n ? j 7
arr ? ? ? ? ? ?
0 1 2 3 4 5
34 [email protected]
DAVV
SCS
x ? k 5.9
n ? j 7
? ? ? ? ?
arr
0 1 2 3 4 5
35 [email protected]
DAVV
SCS
x ? k 5.9
n ? j 7
? ? ? ? ?
arr
0 1 2 3 4 5
36 [email protected]
DAVV
SCS
x ? k 5.9
n 7
j
? ? ? ?
arr
0 1 2 3 4 5
37 [email protected]
DAVV
SCS
x 5.9 k 5.9
n 7
j
? ? ? ?
arr
0 1 2 3 4 5
38 [email protected]
Devi Ahilya Vishwavidyalaya
40 [email protected]
DAVV
SCS
41 [email protected]
DAVV
SCS
42 [email protected]
DAVV
SCS
43 [email protected]
DAVV
SCS
double * ptr;
ptr = (double *) (malloc( sizeof( double ) ) );
44 [email protected]
DAVV
SCS
45 [email protected]
DAVV
SCS
46 [email protected]
DAVV
SCS
p ?
p = (int*)malloc(sizeof(int));
p ?
*p
*p = 24;
p 24 *p
free(p);
24 unstable
p memory
47 [email protected]
DAVV
SCS
arr ?
arr = (double*)(malloc(5*sizeof(double)));
arr ? ? ? ? ?
arr[2] = 8.0;
arr ? ? 8.0 ? ?
48 [email protected]
DAVV
SCS
49 [email protected]
DAVV
SCS
int ** ptrArray;
int k = 7;
ptrArray = (int**)(malloc( 4*sizeof(int*)));
ptrArray ? ? ? ?
k 7
50 [email protected]
DAVV
SCS
ptrArray ? ?
k 7
? *(ptrArray[3])
51 [email protected]
DAVV
SCS
52 [email protected]
Devi Ahilya Vishwavidyalaya
Pointers as Parameters in C
#include <stdio.h>
Example:
void add1(int a, int *b) { add1 accepts as parameters an int
a++; (*b)++; a and a pointer to int b
printf(“%d\n”, a); The call in the main is made, a is
printf(“%d\n”, *b); associated with a copy of main
return program variable j, and b is
associated with a copy of the
}
address of main program variable k
int main() {
int j = 4; k = 8;
Output from the program is:
add1( j, &k ); 5 (in add1)
printf(“%d\n”, j); 9
printf(“%d\n”, k);
4 (back in main)
return 0;
}
9
54 [email protected]
DAVV
SCS
55 [email protected]
DAVV
SCS
56 [email protected]
DAVV
SCS
#include <stdio.h>
Example (cont’d):
void add1(int a, int *b) { After a++; is executed
a++; (*b)++;
printf(“%d\n”, a);
printf(“%d\n”, *b);
return
}
int main() {
int j = 4; k = 8; 5
a b
add1( j, &k );
printf(“%d\n”, j);
printf(“%d\n”, k);
j 4 k 8
return 0;
}
57 [email protected]
DAVV
SCS
#include <stdio.h>
Example (cont’d):
void add1(int a, int *b) { After (*b)++; is executed
a++; (*b)++;
printf(“%d\n”, a);
printf(“%d\n”, *b);
return
}
int main() {
int j = 4; k = 8; 5
a b
add1( j, &k );
printf(“%d\n”, j);
printf(“%d\n”, k);
j 4 k 9
return 0;
}
58 [email protected]
DAVV
SCS
59 [email protected]
DAVV
SCS
60 [email protected]
DAVV
SCS
p 6.3 dptr1
We will examine
? ?
a variety of valid
q dptr2
calls to fn
a ? d e ?
g
15 ?
b c f
61 [email protected]
DAVV
SCS
fn ( &p, &c );
x k
Recall the
prototype:
p 6.3 dptr1 void fn( double * x,
int ** k)
q ? ? dptr2
Recall from main:
? ? int b,*c=&b;
a d e g
double p=6.3;
15 ?
b c f
62 [email protected]
DAVV
SCS
fn ( dptr1, &d );
x k
Recall the
prototype:
63 [email protected]
DAVV
SCS
fn ( &q, f );
x ?? k Danger: f doesn’t
point at anything yet
64 [email protected]
DAVV
SCS
fn ( dptr2, &e);
?? x k Danger: dptr2 is
uninitialized
65 [email protected]
DAVV
SCS
fn ( &p, g );
x k
Recall the
prototype:
p 6.3 dptr1 void fn( double * x,
int ** k)
q ? ? dptr2
Recall from main:
int *e, **g=&e;
a ? d e ? g
double p=6.3;
15 ?
b c f
66 [email protected]
DAVV
SCS
67 [email protected]
DAVV
SCS
Arrays as Parameters
C does not allow arrays to be copied as parameters
Recall:
Array name is really a pointer to the first element (location 0)
Indexing with square brackets has the effect of dereferencing to a
particular array location
68 [email protected]
DAVV
SCS
Arrays as Parameters
When we put an array name in a list of actual parameters, we are really
passing the pointer to the first element
Do not use the address operator & when passing an array
69 [email protected]
DAVV
SCS
Arrays as Parameters
Suppose that we wish to pass an array of integers to a function fn, along
with the actual number of array locations currently in use
The following function prototypes are equivalent:
70 [email protected]
DAVV
SCS
#include <stdlib.h>
Example
void init1 ( int [ ] a, int s1, int * b, int s2 ) {
for (int j = 0; j < s1; j++)
Could use int *a
a[ j ] = j;
and int[ ] b instead
for (int k = 0; k < s2; k++)
b[ k ] = s2 - k;
}
We trace through
int main( ) {
this code on the
int s[4], *t; next few slides
t = (int*)(malloc(6*sizeof(int));
t[0] = 6;
init1( s, 4, t, t[0] );
…
71 [email protected]
DAVV
SCS
Example (cont’d)
t 6 ? ? ? ? ?
72 [email protected]
DAVV
SCS
Example (cont’d)
After call to init1, but before its execution begins:
local vars j and k have been ignored in the call frame for init1
Function prototype:
a s1 b s2
void init1 ( int [ ] a, int s1,
4 6
int * b, int s2 );
Function call:
? ? ? ? init1( s, 4, t, t[0] );
s
t 6 ? ? ? ? ?
Call stack
Heap
73 [email protected]
DAVV
SCS
Example (cont’d)
After execution of init1, but before return to main:
local vars j and k have been ignored in the call frame for init1
After:
a s1 b s2
for (int j = 0; j < s1; j++)
4 6
a[ j ] = j;
for (int k = 0; k < s2; k++)
0 1 2 3 b[ k ] = s2 - k;
s
t 6 5 4 3 2 1
Call stack
Heap
74 [email protected]
DAVV
SCS
Example (cont’d)
After returning to main:
s 0 1 2 3
t 6 5 4 3 2 1
Heap
Call stack
75 [email protected]
DAVV
SCS
76 [email protected]
DAVV
SCS
#include <stdlib.h>
Example
#include<time.h>
void init2( int *** t, int ** j ) { Dynamic allocation in init2
int k = 3 + rand( )%10; creates an array of
*t = (int**)(malloc(k*sizeof(int*))); pointers for main program
*j = (int*)(malloc(sizeof(int))); variable v to point at, and
**j = k; an int location for q to point
} at; the value that q points
int main( ) { at is also initialized
int **v; int *q;
srand((unsigned int) time(NULL));
init2( &v, &q );
Trace follows on next
v[1] = q;
slides
…
77 [email protected]
DAVV
SCS
Example (cont’d)
After declarations:
v ? int **v;
int *q;
q ?
Call stack
78 [email protected]
DAVV
SCS
Example (cont’d)
q ?
int*
Call stack
79 [email protected]
DAVV
SCS
Example (cont’d)
v
? ? ? ? ? ? ?
int**
q ?
Heap
int*
Call stack
80 [email protected]
DAVV
SCS
Example (cont’d)
v
? ? ? ? ? ? ?
int**
int* ?
81 [email protected]
DAVV
SCS
Example (cont’d)
int** int*** int After execution of:
j t k 7 **j = k;
v
? ? ? ? ? ? ?
int**
int* 7
82 [email protected]
DAVV
SCS
Example (cont’d)
v
? ? ? ? ? ? ?
int**
int* 7
83 [email protected]
DAVV
SCS
Example (cont’d)
v
? ? ? ? ? ?
int**
int* 7
84 [email protected]
DAVV
SCS
85 [email protected]
DAVV
SCS
No warning from the final line: the value from the calling
module that’s being referenced is not modified; however,
the function’s copy of the value’s address changes
86 [email protected]
Devi Ahilya Vishwavidyalaya
88 [email protected]
DAVV
SCS
#include <stdlib.h>
Example
int * init3( int j ) {
int *k, t;
The function init3
k = (int*)malloc(j*sizeof(int)); dynamically allocates an
for (t=0; t<j; t++) array of int, initializes it,
k[t] = t; and returns a reference to
it; in this case, the array
return k;
has the capacity to hold 40
} integers
int main() {
int *q;
q = init3( 40 );
…
89 [email protected]
DAVV
SCS
Example (cont’d)
After the call to init3, but Function prototype:
before body is executed:
int * init3( int j );
int int int* Function call:
40 ? ? q = init3( 40 );
j t k
q ?
int*
Call stack
90 [email protected]
DAVV
SCS
Example (cont’d)
q ? 0 1 2 3 … 39
int*
Call stack Value to be returned is in k
Heap
91 [email protected]
DAVV
SCS
Example (cont’d)
q 0 1 2 3 … 39
int*
Call stack Heap
Portion of the call stack for the call to init3 has been recycled
92 [email protected]
DAVV
SCS
93 [email protected]
DAVV
SCS
#include <stdlib.h>
Example
#include <time.h>
int ** init4( int ** size ) {
Local variables k and arr
int k, *arr;
exist only while init4 is
k = (int) 5 + rand( )%10;
being executed
arr = (int*)malloc(k*sizeof(int));
*size = &k; // Wrong Values stored at those
return &arr; // Wrong locations will likely be
} overwritten the next time
int main() { any function is called
int ** vals, *numvals;
Values of vals and
srand((unsigned int) time(NULL));
vals = init4( &numvals );
numvals (in main) would
…
therefore be destroyed
94 [email protected]
DAVV
SCS
Example (cont’d)
Function prototype:
int* int** int
int ** init4( int ** size );
arr ? size k ?
Function call:
vals = init4( &numvals );
vals ? numvals ?
int** int*
Call stack
95 [email protected]
DAVV
SCS
size k 8 arr
Value to be returned is
address of arr
numvals vals ?
? ? ? ? ? ? ? ?
int* int**
Call stack Heap
96 [email protected]
DAVV
SCS
numvals vals
? ? ? ? ? ? ? ?
int* int**
Call stack Heap
97 [email protected]
DAVV
SCS
numvals vals
? ? ? ? ? ? ? ?
int* int**
Call stack Heap
98 [email protected]
Devi Ahilya Vishwavidyalaya
Pointer Arithmetic
Pointer Arithmetic
Pointers are really numeric memory addresses
C allows programmers to perform arithmetic on pointers
Most commonly used with arrays and strings, instead of indexing, but
can be used with any pointer
We won’t use pointer arithmetic much, but you may need to understand
it to read text books and other people’s code
100 [email protected]
DAVV
SCS
Pointer Arithmetic
When used with an int array a:
a is a pointer to int, and points to a[0]
a+1 points to array element a[1]
a+2 points to array element a[2] , etc
*(a+4) = 10; is equivalent to a[4] = 10;
Can compare pointers using ==, !=, >, <=, etc
101 [email protected]
DAVV
SCS
Pointer Arithmetic
More examples:
int a[10], *p, *q;
p = &a[2];
q = p + 3; /* q points to a[5] now */
p = q – 1; /* p points to a[4] now */
p++; /* p points to a[5] now */
p--; /* p points to a[4] now */
*p = 123; /* a[4] = 123 */
*q = *p; /* a[5] = a[4] */
q = p; /* q points to a[4] now */
102 [email protected]
DAVV
SCS
Pointer Arithmetic
The difference between two pointers of the same type yields an int result
103 [email protected]
DAVV
SCS
Pointer Arithmetic
Note that pointer arithmetic and int arithmetic are not, in general, the
same
In our previous examples: on most computers, an int requires 4 bytes
(In Turbo C it is 2 Bytes) of storage
Adding 1 to a pointer to int actually increments the address by 4, so
that it points at the next memory location beyond the current int
Casting a pointer to the wrong type leads to pointer arithmetic errors
104 [email protected]
DAVV
SCS
Pointer Arithmetic
int a[10], *p, *q , i;
char s[25], *u, *v, k;
p = &a[2]; q = &a[5];
i = q - p; /* i is 3, but the difference between the two
addresses is 12: space for 3 ints */
q++; /* address in q actually goes up by 4 bytes */
u = &s[6]; v = &s[12];
i = v – u; /* i is 6, and the difference between the two
addresses is 6, because a char requires
only 1 byte of storage */
u++; /* u = &s[7]; address in u goes up 1 byte */
105 [email protected]
DAVV
SCS
Example
106 [email protected]
DAVV
SCS
Strings in C
No explicit string type in C; strings are simply arrays of characters that
are subject to a few special conventions
Example: char s [10]; declares a 10-element array that can hold a
character string of up to 9 characters
Convention: Use the null character '\0' to terminate all strings
107 [email protected]
DAVV
SCS
Strings in C
C does not know where an array ends at run time – no boundary
checking
All C library functions that use strings depend on the null character being
stored so that the end of the string can be detected
Example: char str [10] = {'u', 'n', 'i', 'x', '\0'};
Length of str is 4 (not 5, and not the declared size of the array)
108 [email protected]
DAVV
SCS
109 [email protected]
DAVV
SCS
String Literals
Example: printf("Long long ago.");
Other ways to initialize a string:
110 [email protected]
DAVV
SCS
111 [email protected]
DAVV
SCS
112 [email protected]
DAVV
SCS
Example
char str[11]="unix and c";
printf("%s\n", str);
str[6]='\0'; What output does this
printf("%s\n", str); code segment produce?
printf(str); printf("\n");
str[2]='%';
str[3]= ‘s';
printf(str,str);
printf("\n");
113 [email protected]
DAVV
SCS
114 [email protected]
DAVV
SCS
Example:
char sentence[ ] = "The quick brown fox\n";
puts(sentence);
Prints out two lines:
The quick brown fox
this blank line is part of the output
puts adds a newline ‘\n’ character following the string
115 [email protected]
DAVV
SCS
116 [email protected]
DAVV
SCS
117 [email protected]
DAVV
SCS
118 [email protected]
DAVV
SCS
119 [email protected]
DAVV
SCS
Example
#include <stdio.h>
int main ( )
{
char lname[81], fname[81];
int count, age;
puts ("Enter the last name, first name, and age, separated");
puts ("by spaces; then press Enter \n");
count = scanf ("%s%s%d", lname, fname, &age);
printf ("%d items entered: %s %s %d\n",
count, fname, lname, age);
return 0;
}
120 [email protected]
DAVV
SCS
121 [email protected]
DAVV
SCS
122 [email protected]
DAVV
SCS
123 [email protected]
DAVV
SCS
124 [email protected]
DAVV
SCS
Example
#include <string.h>
#include <stdio.h>
int main( )
{ Show the output
char str1[27] = "abc";
char str2[100];
printf("%d\n",strlen(str1));
strcpy(str2,str1);
puts(str2);
puts("\n");
strcat(str2,str1);
puts(str2);
}
125 [email protected]
DAVV
SCS
126 [email protected]
DAVV
SCS
127 [email protected]
DAVV
SCS
128 [email protected]
DAVV
SCS
129 [email protected]
DAVV
SCS
130 [email protected]
DAVV
SCS
131 [email protected]
DAVV
SCS
132 [email protected]
DAVV
SCS
133 [email protected]
DAVV
SCS
134 [email protected]
DAVV
SCS
135 [email protected]
DAVV
SCS
#include <stdio.h>
#include <string.h>
int main( )
{
char result[100];
sprintf(result, "%f", (float)17/37 );
if (strstr(result, "45") != NULL)
printf("The digit sequence 45 is in 17 divided by 37. \n");
return 0;
}
136 [email protected]
DAVV
SCS
137 [email protected]
DAVV
SCS
138 [email protected]
DAVV
SCS
139 [email protected]
Devi Ahilya Vishwavidyalaya
141 [email protected]
DAVV
SCS
142 [email protected]
Devi Ahilya Vishwavidyalaya
Passing Parameters to C
Often a user wants to pass parameters into the program from
the command prompt
:\tc\bin>progname arg1 arg2 arg3
This is accomplished in C using argc and argv
144 [email protected]
DAVV
SCS
Passing Parameters to C
#include <stdio.h>
int main(int argc, char *argv[ ])
{
int count;
printf ("Program name: %s\n", argv [0]);
if (argc > 1)
{
for (count=1; count<argc; count++)
printf ("Argument %d: %s\n",count,argv[count]);
}
else
puts ("No command line arguments entered.");
return 0;
}
145 [email protected]
DAVV
SCS
Passing Parameters to C
146 [email protected]
DAVV
SCS
Passing Parameters to C
C program should check the command line arguments for validity:
Are there the right number of arguments?
Are numeric arguments in the expected range of acceptable values?
If an argument is an input or output file, can it be opened
successfully?
Issue an error message and abort execution if arguments are
incorrect
147 [email protected]
Devi Ahilya Vishwavidyalaya
Compiler Directives
The C Preprocessor
The C preprocessor is invoked by the compilation command before compiling
begins
Changes your source code based on instructions called preprocessor
directives that are embedded in the source code
The preprocessor creates a new version of your program and it is this new
program that actually gets compiled
149 [email protected]
DAVV
SCS
The C Preprocessor
Normally, you do not see these new versions on the hard disk, as they
are deleted after compilation
You can force the compiler to keep them to see the results
Each preprocessor directive appears in the source code preceded by a
‘#’ sign
150 [email protected]
DAVV
SCS
151 [email protected]
DAVV
SCS
#include <stdio.h>
#define PI 3.1416
#define PRINT printf
int main( )
{
PRINT(“Approximate value of pi: %f”, PI);
return 0;
}
152 [email protected]
DAVV
SCS
Function Macros
You can also define function macros:
#define MAX(A,B) ( (a) > (b) ? (a) : (b) )
……
printf("%d", 2 * MAX(3+3, 7)); /* is equivalent to */
printf("%d", 2 * ( (3+3) > (7) ? (3+3) : (7) );
The parentheses are important:
#define MAX(A,B) a>b?a:b
printf("%d", 2 * MAX(3+3, 7)); /*is equivalent to */
printf("%d", 2 * 3+3 > 7 ? 3+3 : 7 );
153 [email protected]
DAVV
SCS
154 [email protected]
DAVV
SCS
Conditional Compilation
The pre-processor directives #if, #elif, #else, and #endif tell the compiler if the
enclosed source code should be compiled
Structure:
#if condition_1
statement_block_1
#elif condition_2
statement_block_2
...
#elif condition_n
Any constant expression
statement_block_n • If true (non-zero), compile
#else statement_block_1
default_statement_block • If false (zero), don't compile
#endif statement_block_1
155 [email protected]
DAVV
SCS
Conditional Compilation
For the most part, the only things that can be tested are the things that
have been defined by #define statements
#define ENGLAND 0
#define FRANCE 1
#define ITALY 0
#if ENGLAND
#include "england.h"
#elif FRANCE
#include "france.h"
#elif ITALY
#include "italy.h"
#else
#include "canada.h"
#endif
156 [email protected]
DAVV
SCS
Conditional Compilation
Conditional compilation can also be very useful for including debugging code
When you are debugging your code you may wish to print out some
information during the running of your program
You may not need want this extra output when you release your program;
you’d need to go back through your code to delete the statements
157 [email protected]
DAVV
SCS
Conditional Compilation
Instead, you can use #if … #endif to save time:
#define DEBUG 1
……
#if DEBUG
printf("Debug reporting at function my_sort()!\n");
#endif
……
Change DEBUG to zero and recompile to suppress the debugging
output
158 [email protected]
DAVV
SCS
Conditional Compilation
We can use a preprocessor function as the condition of
compilation:
defined ( NAME )
Returns true if NAME has been defined; else false
Example:
#define DEBUG
#if defined ( DEBUG )
printf("debug report at function my_sort() \n");
#endif
159 [email protected]
DAVV
SCS
Conditional Compilation
Note: Value of the defined function depends only on whether
the name DEBUG has been defined
It has nothing to do with which value (if any) DEBUG is
defined to; in fact, we don’t have to provide a value at all
Can use the notation #ifdef NAME instead
We also have #ifndef (if not defined)
160 [email protected]
DAVV
SCS
Conditional Compilation
The #undef … directive makes sure that defined( …) evaluates to false.
Example: Suppose that, for the first part of a source file, you want
DEBUG to be defined, and for the last part, you want DEBUG to be
undefined
161 [email protected]
DAVV
SCS
Conditional Compilation
A directive can also be set on the Unix/DOS command line at compile
time:
tcc/cc –DDEBUG myprog.c
Compiles myprog.c with the symbol DEBUG defined
as if #define DEBUG was in written at the top of
myprog.c
162 [email protected]
DAVV
SCS
163 [email protected]
DAVV
SCS
164 [email protected]
Devi Ahilya Vishwavidyalaya
Structures in C
Structures are used in C to group together related data into a composite
variable. This technique has several advantages:
It clarifies the code by showing that the data defined in the structure
are intimately related.
It simplifies passing the data to functions. Instead of passing multiple
variables separately, they can be passed as a single unit.
166 [email protected]
DAVV
SCS
Structures
Structure: C’s way of grouping a collection of data into a single
manageable unit
Defining a structure type:
struct coord {
int x ;
int y ;
};
This defines a new type struct coord; no variable is actually declared
or generated
167 [email protected]
DAVV
SCS
Defines the
Structures structured type struct
coord and statically
To define struct variables: allocates space for
struct coord { two structures, first
int x,y ; and second; the
structures are not
} first, second; initialized
Another approach:
struct coord {
int x,y ; Just defines the
}; structured type
............... Statically allocated
struct coord first, second; variables are
declared here
struct coord third;
168 [email protected]
DAVV
SCS
Structures
You can use a typedef if you want to avoid two-word type names such as
struct coord:
typedef struct coord coordinate;
coordinate first, second;
In some compilers, and all C++ compilers, you can usually simply say
just:
coord first, second;
169 [email protected]
DAVV
SCS
Structures
Type definition can also be written as:
typedef struct coord {
int x,y ;
} coordinate;
In general, it’s best to separate the type definition from
the declaration of variables
170 [email protected]
DAVV
SCS
Structures
Access structure members by the dot (.) operator
Generic form:
structure_var.member_name
For example:
coordinate pair1, pair2;
pair1.x = 50 ;
pair2.y = 100;
171 [email protected]
DAVV
SCS
Structures
struct_var.member_name can be used anywhere a variable can be
used:
printf ("%d , %d", second.x , second.y );
scanf("%d, %d", &first.x, &first.y);
172 [email protected]
DAVV
SCS
Structures
Can copy entire structures using =
pair1 = pair2;
performs the same task as:
pair1.x = pair2.x ;
pair1.y = pair2.y ;
173 [email protected]
DAVV
SCS
174 [email protected]
DAVV
SCS
? ? ? ? Rectangle blueprint
x y x y
topleft bottomright
175 [email protected]
DAVV
SCS
topleft bottomright
176 [email protected]
DAVV
SCS
int main ( )
Example {
int length, width;
#include <stdio.h> long area;
typedef struct coord { rectangle mybox;
int x; mybox.topleft.x = 0;
int y; mybox.topleft.y = 0;
}coordinate; mybox.bottomright.x = 100;
typedef struct rect { mybox.bottomright.y = 50;
coordinate topleft; width = mybox.bottomright.x –
coordinate bottomright; mybox.topleft.x;
}rectangle; length = mybox.bottomright.y –
mybox.topleft.y;
area = width * length;
printf (“Area is %ld units.\n", area);
}
177 [email protected]
DAVV
SCS
float char[5]
178 [email protected]
DAVV
SCS
179 [email protected]
DAVV
SCS
Arrays of Structures
Example:
struct entry {
char fname [10] ;
char lname [12] ;
char phone [8] ; This creates an
array of 1000
}; structures of type
struct entry list [1000]; struct entry
Possible assignments:
list [1] = list [6];
strcpy (list[1].phone, list[6].phone);
list[6].phone[1] = list[3].phone[4] ;
180 [email protected]
DAVV
SCS
int main() {
Example struct entry list[4];
int i;
#include <stdio.h> for (i=0; i < 4; i++) {
struct entry { printf ("\nEnter first name: ");
char fname [20]; scanf ("%s", list[i].fname);
char lname [20]; printf ("Enter last name: ");
char phone [10]; scanf ("%s", list[i].lname);
}; printf ("Enter phone in 123-4567 format: ");
scanf ("%s", list[i].phone);
}
printf ("\n\n");
for (i=0; i < 4; i++) {
printf ("Name: %s %s", list[i].fname,
list[i].lname);
printf ("\t\tPhone: %s\n", list[i].phone);
}
}
181 [email protected]
DAVV
SCS
Initializing Structures
• Example:
struct sale {
char customer [20] ;
char item [20] ;
int amount ;
};
struct sale mysale = { "Acme Industries",
"Zorgle blaster",
1000 } ;
182 [email protected]
DAVV
SCS
Initializing Structures
Example: Structures within structures:
struct customer {
char firm [20] ;
char contact [25] ;
};
struct sale {
struct customer buyer ;
char item [20] ;
int amount ;
} mysale =
{ { "Acme Industries", "George Adams"} ,
"Zorgle Blaster", 1000
};
183 [email protected]
DAVV
SCS
Initializing Structures
184 [email protected]
DAVV
SCS
Pointers to Structures
struct part {
float price ;
char name [10] ;
};
struct part *p , thing;
p = &thing;
/* The following two statements are equivalent */
thing.price = 50;
(*p).price = 50; /* ( ) around *p is needed */
185 [email protected]
DAVV
SCS
Pointers to Structures
thing.price thing.name [ ]
186 [email protected]
DAVV
SCS
Pointers to Structures
187 [email protected]
DAVV
SCS
Pointers to Structures
188 [email protected]
DAVV
SCS
Pointers to Structures
189 [email protected]
DAVV
SCS
Pointers to Structures
You can allocate a structure array as well:
struct part *ptr;
ptr = (struct part *) malloc(10*sizeof(struct part) );
for( i=0; i< 10; i++)
{
ptr[ i ].price = 10.0 * i;
sprintf( ptr[ i ].name, "part %d", i );
}
……
free(ptr);
}
190 [email protected]
DAVV
SCS
Pointers to Structures
191 [email protected]
DAVV
SCS
? ? ? ? ? ?
a b c
struct node a,b,c;
a.next = &b;
b.next = &c;
c.next = NULL;
? ? ? NULL
a b c
192 [email protected]
DAVV
SCS
1 2 3
a b c
193 [email protected]
DAVV
SCS
/* This copies one struct into /* Equivalently, you can use memcpy */
another */ #include <string.h>
#include<string.h> {
{ struct part a,b;
struct part a,b; b.price = 39.99;
b.price = 39.99; strcpy(b.name,"floppy“);
strcpy(b.name,"floppy“); memcpy(&a,&b,sizeof(part));
a = b; }
}
194 [email protected]
DAVV
SCS
195 [email protected]
DAVV
SCS
b a
b a
196 [email protected]
DAVV
SCS
197 [email protected]
DAVV
SCS
198 [email protected]
DAVV
SCS
199 [email protected]
DAVV
SCS
200 [email protected]
DAVV
SCS
201 [email protected]
DAVV
SCS
202 [email protected]
DAVV
SCS
203 [email protected]
DAVV
SCS
204 [email protected]
DAVV
SCS
#include<stdio.h>
struct book {
float price;
char abstract[5000];
};
void print_abstract( struct book
*p_book)
{
puts( p_book->abstract );
};
205 [email protected]
DAVV
SCS
Unions
union
Memory that contains a variety of objects over time
Only contains one data member at a time
Members of a union share space
Conserves storage
Only the last data member defined can be accessed
union declarations
Same as struct
union Number {
int x;
float y;
};
union Number value;
206 [email protected]
DAVV
SCS
Unions
Valid union operations
Assignment to union of same type: =
Taking address: &
Accessing union members: .
Accessing members using pointers: ->
207 [email protected]
DAVV
SCS
208 [email protected]
DAVV
SCS
209 [email protected]
DAVV
SCS
210 [email protected]
Devi Ahilya Vishwavidyalaya
Bit Fields
Bit fields allow one to specify members of a struct that only use a
specified number of bits. The size of bits does not have to be a multiple
of eight.
A bit field member is defined like an unsigned int or int member with a
colon and bit size appended to it.
212 [email protected]
DAVV
SCS
An example of bitfield
The first bitfield is assigned to the least significant bits of its word
213 [email protected]
DAVV
SCS
Bitwise Operators
All data represented internally as sequences of bits
Each bit can be either 0 or 1
Sequence of 8 bits forms a byte
Operator Name Description
& bitwise AND The bits in the result are set to 1 if the corresponding
bits in the two operands are both 1.
| bitwise OR The bits in the result are set to 1 if at least one of the
corresponding bits in the two operands is 1.
^ bitwise exclusive OR The bits in the result are set to 1 if exactly one of the
corresponding bits in the two operands is 1.
<< left shift Shifts the bits of the first operand left by the number
of bits specified by the second operand; fill from right
with 0 bits.
>> right shift Shifts the bits of the first operand right by the number
of bits specified by the second operand; the method
of filling from the left is machine dependent.
~ One’s complement All 0 bits are set to 1 and all 1 bits are set to 0.
214 [email protected]
Devi Ahilya Vishwavidyalaya
Files in C
FILE *
C uses the FILE* data type to access files
FILE is defined in <stdio.h>
#include <stdio.h>
int main( )
{
FILE * fp;
fp = fopen("tmp.txt", "w");
fprintf(fp,"This is a test\n");
fclose(fp);
return 0;
}
216 [email protected]
DAVV
SCS
Opening a File
217 [email protected]
DAVV
SCS
Opening a File
218 [email protected]
DAVV
SCS
Opening a File
Enclose the mode in double quotes or pass as a string variable
Modes are:
r: open the file for reading; fopen returns NULL if the file doesn’t
exist or can’t be opened
w: create file for writing; destroy old if file exists
a: open for writing; create if not there; start at the end-of-file
(append mode)
r+: open for update (r/w); create if not there; start at the beginning
w+: create for r/w; destroy old if there
a+: open for r/w;create if not there; start at the end-of-file
219 [email protected]
DAVV
SCS
220 [email protected]
DAVV
SCS
221 [email protected]
DAVV
SCS
{ …
FILE *fp1, *fp2;
int n;
fp1 = fopen("file1", "r");
fp2 = fopen("file2", "w");
fscanf(fp1, "%d", &n);
fprintf(fp2, "%d", n);
fclose(fp1);
fclose(fp2);
}
222 [email protected]
DAVV
SCS
223 [email protected]
DAVV
SCS
#include <stdio.h>
char *fgets(char *s, int n, FILE * fp);
int fputs(char *s, FILE * fp);
fgets reads an entire line into s, up to n-1 chars in length; includes the
newline char in the string, unless line is longer than n-1
fgets returns the pointer s on success, or NULL if an error or end-of-file
is reached
fputs returns the number of chars written if successful; otherwise,
returns EOF
224 [email protected]
DAVV
SCS
225 [email protected]
DAVV
SCS
226 [email protected]
DAVV
SCS
227 [email protected]
DAVV
SCS
Example
#include<stdio.h>
#define BUFSIZE 100 This program echoes
int main ( ) { the contents of file1 to
char buf[BUFSIZE]; standard output with
if ( (fp=fopen("file1", "r"))==NULL) { one flaw: the last line is
fprintf (stderr,"Error opening file."); echoed twice; it would
exit (1); be better to use:
}
while (!feof(fp)) { while (fgets(buf, BUFSIZE,
fgets (buf,BUFSIZE,fp);
fp) != NULL)
printf ("%s",buf);
} printf(“%s”,buf);
fclose (fp);
return 0;
}
228 [email protected]
Devi Ahilya Vishwavidyalaya
fread and fwrite are binary file reading and writing functions
Prototypes are found in stdio.h
Advantages of using binary files:
Reading and writing are quick, since I/O is not being converted
from/to ASCII characters
Large amounts of data can be read/written with a single function
call (block reading and writing)
Disadvantage of using binary files:
Contents are not easily read by humans
230 [email protected]
DAVV
SCS
Generic form:
int fwrite (void *buf, int size, int count, FILE *fp) ;
int fread (void *buf, int size, int count, FILE *fp) ;
buf: is a pointer to the region in memory to be written/read; it can be a
pointer to anything (a simple variable, an array, a structure, etc)
size: the size in bytes of each individual data item
count: the number of data items to be written/read
231 [email protected]
DAVV
SCS
232 [email protected]
DAVV
SCS
233 [email protected]
DAVV
SCS
234 [email protected]
DAVV
SCS
235 [email protected]
DAVV
SCS
236 [email protected]
DAVV
SCS
Random Access
If we’re aware of the structure of a file, we can move the file’s position indicator
anywhere we want within the file (random access):
int fseek (FILE * fp, long offset, int origin) ;
offset is the number of bytes to move the position indicator
origin says where to move from
237 [email protected]
DAVV
SCS
Random Access
Three options/constants are defined for origin:
SEEK_SET: move the indicator offset bytes from the beginning
SEEK_CUR: move the indicator offset bytes from its current position
SEEK_END: move the indicator offset bytes from the end
238 [email protected]
DAVV
SCS
Random Access
Random access is most often used with binary input files, when speed of
execution matters: we want to avoid having to read in data sequentially
to get to a known location
Writing to a location in a file other than the end does not insert content: it
overwrites
239 [email protected]
DAVV
SCS
240 [email protected]
DAVV
SCS
Erasing a file:
int remove (const char * filename);
This is a character string naming the file
Returns 0 if deleted, and -1otherwise
If no pathname is provided, attempts to delete the file
from the current working directory
Can fail for several reasons: file not found, user does not
have write privileges, file is in use by another process,
etc
241 [email protected]
DAVV
SCS
242 [email protected]
DAVV
SCS
243 [email protected]
DAVV
SCS
Example
#include <stdio.h>
int main () {
char buffer[25];
tmpnam(buffer);
printf ("Temporary name is: %s", buffer);
return 0;
}
Output:
Temporary name is: c:\tc\bin\aaaceaywB
244 [email protected]
DAVV
SCS
Every C program has three files opened for them at start-up: stdin,
stdout, and stderr
stdin (standard input) is opened for reading, while stdout (standard
output) and stderr (standard error) are opened for writing
They can be used wherever a FILE * can be used
Writing to stderr is a good practice when reporting error messages: it
causes all output buffers to be flushed (written), and aids debugging
245 [email protected]
DAVV
SCS
246 [email protected]
DAVV
SCS
247 [email protected]
Devi Ahilya Vishwavidyalaya
249 [email protected]
DAVV
SCS
250 [email protected]
DAVV
SCS
251 [email protected]
DAVV
SCS
Enumeration Constants
Enumeration
Set of integer constants represented by identifiers
Enumeration constants are like symbolic constants whose values are
automatically set
Values start at 0 and are incremented by 1
Values can be set explicitly with =
Need unique constant names
Example:
enum Months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL,
AUG, SEP, OCT, NOV, DEC};
Creates a new type enum Months in which the identifiers are set
to the integers 1 to 12
Enumeration variables can only assume their enumeration constant
values (not the integer representations)
252 [email protected]
Devi Ahilya Vishwavidyalaya
Inline Functions
Recall the two different ways to compute the larger of two integers:
#define max(a,b) ((a)>(b)? (a):(b))
int max(int a, int b) { return a>b?a:b; }
To execute a function call, computer must:
Save current registers
Allocate memory on the call stack for the local variables, etc, of the
function being called
Initialize function parameters
Jump to the area of memory where the function code is, and jump
back when done
254 [email protected]
DAVV
SCS
Inline Functions
The macro approach is more efficient since it does not have function call
overhead, but, this approach can be dangerous, as we saw earlier
Modern C compilers provide inline functions to solve the problem:
Put the inline keyword before the function header
inline int max(int a, int b) {
return a>b?a:b;
}
255 [email protected]
DAVV
SCS
Inline Functions
You then use the inline function just like a normal function in your
source code
printf( "%d", max( x, y) );
When the compiler compiles your program, it will not compile it as a
function; rather, it integrates the necessary code in the line where
max( ) is called, and avoids an actual function call
The above printf(…) is compiled to be something like:
printf("%d", x>y?x:y);
256 [email protected]
DAVV
SCS
Inline Functions
Writing the small but often-used functions as inline functions can
improve the speed of your program
A small problem: You must include the inline function definition (not just
its prototype) before using it in a file
Therefore, inline functions are often defined in header (.h) files
257 [email protected]
DAVV
SCS
Inline Functions
Once you include a header file, you can use:
Inline functions whose definitions are in the header file
Normal functions whose prototypes are in the header file
Another minor problem: Some debuggers get confused when handling inline
functions – it may be best to turn functions into inline functions only after
debugging is finished
258 [email protected]
DAVV
SCS
259 [email protected]
DAVV
SCS
Type Qualifiers
const
Variables of type const may not be changed by your program. The compiler
is free to place variables of this type into read-only memory (ROM).
const int a=10;
creates an integer variable called a with an initial value of 10 that your program may
not modify.
The const qualifier can be used to prevent the object pointed to by an argument to a
function from being modified by that function. That is, when a pointer is passed to a
function, that function can modify the actual object pointed to by the pointer.
260 [email protected]
DAVV
SCS
Volatile
The modifier volatile tells the compiler that a variable's value may be changed in
ways not explicitly specified by the program. For example, a global variable's
address may be passed to the operating system's clock routine and used to hold the
system time. In this situation, the contents of the variable are altered without any
explicit assignment statements in the program. This is important because most C
compilers automatically optimize certain expressions by assuming that a variable's
content is unchanging if it does not occur on the left side of an assignment
statement; thus, it might not be reexamined each time it is referenced.
261 [email protected]
DAVV
SCS
Const + Volatile
You can use const and volatile together. For example, if 0x30 is assumed to
be the value of a port that is changed by external conditions only, the
following declaration would prevent any possibility of accidental side effects:
262 [email protected]
DAVV
SCS
These specifiers tell the compiler how to store the subsequent variable. The
general form of a variable declaration that uses one is shown here:
263 [email protected]
DAVV
SCS
Global Variables
Global variables are known throughout the program and
may be used by any piece of code. Also, they will hold their value throughout
the program's execution. You create global variables by declaring them outside
of any function. Any expression may access them, regardless of what block of
code that expression is in. In the following program, the variable count has been
declared outside of all functions. Although its declaration occurs before the
main( ) function, you could have placed it anywhere before its first use as long
as it was not in a function. However, it is usually best to declare global variables
at the top of the program.
264 [email protected]
DAVV
SCS
Storage for global variables is in a fixed region of memory set aside for this
purpose by the compiler. Global variables are helpful when many functions in
your program use the same data. You should avoid using unnecessary global
variables, however. They take up memory the entire time your program is
executing, not just when they are needed.
265 [email protected]
DAVV
SCS
Linkage
266 [email protected]
DAVV
SCS
Extern
The principal use of extern is to specify that an object is declared with external
linkage elsewhere in the program.
A declaration declares the name and type of an object. A definition causes
storage to be allocated for the object. The same object may have many
declarations, but there can be only one definition.
267 [email protected]
DAVV
SCS
Extern
#include <stdio.h>
int main(void)
{
extern int first, last; /* use global vars */
printf("%d %d", first, last);
return 0;
}
/* global definition of first and last */
int first = 10, last = 20;
268 [email protected]
DAVV
SCS
Multiple-File Programs
An important use of extern relates to multiple-file programs. C allows a program
to be spread across two or more files, compiled separately, and then linked
together. When this is the case, there must be some way of telling all the files
about the global variables required by the program. The best (and most
portable) way to do this is to declare all of your global variables in one file and
use extern declarations in the other.
269 [email protected]
DAVV
SCS
Multiple-File Programs
int x, y; extern int x, y;
char ch; extern char ch;
int main(void) void func22(void)
{ {
/* . . . */ x = y / 10;
} }
void func1(void) void func23(void)
{ {
x = 123; y = 10;
} }
270 [email protected]
DAVV
SCS
Static Variables
Variables declared as static are permanent variables within their own function or
file. Unlike global variables, they are not known outside their function or file, but
they maintain their values between calls. This feature makes them useful when
you write generalized functions and function libraries that other programmers
may use. The static modifier has different effects upon local variables and global
variables.
271 [email protected]
DAVV
SCS
When you apply the static modifier to a local variable, the compiler creates
permanent storage for it a static local variable is a local variable that retains its
value Between function calls.
272 [email protected]
DAVV
SCS
273 [email protected]
DAVV
SCS
Register Variables
The register specifier requested that the compiler keep the value of a variable in
a register of the CPU rather than in memory, where normal variables are stored.
This meant that operations on a register variable could occur much faster than
on a normal variable because the register variable was actually held in the CPU
and did not require a memory access to determine or modify its value.
The register storage specifier originally applied only to variables of type int, char,
or pointer types. type of variable.
274 [email protected]
Devi Ahilya Vishwavidyalaya
Any Questions