Οδηγός Μελέτης - Εισαγωγή στον Προγραμματισμό

Διάλεξη 19 · 05/12/2025 · Διαφάνειες (PDF) · Σημειώσεις 7 · Εργαστήριο 9

Κεφάλαιο 19: Δομές

Στόχοι: μετά από αυτό το κεφάλαιο θα μπορείτε να ορίζετε δικούς σας τύπους με struct, να δηλώνετε, να αρχικοποιείτε και να αντιγράφετε μεταβλητές τύπου δομής, να προσπελαύνετε τα πεδία τους με . και, μέσω δείκτη, με ->· να εξηγείτε πώς μια δομή κάθεται στη μνήμη και γιατί το sizeof της μπορεί να είναι μεγαλύτερο από το άθροισμα των πεδίων της (padding)· και να δίνετε συνώνυμα τύπων με typedef.

Προαπαιτούμενα: Κεφάλαιο 12, Κεφάλαιο 13

Χρόνος μελέτης: ~2 ώρες

Σύνοψη

Μέχρι τώρα τα δεδομένα μας ήταν int, double, char, δείκτες και πίνακες. Τα πραγματικά δεδομένα όμως είναι πιο δομημένα: ένας φοιτητής έχει όνομα, επώνυμο, έτος και βαθμό, διαφορετικών τύπων, που ανήκουν μαζί. Η δομή (struct) της C ομαδοποιεί τέτοια πεδία κάτω από ένα όνομα και έτσι ορίζουμε δικούς μας τύπους. Η διάλεξη δείχνει πώς δηλώνουμε, αρχικοποιούμε, αντιγράφουμε και συγκρίνουμε δομές, πώς απλώνονται στη μνήμη (με το padding που προσθέτει ο μεταγλωττιστής), πώς το typedef δίνει σύντομα ονόματα, και πώς δουλεύουμε με ένθετες δομές και δείκτες σε δομές. Οι δομές είναι το υλικό από το οποίο θα φτιάξουμε λίστες και δέντρα στα επόμενα κεφάλαια.

Θεωρία

§19.1 Γιατί χρειαζόμαστε δομές

Έστω ένα πρόγραμμα που διαχειρίζεται μια λίστα φοιτητών. Για κάθε φοιτητή χρειάζεστε char first_name[128], char last_name[128], unsigned int year και double grade. Για 100 φοιτητές, χωρίς δομές, θα έπρεπε να κρατάτε τέσσερις παράλληλους πίνακες (first_names[100][128], last_names[100][128], years[100], grades[100]) και να φροντίζετε ότι η θέση i σε όλους αφορά τον ίδιο άνθρωπο. Αυτό είναι εύθραυστο: μια ταξινόμηση που ξεχνά να μετακινήσει έναν από τους πίνακες χαλάει τα δεδομένα.

Μια δομή (struct), αλλιώς εγγραφή (record), είναι μια συλλογή πεδίων (fields) που ομαδοποιούν την πληροφορία μιας λογικής οντότητας. Με δομή, ο φοιτητής γίνεται μία μεταβλητή και οι 100 φοιτητές ένας πίνακας.

§19.2 Δήλωση τύπου δομής

Η δήλωση δομής δημιουργεί έναν τύπο ορισμένο από τον χρήστη (user-defined type):

struct student {
  char first_name[128];
  char last_name[128];
  unsigned int year;
  double grade;
};

Η λέξη-κλειδί struct λέει ότι ορίζουμε δομή. Το student είναι το όνομα ή ετικέτα (tag) της δομής, και ο τύπος λέγεται struct student (και οι δύο λέξεις). Στα άγκιστρα δηλώνονται τα πεδία όπως μεταβλητές· πεδίο μπορεί να είναι βασικός τύπος, πίνακας, δείκτης ή άλλη δομή. Η δήλωση κλείνει με };.

