∆ΟΜΕΣ ∆οµές-Structures

∆ΟΜΕΣ
8η ∆ΙΑΛΕΞΗ
∆οµές-Structures
„
Στην C µπορούµε να προσθέσουµε τους δικούς µας τύπους (π.χ. FILE)
„
Βασικά εργαλεία: struct, typedef.
struct:
ορίζει ένα νέο τύπο δεδοµένων.
typedef: συσχετίζει ένα όνοµα µε αυτόν.
„
int, double, char είναι εγγενείς τύποι.
„
Με την typedef συσχετίζεις ένα όνοµα µε αυτούς.
„
Οι δοµές µπορούν να αντιγράφονται, να αποδίδονται σαν τιµές, να
µεταβιβάζονται σε συναρτήσεις και να επιστρέφονται από συναρτήσεις.
„
Η αναφορά σε ένα µέλος γίνεται: όνοµα-δοµής.µέλος
1
„
„
„
„
∆οµή (structure): Ένας πολυπληθυσµιακός τύπος δεδοµένων απαρτιζόµενος από 2 ή
περισσότερες σχετιζόµενες µεταβλητές (µέλη).
struct catalog {
char name[40]; /* author name */
char title[40]; /* title */
char pub[40]; /* publisher */
unsigned date; /* copyright date */
unsigned char ed; /* edition */
} card;
Προσπέλαση µέλους δοµής: Όνοµα_µεταβλητής_δοµής.όνοµα_µέλους
card.date = 1776;
printf("Copyright date: %u", card.date);
scanf("%u", &card.date);
•Εκχώρηση δοµών
gets(card.name);
struct s_type {
printf("%s", card.title);
int a;
float f;
printf("%c", card.title[2]);
} var1, var2;
∆ήλωση επιπλέον µεταβλητών τύπου δοµής
struct catalog varl, var2, var3;
var1.a = 10;
∆ιατάξεις δοµών
var1.f = 100.23;
struct catalog cat[100];
cat[0]
var2 = var1;
cat[33].ed = 2;
Η εντολή struct (1)
#include <stdio.h>
struct line {
int x1, y1; /* co-ords of 1 end of line*/
int x2, y2; /* co-ords of other end */
};
main()
{
struct line line1={1,2,3,4};
.
.
}
2
Typedef
„
„
H typedef επιτρέπει τη συσχέτιση ενός ονόµατος µε
µία δοµή (ή άλλο τύπο δεδοµένων)
Τοποθέτησε την typedef στην αρχή του
προγράµµατος.
typedef struct line {
int x1, y1;
int x2, y2;
} LINE;
int main()
{
LINE line1;
}
Αναφορά στα Μέλη ∆οµής
Χρησιµοποιείται ο τελεστής . και έχουµε:
<όνοµα µεταβλητής>.<όνοµα µέλους>
LINE line1;
line1.x1= 3;
line1.y1= 5;
line1.x2= 7;
if (line1.y2 == 3) {
printf ("Y co-ord of end is 3\n");
}
3
Παράδειγµα
typedef struct point{
int x, y;
} POINT;
typedef struct line {
POINT left;
POINT right;
} LINE;
int main()
{
LINE line1;
Line1.left.x=2;
}
Παρατηρήσεις (1)
Μπορούµε να περνάµε και να επιστρέφουµε
δοµές σε συναρτήσεις (το πρωτότυπο όµως
θα πρέπει να έχει οριστεί µετά τη δήλωση
δοµής)
typedef struct line {
int x1,y1;
int x2,y2;
} LINE;
LINE find_perp_line (LINE);
/* Function takes a line and returns a
perpendicular line */
4
Παράδειγµα
typedef struct complex {
float imag;
float real;
} CPLX;
CPLX mult_complex (CPLX, CPLX);
int main()
{
/* Main goes here */
}
CPLX mult_complex (CPLX no1, CPLX no2)
{
CPLX answer;
answer.real= no1.real*no2.real - no1.imag*no2.imag;
answer.imag= no1.imag*no2.real + no1.real*no2.imag;
return answer;
}
Χρησιµότητα
ƒ ∆ιευκολύνουν τον προγραµµατισµό.
ƒ FILE * είναι µία typedef δοµή αλλά µπορούµε να τη
χρησιµοποιήσουµε χωρίς να ξέρουµε τι εµπεριέχει.
ƒ Μπορούµε να επεκτείνουµε τη γλώσσα, για παράδειγµα αν
χρησιµοποιούµε µιγαδικούς αριθµούς µπορούµε να επεκτείνουµε τη
γλώσσα µε τον τύπο αυτό.
5
Παραδείγµατα
#include <stdio.h>
#include <stdio.h>
struct s_type {
int i;
char ch;
int *p;
double d;
} s;
int main(void)
{
struct s_type {
int i;
int j;
} s;
int main(void)
{
printf("s_type is %d bytes long",
sizeof(struct s_type));
int i;
i = 10;
s.i = 100;
s.j = 101;
return 0;
printf("%d %d %d", i, s.i, s.j);
}
return 0;
}
Παραδείγµατα ΙΙ
#include <stdio.h>
#include <stdio.h>
struct s_type {
int i;
double d;
};
struct s_type {
int i;
double d;
};
struct s_type f(void);
void f(struct s_type temp);
int main(void)
{
struct s_type var1;
int main(void)
{
struct s_type var1;
var1 = f();
printf("%d %f", var1.i, var1.d);
}
struct s_type f(void)
{
struct s_type temp;
temp.i = 100;
temp.d = 123.23;
return temp;
var1.i = 99;
var1.d = 98.6;
f(var1);
return 0;
}
void f(struct s_type temp)
{
printf("%d %f", temp.i, temp.d);
}
}
6
Παραδείγµατα ΙΙI
/* An electronic card catalog. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
int menu(void);
void display(int i);
void author_search(void);
void title_search(void);
void enter(void);
void save(void);
void load(void);
struct catalog {
char name[80]; /* author name */
char title[80]; /* title */
char pub[80]; /* publisher */
unsigned date; /* copyright date */
unsigned char ed; /* edition */
} cat[MAX];
int main(void)
{
int choice;
load(); /* read in catalog */
do {
choice = menu();
switch(choice) {
case 1: enter(); break;
case 2: author_search(); break;
case 3: title_search(); break;
case 4: save();
}
} while(choice!=5);
}
menu(void)
{
int i;
char str[80];
printf("Card catalog:\n");
printf(" 1. Enter\n");
printf(" 2. Search by Author\n");
printf(" 3. Search by Title\n");
printf(" 4. Save catalog\n");
printf(" 5. Quit\n");
int top = 0; /* last location used */
Παραδείγµατα ΙΙI (συνέχεια)
do {
printf("Choose your selection: ");
gets(str);
i = atoi(str);
printf("\n");
} while(i<1 || i>5);
/* Enter books into database. */
void enter(void)
{
int i;
char temp[80];
for(i=top; i<MAX; i++) {
printf("Enter author name (ENTER to quit): ");
gets(cat[i].name);
if(!*cat[i].name) break;
printf("Enter title: ");
gets(cat[i].title);
printf("Enter publisher: ");
gets(cat[i].pub);
printf("Enter copyright date: ");
gets(temp);
cat[i].date = (unsigned) atoi(temp);
printf("Enter edition: ");
gets(temp);
cat[i].ed = (unsigned char) atoi(temp);
}
top = i;
return i;
}
/* Search by author. */
void author_search(void)
{
char name[80];
int i, found;
printf("Name: "); gets(name);
found = 0;
for(i=0; i<top; i++)
if(!strcmp(name, cat[i].name)) {
display(i);
found = 1;
printf("\n");
}
if(!found) printf("Not Found\n");
}
}
7
Παραδείγµατα ΙΙI (συνέχεια)
/* Search by title. */
void title_search(void)
{
char title[80];
int i, found;
printf("Title: ");
gets(title);
/* Display catalog entry. */
void display(int i)
{
printf("%s\n", cat[i].title);
printf("by %s\n", cat[i].name);
printf("Published by %s\n", cat[i].pub);
printf("Copyright: %u, %u edition\n", cat[i].date,
cat[i].ed);
}
found = 0;
for(i=0; i<top; i++)
if(!strcmp(title, cat[i].title)) {
display(i);
found = 1;
printf("\n");
}
if(!found) printf("Not Found\n");
}
∆ΗΛΩΣΗ ∆ΕΙΚΤΩΝ ΠΡΟΣ ∆ΟΜΕΣ
#include <stdio.h>
#include <string.h>
struct s_type {
int i;
char str[80];
} s, *p;
int main(void)
{
p = &s;
s.i = 10; /* this is functionally the same */
p->i = 10; /* as this */
strcpy(p->str, "I like structures.");
printf("%d %d %s", s.i, p->i, p->str);
return 0;
}
8
ΕΝΘΕΤΕΣ ∆ΟΜΕΣ
#define NUM_ON_LINE 10
struct worker {
char name[80];
int avg_units_per_hour;
int avg_errs_per_hour;
};
struct asm_line {
int product_code;
double material_cost;
struct worker wkers[NUM_ON_LINE];
} line1, line2;
line1.wkers[1].avg_units_per_hour = 12;
ΠΕ∆ΙΑ BIT
struct b_type {
unsigned department: 3; /* up to 7 departments */
unsigned instock: 1; /* 1 if in stock, 0 if out */
unsigned backordered: 1; /* 1 if backordered, 0 if not */
unsigned lead_time: 3; /* order lead time in months */
} inv[MAX_ITEM];
inv[9].department = 3;
if(!inv[4].instock) printf("Out of Stock");
else printf("In Stock");
struct b_type {
int a: 2;
int b: 3;
};
struct b_type {
char name[40];
/* name of item */
unsigned department: 3; /* up to 7 departments */
unsigned backordered: 1; /* 1 if backordered, 0 if not */
unsigned lead_time: 3; /* order lead time in months */
} inv[MAX_ITEM];
9
∆ΗΜΙΟΥΡΓΙΑ ΕΝΩΣΕΩΝ
•Ένωση (Union): Είναι ένα µεµονωµένο κοµµάτι µνήµης το οποίο είναι κοινόχρηστο
για 2 ή περισσότερες µεταβλητές. Οι µεταβλητές που µοιράζονται την ίδια µνήµη
µπορούν να έχουν διαφορετικό τύπο δεδοµένων. Ωστόσο, µόνο µία µεταβλητή
µπορεί να χρησιµοποιεί αυτήν την περιοχή µνήµης ανά πάσα στιγµή.
#include <stdio.h>
int encode(int i);
int main(void)
{
int i;
i = encode(10); /* encode it */
printf("10 encoded is %d\n", i);
i = encode(i); /* decode it */
printf("i decoded is %d", i);
return 0;
}
int encode(int i)
{
union crypt_type {
int num;
char c[2];
} crypt;
unsigned char ch;
crypt.num = i;
/* swap bytes */
ch = crypt.c[0];
crypt.c[0] = crypt.c[1];
crypt.c[1] = ch;
return crypt.num;
}
ΕΙΣΟ∆ΟΣ/ΕΞΟ∆ΟΣ ΧΑΡΑΚΤΗΡΩΝ ΚΑΙ ΑΛΦΑΡΙΘΜΗΤΙΚΩΝ
„
„
int getchar(void);
int putchar(int);
Επιστρέφουν EOF (συνήθως -1) σε περίπτωση λάθους
#include <stdio.h>
#include <stdio.h>
int main(void)
{
char ch;
do {
ch = getchar();
putchar('.');
} while(ch != '\n');
int main(void)
{
putchar('A');
putchar('\n');
putchar('B');
return 0;
}
return 0;
}
10