Κοινή χρήση τεχνολογίας

Γ γλώσσα - δομή

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Ορίστε και χρησιμοποιήστε δομές

1.1 Επισκόπηση

Οι τύποι δεδομένων που έχουμε δει στο παρελθόν, όπως int, float, char κ.λπ., χρησιμοποιούνται απλά σε προγράμματα Αν θέλουμε να δημιουργήσουμε κάποια σύνθετα δεδομένα σύμφωνα με τις δικές μας ανάγκες, πρέπει να χρησιμοποιήσουμε δομές.

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

  1. 结构体类型:
  2.         struct Student
  3.         {
  4.               int num;//学号为整形;
  5.               char name[20];//姓名为字符串;
  6.               char sex;//性别为字符型;
  7.               int age;//年龄为整形
  8.               float score;//成绩为浮点型
  9. char addr[30];//地址为字符型;
  10. }

σε:

struct Το Student είναι ένας τύπος δομής.

struct είναι μια λέξη-κλειδί που δηλώνει έναν τύπο δομής.

Student είναι το όνομα της δομής, προκειμένου να διακρίνεται από άλλες δομές.

Τα σγουρά στηρίγματα περιέχουν τα μέλη της δομής Η ομάδα μαζί ονομάζεται λίστα μελών και η ονομασία της είναι συνεπής με την ονομασία των μεταβλητών.

Σημείωση: Οι τύποι δομής μπορούν να έχουν πολλαπλούς τύπους, όπως: struct struct Teacher;

Τα μέλη μιας δομής μπορούν επίσης να είναι ο τύπος μιας άλλης δομής.

struct Ημερομηνία

{        

int μήνα?

int ημέρα?

int έτος?

};

struct Μαθητής

{

int num;

όνομα char[20];

char σεξ?

int ηλικία?

struct Ημερομηνία γενέθλια?

char addr[30];

}

1.2 Ορισμός μεταβλητών δομής

Παλαιότερα ορίσαμε μόνο έναν τύπο δομής, ο οποίος είναι ισοδύναμος με ένα μοντέλο, και δεν ορίσαμε μεταβλητές Στη συνέχεια ορίζουμε μεταβλητές δομής και αποθηκεύουμε συγκεκριμένα δεδομένα σε αυτές, 3 μεθόδους.

Μέθοδος 1: Δηλώστε πρώτα τον τύπο δομής και, στη συνέχεια, ορίστε τις μεταβλητές δομής

Με βάση την προηγούμενη δομή τύπου struct Student, ορίστε μεταβλητές δομής.

struct Student student1,student2;

Αυτή η μέθοδος είναι παρόμοια με την int a,b η μόνη προϋπόθεση είναι να υπάρχει ήδη ένας τύπος δομής και η μεταβλητή δομής να ορίζεται με βάση τον τύπο.

    Μέθοδος 2: Καθορισμός μεταβλητών κατά τη δήλωση του τύπου

μορφή:

όνομα δομής

                {

λίστα μελών?

}Λίστα ονομάτων μεταβλητών.

Παράδειγμα:

struct Μαθητής
                {
int num;
όνομα char[20];
char σεξ?
int ηλικία?
float score?
char addr[30];
}μαθητής1,μαθητής2;

      Μέθοδος 3: Καθορίστε άμεσα μεταβλητές τύπου δομής χωρίς να καθορίσετε όνομα τύπου

μορφή:

struct

                        {

Μεταβλητές μέλους;

}Λίστα ονομάτων μεταβλητών.

Είναι ένας τύπος δομής χωρίς όνομα και δεν χρησιμοποιείται συνήθως.

Σημείωση: 1. Τα ονόματα των μελών στις μεταβλητές δομής μπορεί να είναι ίδια με τα ονόματα των μεταβλητών στο πρόγραμμα.

2. Τα μέλη των μεταβλητών δομής μπορούν να χρησιμοποιηθούν μόνα τους η κατάσταση και η λειτουργία τους είναι ισοδύναμες με τις συνήθεις μεταβλητές.

1.3 Αρχικοποίηση και αναφορά μεταβλητών δομής