Η δήλωση του τύπου δεν δεσμεύει μνήμη· περιγράφει μόνο το «καλούπι». Μνήμη δεσμεύεται όταν δηλώσουμε μεταβλητές αυτού του τύπου.

§19.3 Μεταβλητές τύπου δομής

Μεταβλητή δηλώνεται με struct όνομα_δομής όνομα_μεταβλητής;, και ο τύπος συνδυάζεται με δείκτες και πίνακες όπως κάθε άλλος:

struct student st1, st2;          // δύο μεταβλητές
struct student *student_ptr;      // δείκτης σε struct student
struct student student_array[100];// πίνακας με 100 δομές

Μπορείτε επίσης να δηλώσετε μεταβλητές μαζί με τον τύπο, γράφοντάς τες πριν από το τελικό ;: struct student { ... } st1;.

§19.4 Προσπέλαση πεδίων με τον τελεστή .

Στο πεδίο μιας μεταβλητής δομής αναφερόμαστε με μεταβλητή.πεδίο. Το st1.year είναι το ακέραιο πεδίο year της δομής st1. Ένα πεδίο συμπεριφέρεται ακριβώς όπως μια μεταβλητή του τύπου του: ανατίθεται (st1.year = 1;), διαβάζεται, περνά σε συναρτήσεις, και αν είναι πίνακας χαρακτήρων δουλεύει με τις συναρτήσεις συμβολοσειρών (strncpy(st1.first_name, ...)). Ένας πίνακας όμως δεν ανατίθεται με =, οπότε το st1.first_name = "Thanos"; δεν μεταγλωττίζεται.

§19.5 Αρχικοποίηση δομής

Όπως οι πίνακες, μια δομή αρχικοποιείται με λίστα τιμών σε άγκιστρα:

struct student st1 = { "Thanos", "Barbounis", 1, 7.54 };

Οι τιμές αντιστοιχούν στα πεδία με τη σειρά της δήλωσης της δομής: πρώτη τιμή στο first_name, δεύτερη στο last_name κ.ο.κ. Αν παραλείψετε τιμές στο τέλος, τα πεδία που μένουν αρχικοποιούνται στο 0: με { "Thanos", "Barbounis", 1 } το grade είναι 0.0. Αντίθετα, μια τοπική δομή χωρίς καθόλου αρχικοποίηση περιέχει ό,τι υπήρχε στη μνήμη (σκουπίδια), όπως κάθε τοπική μεταβλητή.

Υπάρχει και αρχικοποίηση με ονόματα πεδίων, ανεξάρτητη από τη σειρά: { .year = 2, .grade = 8.5 } (σύνδεσμος «struct initialization» στο «Διάβασμα»).

§19.6 Η δομή στη μνήμη

Όπως κάθε μεταβλητή, μια μεταβλητή δομής πιάνει bytes στη μνήμη. Τα πεδία αποθηκεύονται με τη σειρά της δήλωσης, το ένα μετά το άλλο. Η διαφάνεια δείχνει το st1 με αρχή στη διεύθυνση 31000:

Πεδίο Bytes Μέγεθος Τιμή
first_name 31000–31127 128 "Thanos"
last_name 31128–31255 128 "Barbounis"
year 31256–31259 4 1
grade 31260–31267 8 7.54

Σύνολο \(128 + 128 + 4 + 8 = 268\) bytes, και πράγματι με gcc -m32 (μεταγλώττιση για 32 bit) το sizeof(struct student) είναι 268. Σε ένα σύγχρονο σύστημα 64 bit όμως τυπώνει 272: ο μεταγλωττιστής αφήνει 4 κενά bytes μετά το year ώστε το grade να ξεκινά σε διεύθυνση πολλαπλάσιο του 8. Αυτό είναι το padding της επόμενης ενότητας.

§19.7 Μέγεθος δομής και padding

