You are on page 1of 30

Object Oriented

Programming
Lec # 6
By
Engr. Sajid Saleem

Structure, Bitwise and Bitfields

Structures
Structure Arrays
Nested Structure
Pointer to Structure
Passing a structure to a function
Unions
Logical Operators
Bitwise Operators
Bit-fields
Linked Lists

Structures(1)
These are the three main skills you must
acquire:
Setting up a format or layout for a structure, eg:
Declaring a variable to fit that layout, eg:
Gaining access to the individual components of
a structure variable, eg:

The structure shown* has three parts


(called members or fields):
one to store the title
one to store the author
and one to store the value
*Chap 14, Prog. 14.1, C Primer Plus, Third Edition

Structures(2)
/* book.c -- one-book inventory */
#include <stdio.h>
#define MAXTITL 41 /* maximum length of title + 1 */
#define MAXAUTL 31 /* maximum length of author's name + 1 */
struct book { /* structure template: tag is book */
char title[MAXTITL];
char author[MAXAUTL];
float value;
}; /* end of structure template */
int main(void)
{
struct book libry; /* declare libry as book-type variable */
printf("Please enter the book title.\n");
gets(libry.title); /* access to the title portion */
printf("Now enter the author.\n");
gets(libry.author);
printf("Now enter the value.\n");
scanf("%f", &libry.value);
printf("%s by %s: $%.2f\n",libry.title, libry.author, libry.value);
printf("%s: \"%s\" ($%.2f)\n", libry.author, libry.title, libry.value); return 0;
}

Structure Arrays(1)
/* manybook.c -- multiple book inventory */
#include <stdio.h>
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 100 /* maximum number of books */
struct book { /* set up book template */
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
struct book libry[MAXBKS]; /* array of book structures */
int count = 0;
int index;
printf("Please enter the book title.\n");
printf("Press [enter] at the start of a line to stop.\n");

Structure Arrays(2)
while (count < MAXBKS && gets(libry[count].title) != NULL && libry[count].title[0] != '\0')
{
printf("Now enter the author.\n");
gets(libry[count].author);
printf("Now enter the value.\n");
scanf("%f", &libry[count++].value);
while (getchar() != '\n')
continue; /* clear input line */
if (count < MAXBKS)
printf("Enter the next title.\n");
}
printf("Here is the list of your books:\n");
for (index = 0; index < count; index++)
printf("%s by %s: $%.2f\n", libry[index].title, libry[index].author, libry[index].value);
return 0;
}

*Chap 14, Prog. 14.2, C Primer Plus, Third Edition

Nested Structure(1)
/* friend.c -- example of a nested structure */
#include <stdio.h>
#define LEN 20
const char * msgs[5] = { " Thank you for the wonderful evening, ", "You
certainly prove that a ", "is a special kind of guy. We must get together",
"over a delicious ", " and have a few laughs" };
struct names { /* first template */
char first[LEN];
char last[LEN];
};
struct guy { /* second template */
struct names handle; /* nested structure */
char favfood[LEN];
char job[LEN];
float income;
};

Nested Structure(2)
int main(void)
{
struct guy fellow = { /* initialize a variable */
{ "Chip", "Vejer" }, "nachos plate", "memory broker", 36827.00 };
printf("Dear %s, \n\n", fellow.handle.first);
printf("%s%s.\n", msgs[0], fellow.handle.first);
printf("%s%s\n", msgs[1], fellow.job);
printf("%s\n", msgs[2]); printf("%s%s%s", msgs[3], fellow.favfood, msgs[4]);
if (fellow.income > 150000.0)
puts("!!");
else if (fellow.income > 75000.0)
puts("!");
else puts(".");
printf("\n%40s%s\n", " ", "See you soon,");
printf("%40s%s\n", " ", "Shalala");
return 0;
}
*Chap 14, Prog. 14.3, C Primer Plus, Third Edition

Pointer to Structure(1)
/* friends.c -- uses pointer to a structure */
#include <stdio.h>
#define LEN 20 struct names { char first[LEN]; char last[LEN]; };
struct guy {
struct names handle;
char favfood[LEN];
char job[LEN];
float income; };
int main(void)
{
struct guy fellow[2] = { {{ "Chip", "Vejer"}, "nachos plate", "memory broker",
36827.00 }, {{"Rodney", "Swillbelly"}, "salmon mousse", "tabloid editor",
148500.00 } };
struct guy * him; /* here is a pointer to a structure */
printf("address #1: %p #2: %p\n", &fellow[0], &fellow[1]);
him = &fellow[0]; /* tell the pointer where to point */

Pointer to Structure(2)
printf("pointer #1: %p #2: %p\n", him, him + 1);
printf("him->income is $%.2f: (*him).income is $%.2f\n", him->income,
(*him).income);
him++; /* point to the next structure */
printf("him->favfood is %s: him->handle.last is %s\n", him->favfood, him>handle.last);
return 0;
}

