Anda di halaman 1dari 23

Session 1

Advanced Concepts of C and Introduction to data structures During this session you will learn about: Structures. Arrays. Pointers. Advantages and disadvantages of a pointer. Usage of pointers. Difference between arrays and pointers. Passing parameters by value, by reference and by address. Dynamic allocation and de allocation of memory. Dynamic arrays. Scope and lifetime of a variable. Unions. !numerations.

1.1. Introduction
This chapter familiarizes you with the concepts of arrays, pointers and dynamic memory allocation and deallocation techniques. We briefly discuss about types of data structures and algorithms. Let us start the discussion with data types.

1.2. Data Types

As we know that the data, which will be gi en to us, should be stored and again referred back. These are done with the help of ariables. A particular ariable!s memory requirement depends on which type it belongs to. The different types in " are integers, float #$eal numbers%, characters, double, long, short etc. These are the a ailable built in types. &any a times we may come across many data members of same type that are related. 'i ing them different ariable names +

(ata )tructures with *c!

and later remembering them is a tedious process. ,t would be easier for us if we could gi e a single name as a parent name to refer to all the identifiers of the same type. A particular alue is referred using an inde-, which indicates whether the alue is first, second or tenth in that parents name. We ha e decided to use the inde- for reference as the alues occupy successi e memory locations. We will simply remember one name #starting address% and then can refer to any alue, using inde-. )uch a facility is known as A$$A.).

1.3. Arrays
An array can be defined as the collection of the se"uential memory locations, which can be referred to by a single name along with a number, #nown as the inde$, to access a particular field or data. When we declare an array, we will ha e to assign a type as well as size. e.g. When we want to store +/ integer the following declaration. int A0+/12 3y this declaration we are declaring A to be an array, which is supposed to contain in all +/ integer alues. When the allocation is done for array a then in all +/ locations of size 4 bytes for each integer i.e. 4/ bytes will be allocated and the starting address is stored in A. When we say A0/1 we are referring to the first integer alue in A. 5 ----------------- Array----------------5 A0/1A0+1 A061 fig#+%. Array representation 7ence if we refer to the i th alue in array we should write A0i-+1. When we declare the array of ),89 elements, alues, then we can use

(ata )tructures with *c!

where, ),89 is gi en by the user, the inde/ to ),89-+.

alue changes from

7ere it should be remembered that the size of the array is *always a constant! and not a ariable. This is because the fi-ed amount of memory will be allocated to the array before e-ecution of the program. This method of allocating the memory is known as *static allocation! of memory.

1.4. Handling Arrays

:ormally following procedure is followed for programming so that, by changing only one ;define statement we can run the program for arrays of different sizes. ;define ),89 +/ int a0),891, b0),8912 :ow if we want this program to run for an array elements we need to change <ust the ;define statement. 1.5. Initiali ing t!e Arrays. =ne method of initializing the array members is by using the *for! loop. The following for loop initializes +/ elements with the alue of their inde-. ;define ),89 +/ main#% > int arr0),891, i2 for#i ? /2 i @ ),89 2 iAA % > arr0i1 ? i2 B B An array can also be initialized directly as follows. int arr0C1 ? >/,+,4B2 An e-plicitly initialized array need not specify size but if specified the number of elements pro ided must not e-ceed the size. ,f the size is gi en and some elements are not e-plicitly initialized they are set to zero. C of 4//

(ata )tructures with *c!