Ο επεξεργαστής διαβάζει γρηγορότερα ένα int ή ένα double όταν η διεύθυνσή του είναι πολλαπλάσιο του μεγέθους του. Γι’ αυτό ο μεταγλωττιστής μπορεί να προσθέσει padding («κενά» bytes που δεν χρησιμοποιούνται) ανάμεσα στα πεδία ή στο τέλος της δομής, ώστε οι διευθύνσεις των πεδίων να είναι πολλαπλάσια του 4 (ή του 8, sizeof(void *)). Αυτό λέγεται ευθυγράμμιση μνήμης (memory alignment) και γίνεται για λόγους απόδοσης.

Στη δομή { char red; char green; char blue; int alpha; } τα πεδία είναι \(3 + 4 = 7\) bytes, αλλά το sizeof δίνει 8: ένα byte padding μπαίνει μετά το blue ώστε το alpha να ξεκινά σε πολλαπλάσιο του 4.

Offset 0 1 2 3 4–7
Πεδίο red green blue padding alpha

Η σειρά των πεδίων μετράει. Αν εναλλάξετε char και int (char red; int alpha; char green; int beta; char blue; int gamma;), κάθε char ακολουθείται από 3 bytes padding και το μέγεθος γίνεται 24, ενώ χρησιμοποιούνται μόνο \(3 \cdot 1 + 3 \cdot 4 = 15\):

Offset 0 1–3 4–7 8 9–11 12–15 16 17–19 20–23
Πεδίο red pad alpha green pad beta blue pad gamma

Το συμπέρασμα της διάλεξης: το μέγεθος μιας δομής είναι ό,τι επιστρέφει το sizeof. Μην το υπολογίζετε με το χέρι αθροίζοντας πεδία· γράφετε πάντα sizeof(struct student) (π.χ. στη malloc). Τυπώνεται με %zu.

§19.8 Ανάθεση δομών

Ο τελεστής = αντιγράφει όλα τα περιεχόμενα μιας δομής σε μια άλλη, πεδίο προς πεδίο, ακόμα και πίνακες που είναι πεδία της (που αλλιώς δεν ανατίθενται). Με struct point pt1 = { 3, 4 }, pt2;, μετά το pt2 = pt1; ισχύει pt2.x == 3 και pt2.y == 4. Οι δύο μεταβλητές πρέπει να έχουν ακριβώς τον ίδιο τύπο. Δύο δομές με διαφορετικό όνομα είναι διαφορετικοί τύποι, ακόμα κι αν έχουν ίδια πεδία: η ανάθεση ενός struct point1 σε struct point2 δίνει error: incompatible types when assigning to type 'struct point2' from type 'struct point1'.

§19.9 Σύγκριση δομών

Δύο δομές δεν συγκρίνονται με == ή !=. Το if (pt1 == pt2) δίνει error: invalid operands to binary ==. Πρέπει να συγκρίνετε τα πεδία ένα-ένα: pt1.x == pt2.x && pt1.y == pt2.y (και για πεδία-συμβολοσειρές με strcmp).

§19.10 Το typedef

Το προσδιοριστικό typedef (type definition) ορίζει ένα συνώνυμο για έναν υπάρχοντα τύπο: typedef υπάρχων_τύπος νέος_τύπος;. Μετά από typedef unsigned int myuint; οι δηλώσεις unsigned int x; και myuint x; είναι ισοδύναμες. Δεν δημιουργείται νέος τύπος, μόνο νέο όνομα.

Η σύνταξη μοιάζει με δήλωση μεταβλητής, με το νέο όνομα στη θέση της μεταβλητής. Έτσι ονομάζουμε και τύπους πίνακα: μετά από typedef int page[1024]; η δήλωση page mypage; φτιάχνει πίνακα 1024 ακεραίων, και το sizeof(mypage) είναι 4096.