*Chap 14, Prog. 14.4, C Primer Plus, Third Edition

Passing Structure to a
function(1)
/* funds1.c -- passing structure members as arguments */
#include <stdio.h>
#define FUNDLEN 50 struct funds { char bank[FUNDLEN]; double bankfund;
char save[FUNDLEN]; double savefund; };
double sum(double, double);
int main(void)
{
struct funds stan = { "Garlic-Melon Bank", 2024.72, "Lucky's Savings and
Loan", 8237.11 };
printf("Stan has a total of $%.2f.\n", sum(stan.bankfund, stan.savefund) );
return 0;
}
/* adds two double numbers */
double sum(double x, double y)
{
return(x + y);
*Chap}14, Prog. 14.5, C Primer Plus, Third Edition

Passing Structure to a
function(2)

/* funds3.c -- passing a pointer to a structure */


#include <stdio.h>
#define FUNDLEN 50
struct funds { char bank[FUNDLEN];
double bankfund;
char save[FUNDLEN];
double savefund;
};
double sum(struct funds moolah); /* argument is a structure */
int main(void)
{
struct funds stan = { "Garlic-Melon Bank", 2024.72, "Lucky's Savings and Loan",
8237.11 };
printf("Stan has a total of $%.2f.\n", sum(stan));
return 0;
}
double sum(struct funds moolah)
{
return(moolah.bankfund + moolah.savefund);
}
*Chap 14, Prog. 14.7, C Primer Plus, Third Edition

Passing Structure to a
function(3)

/* nameln2.c -- passes and returns structures */


#include <stdio.h>
#include <string.h>
struct namect { char fname[20]; char lname[20]; int letters; };
struct namect getinfo(void);
struct namect makeinfo(struct namect);
void showinfo(struct namect);
int main(void)
{
struct namect person;
person = getinfo();
person = makeinfo(person);
showinfo(person);
return 0;
}

Passing Structure to a
function(4)
struct namect getinfo(void)
{
struct namect temp;
printf("Please enter your first name.\n");
gets(temp.fname);
printf("Please enter your last name.\n");
gets(temp.lname);
return temp;
}
struct namect makeinfo(struct namect info)
{
info.letters = strlen(info.fname) + strlen(info.lname);
return info;
}
void showinfo(struct namect info)
{
printf("%s %s, your name contains %d letters.\n", info.fname, info.lname, info.letters);
}

*Chap 14, Prog. 14.9, C Primer Plus, Third Edition

Unions

A union is a type that enables you to store different data


types in the same memory space (but not simultaneously).
A typical use is a table designed to hold a mixture of types
in some order that is neither regular nor known in advance.
With a union, you can create an array of equal-sized units,
each of which can hold a variety of data types.
Unions are set up in much the same way as structures.
There is a union template and a union variable. They can be
defined in one step or, by using a union tag, in two. Here is
an example of a union template with a tag:
union hold {
int digit;
double bigfl;
char letter;
};
*Chap 14,C Primer Plus, Third Edition

Logical Opertors
Logical operators normally take relational expressions as
operands.
The ! operator takes one operand.
The rest take two: one to the left, and one to the right.
&& AND
|| OR
! NOT
For Eg:

expression1 && expression2 is true if, and only if, both expressions are
true.
expression1 || expression2 is true if either one or both expressions are true.
!expression is true if the expression is false, and vice versa.

Bitwise operations
All of the following bitwise operators, except ~, are
binary operators:
~ is the unary operator and produces a value with each bit of
the operand inverted.
& is AND and produces a value in which each bit is set to 1
only if both corresponding bits in the two operands are 1.
| is OR and produces a value in which each bit is set to 1 if
either, or both, corresponding bits of the two operands are 1.
^ is EXCLUSIVE OR and produces a value in which each bit is
set to 1 only if one or the other (but not both) of the
corresponding bits of the two operands is 1.
<< is left-shift and produces a value obtained by shifting the
bits of the left-hand operand to the left by the number of
places given by the right-hand operand. Vacated slots are
filled with zeros.
>> is right-shift and produces a value obtained by shifting
the bits of the left-hand operand to the right by the number
of places given by the right-hand operand.
For unsigned integers, the vacated slots are filled with zeros.
The behavior for signed values is implementation dependent.

Structure bit fields(1)

The second method of manipulating bits is to use a bit field, which is just a
set of neighboring bits within an unsigned int.
A bit field is set up with a structure declaration that labels each field and
determines its width.
For instance, the following declaration sets up four 1-bit fields:

struct {
unsigned
unsigned
unsigned
unsigned
} prnt;

int
int
int
int

autfd : 1;
bldfc : 1;
undln : 1;
itals : 1;

This definition causes prnt to contain four 1-bit fields. Now you can use the
usual structure membership operator to assign values to individual fields:

prnt.itals = 0;
prnt.undln = 1;

Because each of these particular fields is just 1 bit, 1 and 0 are the only
values you can use for assignment. The variable prnt is stored in an intsized memory cell, but only 4 bits are used in this example.

Structure bit fields(2)

Fields aren't limited to 1-bit sizes. You can also do this:

struct {
unsigned int code1 : 2;
unsigned int code2 : 2;
unsigned int code3 : 8;
} prcode;

This code creates two 2-bit fields and one 8-bit field. You can now make
assignments such as the following:

prcode.code1 = 0;
prcode.code2 = 3;
prcode.code3 = 102;

Just make sure the value doesn't exceed the capacity of the field.

Structure bit fields(3)

Structure bit fields(4)

What if the total number of bits you declare exceeds the size of an int?

Then the next int storage location is used. A single field is not allowed to
overlap the boundary between two ints.

The compiler automatically shifts an overlapping field definition so that the


field is aligned with the int boundary. When this occurs, it leaves an
unnamed hole in the first int.
In Microsoft compilers the ordering of data declared as bit fields is from low
to high bit, as shown in the figure above.
The underlying type of a bit field must be an integral type (char, bool, short
and long integer)

NOTE:
An unnamed bit field of width 0 forces alignment of the next
bit field to the nexttypeboundary,wheretypeis the type
of the member.

Structure bit fields(5)

Structure bit fields(5)

You can "pad" a field structure with unnamed holes by using


unnamed field widths. Using an unnamed field width of 0 forces the
next field to align with the next integer:

struct {
unsigned
unsigned
unsigned
unsigned
unsigned
} stuff;

int
int
int
int
int

field1 : 1;
:
2;
field1 : 1;
:
0;
field1 : 1;

Here, there is a 2-bit gap between stuff.field1 and stuff.field2, and


stuff.field3 is stored in the next int.
One important machine dependency is the order in which fields are
placed into an int. On some machines the order is left to right, and
on others it is right to left.
Also, machines differ in the location of boundaries between fields.
For these reasons, bit fields tend not to be very portable.
Typically, however, they are used for nonportable purposes, such as
putting data in the exact form used by a particular hardware device.

Structure bit fields(6)


#include<stdio.h>
struct SBT {
unsigned a1:2;
unsigned :2;
unsigned a2:3;
unsigned :3;
unsigned a3:2;
}var;
void main (void)
{
printf("%u",sizeof(v
ar));
getch();
}

The sizeof() function returns the amount


of bytes in no reserved by the variable in the
argument.
Run the code and see the output. How
many bytes are reserved:
1)With current code?
2)With value between a1 and a2 is set to 0?
3)With value between a1, a2 and a2,a3 is
set to 0?

