06 Structure Bitwise Bitfields
06 Structure Bitwise Bitfields
Programming
Lec # 6
By
Engr. Sajid Saleem
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:
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;
}
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;
}
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)
Passing Structure to a
function(3)
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);
}
Unions
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.
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.
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.
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.
NOTE:
An unnamed bit field of width 0 forces alignment of the next
bit field to the nexttypeboundary,wheretypeis the type
of the member.
struct {
unsigned
unsigned
unsigned
unsigned
unsigned
} stuff;
int
int
int
int
int
field1 : 1;
:
2;
field1 : 1;
:
0;
field1 : 1;
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()
Insertion
Listing
Deletion
Updation
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