Με δομές το typedef γλιτώνει τη λέξη struct σε κάθε δήλωση: μετά από typedef struct student { ... } Student; γράφετε Student st1 = {...};, αφού το Student και το struct student είναι ο ίδιος τύπος. Το συνώνυμο μπορεί να έχει και το ίδιο όνομα με την ετικέτα (} student;), γιατί οι ετικέτες των δομών ζουν σε ξεχωριστό χώρο ονομάτων. Μπορείτε και να παραλείψετε την ετικέτα (typedef struct { ... } student;): τότε η δομή είναι ανώνυμη και αναφέρεστε σε αυτήν μόνο με το συνώνυμο.

§19.11 Ένθετες δομές

Μια δομή μπορεί να έχει ως πεδία μία ή περισσότερες άλλες δομές, που λέγονται εμφωλευμένες ή ένθετες δομές (nested structs). Για παράδειγμα ένα προϊόν έχει δύο ημερομηνίες:

struct date { int day; int month; int year; };
struct product {
  char *name;
  double price;
  struct date created;
  struct date updated;
};

Η εσωτερική δομή πρέπει να έχει δηλωθεί πριν χρησιμοποιηθεί. Στην αρχικοποίηση κάθε ένθετη δομή παίρνει τα δικά της άγκιστρα: {"eclass", 3.14, {1, 1, 2021}, {11, 12, 2022}}. Για να φτάσετε σε ένα βαθύ πεδίο χρησιμοποιείτε το . όσες φορές χρειάζεται: prod.updated.year = 2023;. Ο τελεστής . είναι αριστερά προσεταιριστικός, άρα αυτό σημαίνει (prod.updated).year.

§19.12 Δείκτες σε δομές και ο τελεστής ->

Οι δείκτες συνδυάζονται με δομές όπως με κάθε τύπο. Ένας δείκτης σε δομή παίρνει τη διεύθυνση μιας υπάρχουσας δομής (Date *d2 = &d1;) ή ένα μπλοκ από τη malloc (Date *d3 = malloc(sizeof(Date));). Με *d2 φτάνετε στη δομή, άρα στο πεδίο της με (*d2).day. Οι παρενθέσεις είναι απαραίτητες: το . έχει μεγαλύτερη προτεραιότητα από το *, οπότε το *d2.day σημαίνει *(d2.day) και δεν μεταγλωττίζεται.

Επειδή αυτό γράφεται συνέχεια, η C δίνει τον τελεστή βέλους (arrow operator) ->: το ptr->field είναι ισοδύναμο με το (*ptr).field. Γράφετε λιγότερο, και ο αναγνώστης βλέπει αμέσως ότι η μεταβλητή είναι δείκτης. Κανόνας: . όταν έχετε τη δομή, -> όταν έχετε δείκτη σε αυτήν.

Η ανάθεση *d3 = *d2; αντιγράφει ολόκληρη τη δομή όπου δείχνει το d2 στη μνήμη όπου δείχνει το d3, ενώ το d3 = d2; θα αντέγραφε μόνο τη διεύθυνση.

Παραδείγματα

§19.13 Ανάθεση και χρήση πεδίων

Το πρόγραμμα της διάλεξης (Θεωρία: «Προσπέλαση πεδίων», «Δήλωση τύπου δομής») γεμίζει ένα struct student πεδίο-πεδίο. Τα ονόματα αντιγράφονται με strncpy, που δεν βάζει πάντα '\0', γι’ αυτό η επόμενη γραμμή γράφει τον τερματικό χαρακτήρα στο τελευταίο byte του πίνακα. Το sizeof(st1.first_name) είναι 128, το μέγεθος του πεδίου.

#include <stdio.h>
#include <string.h>

struct student {
  char first_name[128]; char last_name[128];
  unsigned int year; double grade;
};

int main() {
  struct student st1;
  st1.year = 1;
  st1.grade = 7.54;
  strncpy(st1.first_name, "Thanos", sizeof(st1.first_name) - 1);
  st1.first_name[sizeof(st1.first_name) - 1] = '\0';
  strncpy(st1.last_name, "Barbounis", sizeof(st1.last_name) - 1);
  st1.last_name[sizeof(st1.last_name) - 1] = '\0';
  printf("%s %s: %f [%u year]\n", st1.first_name, st1.last_name,
         st1.grade, st1.year);
  return 0;
}
$ ./struct
Thanos Barbounis: 7.540000 [1 year]