Structure bit fields(7)


One important machine dependency is the order
in which fields are placed into an int. On some
machines the order is left to right, and on others
it is right to left. Also, machines differ in the
location of boundaries between fields. For these
reasons, bit fields tend not to be very portable.
Typically, however, they are used for nonportable
purposes, such as putting data in the exact form
used by a particular hardware device .

Dynamic Memory
Allocation(1)
malloc()
You can allot more memory as a program runs. The main tool is the
malloc() function, which takes one argument: the number of bytes
of memory you want. Then malloc() finds a suitable block of free
memory and returns the address of the first byte of that block.
Because char represents a byte, malloc() has traditionally been
defined as type pointer-to-char. The ANSI C standard, however,
uses a new type: pointer-to-void. This type is intended to be a
"generic pointer."
The malloc() function can be used to return pointers to arrays,
structures, and so forth, so normally the return value is type-cast to
the proper value. Under ANSI C, you should still typecast for clarity,
but assigning a pointer-to-void value to a pointer of another type is
not considered a type clash. If malloc() fails to find the required
space, it returns the null pointer.
For example, consider this code:
double * ptd;
ptd = (double *) malloc(30 * sizeof(double));

Dynamic Memory
Allocation(2)
free()

the free() function frees memory allocated by malloc().


Think of malloc() and free() as managing a pool of memory.
Each call to malloc() allocates memory for program use,
and each call to free() restores memory to the pool so it can
be reused.
The free() function frees only the block of memory that its
argument points to. The argument to free() should be a
pointer to a block of memory allocated by malloc(); you
can't use free() to free memory allocated by other means,
such as declaring a structure or array.

Building a linked list and performing


operations
A structure can't contain in itself a structure of
the same type, but it can contain a pointer to a
structure of the same type.
Such a definition is the basis for defining a
linked lista list in which each item contains
information describing where to find the next
item.
Linked List has four Basic Operations

Insertion
Listing
Deletion
Updation

*Reference: Chap 17, Prog. 17.2, C Primer Plus, Third Edition

Home Assignment
Try the C++ codings given in course
ebook, sections 22.9-22.11

Topics Covered
C++ How to Program, Fifth Edition By
H.M.Deitel (Ebook references)

5.8
21.3
22.1-22.4, 22.7-22.11
Appendix E Section E.10 and E.12

C Premier Plus (Ebook references)


14.1-14.8 (Structures), 14.11(Union), 17.2(Linked
lists)

You might also like