Αρχικοποιήστε τις μεταβλητές δομής κατά τον ορισμό τους.

      Παράδειγμα:Βάλτε τις πληροφορίες ενός μαθητή (συμπεριλαμβανομένου του αριθμού μαθητή, του ονόματος, του φύλου, της διεύθυνσης) σε μια μεταβλητή δομής και μετά εξάγετε τις πληροφορίες του μαθητή.

  1. #include <stdio.h>
  2. int main()
  3. {
  4. struct Student
  5. {
  6. int num;
  7. char name[20];
  8. char sex;
  9. char addr[20];
  10. }student1 = {101,"Li li",'M',"123XiAn"};
  11. printf("NO:%d,nname:%snssex:%cnaddress:%sn",student1.num,student1.name,student1.sex,student1.addr);
  12. return 0;

Ανάλυση αποτελεσμάτων:

Κατά τον ορισμό μιας μεταβλητής δομής, η λίστα προετοιμασίας είναι ένας αριθμός σταθερών που περικλείονται σε σγουρά άγκιστρα αρχικοποίηση τύπου σώματος.

Η τιμή του μέλους στη μεταβλητή δομής, η μέθοδος αναφοράς είναι:

Όνομα μεταβλητής δομής. Όνομα μέλους

μαθητής1.όνομα

      Για τα μέλη της δομής που ανήκουν σε άλλον τύπο δομής, τα μέλη χαμηλότερου επιπέδου πρέπει να βρεθούν επίπεδο προς επίπεδο.

Γενέθλια μαθητή.μήνας

Οι δομές του ίδιου τύπου μπορούν να αντιστοιχιστούν μεταξύ τους:μαθητής 1 = μαθητής 2.

        Παράδειγμα:Εισαγάγετε την ταυτότητα μαθητή, το όνομα και τους βαθμούς δύο μαθητών και εξάγετε την ταυτότητα μαθητή, το όνομα και τη βαθμολογία του μαθητή με υψηλότερους βαθμούς.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. int main()
  4. {
  5. struct Student
  6. {
  7. int num;
  8. char name[20];
  9. float score;
  10. }student1,student2;
  11. scanf("%d%s%f", &student1.num, student1.name, &student1.score);
  12. scanf("%d%s%f", &student2.num, student2.name, &student2.score);
  13. printf("The higher score is:n");
  14. if (student1.score > student2.score)
  15. {
  16. printf("%d %s %6.2fn", student1.num, student1.name, student1.score);
  17. }
  18. else if (student1.score < student2.score)
  19. {
  20. printf("%d %s %6.2fn", student2.num, student2.name, student2.score);
  21. }
  22. else
  23. {
  24. printf("%d %s %6.2fn", student1.num, student1.name, student1.score);
  25. printf("%d %s %6.2fn", student2.num, student2.name, student2.score);
  26. }
  27. }

Όταν χρησιμοποιείτε τη συνάρτηση scanf για την εισαγωγή μεταβλητών δομής, δεν μπορείτε να χρησιμοποιήσετε το όνομα της μεταβλητής δομής στη συνάρτηση scanf για να εισαγάγετε τις τιμές όλων των μελών ταυτόχρονα του student1.name, επειδή το όνομα του πίνακα αντιπροσωπεύει αρχικά Got the address.

2. Χρησιμοποιήστε πίνακα δομών

2.1 Ορισμός πίνακα δομών

Όταν ορίσαμε τις μεταβλητές δομής νωρίτερα, τις ορίσαμε μία προς μία, ωστόσο, εάν είναι μια ομάδα σχετικών δεδομένων που χρειάζεται να συμμετάσχει στη λειτουργία, είναι προφανές ότι είναι απαραίτητο να χρησιμοποιηθούν δεδομένα, όπως οι πληροφορίες 10 μαθητών είναι ο πίνακας δομής, κάθε στοιχείο πίνακα του πίνακα δομής είναι μια δομή.

Για παράδειγμα: Υπάρχουν τρεις υποψήφιοι και κάθε ψηφοφόρος μπορεί να ψηφίσει μόνο για ένα άτομο.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. struct Person
  5. {
  6. char name[20];
  7. int count;
  8. }leader[3] = { "wang", 0, "zhang", 0, "li", 0 };
  9. int main()
  10. {
  11. int i, j;
  12. char lead_name[20];
  13. for (i = 0; i < 10; i++)
  14. {
  15. scanf("%s", lead_name);
  16. for (j = 0; j < 3; j++)
  17. {
  18. if (strcmp(lead_name, leader[j].name) == 0)
  19. leader[j].count++;
  20. }
  21. }
  22. printf("nResultn");
  23. for (i = 0; i < 3; i++)
  24. {
  25. printf("name:%s,count:%dn", leader[i].name, leader[i].count);
  26. }
  27. return 0;
  28. }

Ορίστε τη γενική μορφή ενός πίνακα δομών:

        όνομα δομής

        {

λίστα μεταβλητών

} όνομα πίνακα [μήκος πίνακα];

ή

Πρώτα δηλώστε έναν τύπο δομής, όπως: struct student, και μετά ορίστε τον πίνακα δομών.

        Τύπος δομής όνομα πίνακα [μήκος πίνακα].

Η μορφή αρχικοποίησης ενός πίνακα δομών είναι να προσθέσετε μετά τον ορισμό:

      ={Λίστα αρχικών τιμών};     

2.2 Χρήση πίνακα δομών

        Παράδειγμα:Υπάρχουν πληροφορίες για n μαθητές (συμπεριλαμβανομένης της ταυτότητας μαθητή, του ονόματος και των βαθμών) και απαιτείται η εξαγωγή των πληροφοριών κάθε μαθητή με σειρά βαθμολογίας.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. struct Student
  5. {
  6. int num;
  7. char name[20];
  8. float score;
  9. };
  10. int main()
  11. {
  12. struct Student stu[5] = { 1001, "Wangwei", 98.25, 1002, "Liuliu", 91, 1003, "Zhangli", 98, 1004, "Xiaozhao", 85, 1005, "Baibai", 94 };
  13. struct Student temp;
  14. printf("The order id:n");
  15. int i, j,k;
  16. for (i = 0; i < 4; i++)
  17. {
  18. k = i;
  19. for (j = i + 1; j < 5; j++)
  20. {
  21. if (stu[j].score>stu[k].score)
  22. {
  23. k = j;
  24. }
  25. }
  26. temp = stu[k];
  27. stu[k] = stu[i];
  28. stu[i] = temp;
  29. }
  30. for (i = 0; i < 5; i++)
  31. {
  32. printf("%d %s %5.2f", stu[i].num, stu[i].name, stu[i].score);
  33. printf("n");
  34. }
  35. return 0;
  36. }

3. Δείκτης δομής

3.1 Δείκτες για μεταβλητές δομής

Ο λεγόμενος δείκτης δομής είναι ένας δείκτης σε μια μεταβλητή δομής Η αρχική διεύθυνση μιας μεταβλητής δομής είναι ο δείκτης της μεταβλητής δομής.

Μια μεταβλητή δείκτη που δείχνει σε ένα αντικείμενο δομής μπορεί να δείχνει είτε σε μια μεταβλητή δομής είτε σε ένα στοιχείο ενός πίνακα δομής Ο βασικός τύπος της μεταβλητής δείκτη πρέπει να είναι ο ίδιος με τον τύπο της μεταβλητής δομής.

Για παράδειγμα: struct Student * pt;

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

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. struct Student
  5. {
  6. long num;
  7. char name[20];
  8. char sex;
  9. float score;
  10. };
  11. int main()
  12. {
  13. struct Student stu1;
  14. struct Student *pt;
  15. pt = &stu1;
  16. stu1.num = 10001;
  17. strcpy(stu1.name, "Lili");
  18. stu1.sex = 'M';
  19. stu1.score = 96.5;
  20. printf("No:%dnname:%snsex:%cnscore:%5.1fn", stu1.num, stu1.name, stu1.sex, stu1.score);
  21. printf("n");
  22. printf("No:%dnname:%snsex:%cnscore:%5.1fn", (*pt).num, (*pt).name, (*pt).sex, (*pt).score);
  23. printf("n");
  24. printf("No:%dnname:%snsex:%cnscore:%5.1fn", pt->num, pt->name, pt->sex, pt->score);
  25. return 0;
  26. }

Ανάλυση αποτελεσμάτων:

Στη συνάρτηση, η πρώτη συνάρτηση printf έχει πρόσβαση σε μέλη μέσω του ονόματος της μεταβλητής δομής stu1.

Η δεύτερη συνάρτηση printf έχει πρόσβαση στα μέλη της μέσω μιας μεταβλητής δείκτη που δείχνει σε μια μεταβλητή δομής (*pt) αντιπροσωπεύει τη μεταβλητή δομής που δείχνει και (*pt).num αντιπροσωπεύει το μέλος δομής που δείχνει.

Επιπλέον, στη γλώσσα C, επιτρέπεται η αντικατάσταση του (*pt).num με pt-&gt;num;

3.2 Πίνακας δείκτη προς δομή

Οι μεταβλητές δείκτη μπορούν να χρησιμοποιηθούν για να δείξουν στοιχεία του πίνακα δομών.

Παράδειγμα:Υπάρχουν τρεις πληροφορίες μαθητών, τοποθετημένες στον πίνακα δομών και οι πληροφορίες του μαθητή πρέπει να εξάγονται.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. struct Student
  5. {
  6. long num;
  7. char name[20];
  8. char sex;
  9. float score;
  10. };
  11. int main()
  12. {
  13. struct Student stu[3] = { 1001, "wangle", 'M', 95, 1002, "chengcai", 'M', 99.9, 1003, "shangmin", 'F', 85.2 };
  14. struct Student *pt;
  15. printf("No. name sex scoren");
  16. for (pt = stu; pt < stu + 3; pt++)
  17. {
  18. printf("%d %s %c %5.2fn", pt->num, pt->name, pt->sex, pt->score);
  19. }
  20. return 0;
  21. }

Στο πρόγραμμα, το pt είναι δείκτης σε μια μεταβλητή δομής Student Χρησιμοποιείται για να δείξει τη μεταβλητή δομής, όχι σε ένα συγκεκριμένο μέλος της δομής μεταβλητή δομής και η άλλη είναι μεταβλητή μέλους δομής. p++, η τιμή του p αυξάνει το μήκος της δομής.

3.3 Χρησιμοποιήστε μεταβλητές δομής και δείκτες για μεταβλητές δομής ως παραμέτρους συνάρτησης

Υπάρχουν τρεις τρόποι για να μεταβιβαστεί η τιμή μιας μεταβλητής δομής σε μια συνάρτηση.

1. Χρησιμοποιήστε τα μέλη των μεταβλητών δομής ως παραμέτρους Αυτή η μέθοδος είναι ισοδύναμη με τη μετάδοση συνηθισμένων μεταβλητών.

2. Χρησιμοποιήστε μεταβλητές δομής ως πραγματικές παραμέτρους. Όταν μια μεταβλητή δομής χρησιμοποιείται ως πραγματική παράμετρος, μεταβιβάζεται επίσης με τιμή Όλα τα περιεχόμενα της μονάδας μνήμης που καταλαμβάνεται από τη μεταβλητή δομής μεταβιβάζονται στην τυπική παράμετρο.

3. Χρησιμοποιήστε τον δείκτη στη μεταβλητή δομής (πίνακας) ως πραγματική παράμετρο για να μεταβιβάσετε τη διεύθυνση της μεταβλητής δομής (πίνακας) στην επίσημη παράμετρο.

Παράδειγμα:

Υπάρχουν n δομές, συμπεριλαμβανομένων των αναγνωριστικών φοιτητών, των ονομάτων και των βαθμών σε 3 μαθήματα. .

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. void print(struct Student stud);
  5. struct Student Max(struct Student stu[]);
  6. void input(struct Student stu[]);
  7. struct Student
  8. {
  9. int num;
  10. char name[20];
  11. float score[3];
  12. float aver;
  13. };
  14. int main()
  15. {
  16. struct Student stu[3], *pt;
  17. pt = stu;
  18. input(pt);
  19. print(Max(pt));
  20. return 0;
  21. }
  22. void input(struct Student stu[])
  23. {
  24. int i;
  25. printf("请输入各学生的信息:学号、姓名、3门成绩:n");
  26. for (i = 0; i < 3;i++)
  27. {
  28. scanf("%d%s%f%f%f", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
  29. stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;
  30. }
  31. }
  32. struct Student Max(struct Student stu[])
  33. {
  34. int i, m = 0;
  35. for (i = 0; i < 3; i++)
  36. {
  37. if (stu[i].aver > stu[m].aver)
  38. m = i;
  39. }
  40. return stu[m];
  41. }
  42. void print(struct Student stud)
  43. {
  44. printf("成绩最好的学生是:n");
  45. printf("学号:%d 姓名:%s 三门课程:%5.2f %5.2f %5.2f平均成绩:%5.2fn", stud.num, stud.name, stud.score[0], stud.score[1], stud.score[2], stud.aver);
  46. }

1. Κατά την κλήση της συνάρτησης εισόδου, η πραγματική παράμετρος είναι η μεταβλητή δείκτη pt και η επίσημη παράμετρος είναι ο πίνακας δομής Αυτό που μεταβιβάζεται είναι η αρχική διεύθυνση του στοιχείου δομής και η συνάρτηση δεν έχει τιμή επιστροφής.

2. Κατά την κλήση της συνάρτησης Max, η πραγματική παράμετρος είναι η μεταβλητή δείκτη pt, η επίσημη παράμετρος είναι ο πίνακας δομής, η διεύθυνση έναρξης του στοιχείου δομής μεταβιβάζεται και η επιστρεφόμενη τιμή συνάρτησης είναι δεδομένα τύπου δομής.

3. Κατά την κλήση της συνάρτησης εκτύπωσης, οι πραγματικές παράμετροι είναι μεταβλητές δομής (στοιχεία πίνακα δομής) και οι τυπικές παράμετροι είναι μεταβλητές δομής Αυτό που μεταβιβάζεται είναι η τιμή κάθε μέλους στη μεταβλητή δομής και η συνάρτηση δεν έχει τιμή επιστροφής.

4. Συνδεδεμένη λίστα

4.1 Επισκόπηση

Η συνδεδεμένη λίστα είναι μια κοινή δομή δεδομένων, η οποία είναι μια δομή για δυναμική κατανομή αποθήκευσης.

Κατά την αποθήκευση δεδομένων σε έναν πίνακα, το μήκος του πίνακα (πολλαπλοί πίνακες) πρέπει να καθοριστεί εκ των προτέρων Εάν ορισμένες τάξεις έχουν 100 μαθητές και ορισμένες τάξεις έχουν 30 μαθητές, εάν ο ίδιος πίνακας χρησιμοποιείται για την αποθήκευση των δεδομένων μαθητών σε διαφορετικές τάξεις. Πρέπει να οριστεί ένας πίνακας με μήκος 100, αλλά αυτό συχνά οδηγεί σε σπατάλη πόρων.

Η συνδεδεμένη λίστα έχει μια μεταβλητή "head pointer", που αντιπροσωπεύεται από το head στο σχήμα, η οποία αποθηκεύει μια διεύθυνση, η οποία δείχνει σε ένα στοιχείο Κάθε στοιχείο στη συνδεδεμένη λίστα ονομάζεται "node" και κάθε κόμβος πρέπει να περιλαμβάνει δύο μέρη:

1. Πραγματικά δεδομένα που απαιτούνται από τους χρήστες.

2. Η διεύθυνση του επόμενου στοιχείου.

Μπορεί να φανεί ότι οι διευθύνσεις κάθε στοιχείου στη συνδεδεμένη λίστα στη μνήμη μπορεί να είναι ασυνεχείς Για να βρείτε ένα συγκεκριμένο στοιχείο, πρέπει πρώτα να βρείτε το προηγούμενο στοιχείο και το επόμενο στοιχείο μπορεί να βρεθεί με βάση τη διεύθυνση του προηγούμενου στοιχείου. . Εάν δεν παρέχεται ο "δείκτης κεφαλής", ολόκληρη η συνδεδεμένη λίστα δεν είναι προσβάσιμη.

Σε αυτήν την περίπτωση, είναι πιο κατάλληλο να χρησιμοποιήσετε μια δομή για τη δημιουργία μιας συνδεδεμένης λίστας Μια δομή περιέχει πολλά μέλη και τα μέλη τύπου δείκτη χρησιμοποιούνται για την αποθήκευση της διεύθυνσης του επόμενου κόμβου.

struct Μαθητής

        {

int num;

int score?

struct Student *next;

        }

Μεταξύ αυτών, το num και το score χρησιμοποιούνται για την αποθήκευση δεδομένων χρήστη και το next χρησιμοποιείται για την αποθήκευση της διεύθυνσης του επόμενου κόμβου.

4.2 Στατική συνδεδεμένη λίστα

Υπόθεση:

Δημιουργήστε μια στατική συνδεδεμένη λίστα, αποτελούμενη από κόμβους με δεδομένα τριών μαθητών και απαιτήστε την έξοδο των δεδομένων κάθε κόμβου.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. struct Student
  4. {
  5. int num;
  6. float score;
  7. struct Student * next;
  8. };
  9. int main()
  10. {
  11. struct Student a, b, c, *head, *p;
  12. a.num = 1001; a.score = 85.5;
  13. b.num = 1002; b.score = 95.5;
  14. c.num = 1003; c.score = 84.5;
  15. head = &a;
  16. a.next = &b;
  17. b.next = &c;
  18. c.next = NULL;
  19. p = head;
  20. do
  21. {
  22. printf("%d %5.2fn", p->num, p->score);
  23. p = p->next;
  24. } while (p != NULL);
  25. return 0;
  26. }

Για παράδειγμα, δημιουργήστε μια συνδεδεμένη λίστα έτσι ώστε η κεφαλή να δείχνει στον κόμβο a, το a.next να δείχνει στον κόμβο b, το b.next να δείχνει στον κόμβο c και το c.next να δείχνει στο null.

Κατά την έξοδο μιας συνδεδεμένης λίστας, πρέπει πρώτα να χρησιμοποιήσετε το p, να κάνετε το p σημείο στο a, και στη συνέχεια να εξάγετε τα δεδομένα στο a p=p-&gt; επόμενο είναι να προετοιμάσετε τον επόμενο κόμβο για έξοδο.

4.3 Δυναμική συνδεδεμένη λίστα

4.3.1 Δυναμική εκχώρηση μνήμης

Πριν μιλήσουμε για δυναμικές συνδεδεμένες λίστες, ας σας παρουσιάσουμε πρώτα τη δυναμική εκχώρηση μνήμης.

Νωρίτερα είπαμε ότι οι μεταβλητές χωρίζονται σε καθολικές μεταβλητές και οι τοπικές μεταβλητές κατανέμονται στη στατική περιοχή αποθήκευσης της μνήμης οι μη στατικά αποθηκευμένες τοπικές μεταβλητές Αυτή η περιοχή αποθήκευσης ονομάζεταισωρός

Επιπλέον, η γλώσσα C επιτρέπει επίσης τη δημιουργία δυναμικών περιοχών εκχώρησης μνήμης για την αποθήκευση ορισμένων προσωρινών δεδομένων. Αυτά τα δεδομένα ανοίγονται όταν δεν χρειάζονταισωρός

Η δυναμική κατανομή της μνήμης επιτυγχάνεται μέσω λειτουργιών που παρέχονται από το σύστημα: συναρτήσεις malloc, calloc, free και realloc.

1. Χρησιμοποιήστε τη λειτουργία malloc για να ανοίξετε μια δυναμική περιοχή αποθήκευσης

λειτουργία: void *malloc (μη υπογεγραμμένο μέγεθος int);

Λειτουργία:

        Εκχωρήστε έναν συνεχή χώρο μεγέθους μήκους (μονάδα: bytes) στη δυναμική περιοχή αποθήκευσης της μνήμης.

επιστρεφόμενη τιμή:

Η διεύθυνση του πρώτου byte που εκχωρήθηκε αυτή η διεύθυνση δεν έχει τύπο, απλώς μια απλή διεύθυνση.

2. Χρησιμοποιήστε τη λειτουργία calloc για να ανοίξετε μια δυναμική περιοχή αποθήκευσης

λειτουργία:void * calloc(unsigned n, unsigned size);

Λειτουργία:

Εκχωρήστε n byte συνεχούς χώρου με μήκος μεγέθους στη δυναμική περιοχή αποθήκευσης της μνήμης. Αυτός ο χώρος είναι σχετικά μεγάλος για να αποθηκεύσει έναν πίνακα.

Χρησιμοποιήστε τη συνάρτηση calloc για να ανοίξετε δυναμικό χώρο αποθήκευσης για έναν μονοδιάστατο πίνακα, το n είναι ο αριθμός των στοιχείων του πίνακα και το μέγεθος είναι το μήκος του στοιχείου.

επιστρεφόμενη τιμή:

Η διεύθυνση του πρώτου εκχωρημένου byte αυτή η διεύθυνση δεν έχει τύπο, απλώς μια απλή διεύθυνση.

3. Χρησιμοποιήστε τη συνάρτηση realloc για να ανακατανείμετε τη δυναμική περιοχή αποθήκευσης

λειτουργία:void * realloc(void *p ,unsigned int size);

Λειτουργία:

Ανακατανομή εκχωρημένης δυναμικής μνήμης.

Χρησιμοποιήστε τη συνάρτηση ανάκλησης για να αλλάξετε το μέγεθος του δυναμικού χώρου που δείχνει το p σε μέγεθος. Η τιμή του p παραμένει αμετάβλητη.

επιστρεφόμενη τιμή:

Η διεύθυνση του πρώτου byte δυναμικής μνήμης μετά την ενημέρωση είναι ουσιαστικά η διεύθυνση στην οποία επισημαίνεται το p.

4. Χρησιμοποιήστε τη λειτουργία δωρεάν για να απελευθερώσετε τη δυναμική περιοχή αποθήκευσης

λειτουργία: void free(void *p);

Λειτουργία:

Απελευθερώστε το δυναμικό διάστημα που δείχνει η μεταβλητή δείκτη p, έτσι ώστε αυτό το τμήμα του χώρου να μπορεί να χρησιμοποιηθεί από άλλες μεταβλητές.

p είναι η τιμή επιστροφής που λαμβάνεται από την τελευταία κλήση προς τις συναρτήσεις malloc και calloc.

επιστρεφόμενη τιμή:

κανένας;

Σημείωση: Οι δηλώσεις των παραπάνω τεσσάρων συναρτήσεων βρίσκονται όλες στο αρχείο κεφαλίδας stdlib.h.

κενός τύπος δείκτη:

Οι επιστρεφόμενες τιμές της συνάρτησης malloc και της συνάρτησης calloc είναι αμφότερες του τύπου void *, που σημαίνει ότι δεν υποδεικνύεται σε κανένα τύπο δεδομένων Δεν το καταλαβαίνω ότι δείχνει σε οποιονδήποτε τύπο, αλλά δείχνει σε έναν κενό τύπο ή δεν δείχνει δεδομένα συγκεκριμένου τύπου.

Κατά την κλήση δυναμικής μνήμης, το πρόγραμμα χρησιμοποιεί μόνο την καθαρή διεύθυνση που επιστρέφει η συνάρτηση και δεν χρησιμοποιεί το χαρακτηριστικό που δείχνει σε ποιον τύπο δεδομένων θέλετε να χρησιμοποιήσετε αυτήν τη διεύθυνση, πρέπει να μετατραπεί.

Για παράδειγμα:

int *p;

p=(int*)malloc(100);

Υπόθεση:

Δημιουργήστε δυναμικά δεδομένα, εισαγάγετε τις βαθμολογίες 5 μαθητών και χρησιμοποιήστε μια συνάρτηση για να ελέγξετε αν υπάρχουν μαθητές με λιγότερους από 60 βαθμούς και να εξάγετε τις βαθμολογίες που δεν πληρούν τις προϋποθέσεις.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int main()
  5. {
  6. void check(int * p);
  7. int *p1, i;
  8. p1 = (int *)malloc(5 * sizeof(int));
  9. for (i = 0; i < 5; i++)
  10. {
  11. scanf("%d", p1 + i);
  12. }
  13. check(p1);
  14. return 0;
  15. }
  16. void check(int * p)
  17. {
  18. int i;
  19. printf("they are fail:n");
  20. for (i = 0; i < 5; i++)
  21. {
  22. if (*(p+i) < 60)
  23. printf("%d ", *(p + i));
  24. }
  25. }

αποτέλεσμα λειτουργίας:

Ανάλυση αποτελεσμάτων:

Δεν ορίζεται πίνακας στο πρόγραμμα, αλλά ανοίγει μια δυναμική ελεύθερη περιοχή εκχώρησης για χρήση ως πίνακας.

Στη συνάρτηση malloc, καμία συγκεκριμένη τιμή δεν μεταβιβάζεται απευθείας για την εκχώρηση δυναμικού χώρου. Χρησιμοποιήστε το p για να δείξετε τη διεύθυνση του πρώτου byte και να το μετατρέψετε σε τύπο int και το p+1 δείχνει στο επόμενο στοιχείο.

4.3.2 Δημιουργία δυναμικής συνδεδεμένης λίστας

Γράψτε μια συνάρτηση για τη δημιουργία μιας δυναμικής συνδεδεμένης λίστας με δεδομένα για 4 μαθητές.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #define LEN sizeof(struct Student)
  5. struct Student
  6. {
  7. long num;
  8. float score;
  9. struct Student * next;
  10. };
  11. int n;
  12. struct Student * creat(void)
  13. {
  14. struct Student * head, *p1, *p2;
  15. n = 0; p1 = p2 = malloc(LEN);
  16. scanf("%ld%f", &p1->num, &p1->score);
  17. head = NULL;
  18. while (p1->num != 0)
  19. {
  20. n = n + 1;
  21. if (n == 1)
  22. head = p1;
  23. else p2->next = p1;
  24. p2 = p1;
  25. p1 = (struct Student *)malloc(LEN);
  26. scanf("%ld%f", &p1->num, &p1->score);
  27. }
  28. p2->next = NULL;
  29. return (head);
  30. }
  31. int main()
  32. {
  33. struct Student * pt;
  34. pt = creat();
  35. printf("n num:%ld score:%5.2fn", pt->num, pt->score);
  36. return 0;
  37. }

αποτέλεσμα λειτουργίας:

Ανάλυση αποτελεσμάτων: Για να δημιουργήσετε μια δυναμική συνδεδεμένη λίστα, καθορίζονται πρώτα τρεις δείκτες δομής και, στη συνέχεια, χρησιμοποιείται η συνάρτηση malloc για τη δημιουργία ενός κόμβου Και οι τρεις δείκτες δομής δείχνουν σε αυτόν τον κόμβο και, στη συνέχεια, το p1 χρησιμοποιεί τη συνάρτηση malloc για να δημιουργήσει τον κόμβο και το p2 Next. Δείχνει στον κόμβο που δημιουργήθηκε, ο p1 δημιουργεί τον κόμβο που δημιουργήθηκε, p2=p1...μέχρι η τιμή του στοιχείου στο p1 να είναι 0. Το επόμενο σημείο του p2 δεν δείχνει το στοιχείο. Ο κόμβος που δημιουργήθηκε πρόσφατα δημιουργείται στον πρώτο κόμβο.

Είσοδος και έξοδος δυναμικής συνδεδεμένης λίστας:

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #define LEN sizeof(struct Student)
  5. struct Student
  6. {
  7. long num;
  8. float score;
  9. struct Student * next;
  10. };
  11. int n;
  12. struct Student * creat(void)
  13. {
  14. struct Student * head, *p1, *p2;
  15. head = NULL;
  16. n = 0;
  17. p2 = p1 = malloc(LEN);
  18. scanf("%ld%f", &p1->num, &p1->score);
  19. while (p1->num != 0)
  20. {
  21. n = n + 1;
  22. if (n == 1)
  23. head = p1;
  24. else
  25. p2->next = p1;
  26. p2 = p1;
  27. p1 = malloc(LEN);
  28. scanf("%ld %f", &p1->num, &p1->score);
  29. }
  30. p2->next = NULL;
  31. return head;
  32. }
  33. void print(struct Student * p)
  34. {
  35. do
  36. {
  37. printf("%ld %5.2fn", p->num ,p->score);
  38. p=p->next;
  39. } while (p->num != NULL);
  40. }
  41. int main(void)
  42. {
  43. struct Student * pt;
  44. pt = creat();
  45. print(pt);
  46. return 0;
  47. }

αποτέλεσμα λειτουργίας:

5. Ενωσιακός τύπος

5.1 Επισκόπηση

Μερικές φορές, θέλετε να αποθηκεύσετε διαφορετικούς τύπους μεταβλητών σε μια μονάδα μνήμης, για παράδειγμα, τοποθετήστε ακέραιες μεταβλητές, μεταβλητές χαρακτήρων και μεταβλητές κινητής υποδιαστολής σε μια μονάδα μνήμης που ξεκινάει από την ίδια διεύθυνση Ένα τμήμα της δομής της μνήμης ονομάζεται "ένωση".

Ορίστε τη γενική μορφή μιας ένωσης:

όνομα συνδικάτου

        {

λίστα μελών?

}Λίστα μεταβλητών.

Για παράδειγμα:

Στοιχεία ένωσης

        {

int i?

char ch;

float f;

}αλφάβητο;

Το μήκος μνήμης που καταλαμβάνεται από μια μεταβλητή δομής είναι το άθροισμα των μηκών μνήμης που καταλαμβάνει κάθε μέλος, ενώ το μήκος μνήμης που καταλαμβάνεται από μια ένωση είναι το μήκος του μεγαλύτερου μέλους.

5.2 Εισαγωγικά

Μόνο οι μεταβλητές ένωσης που έχουν καθοριστεί εκ των προτέρων μπορούν να αναφέρονται.

Το ai αναφέρεται στην ακέραια μεταβλητή στη μεταβλητή ένωση.

Το a.ch αναφέρεται στη μεταβλητή χαρακτήρων στη μεταβλητή ένωση.

Το af αναφέρεται στην πραγματική μεταβλητή στη μεταβλητή ένωση.

5.3 Χαρακτηριστικά

1. Το τμήμα μνήμης μπορεί να χρησιμοποιηθεί για την αποθήκευση πολλών διαφορετικών τύπων μελών, αλλά μόνο ένα από αυτά μπορεί να αποθηκευτεί κάθε στιγμή και όχι πολλά ταυτόχρονα.

2. Οι μεταβλητές της Ένωσης μπορούν να αρχικοποιηθούν, αλλά μπορεί να υπάρχει μόνο μία σταθερά στον πίνακα προετοιμασίας.

3. Το μέλος της μεταβλητής ένωσης είναι το μέλος που εκχωρήθηκε την τελευταία φορά και η προηγούμενη αρχική μεταβλητή αντικαθίσταται και αντικαθίσταται.

4. Η διεύθυνση μιας μεταβλητής ένωσης είναι ίδια με τη διεύθυνση των μελών της.

5. Δεν μπορείτε να εκχωρήσετε μια τιμή σε ένα όνομα μεταβλητής ένωσης, ούτε να επιχειρήσετε να αναφέρετε ένα όνομα μεταβλητής για να λάβετε μια τιμή.

6. Τύπος απαρίθμησης

Εάν ορισμένες μεταβλητές έχουν μόνο λίγες πιθανές τιμές, μπορούν να οριστούν ως τύποι απαρίθμησης, η λεγόμενη απαρίθμηση είναι η λίστα των πιθανών τιμών μία προς μία.

Η δήλωση ενός τύπου απαρίθμησης ξεκινά με το enum

eunm Εβδομαδιαία{κυριος,δευτ.,τρι,τετ.,πέμ.,παρ.,σαβ};

Το παραπάνω δηλώνει έναν τύπο απαρίθμησης enum Weekday. Αυτός ο τύπος μπορεί στη συνέχεια να χρησιμοποιηθεί για τον ορισμό μεταβλητών.

enum Εργάσιμη ημέρα, Σαββατοκύριακο;

Μεταξύ αυτών, η εργάσιμη ημέρα και το Σαββατοκύριακο ορίζονται ως μεταβλητές απαρίθμησης και οι σγουρές αγκύλες ονομάζονται στοιχεία απαρίθμησης ή σταθερές απαρίθμησης.

Η γενική μορφή δήλωσης ενός τύπου απαρίθμησης:

enum [όνομα απαρίθμησης] {λίστα στοιχείων απαρίθμησης};

Παράδειγμα:

Υπάρχουν 5 είδη μικρών μπάλων στην τσέπη: κόκκινη, κίτρινη, μπλε, άσπρη και μαύρη Βγάλτε 3 μπάλες από την τσάντα κάθε φορά και ρωτήστε τους πιθανούς τρόπους για να πάρετε τις 3 μπάλες διαφορετικών χρωμάτων.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. int main()
  4. {
  5. enum Color {red,yellow,bule,white,black};
  6. enum Color i, j, k, pri;
  7. int n, loop;
  8. n = 0;
  9. for (i = red; i <= black; i++)
  10. for (j = red; j <= black; j++)
  11. if (i != j)
  12. {
  13. for (k = red; k <= black; k++)
  14. if ((k != i) && (k != j))
  15. {
  16. n++;
  17. printf("%d ", n);
  18. for (loop = 1; loop <= 3; loop++)
  19. {
  20. switch (loop)
  21. {
  22. case 1:pri = i; break;
  23. case 2:pri = j; break;
  24. case 3:pri = k; break;
  25. default:break;
  26. }
  27. switch (pri)
  28. {
  29. case red:printf("%s ", "red"); break;
  30. case yellow:printf("%s ", "yellow"); break;
  31. case bule:printf("%s ", "bule"); break;
  32. case white:printf("%s ", "white"); break;
  33. case black:printf("%s ", "black"); break;
  34. default:break;
  35. }
  36. }
  37. printf("n");
  38. }
  39. }
  40. printf("n total:%dn", n);
  41. return 0;
  42. }

αποτέλεσμα λειτουργίας:

7. Χρησιμοποιήστε το typedef για να δηλώσετε ένα νέο όνομα τύπου

Χρησιμοποιήστε το typedef για να καθορίσετε ένα νέο όνομα τύπου για να αντικαταστήσετε το υπάρχον όνομα τύπου.

1. Απλώς αντικαταστήστε το αρχικό όνομα τύπου με ένα νέο όνομα τύπου.

Για παράδειγμα:

typedef int Ακέραιος;

typedef float Real;

Έτσι, οι ακόλουθες δύο γραμμές είναι ισοδύναμες:

int i,j;——— Ακέραιος i,j;

2. Ονομάστε ένα όνομα απλού τύπου αντί για μια μέθοδο αναπαράστασης σύνθετου τύπου

  Ονομάστε το όνομα του νέου τύπου για να αντιπροσωπεύσετε τον τύπο δομής:

typedef struct

        {

int mun?

                ......

} Δεδομένα;

Στη συνέχεια, χρησιμοποιήστε το νέο όνομα τύπου Data για να ορίσετε τη μεταβλητή.

Δεδομένα γέννησης;

Δεδομένα * p;

      Ονομάστε ένα όνομα νέου τύπου αντί για τον τύπο πίνακα:

typedef int Num[100];

Num a;

      Ονομάστε ένα νέο όνομα τύπου για να αντιπροσωπεύσετε τον τύπο δείκτη

typedef char * Συμβολοσειρά;

Συμβολοσειρά p,a[10];

      Ονομάστε ένα όνομα νέου τύπου για να αναπαραστήσετε έναν δείκτη σε μια συνάρτηση.

typedef int (* Pointer)();

Δείκτης p1,p2;

           Περίληψη: Σύμφωνα με τον τρόπο ορισμού των μεταβλητών, αντικαταστήστε το όνομα της μεταβλητής με ένα νέο όνομα τύπου και προσθέστε typedef στο μπροστινό μέρος για να δηλώσετε ότι το όνομα του νέου τύπου αντιπροσωπεύει τον αρχικό τύπο.

Το typetef καθορίζει μόνο ένα νέο όνομα τύπου για έναν υπάρχοντα τύπο, αλλά δεν δημιουργεί νέο τύπο.

Το typetef και το #define έχουν επιφανειακές ομοιότητες.

typedef int Count

#define Καταμέτρηση int

Η λειτουργία τους είναι να χρησιμοποιούν το Count αντί για το int, αλλά στην πραγματικότητα το #define επεξεργάζεται στην προ-μεταγλώττιση, μπορεί να χρησιμοποιηθεί μόνο ως απλή αντικατάσταση συμβολοσειράς, ενώ το typedef επεξεργάζεται στο στάδιο της μεταγλώττισης. Στην πραγματικότητα δεν είναι μια απλή αντικατάσταση. Αντίθετα, δημιουργείται ένα νέο όνομα τύπου και ορίζεται η μεταβλητή.