Με αρχικοποίηση struct student st1 = { "Thanos", "Barbounis", 1, 7.54 }; η έξοδος είναι ίδια. Αν παραλείψετε το 7.54, το grade γίνεται 0:

$ ./struct
Thanos Barbounis: 0.000000 [1 year]

§19.14 Μέγεθος δομής και padding

Τρία προγράμματα της διάλεξης μεταγλωττισμένα με -m32 (Θεωρία: «Η δομή στη μνήμη», «Μέγεθος δομής και padding»):

#include <stdio.h>

int main() {
  struct pixel_tag {
    char red; char green; char blue; int alpha;
  } pixel = {0xFF, 0xFF, 0xFF, 42};
  printf("%zu\n", sizeof(pixel));
  return 0;
}

Το struct3.c είναι το ίδιο με τα πεδία ανακατεμένα (char red; int alpha; char green; int beta; char blue; int gamma;), και το struct.c τυπώνει sizeof(struct student):

$ gcc -m32 -o struct2 struct2.c
$ ./struct2
8
$ gcc -m32 -o struct3 struct3.c
$ ./struct3
24
$ gcc -m32 -o struct struct.c
$ ./struct
268

Χωρίς -m32, σε 64 bit, τα δύο πρώτα δίνουν πάλι 8 και 24, αλλά το struct student δίνει 272 λόγω του padding πριν από το double.

§19.15 Αντιγραφή δομής με ανάθεση

Θεωρία: «Ανάθεση δομών». Το pt2 τυπώνεται πρώτα χωρίς αρχικοποίηση:

#include <stdio.h>

struct point { int x; int y; };

int main() {
  struct point pt1 = { 3, 4 };
  struct point pt2;
  printf("%d %d\n", pt2.x, pt2.y);
  pt2 = pt1;
  printf("%d %d\n", pt2.x, pt2.y);
  return 0;
}
$ ./copy
-29387249 0
3 4

Η πρώτη γραμμή είναι ό,τι υπήρχε στη μνήμη και αλλάζει από εκτέλεση σε εκτέλεση (ο gcc -Wall προειδοποιεί ότι το pt2 χρησιμοποιείται χωρίς αρχικοποίηση). Η δεύτερη δείχνει ότι η ανάθεση αντέγραψε όλα τα πεδία.

§19.16 Ένθετες δομές με και χωρίς typedef

Θεωρία: «Ένθετες δομές», «Το typedef». Με τους τύπους struct date και struct product της Θεωρίας, το sizeof(prod) είναι 40 (8 για τον δείκτη, 8 για το double, 2 × 12 για τις ημερομηνίες). Η ίδια λογική γραμμένη με typedef και ανώνυμες δομές:

#include <stdio.h>

typedef struct { int day; int month; int year; } Date;

typedef struct {
  char *name;
  double price;
  Date created, updated;
} Product;

int main() {
  Product prod = {"eclass", 3.14, {1, 1, 2021}, {11, 12, 2022}};
  prod.updated.year = 2023;
  printf("%s [eu: %.2f] [created: %d/%d/%d] [updated: %d/%d/%d]\n",
         prod.name, prod.price,
         prod.created.day, prod.created.month, prod.created.year,
         prod.updated.day, prod.updated.month, prod.updated.year);
  return 0;
}
$ ./nested3
eclass [eu: 3.14] [created: 1/1/2021] [updated: 11/12/2023]

Η εκδοχή με struct date / struct product (χωρίς typedef) τυπώνει ακριβώς το ίδιο.

§19.17 Δείκτες σε δομές: η διαφορά ημερομηνιών

Θεωρία: «Δείκτες σε δομές και ο τελεστής ->». Γραμμένο με ->· η εκδοχή της διάλεξης με (*d2).day, (*d3).month κ.λπ. δίνει την ίδια έξοδο.