e.g. int arr01 ? >/,+,4B2 int arr+0D1 ? >/,+,4B2 EF ,nitialized as >/,+,4,/,/BFE const char aGarrC0H1 ? I(anielI2 EF 9$$=$2 (aniel has J elements H in (aniel and a K/FE To copy one array to another each element has to be copied using for structure. Any e-pression that e aluates into an integral be used as an inde- into array. e.g. arr0getG alue#%1 ? some alue2 alue can

1.". #ultidi$ensional Arrays

An array in which the elements need to be referred by two indices it is called a two dimensional array or a %matri$& and if it is referred using more than two indices, it will be 'ultidimensional Array. e.g. int arr0L10C12 This is a two-dimensional array with L as row dimension and C as a column dimension.

1.%. Initiali ation of T&o Di$ensional Array

Must like one-dimensional arrays, members of matrices can also be initialized in two ways N using *for! loop and directly. ,nitialization using nested loops is shown below. e.g. int arr0+/10+/12 for#int i ? +2i@ ? +/2iAA% for#int < ? +2 <@ ? +/2<AA% > arr0i10<1 ? iA<2 B

(ata )tructures with *c!

:ow let us directly. e.g.








int arr0L10C1 ? >>/,+,4B,>C,L,DB,>H,J,OB,>6,+/,++BB2 The nested brackets are optional.

1.'. (ointers
The computer memory is a collection of storage cells. These locations are numbered sequentially and are called addresses. Pointers are addresses of memory location. Any variable, which contains an address is a pointer variable. Pointer ariables store the address of an ob<ect, allowing for the indirect manipulation of that ob<ect. They are used in creation and management of ob<ects that are dynamically created during program e-ecution.

1.). Advantages and disadvantages of pointers

Pointers are ery effecti e when

The data in one function can be modified by other function by passing the address. &emory has to be allocated while running the program and released back if it is not required thereafter. (ata can be accessed faster because of direct addressing.

The only disad antage of pointers is, if not understood and not used properly can introduce bugs in the program.

1.1*. Declaring and initiali ing pointers

Pointers are declared using the #F% operator. The general format isQ dataGtype Fptrname2

(ata )tructures with *c!

where type can be any of the basic data type such as integer, float etc., or any of the user-defined data type. Pointer name becomes the pointer of that data type. e.g. int char float Fiptr2 Fcptr2 Ffptr2

The pointer iptr stores the address of an integer. ,n other words it points to an integer, cptr to a character and fptr to a float alue. =nce the pointer ariable is declared it can be made to point to a ariable with the help of an address #reference% operator#R%. e.g. int num ? +/4L2 int Fiptr2 iptr ? Rnum2 EE iptr points to the

ariable num.

The pointer can hold the alue of /#:SLL%, indicating that it points to no ob<ect at present. Pointers can never store a non address value. e.g.

iptr+?i al2

EE in alid, i al is not address.

A pointer of one type cannot be assigned the address alue of the ob<ect of another type. e.g. double d al, iptr ? Rd al 2 Fdptr ? Rd al2 EE allowed EEnot allowed

1.11.(ointer Arit!$etic
The pointer alues stored in a pointer ariable can be altered using arithmetic operators. .ou can increment or decrement pointers, you can subtract one pointer from another, you can add or subtract integers to pointers but two pointers can not be added as it may lead to an address that is not present in the memory. :o other arithmetic operations are H

(ata )tructures with *c!

allowed on pointers than the ones discussed here. "onsider a program to demonstrate the pointer arithmetic. e.g. ; include@stdio.hT main#% > int a01?>+/,4/,C/,L/,D/B2 int Fptr2 int i2 ptr?a2 for#i?/2 i@D2 iAA% > printf#VWdI,FptrAA%2 B B =utputQ +/ 4/ C/ L/ D/ The addresses of each memory location for the array *a! are shown starting from U//4 to U//O. ,nitial address of U/// is assigned to *ptr!. Then by incrementing the pointer alue ne-t alues are obtained. 7ere each increment statement increments the pointer ariable by 4 bytes because the size of the integer is 4 bytes. The size of the arious data types is shown below for a +H-bit machine. ,t may ary from system to system. char int float long int double short int +byte 4bytes Lbytes Lbytes Obytes 4bytes ptr--T U/// U//4 U//L U//H U//O +/ 4/ C/ L/ D/

1.12.Array of pointers
"onsider the declaration shown belowQ char FA0C1?>VaI, VbI, VTe-t 3ookIB2

(ata )tructures with *c!

The e-ample declares *A! as an array of character pointers. 9ach location in the array points to string of characters of arying length. 7ere A0/1 points to the first character of the first string and A0+1 points to the first character of the second string, both of which contain only one character. howe er, A041 points to the first character of the third string, which contains 6 characters.

1.13.(assing para$eters to t!e functions

The different ways of passing parameters function areQ - Pass by alue# call by alue% - Pass by addressEpointer#call by address% into the

,n pass by alue we copy the actual argument into the formal argument declared in the function definition. Therefore any changes made to the formal arguments are not returned back to the calling program. ,n pass by address we use pointer ariables as arguments. Pointer ariables are particularly useful when passing to functions. The changes made in the called functions are reflected back to the calling function. The program uses the classic problem in programming, swapping the alues of two ariables. oid alGswap#int -, int y% > int t2 t ? -2 - ? y2 y ? t2 oid addGswap#int F-, int Fy% > int t2 t ? F-2 F- ? Fy2 Fy ? t2 B oid main#% > O EE "all by Address EE "all by Xalue

(ata )tructures with *c!

int n+ ? 4D, n4 ? D/2 printf#VKn 3efore call by Xalue Q I%2 printf#VKn n+ ? Wd n4 ? WdI,n+,n4%2 alGswap# n+, n4 %2 printf#VKn After call by alue Q I%2 printf#VKn n+ ? Wd n4 ? WdI,n+,n4%2 printf#VKn 3efore call by Address Q I%2 printf#VKn n+ ? Wd n4 ? WdI,n+,n4%2 alGswap# Rn+, Rn4 %2 printf#VKn After call by alue Q I%2 printf#VKn n+ ? Wd n4 ? WdI,n+,n4%2 B =utputQ 3efore call by alue After call by alue 4D 3efore call by address After call by address 4D Q n+ ? 4D n4 ? D/ Q n+ ? D/ n4 ? 4D EE- ? D/, y ? Q n+ ? 4D n4 ? D/ Q n+ ? 4D n4 ? D/ EE - ? D/, y ?

1.14. +elation ,et&een (ointers and Arrays

Pointers and Arrays are related to each other. All programs written with arrays can also be written with the pointers. "onsider the followingQ int arr01 ? >/,+,4,C,L,D,H,J,O,6B2 To access the alue we can write,

arr0/1 or Farr2 arr0+1 or F#arrA+%2 )ince *F! is used as pointer operator and is also used to dereference the pointer ariables, you ha e to know the difference between them thoroughly. F#arrA+% means the address of arr is increased by + and then the contents are fetched. FarrA+ means the contents are fetched from address arr and one is added to the content.

(ata )tructures with *c!

:ow we ha e understood the relation between an array and pointer. The tra ersal of an array can be made either through subscripting or by direct pointer manipulation. e.g. > oid print#int FarrGbeg, int FarrGend% while#arrGbeg Y ? arrGend% > printf#VWiI,Farr%2 AAarrGbeg2 B oid main#% > int arr01 ? >/,+,4,C,L,D,H,J,O,6B print#arr,arrA6%2

arrGend initializes element past the end of the array so that we can iterate through all the elements of the array. This howe er works only with pointers to array containing integers.

1.15. Scope +ules and Storage Classes

)ince we e-plained that the alues in formal ariables are not reflected back to the calling program, it becomes important to understand the scope and lifetime of the ariables. The storage class determines the life of a ariable in terms of its duration or its scope. There are four storage classesQ automatic static e-ternal register

1.15.1 Auto$atic -aria,les

Automatic ariables are defined within the functions. They lose their alue when the function terminates. ,t can be accessed only in that function. All ariables when declared


(ata )tructures with *c!

within the function are, by default, *automatic!. 7owe er, we can e-plicitly declare them by using the keyword (automatic). e.g. oid print#% > auto int i ?/2 printf#VKn Xalue of i before incrementing is WdI, i%2 i ? i A +/2 printf#VKn Xalue of i after incrementing is WdI, i%2 B main#% > print#%2 print#%2 print#%2 B =utputQ Xalue Xalue Xalue Xalue Xalue Xalue of of of of of of i i i i i i before incrementing after incrementing before incrementing after incrementing before incrementing after incrementing is is is is is is Q Q Q Q Q Q / +/ / +/ / +/

1.15.2. Static -aria,les

)tatic ariables ha e the same scope s automatic ariables, but, unlike automatic ariables, static ariables retain their alues o er number of function calls. The life of a static ariable starts, when the first time the function in which it is declared, is e-ecuted and it remains in e-istence, till the program terminates. They are declared with the keyword static. e.g. oid print#% > static int i ?/2 ++

(ata )tructures with *c!


printf#VKn Xalue of i before incrementing is WdI, i ? i A +/2 printf#VKn Xalue of i after incrementing is WdI, i%2 B main#% > print#%2 print#%2 print#%2 B

=utputQ Xalue Xalue Xalue Xalue Xalue Xalue of of of of of of i i i i i i before incrementing after incrementing before incrementing after incrementing before incrementing after incrementing is is is is is is Q Q Q Q Q Q / +/ +/ 4/ 4/ C/

,t can be seen from the abo e e-ample that the alue of the ariable is retained when the function is called again. ,t is allocated memory and is initialized only for the first time.

1.15.3. ./ternal -aria,les

(ifferent functions of the same program can be written in different source files and can be compiled together. The scope of a global ariable is not limited to any one function, but is e-tended to all the functions that are defined after it is declared. 7owe er, the scope of a global ariable is limited to only those functions, which are in the same file scope. ,f we want to use a ariable defined in another file, we can use e$tern to declare them. e.g. EE U,L9 + N g is global and can be used only in main#% and EE EE fn+#%2 int g ? /2 oid main#% > +4

(ata )tructures with *c!

Q Q B oid fn+#% > Q Q B EE U,L9 4 ,f the ariable declared in file + is required to be used in file 4 then it is to be declared as an e-tern. e-tern int g ? /2 oid fn4#% > Q Q B oid fnC#% > Q B

1.15.4. +egister -aria,le

"omputers ha e internal registers, which are used to store data temporarily, before any operation can be performed. ,ntermediate results of the calculations are also stored in registers. =perations can be performed on the data stored in registers more quickly than on the data stored in memory. This is because the registers are a part of the processor itself. ,f a particular ariable is used often N for instance, the control ariable in a loop, can be assigned a register, rather than a ariable. This is done using the keyword register. 7owe er, a register is assigned by the compiler only if it is free, otherwise it is taken as automatic. Also, global ariables cannot be register ariables. e.g. oid loopfn#% +C

(ata )tructures with *c!


register int i2 for#i?/2 i@ +//2 iAA% > printf#VWdI, i%2 B

1.1".Dyna$ic allocation and de0allocation of $e$ory

&emory for system defined ariables and arrays are allocated at compilation time. The size of these ariables cannot be aried during run time. These are called *static data structures). The disad antage of these data structures is that they require fi-ed amount of storage. =nce the storage is fi-ed if the program uses small memory out of it remaining locations are wasted. ,f we try to use more memory than declared o erflow occurs. ,f there is an unpredictable storage requirement, sequential allocation is not recommended. The process of allocating memory at run time is called (dynamic allocation). 7ere, the required amount of memory can be obtained from free memory called *7eap!, a ailable for the user. This free memory is stored as a list called (Availability *ist). 'etting a block of memory and returning it to the a ailability list, can be done by using functions likeQ - malloc#% - calloc#% - free#%

1.1".1. 1unction $alloc2si e3

This function is defined in the header file and @alloc.hT. This function allocates a block bytes from the heap or a ailability list. =n returns a pointer of type * oid! to the allocated must typecast it to the type we require like int, ,f required space does not e-ist it returns :SLL. )ynta-Q ptr ? #dataGtypeF% malloc#size%2 +L @stdlib.hT of * si+e) success it memory. We float etc.

(ata )tructures with *c!

where e.g. ptr ?#intF%malloc#sizeof#int%Fn%2 allocates memory depending on the ; ; ; ; include@stdio.hT include@string.hT include@alloc.hT include@process.hT alue of ariable n. ptr is a pointer ariable of type dataGtype. dataGtype can be any of the basic data type, user defined or deri ed data type. size is the number of bytes required.

main#% > char Fstr2 if##str?#charF%malloc#+/%%??:SLL% > FE B strcpy#str,I7elloI%2 FE B printf#VKn str? Ws V,str%2 free#str%2 EF copy hello into str EF allocate memory for string FE

printf#VKn =ST =U &9&=$.I%2 e-it#+%2 EF terminate the program

EF display str FE EF free memory FE

,n the abo e program if memory is allocated to the str, a string hello is copied into it. Then str is displayed. When it is no longer needed, the memory occupied by it is released back to the memory heap.

1.1".2. 1unction calloc2n4si e3

This function is defined in the header file @stdlib.hT and @alloc.hT. This function allocates memory from the heap or a ailability list. ,f required space does not e-ist for the new block or n, or size is zero it returns :SLL. +D

(ata )tructures with *c!

)ynta-Q ptr ? #dataGtypeF% malloc#n,size%2 where ptr is a pointer ariable of type dataGtype. dataGtype can be any of the basic data type, user defined or deri ed data type. - size is the number of bytes required. - n is the number of blocks to be allocated of size bytes. and a pointer to the first byte of the allocated region is returned. e.g. ; ; ; ; include@stdio.hT include@string.hT include@alloc.hT include@process.hT -

main#% > char Fstr ? :SLL2 for str?#charF%calloc#+/,sizeof#char%%2 EF allocate memory


string FE if#str ?? :SLL%2 > printf#VKn =ST =U &9&=$.I%2 e-it#+%2 EF terminate the program B strcpy#str,I7elloI%2 printf#VKn str? Ws V,str%2 free#str%2







EF display str FE EF free memory FE

1.1".3. 1unction free2,loc53

This function frees allocated block of memory using malloc#% or calloc#%. The programmer can use this function and de-allocate the memory that is not required any more by the ariable. ,t does not return any alue.

1.1%.Dangling pointer pro,le$.


(ata )tructures with *c!

We can allocate memory to the same ariable more than once. The compiler will not raise any error. 3ut it could lead to bugs in the program. We can understand this problem with the following e-ample. ; include@stdio.hT ; include@alloc.hT main#% > int Fa2 a? #intF%malloc#sizeof#int%%2 Fa ? +/2 a? #intF%malloc#sizeof#int%%2 Fa ? 4/2 B *a! ,s done twice. ,n this case the ariable contains the address of the most recently allocated memory, thereby making the earlier allocated memory inaccessible. )o, memory location where the alue +/ is stored, is inaccessible to any of the application and is not possible to free it so that it can be reused. To see segmentQ main#% > int Fa2 a? #intF%malloc#sizeof#int%%2 Fa ? +/2 free#a%2 B , Z ----T +/ another problem, consider the ne-t program ,n this program segment memory allocation for ariable ----T ----T +/ 4/

7ere, if we de-allocate the memory for the ariable *a! using free#a%, the memory location pointed by *a! is returned to the memory pool. :ow since pointer *a! does not contain any


(ata )tructures with *c!

alid address we call it as (Dangling Pointer). ,f we want to reuse this pointer we can allocate memory for it again. 1.1'. Structures A structure is a deri ed data type. ,t is a combination of logically related data items. Snlike arrays, which are a collection of similar data types, structures can contain members of different data type. The data items in the structures generally belong to the same entity, like information of an employee, players etc. The general format of structure declaration isQ struct tag > type member+2 type member42 type memberC2 Q Q B ariables2 We can omit the ariable declaration in the structure declaration and define it separately as follows Q struct tag e.g. struct Account > int accnum2 char acctype2 char name04D12 float balance2 B2 We can declare structure ariables as Q ariable2

struct Account oldcust2 We can refer to the member using a dot operator #.%. e.g. ariables of the structures by


(ata )tructures with *c!

newcust.balance ? +//./ printf#VWsI, We can initialize the members as follows Q e.g. Account customer ? >+//, *w!, *(a id!, HD//.//B2 We cannot copy one structure ariable into another. ,f this has to be done then we ha e to do member-wise assignment. We can also following e-ampleQ ha e nested structures as shown in the

struct (ate > int dd, mm, yy2 B2 struct Account > int accnum2 char acctype2 char name04D12 float balance2 struct (ate d+2 B2 :ow if we ha e to access the members of date then we ha e to use the following method. Account c+2 c+.d+.dd?4+2 We can pass and return structures into functions. The whole structure will get copied into formal ariable. We can also ha e array of structures. ,f we declare array to account structure it will look like, Account a0+/12 9 ery thing is same as that of a single element e-cept that it requires subscript in order to know which structure we are referring to.


(ata )tructures with *c!

We can also declare pointers to structures and to access member ariables we ha e to use the pointer operator -T instead of a dot operator. Account Faptr2 printf#VWsI,aptr-Tname%2 A structure can contain pointer to itself as one of the ariables, also called self-referential structures. e.g. struct info > int i, <, k2 info Fne-t2 B2 ,n short we can list the uses of the structure asQ $elated data items of dissimilar data types can be logically grouped under a common name. "an be used to pass parameters so as to minimize the number of function arguments. When more than one data has to be returned from the function these are useful. &akes the program more readable.

1.1)$erated Constants
9numerated constants enable the creation of new types and then define ariables of these types so that their alues are restricted to a set of possible alues. There synta- isQ enum identifier >c+,c4,...B0 arGlist12 where e.g. 4/ enum is the keyword. identifier is the user defined enumerated data type, which can be used to declare the ariables in the program. >c+,c4,...B are the names of constants and are called enumeration constants. arGlist is an optional list of ariables.

(ata )tructures with *c!

enum "olour>$9(, 3LS9, '$99:, W7,T9, 3LA"[B2 "olour is the name of an enumerated data type. ,t makes $9( a symbolic constant with the alue /, 3LS9 a symbolic constant with the alue + and so on. 9 ery enumerated constant has an integer alue. ,f the program doesn!t specify otherwise, the first constant will ha e the alue /, the remaining constants will count up by + as compared to their predecessors. Any of the enumerated constant can be initialised to ha e a particular alue, howe er, those that are not initialised will count upwards from the alue of pre ious ariables. e.g. enum "olour>$9( +///B2 ? +//, 3LS9, '$99: ? D//, W7,T9, 3LA"[ ?

The alues assigned will be $9( ? +//,3LS9 ? +/+,'$999: ? D//,W7,T9 ? D/+,3LA"[ ? +/// .ou can define ariables of type "olour, but they can hold only one of the enumerated alues. ,n our case $9(, 3LS9, '$999:, W7,T9, 3LA"[ . .ou can declare ob<ects of enum types. e.g. enum (ays>)S:, &=:, TS9, W9(, T7S, U$,, )ATB2 (ays day2 (ay ? )S:2 (ay ? C2 EE error int and day are of different types (ay ? hello2 EE hello is not a member of (ays. 9 en though enum symbolic constants are internally considered to be of type unsigned int we cannot use them for iterations. e.g. enum (ays>)S:, &=:, TS9, W9(, T7S, U$,, )ATB2 for#enum i ? )S:2 i@)AT2 iAA% EEnot allowed. There is no support for mo ing backward or forward from one enumerator to another.


(ata )tructures with *c!

7owe er whene er necessary, an automatically promoted to arithmetic type.



e.g. if# &=: T /% > printf#V &onday is greaterI%2 B int num ? 4F&=:2

A union is also like a structure, e-cept that only one ariable in the union is stored in the allocated memory at a time. ,t is a collection of mutually e-clusi e ariables, which means all of its member ariables share the same physical storage and only one ariable is defined at a time. The size of the union is equal to the largest member ariables. A union is defined as followsQ union tag > type mem ar+2 type mem ar42 type mem arC2 Q Q B2 A union ariable of this data type can be declared as follows, ariableGname2

union tag e.g.

union utag > int num2 char ch2 B2 union tag ff2


(ata )tructures with *c!

The abo e union will ha e two bytes of storage allocated to it. The ariable num can be accessed as ff.sum and ch is accessed as At any time, only one of these two ariables can be referred to. Any change made to one ariable affects another. Thus unions use memory efficiently by using the same memory to store all the ariables, which may be of different types, which e-ist at mutually e-clusi e times and are to be used in the program only once. ,n this chapter we ha e studies some ad anced features of ". We ha e seen how the fle-ibility of language allowed us to define a user-defined ariable, is a combination of different types of ariables, which belong to some entity. We also studies arrays and pointers in detail. These are ery useful in the study of arious data structures.


(ata )tructures with *c!