2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Aiemmin nähtyjä tietotyyppejä, kuten int, float, char jne., käytetään yksinkertaisesti ohjelmissa. Jos haluamme luoda monimutkaisia tietoja omien tarpeidemme mukaan, meidän on käytettävä rakenteita.
Esimerkiksi opiskelijan opiskelijanumero, nimi, sukupuoli, ikä jne. kuuluvat samalle opiskelijalle, mutta nämä muuttujat kuuluvat eri tyyppeihin . Sitten luomme muuttujan, joka voi yhdistää nämä tiedot ja laittaa sen muuttujaan, jotta sitä on paljon helpompi käyttää. Tämä on rakenteen oppimista.
- 结构体类型:
- struct Student
- {
- int num;//学号为整形;
- char name[20];//姓名为字符串;
- char sex;//性别为字符型;
- int age;//年龄为整形
- float score;//成绩为浮点型
- char addr[30];//地址为字符型;
- }
sisään:
struct Opiskelija on rakennetyyppi;
struct on avainsana, joka ilmoittaa rakenteen tyypin.
Student on rakenteen nimi, jotta se voidaan erottaa muista rakenteista;
Aaltosulkeet sisältävät rakenteen jäsenet Ryhmää kutsutaan jäsenluetteloksi, ja sen nimeäminen on yhdenmukainen muuttujien nimeämisen kanssa.
Huomautus: Rakennetyypeillä voi olla useita tyyppejä, kuten: struct Opettaja;
Rakenteen jäsenet voivat olla myös toisen rakenteen tyyppiä;
rakenteen päivämäärä
{
int kuukausi;
int päivä;
int vuosi;
};
rakenne Opiskelija
{
int num;
merkin nimi[20];
char sukupuoli;
int ikä;
struct Päivämäärä syntymäpäivä;
char addr[30];
}
Aiemmin määritimme vain rakennetyypin, joka vastaa mallia, emmekä määrittäneet muuttujia. Seuraavaksi määritellään rakennemuuttujat ja tallennetaan niihin tiettyjä tietoja, 3 menetelmää.
Tapa 1: Määritä ensin rakenteen tyyppi ja määritä sitten rakennemuuttujat
Määritä rakennemuuttujat edellisen rakennetyypin struct Student perusteella;
struct Opiskelija opiskelija1,opiskelija2;
Tämä menetelmä on samanlainen kuin int a,b, ainoa edellytys on, että rakennetyyppi on jo olemassa ja rakennemuuttuja määritellään tyypin perusteella.
Tapa 2: Määrittele muuttujat tyypin ilmoittamisen yhteydessä
muoto:
rakenteen rakenteen nimi
{
jäsenluettelo;
}Muuttujanimien luettelo;
Esimerkki:
rakenne Opiskelija
{
int num;
merkin nimi[20];
char sukupuoli;
int ikä;
float pisteet;
char addr[30];
}opiskelija1,opiskelija2;
Tapa 3: Määritä rakennetyyppimuuttujat suoraan määrittämättä tyypin nimeä
muoto:
struct
{
Jäsenmuuttujat;
}Muuttujanimien luettelo;
Se on nimeämätön rakennetyyppi, eikä sitä käytetä yleisesti;
Huomautus: 1. Rakennemuuttujien jäsenten nimet voivat olla samat kuin ohjelman muuttujien nimet;
2. Rakennemuuttujien jäseniä voidaan käyttää yksinään niiden tila ja toiminta vastaavat tavallisia muuttujia;
Alusta rakennemuuttujat, kun määrität niitä;
Esimerkki:Laita opiskelijan tiedot (mukaan lukien opiskelijanumero, nimi, sukupuoli, osoite) rakennemuuttujaan ja tulosta sitten opiskelijan tiedot;
- #include <stdio.h>
-
- int main()
- {
- struct Student
- {
- int num;
- char name[20];
- char sex;
- char addr[20];
- }student1 = {101,"Li li",'M',"123XiAn"};
- printf("NO:%d,nname:%snssex:%cnaddress:%sn",student1.num,student1.name,student1.sex,student1.addr);
- return 0;
Tulosanalyysi:
Kun määrität rakennemuuttujan, alusta sen jäsenet muuten runkotyypin alustus.
Jäsenen arvo rakennemuuttujassa, referenssimenetelmä on:
Rakennemuuttujan nimi. Jäsennimi
opiskelija1.nimi
Muuhun rakennetyyppiin kuuluville rakenteen jäsenille alimman tason jäsenet on löydettävä tasoittain. Esimerkiksi edellä mainittu struct Student sisältää struct Date syntymäpäivä;
Opiskelijan syntymäpäivä.kuukausi
Samantyyppisiä rakenteita voidaan osoittaa toisilleen:opiskelija1 = opiskelija2;
Esimerkki:Syötä kahden opiskelijan opiskelijatunnus, nimi ja arvosanat ja tulosta korkeammalla arvosanalla saaneen opiskelijan opiskelijatunnus, nimi ja arvosana.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
-
- int main()
- {
- struct Student
- {
- int num;
- char name[20];
- float score;
- }student1,student2;
- scanf("%d%s%f", &student1.num, student1.name, &student1.score);
- scanf("%d%s%f", &student2.num, student2.name, &student2.score);
- printf("The higher score is:n");
- if (student1.score > student2.score)
- {
- printf("%d %s %6.2fn", student1.num, student1.name, student1.score);
- }
- else if (student1.score < student2.score)
- {
- printf("%d %s %6.2fn", student2.num, student2.name, student2.score);
- }
- else
- {
- printf("%d %s %6.2fn", student1.num, student1.name, student1.score);
- printf("%d %s %6.2fn", student2.num, student2.name, student2.score);
- }
- }
Kun käytät scanf-funktiota rakennemuuttujien syöttämiseen, sinun on syötettävä ne erikseen Et voi syöttää kaikkien jäsenten arvoja kerralla opiskelija1.nimi, koska taulukon nimi edustaa alun perin Sain osoitteen.
Kun määritimme rakennemuuttujat aiemmin, määritimme ne yksitellen. Jos operaatioon on kuitenkin osallistuttava joukko toisiinsa liittyviä tietoja, on luonnollisesti tarpeen käyttää tietoja, kuten 10 opiskelijan tietoja on rakennetaulukko , jokainen rakennetaulukon taulukkoelementti on rakenne.
Esimerkiksi: Ehdokkaita on kolme, ja jokainen äänestäjä voi äänestää vain yhtä henkilöä. Ensin on kirjoitettava ääntenlaskuohjelma ja näytettävä lopuksi kunkin henkilön äänestystulos.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
-
- struct Person
- {
- char name[20];
- int count;
- }leader[3] = { "wang", 0, "zhang", 0, "li", 0 };
- int main()
- {
- int i, j;
- char lead_name[20];
- for (i = 0; i < 10; i++)
- {
- scanf("%s", lead_name);
- for (j = 0; j < 3; j++)
- {
- if (strcmp(lead_name, leader[j].name) == 0)
- leader[j].count++;
- }
- }
- printf("nResultn");
- for (i = 0; i < 3; i++)
- {
- printf("name:%s,count:%dn", leader[i].name, leader[i].count);
- }
- return 0;
- }
Määritä rakennetaulukon yleinen muoto:
rakenteen rakenteen nimi
{
muuttujaluettelo
} taulukon nimi [taulukon pituus];
tai
Ilmoita ensin rakenteen tyyppi, kuten: struct student, ja määritä sitten rakennetaulukko;
Rakennetyyppi taulukon nimi [taulukon pituus];
Rakennetaulukon alustusmuoto on lisätä määritelmän jälkeen:
={Alkuarvoluettelo};
Esimerkki:Tietoja on n opiskelijasta (mukaan lukien opiskelijatunnus, nimi ja arvosanat), ja jokaisen opiskelijan tiedot on tulostettava arvosanajärjestyksessä;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
-
- struct Student
- {
- int num;
- char name[20];
- float score;
- };
-
- int main()
- {
- struct Student stu[5] = { 1001, "Wangwei", 98.25, 1002, "Liuliu", 91, 1003, "Zhangli", 98, 1004, "Xiaozhao", 85, 1005, "Baibai", 94 };
- struct Student temp;
- printf("The order id:n");
- int i, j,k;
- for (i = 0; i < 4; i++)
- {
- k = i;
- for (j = i + 1; j < 5; j++)
- {
- if (stu[j].score>stu[k].score)
- {
- k = j;
- }
- }
- temp = stu[k];
- stu[k] = stu[i];
- stu[i] = temp;
- }
- for (i = 0; i < 5; i++)
- {
- printf("%d %s %5.2f", stu[i].num, stu[i].name, stu[i].score);
- printf("n");
- }
- return 0;
- }
Ns. rakenneosoitin on osoitin rakennemuuttujaan Rakennemuuttujan aloitusosoite on rakennemuuttujan osoitin.
Rakenneobjektiin osoittava osoitinmuuttuja voi osoittaa joko rakennemuuttujaan tai rakennetaulukon elementtiin. Osoitinmuuttujan perustyypin on oltava sama kuin rakennemuuttujan tyyppi.
Esimerkiksi: struct Opiskelija * pt;
Esimerkki:Tulosta rakennemuuttujan jäsenten tiedot rakennemuuttujaan osoittavan osoitinmuuttujan kautta;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
-
- struct Student
- {
- long num;
- char name[20];
- char sex;
- float score;
- };
-
- int main()
- {
- struct Student stu1;
- struct Student *pt;
- pt = &stu1;
- stu1.num = 10001;
- strcpy(stu1.name, "Lili");
- stu1.sex = 'M';
- stu1.score = 96.5;
- printf("No:%dnname:%snsex:%cnscore:%5.1fn", stu1.num, stu1.name, stu1.sex, stu1.score);
- printf("n");
- printf("No:%dnname:%snsex:%cnscore:%5.1fn", (*pt).num, (*pt).name, (*pt).sex, (*pt).score);
- printf("n");
- printf("No:%dnname:%snsex:%cnscore:%5.1fn", pt->num, pt->name, pt->sex, pt->score);
- return 0;
- }
Tulosanalyysi:
Funktiossa ensimmäinen printf-funktio käyttää jäseniä rakennemuuttujan nimen stu1 kautta;
Toinen printf-funktio käyttää jäseniä rakennemuuttujaan osoittavan osoitinmuuttujan kautta (*pt) edustaa osoitettua rakennemuuttujaa ja (*pt).num edustaa osoitettua rakennemuuttujaa.
Lisäksi C-kielessä on sallittua korvata (*pt).num:lla pt->num;
Osoitinmuuttujia voidaan käyttää osoittamaan rakennetaulukon elementtejä.
Esimerkki:Rakennetaulukkoon on sijoitettu kolmen opiskelijan tiedot, ja opiskelijan tiedot on tulostettava;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
-
- struct Student
- {
- long num;
- char name[20];
- char sex;
- float score;
- };
-
- int main()
- {
- struct Student stu[3] = { 1001, "wangle", 'M', 95, 1002, "chengcai", 'M', 99.9, 1003, "shangmin", 'F', 85.2 };
- struct Student *pt;
- printf("No. name sex scoren");
- for (pt = stu; pt < stu + 3; pt++)
- {
- printf("%d %s %c %5.2fn", pt->num, pt->name, pt->sex, pt->score);
- }
- return 0;
- }
Ohjelmassa pt on osoitin rakennemuuttujaan, ei tiettyyn rakenteen jäseneen. Nimi on laiton rakennemuuttuja ja toinen on rakenteen jäsenmuuttuja. p++, p:n arvo lisää rakenteen pituutta.
On kolme tapaa siirtää rakennemuuttujan arvo funktiolle;
1. Käytä rakennemuuttujien jäseniä parametreina Tämä menetelmä vastaa tavallisten muuttujien välitystä.
2. Käytä rakennemuuttujia todellisina parametreina. Kun rakennemuuttujaa käytetään varsinaisena parametrina, se välitetään myös koko rakennemuuttujan varaama muistiyksikön sisältö muodolliseen parametriin.
3. Käytä osoitinta rakennemuuttujaan (taulukko) varsinaisena parametrina siirtääksesi rakennemuuttujan (taulukon) osoitteen muodolliseen parametriin.
Esimerkki:
Rakenteita on n, mukaan lukien opiskelijoiden oppilastunnukset, nimet ja arvosanat 3 kurssilla. On tulostettava korkeimman keskiarvosanan saaneiden opiskelijoiden tiedot (mukaan lukien opiskelijatunnukset, nimet, arvosanat 3 kurssilla ja arvosanat). .
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
- void print(struct Student stud);
- struct Student Max(struct Student stu[]);
- void input(struct Student stu[]);
- struct Student
- {
- int num;
- char name[20];
- float score[3];
- float aver;
- };
-
- int main()
- {
- struct Student stu[3], *pt;
- pt = stu;
- input(pt);
- print(Max(pt));
- return 0;
- }
- void input(struct Student stu[])
- {
- int i;
- printf("请输入各学生的信息:学号、姓名、3门成绩:n");
- for (i = 0; i < 3;i++)
- {
- scanf("%d%s%f%f%f", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
- stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;
- }
- }
-
- struct Student Max(struct Student stu[])
- {
- int i, m = 0;
- for (i = 0; i < 3; i++)
- {
- if (stu[i].aver > stu[m].aver)
- m = i;
- }
- return stu[m];
- }
- void print(struct Student stud)
- {
- printf("成绩最好的学生是:n");
- 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);
- }
1. Syötefunktiota kutsuttaessa varsinainen parametri on osoitinmuuttuja pt ja muodollinen parametri on rakenne-elementin aloitusosoite, eikä funktiolla ole palautusarvoa.
2. Max-funktiota kutsuttaessa varsinainen parametri on osoitinmuuttuja pt, muodollinen parametri rakennetaulukko, rakenne-elementin aloitusosoite välitetään ja funktion palautusarvo on rakennetyypin data.
3. Tulostusfunktiota kutsuttaessa varsinaiset parametrit ovat rakennemuuttujia (rakennetaulukon elementtejä) ja muodolliset parametrit ovat rakennemuuttujia Se, mitä välitetään, on rakennemuuttujan kunkin jäsenen arvo, eikä funktiolla ole palautusarvoa.
Linkitetty luettelo on yleinen tietorakenne, joka on rakenne dynaamiseen tallennustilan allokointiin.
Kun tietoja tallennetaan taulukkoon, taulukon pituus (useita taulukoita) on määritettävä etukäteen. on määritettävä 100 pituinen taulukko, mutta tämä johtaa usein resurssien tuhlaukseen.
Linkitetyssä luettelossa on "head pointer" -muuttuja, jota kuvassa edustaa head ja joka tallentaa osoitteen, joka osoittaa elementtiin Jokaista linkitetyn luettelon elementtiä kutsutaan "solmuksi", ja jokaisen solmun tulee sisältää kaksi osaa:
1. Käyttäjien vaatimat todelliset tiedot;
2. Seuraavan elementin osoite;
Voidaan nähdä, että muistissa olevan linkitetyn listan jokaisen elementin osoitteet voivat olla epäjatkuvia Tietyn elementin löytämiseksi on ensin löydettävä edellinen elementti, ja seuraava elementti voidaan löytää edellisen elementin osoitteen perusteella. . Jos "pääosoitinta" ei ole annettu, koko linkitetty luettelo ei ole käytettävissä.
Tässä tapauksessa on tarkoituksenmukaisinta käyttää rakennetta linkitetyn listan rakentamiseen. Rakenne sisältää useita jäseniä, ja osoitintyyppisiä jäseniä käytetään seuraavan solmun osoitteen tallentamiseen.
rakenne Opiskelija
{
int num;
int pisteet;
struct Opiskelija *seuraava;
}
Niiden joukossa numeroa ja pistemäärää käytetään käyttäjätietojen tallentamiseen, ja seuraavaa käytetään seuraavan solmun osoitteen tallentamiseen.
Tapaus:
Luo staattinen linkitetty luettelo, joka koostuu solmuista, joissa on kolmen opiskelijan tiedot, ja vaadi kunkin solmun tietojen tulostamista.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
-
- struct Student
- {
- int num;
- float score;
- struct Student * next;
- };
-
- int main()
- {
- struct Student a, b, c, *head, *p;
- a.num = 1001; a.score = 85.5;
- b.num = 1002; b.score = 95.5;
- c.num = 1003; c.score = 84.5;
- head = &a;
- a.next = &b;
- b.next = &c;
- c.next = NULL;
- p = head;
- do
- {
- printf("%d %5.2fn", p->num, p->score);
- p = p->next;
- } while (p != NULL);
- return 0;
- }
Luo esimerkiksi linkitetty luettelo siten, että pää osoittaa solmuun a, a.next osoittaa solmuun b, b.next osoittaa solmuun c ja c.next osoittaa nollaan. Tämä muodostaa linkitetyn luettelon suhteen.
Kun tulostat linkitettyä listaa, sinun on ensin käytettävä p:tä, tehtävä p osoittamaan a ja sitten tulostettava tiedot kohdassa a p=p->seuraava on valmistella seuraava solmu tulostusta varten.
Ennen kuin puhumme dynaamisista linkitetyistä luetteloista, esittelemme sinulle dynaamisen muistin allokoinnin.
Aiemmin sanoimme, että muuttujat on jaettu globaaleihin muuttujiin ja paikalliset muuttujat allokoidaan muistin staattiseen tallennusalueeseen Tämä muistialue on nimeltäänpino。
Lisäksi C-kieli mahdollistaa myös dynaamisten muistin varausalueiden perustamisen, kun niitä tarvitaan, ja ne vapautetaan, kun niitä ei tarvita. Tätä tallennusaluetta kutsutaan tilapäisestipino。
Dynaaminen muistin allokointi saavutetaan järjestelmän tarjoamilla toiminnoilla: malloc, calloc, free ja realloc-funktiot.
1. Käytä malloc-toimintoa avataksesi dynaamisen tallennusalueen
toiminto: void *malloc (signed int size);
Tehtävä:
Varaa jatkuva pituus (yksikkö: tavua) muistin dynaamiselle tallennusalueelle.
palautusarvo:
Ensimmäisen varatun tavun osoitteella ei ole tyyppiä, vain pelkkä osoite;
2. Käytä calloc-toimintoa dynaamisen tallennusalueen avaamiseen
toiminto:void * calloc(signed n,signed size);
Tehtävä:
Varaa muistin dynaamiselle tallennusalueelle n tavua jatkuvaa tilaa, jonka koko on pituudeltaan. Tämä tila on suhteellisen suuri taulukon säästämiseksi;
Käytä calloc-funktiota avataksesi dynaamista tallennustilaa yksiulotteiselle taulukolle, n on taulukon elementtien lukumäärä ja koko on elementin pituus.
palautusarvo:
Ensimmäisen varatun tavun osoitteella ei ole tyyppiä, vain pelkkä osoite;
3. Käytä realloc-funktiota dynaamisen tallennusalueen uudelleenallokointiin
toiminto:void * realloc(void *p ,signed int size);
Tehtävä:
Kohdista varattu dynaaminen muisti uudelleen.
Käytä callloc-funktiota muuttaaksesi p:llä osoittaman dynaamisen avaruuden koon kooksi. p:n arvo pysyy ennallaan;
palautusarvo:
Dynaamisen muistin ensimmäisen tavun osoite päivityksen jälkeen on olennaisesti osoite, johon p osoittaa.
4. Vapauta dynaaminen tallennusalue vapaalla toiminnolla
toiminto: void free(void *p);
Tehtävä:
Vapauta osoitinmuuttujan p osoittama dynaaminen avaruus, jotta muut muuttujat voivat käyttää tätä avaruuden osaa.
p on viimeisimmästä malloc- ja calloc-funktioiden kutsusta saatu palautusarvo;
palautusarvo:
ei mitään;
Huomautus: Yllä olevien neljän funktion ilmoitukset ovat kaikki stdlib.h-otsikkotiedostossa.
tyhjä osoittimen tyyppi:
Yllä olevien funktioiden malloc- ja calloc-funktioiden palautusarvot ovat kumpikin void * -tyyppiä, mikä tarkoittaa, että se ei osoita minkään tyyppiseen tietoon tai ei osoita tietyn tyyppisiä tietoja.
Dynaamista muistia kutsuessaan ohjelma käyttää vain funktion palauttamaa puhdasta osoitetta, eikä käytä attribuuttia, joka osoittaa mihin tietotyyppiin halutaan käyttää tätä osoitetta, se on muunnettava.
Esimerkiksi:
int *p;
p=(int*)malloc(100);
Tapaus:
Luo dynaaminen data, syötä viiden oppilaan pisteet ja tarkista funktion avulla, onko oppilaita alle 60 pistettä, ja tulosta epämääräiset pisteet.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <stdlib.h>
-
- int main()
- {
- void check(int * p);
- int *p1, i;
- p1 = (int *)malloc(5 * sizeof(int));
- for (i = 0; i < 5; i++)
- {
- scanf("%d", p1 + i);
- }
- check(p1);
- return 0;
- }
- void check(int * p)
- {
- int i;
- printf("they are fail:n");
- for (i = 0; i < 5; i++)
- {
- if (*(p+i) < 60)
- printf("%d ", *(p + i));
- }
- }
operaation tulos:
Tulosanalyysi:
Ohjelmassa ei ole määritelty taulukkoa, vaan dynaaminen vapaa allokaatioalue avataan käytettäväksi taulukona.
Malloc-funktiossa ei välitetä suoraan mitään arvoa dynaamisen tilan varaamiseen. Sen sijaan sizeof-arvoa käytetään järjestelmän kokonaisluvun tavujen laskemiseen, ja sitten luodaan 5 elementtiä. Käytä p osoittaaksesi ensimmäisen tavun osoitteeseen ja muuntaaksesi sen int-tyypiksi, ja p+1 osoittaa seuraavaan elementtiin.
Kirjoita funktio dynaamisen linkitetyn luettelon luomiseksi neljän oppilaan tiedoista.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <stdlib.h>
-
- #define LEN sizeof(struct Student)
-
- struct Student
- {
- long num;
- float score;
- struct Student * next;
- };
-
- int n;
- struct Student * creat(void)
- {
- struct Student * head, *p1, *p2;
- n = 0; p1 = p2 = malloc(LEN);
- scanf("%ld%f", &p1->num, &p1->score);
- head = NULL;
- while (p1->num != 0)
- {
- n = n + 1;
- if (n == 1)
- head = p1;
- else p2->next = p1;
- p2 = p1;
- p1 = (struct Student *)malloc(LEN);
- scanf("%ld%f", &p1->num, &p1->score);
- }
- p2->next = NULL;
- return (head);
- }
-
- int main()
- {
- struct Student * pt;
- pt = creat();
- printf("n num:%ld score:%5.2fn", pt->num, pt->score);
- return 0;
- }
-
-
operaation tulos:
Tulosanalyysi: Dynaamisen linkitetyn luettelon luomiseksi määritetään ensin kolme rakenneosoitinta ja sitten luodaan solmu malloc-funktiolla. Kaikki kolme rakenneosoitinta osoittavat tämän solmun, ja sitten p1 käyttää malloc-funktiota solmun luomiseen ja p2 Next. Osoittaa luodun solmun p2=p1, p1 luo p2:n seuraavaksi luotuun solmuun, p2=p1...kunnes p1:n elementin arvo on 0. Seuraava p2:sta ei osoita. äskettäin luotu solmu. Tällä tavalla luodaan dynaaminen linkitetty lista, joka on pääsolmu.
Dynaamisen linkitetyn luettelon syöttö ja tulos:
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <stdlib.h>
-
- #define LEN sizeof(struct Student)
-
- struct Student
- {
- long num;
- float score;
- struct Student * next;
- };
- int n;
- struct Student * creat(void)
- {
- struct Student * head, *p1, *p2;
- head = NULL;
- n = 0;
- p2 = p1 = malloc(LEN);
- scanf("%ld%f", &p1->num, &p1->score);
- while (p1->num != 0)
- {
- n = n + 1;
- if (n == 1)
- head = p1;
- else
- p2->next = p1;
- p2 = p1;
- p1 = malloc(LEN);
- scanf("%ld %f", &p1->num, &p1->score);
- }
- p2->next = NULL;
- return head;
- }
-
- void print(struct Student * p)
- {
- do
- {
- printf("%ld %5.2fn", p->num ,p->score);
- p=p->next;
- } while (p->num != NULL);
- }
-
- int main(void)
- {
- struct Student * pt;
- pt = creat();
- print(pt);
- return 0;
- }
operaation tulos:
Joskus haluat tallentaa erityyppisiä muuttujia muistiyksikköön. Voit esimerkiksi sijoittaa kokonaislukumuuttujia, merkkimuuttujia ja liukulukumuuttujia samasta osoitteesta alkaen Muistirakenteen osaa kutsutaan "liitoksi".
Määrittele liiton yleinen muoto:
ammattiliiton nimi
{
jäsenluettelo;
}Muuttujaluettelo;
Esimerkiksi:
liiton tiedot
{
int i;
char ch;
kellua f;
}a,b,c;
Rakennemuuttujan käyttämä muistin pituus on kunkin jäsenen käyttämien muistin pituuksien summa, kun taas liiton käyttämä muistin pituus on pisimmän jäsenen pituus.
Vain ennalta määriteltyihin liittomuuttujiin voidaan viitata. Huomaa, että emme viittaa liittomuuttujiin vaan viitattujen liittomuuttujien jäseniin.
ai viittaa liittomuuttujan kokonaislukumuuttujaan;
a.ch viittaa merkkimuuttujaan liittomuuttujassa;
af viittaa liittomuuttujan todelliseen muuttujaan;
1. Muistisegmenttiä voidaan käyttää useiden erityyppisten jäsenten tallentamiseen, mutta kullakin hetkellä niistä voidaan tallentaa vain yksi, ei useita samanaikaisesti.
2. Unionin muuttujat voidaan alustaa, mutta alustustaulukossa voi olla vain yksi vakio.
3. Liitosmuuttujan jäsen on viimeksi määritetty jäsen, ja edellinen alkuperäinen muuttuja korvataan ja korvataan.
4. Liiton muuttujan osoite on sama kuin sen jäsenten osoite.
5. Et voi määrittää arvoa liittomuuttujan nimelle etkä yrittää viitata muuttujan nimeen arvon saamiseksi.
Jos joillakin muuttujilla on vain muutamia mahdollisia arvoja, ne voidaan määritellä luettelointityypeiksi, niin sanottu luettelointi on mahdollista arvojen luettelointi yksitellen.
Luettelotyypin ilmoittaminen alkaa esimerkiksi enumilla
eunm arkipäivä{su,ma,ti,ke,to,pe,la};
Yllä oleva ilmoittaa luettelotyypin enum Weekday. Tätä tyyppiä voidaan sitten käyttää muuttujien määrittämiseen.
enum Arkipäivä työpäivä,viikonloppu;
Niistä työpäivä ja viikonloppu määritellään laskentamuuttujiksi, ja kaarevia sulkuja kutsutaan numeraatioelementeiksi tai lukuvakioksi.
Luettelotyypin ilmoittamisen yleinen muoto:
enum [luettelon nimi] {luetteloelementtien luettelo};
Esimerkki:
Taskussa on 5 erilaista palloa: punainen, keltainen, sininen, valkoinen ja musta. Ota pussista 3 palloa joka kerta. Kysy mahdollisia tapoja saada 3 eriväristä palloa.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
-
- int main()
- {
- enum Color {red,yellow,bule,white,black};
- enum Color i, j, k, pri;
- int n, loop;
- n = 0;
- for (i = red; i <= black; i++)
- for (j = red; j <= black; j++)
- if (i != j)
- {
- for (k = red; k <= black; k++)
-
- if ((k != i) && (k != j))
- {
- n++;
- printf("%d ", n);
- for (loop = 1; loop <= 3; loop++)
- {
- switch (loop)
- {
- case 1:pri = i; break;
- case 2:pri = j; break;
- case 3:pri = k; break;
- default:break;
- }
-
- switch (pri)
- {
- case red:printf("%s ", "red"); break;
- case yellow:printf("%s ", "yellow"); break;
- case bule:printf("%s ", "bule"); break;
- case white:printf("%s ", "white"); break;
- case black:printf("%s ", "black"); break;
- default:break;
- }
- }
- printf("n");
- }
- }
- printf("n total:%dn", n);
- return 0;
- }
operaation tulos:
Käytä typedefiä määrittääksesi uuden tyypin nimen nykyisen tyypin nimen tilalle;
1. Korvaa alkuperäinen tyypin nimi uudella tyypin nimellä.
Esimerkiksi:
typedef int Kokonaisluku;
typedef kellua Real;
Siten seuraavat kaksi riviä ovat samanarvoisia:
int i,j;——- Kokonaisluku i,j;
2. Nimeä yksinkertainen tyypin nimi monimutkaisen tyypin esitystavan sijaan
Nimeä uusi tyypin nimi edustamaan rakennetyyppiä:
typedef rakenne
{
int mun;
......
} Data;
Määritä muuttuja sitten uudella tyypin nimellä Data;
Datan syntymäpäivä;
Data * p;
Nimeä uusi tyypin nimi taulukkotyypin sijaan:
typedef int Num[100];
Num a;
Nimeä uusi tyypin nimi edustamaan osoittimen tyyppiä:
typedef char * merkkijono;
merkkijono p,a[10];
Nimeä uusi tyypin nimi edustamaan funktion osoitinta;
typedef int (* Osoitin)();
Osoitin p1,p2;
Yhteenveto: Muuttujien määrittelytavan mukaisesti korvaa muuttujan nimi uudella tyypin nimellä ja lisää eteen typedef ilmoittaaksesi, että uusi tyypin nimi edustaa alkuperäistä tyyppiä.
typetef määrittää vain uuden tyypin nimen olemassa olevalle tyypille, mutta ei luo uutta tyyppiä.
typetef ja #define ovat pinnallisia yhtäläisyyksiä.
typedef int Count
#define Count int
Niiden tehtävänä on käyttää Countia int:n sijaan, mutta itse asiassa ne ovat erilaisia. #define käsitellään esikäännöksessä, sitä voidaan käyttää vain yksinkertaisena merkkijonon korvaavana, kun taas typedef käsitellään käännösvaiheessa. Se ei todellakaan ole yksinkertainen korvaaminen. Sen sijaan luodaan uusi tyypin nimi ja määritetään muuttuja.