#include <stdio.h>
#include <stdlib.h>

typedef struct { int day; int month; int year; } Date;

int main() {
  Date d1 = {1, 10, 2023};
  Date *d2 = &d1;
  d2->day = 2;
  Date *d3 = malloc(sizeof(Date));
  *d3 = *d2;
  d3->month = 12; d3->day = 11;
  printf("Diff: %d/%d/%d\n", d3->day - d1.day, d3->month - d1.month,
         d3->year - d1.year);
  return 0;
}
$ ./dateptr
Diff: 9/2/0

Το d2 δείχνει στο ίδιο το d1, άρα το d2->day = 2 αλλάζει το d1 σε 2/10/2023. Το *d3 = *d2 αντιγράφει αυτή την ημερομηνία στο μπλοκ της malloc, που μετά γίνεται 11/12/2023. Οι διαφορές είναι \(11 - 2 = 9\), \(12 - 10 = 2\), \(2023 - 2023 = 0\). (Σε κανονικό πρόγραμμα θα ελέγχατε ότι η malloc δεν επέστρεψε NULL και θα καλούσατε free(d3)· δείτε Κεφάλαιο 13.)

flowchart LR
  D2["d2 (Date *)"] --> D1["d1: 2/10/2023 (στοίβα)"]
  D3["d3 (Date *)"] --> H["μπλοκ malloc: 11/12/2023 (σωρός)"]
  D1 -. "*d3 = *d2 (αντιγραφή)" .-> H

Σχήμα: το d2 δείχνει στο d1, το d3 σε νέα μνήμη· η ανάθεση *d3 = *d2 αντιγράφει τη δομή, όχι τη διεύθυνση.

§19.18 Για το εργαστήριο

Το Εργαστήριο 9 εφαρμόζει αυτό το κεφάλαιο στις δύο πρώτες ασκήσεις: το point.c ορίζει struct point με συντεταγμένες double και μια συνάρτηση που επιστρέφει δομή (το μέσο δύο σημείων), και το person.c δεσμεύει δομή με malloc και την προσπελαύνει με ->. Το πέρασμα και η επιστροφή δομών από συναρτήσεις αναλύονται στο Κεφάλαιο 20.

Κύρια σημεία

  1. Μια δομή (struct) ομαδοποιεί πεδία, πιθανώς διαφορετικών τύπων, που περιγράφουν μια λογική οντότητα, και ορίζει έναν νέο τύπο, π.χ. struct student.
  2. Η δήλωση του τύπου δεν δεσμεύει μνήμη· μνήμη δεσμεύουν οι μεταβλητές, οι πίνακες και οι δομές από malloc αυτού του τύπου.
  3. Στα πεδία φτάνουμε με μεταβλητή.πεδίο, και κάθε πεδίο χρησιμοποιείται όπως μια μεταβλητή του τύπου του.
  4. Η αρχικοποίηση { ... } αντιστοιχεί τιμές στα πεδία με τη σειρά της δήλωσης· όσα πεδία παραλείπονται γίνονται 0.
  5. Τα πεδία αποθηκεύονται στη μνήμη με τη σειρά της δήλωσης, αλλά ο μεταγλωττιστής μπορεί να προσθέσει padding για ευθυγράμμιση, οπότε η σειρά των πεδίων επηρεάζει το μέγεθος.
  6. Το μέγεθος μιας δομής είναι ό,τι επιστρέφει το sizeof(struct όνομα), όχι το άθροισμα των πεδίων της.
  7. Η ανάθεση = αντιγράφει όλα τα πεδία, μόνο ανάμεσα σε δομές του ίδιου τύπου· σύγκριση με == δεν υπάρχει, συγκρίνουμε τα πεδία ένα-ένα.
  8. Το typedef δίνει συνώνυμο σε έναν τύπο· με δομές γλιτώνει το struct, και η ετικέτα μπορεί να παραλειφθεί (ανώνυμη δομή).
  9. Μια δομή μπορεί να περιέχει άλλες δομές, και φτάνουμε σε βαθιά πεδία με διαδοχικά . (prod.updated.year).
  10. Για δείκτη σε δομή, το ptr->field είναι ισοδύναμο με το (*ptr).field.

