Rabu, 26 Mei 2010

struct

Structs
Overview
(http://www.fredosaurus.com/notes-cpp/index.html)
In addition to the simple data types (int, char, double, ...) there are composite data types
which combine more than one data element. Arrays store elements of the same type,
which are accessed by subscript, eg, a[i]. Structs (also called records, or classes) group
elements which don't need to all be the same type, and are accessed by field (member)
name, eg, r.name.
Struct Declaration defines a new Type
The most common struct declaration in C++ is to define a new type. This example
represents information about products.
struct Product {
char mfg_id[4]; // 4 char code for the manufacturer.
char prod_id[8]; // 8-char code for the product
int price; // price of the product in dollars.
int qty_on_hand; // quantity on hand in inventory
};
This defines a new type, Product. The order of the fields is generally not important. Don't
forget the semicolon after the right brace. The convention is to capitalize the first letter in
any new type name.
Declaring struct variables
The new struct type can now be used to declare variables. For example,
Product widget;
Accessing the fields of a struct
Access the fields of a struct by using the "." operator followed by the name of the field.
widget.price = 200;
widget.qty_on_hand = 17;
strcpy(widget.mfg_id, "IBM");
strcpy(widget.prod_id, "Thingee");
Like database records
Structs are like database records - a row in a table, where the field names are like the
column names.
Problem - Points
Suppose we have the following problem. We want to read a set of (x, y) coordinates and
a name, then sort them in order increasing distance from the origin (0, 0). This is the kind
of data you might have if we digitized a map with the origin at some central point (eg,
London) and the coordinates of other cities.
Global Declaration
Types are usually used in more than one function, and are therefore global or defined in
an include file.
// Define a struct to hold each point.
struct Point {
float x; // x coordinate
float y; // y coordinate
char name[20]; // name of the point
};
Local Declarations
Point pts[1000]; // array to hold up to 1000 points.
int n = 0; // number of points in the array.
Reading the input
To read structs, you need to read each of the fields.
while (cin >> pts[n].name >> pts[n].x >> pts[n].y) {
n++;
}
Utility function to compute distance to origin
float dist(Point p) {
// Compute the distance from the origin
return sqrt(p.x*p.x + p.y*p.y);
}
Sorting an array of Points
Here's a simple bubble sort function that stops when there are no more exchanges. It sorts
Points by their distance from the origin by calling on the function defined above.
void bubbleSort(Point pt[], int size) {
bool doMore = true;
while (doMore) {
doMore = false; // Assume no more passes unless exchange made.
for (int i=0; iif (dist(pt[i]) > dist(pt[i+1])) {
// Exchange elements
Point temp = pt[i]; pt[i] = pt[i+1]; pt[i+1] = temp;
doMore = true; // Exchange requires another pass.
}
}
}
}
Problem - Product info
Let's use the Product struct, read into an array of Products, and sort by increasing price.
Global Declaration
Typically types are used in more than one function, and are therefore global or defined in
an include file.
struct Product {
char mfg_id[4]; // 4 char code for the manufacturer.
char prod_id[8]; // 8-char code for the product
int price; // price of the product in dollars.
int qty_on_hand; // quantity on hand in inventory
};
Local Declarations
Product prods[1000]; // array to hold up to 1000 products
int n = 0; // number of products in the array.
Reading the input
while (cin >> prods[n].mfg_id >> prods[n].prod_id
>> prods[n].price >> prods[n].qty_on_hand) {
n++;
}
Sorting the array of products
Here's a simple bubble sort function that stops when there are no more exchanges. This is
a fairly inefficient sort, and it's used here just as an example. Notice we can't compare the
entire struct, only individual fields.
void bubbleSort2(Product pd[], int size) {
bool doMore;
do {
doMore = false; // assume this is last pass over array
for (int i=0; iif (pd[i].price > pd[i+1].price) {
// exchange elements
Product temp = pd[i]; pd[i] = pd[i+1]; pd[i+1] = temp;
doMore = true; // after exchange, must look again
}
}
} while (doMore);
}
Struct Operations
Assume the following declaration
//--- Define a new struct type
struct Point {
int x;
int y;
};
//--- Declare some variables of type Point.
Point p1;
Point p2;
Point* paddr; // declare pointer to a Point struct
Member (field) selection - dot operator
The "." (dot) operator is used to select a member of a struct. This operator can be applied
to any expression that yields a struct (function call, subscription, etc).
int h = p1.x;
p2.y = p1.y;
Member (field) selection - arrow operator
When using a pointer to a struct, the "->" (arrow) operator is typically used as a more
readable way to both dereference the pointer and select a member. See -> operator.
// The following are equivalent.
int h = paddr->x // using arrow notation.
int h = (*paddr).x; // using deref plus dot.
Assignment
A struct variable can be assigned to/from.
p1 = p2;
Parameter
A struct can be passed to a function either as a value or a reference parameter. Large
structs are sometimes passed as reference parameters to avoid the cost of the copy, even
tho the value is not going to be changed.
Returned by function
A struct may be returned by a function.
Comparison - NO
The comparison operators do not work on structs. To compare structs, compare
individual fields.
if (p1.x==p2.x && p1.y==p2.y) . . .
It is not possible to write p1==p2.
There are good reasons to forbid comparison.
• What would a greater than comparison even mean on a Point for example.
• A bit-by-bit equal comparison is not feasible in general because there may be
padding or unfilled elements (eg in a C-string).
A subelement of array or another struct
A struct value can be used inside of another struct or as an element type in an array.
Arithmetic operators - NO
By default none of the arithmetic operators work on structs.
I/O - NO
The I/O operators >> and << do not work for structs; you must read/write the fields
individually.
Solutions
You may redefine operators so that they do work with your structs. When providing
functions and overloaded operators for your struct, use the class keyword instead -- it's
what programmers expect.

Tidak ada komentar:

Posting Komentar