Ορολογία

Ελληνικά English Σύντομος ορισμός
δομή / εγγραφή struct / record Συλλογή πεδίων που περιγράφουν μια οντότητα· νέος τύπος.
πεδίο / μέλος field / member Μία από τις μεταβλητές μέσα σε μια δομή.
ετικέτα δομής struct tag Το όνομα μετά το struct, π.χ. student.
τύπος ορισμένος από τον χρήστη user-defined type Τύπος που ορίζει το πρόγραμμα, όπως μια δομή.
αρχικοποίηση δομής struct initialization Τιμές σε { } με τη σειρά των πεδίων.
γέμισμα padding Αχρησιμοποίητα bytes που προσθέτει ο μεταγλωττιστής.
ευθυγράμμιση μνήμης memory alignment Διευθύνσεις πεδίων πολλαπλάσιες του 4 ή του 8.
συνώνυμο τύπου typedef Νέο όνομα για υπάρχοντα τύπο.
ανώνυμη δομή anonymous struct Δομή χωρίς ετικέτα, συνήθως με typedef.
ένθετη / εμφωλευμένη δομή nested struct Δομή που είναι πεδίο άλλης δομής.
τελεστής βέλους arrow operator (->) ptr->f ισοδυναμεί με (*ptr).f.

Διάβασμα

Συχνά λάθη

Τι δυσκόλεψε την τάξη

Από τα Kahoot των διαλέξεων: οι ερωτήσεις όπου μια λάθος απάντηση μάζεψε πολλές ψήφους, με το ποσοστό σωστών απαντήσεων.

Ερωτήσεις κατανόησης

Kahoot από το αμφιθέατρο (Κ19.1–Κ19.9)

Ερωτήσεις που παίχτηκαν στις διαλέξεις, με το ποσοστό των φοιτητών που απάντησαν σωστά.

Ασκήσεις

Ζέσταμα: από τις διαφάνειες (Α19.1–Α19.8)

Εργαστήριο (Α19.9–Α19.10)

Θέματα εξετάσεων (Α19.11–Α19.12)

Σχετικές ασκήσεις από άλλα κεφάλαια

  1. Καμία. Η δήλωση ορίζει μόνο τον τύπο· μνήμη δεσμεύεται όταν δηλωθεί μεταβλητή (ή κληθεί malloc). [^q2]: 0.0: τα πεδία που λείπουν από τη λίστα αρχικοποίησης γίνονται 0 (και το year επίσης 0). [^q3]: Λόγω padding: ο μεταγλωττιστής αφήνει κενά bytes ώστε κάθε πεδίο να ξεκινά σε διεύθυνση κατάλληλη για τον τύπο του (memory alignment), για λόγους απόδοσης. [^q4]: Βάζοντας μαζί τα int και μαζί τα char, π.χ. int alpha, beta, gamma; char red, green, blue;: 12 + 3 = 15 bytes, που με padding στο τέλος γίνονται 16 αντί για 24. [^q5]: Αντιγράφει όλα τα πεδία του pt1 στο pt2. Η C δεν ορίζει == για δομές (invalid operands to binary ==)· συγκρίνουμε pt1.x == pt2.x && pt1.y == pt2.y. [^q6]: p->created.day: το -> για τον δείκτη, το . για την ένθετη δομή. [^q7]: Το d3 = d2; αντιγράφει τη διεύθυνση (και οι δύο δείχνουν στην ίδια δομή, ενώ χάνεται το μπλοκ του d3)· το *d3 = *d2; αντιγράφει τα περιεχόμενα της δομής. ↩

Κατεβάστε το κεφάλαιο: PDF · Markdown · GitHub