stdarg-makrot
va_list, va_start, va_arg.
stdarg-makrot on ilmainen C Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C Academy-kurssilla on yhteensä 4 oppituntia.
Mitä variadiset funktiot ovat?
Variadinen funktio hyväksyy vaihtelevan määrän argumentteja. Olette jo käyttäneet sellaista: printf voi ottaa minkä tahansa määrän arvoja.
C-kielessä voitte kirjoittaa omia variadisia funktioita makrojen <stdarg.h> avulla.
#include <stdio.h>
int main(void) {
printf("%d %d %d\n", 1, 2, 3);
printf("%s\n", "any count of args");
return 0;
}Kolme pistettä
Variadinen funktio määritellään käyttämällä viimeisenä parametrina kolmea pistettä ....
Sitä ennen on oltava vähintään yksi nimetty parametri, jotta funktio tietää, mistä muuttuva osa alkaa.
#include <stdio.h>
#include <stdarg.h>
void demo(int count, ...) {
printf("This function takes %d extra args\n", count);
}
int main(void) {
demo(3, 10, 20, 30);
return 0;
}stdarg.h:n sisällyttäminen
Muuttuvien argumenttien lukemista varten tarvitsette direktiivin #include <stdarg.h>.
Se määrittelee tyypin va_list sekä makrot va_start, va_arg ja va_end.
#include <stdio.h>
#include <stdarg.h>
void show(int n, ...) {
va_list args;
va_start(args, n);
va_end(args);
printf("set up and cleaned up\n");
}
int main(void) {
show(2, 5, 6);
return 0;
}va_list ja va_start
Ilmoittakaa va_list-muuttuja seuraamaan nykyistä sijaintia. Kutsukaa sitten va_start(list, last) ja välittäkää sille viimeinen nimetty parametri.
Tämä kohdistaa luettelon ensimmäiseen muuttuvaan argumenttiin.
#include <stdio.h>
#include <stdarg.h>
void first(int count, ...) {
va_list args;
va_start(args, count);
int value = va_arg(args, int);
printf("first variadic arg = %d\n", value);
va_end(args);
}
int main(void) {
first(1, 99);
return 0;
}va_arg: arvojen lukeminen
va_arg(list, type) palauttaa seuraavan argumentin ja siirtää luetteloa eteenpäin. Teidän on ilmoitettava sille luettavan arvon täsmällinen tyyppi.
Jokainen kutsu siirtyy yhden argumentin eteenpäin.
#include <stdio.h>
#include <stdarg.h>
void three(int n, ...) {
va_list args;
va_start(args, n);
int a = va_arg(args, int);
int b = va_arg(args, int);
int c = va_arg(args, int);
printf("%d %d %d\n", a, b, c);
va_end(args);
}
int main(void) {
three(3, 7, 8, 9);
return 0;
}va_end: siivous
Kutsukaa aina va_end(list), kun olette lopettaneet lukemisen. Se suorittaa alustan tarvitsemat siivoustoimet.
Sen unohtaminen johtaa joissakin järjestelmissä määrittelemättömään toimintaan.
#include <stdio.h>
#include <stdarg.h>
int add_two(int dummy, ...) {
va_list args;
va_start(args, dummy);
int sum = va_arg(args, int) + va_arg(args, int);
va_end(args);
return sum;
}
int main(void) {
printf("%d\n", add_two(0, 4, 6));
return 0;
}Argumenttien määrän tietäminen
Makrot eivät voi tietää, kuinka monta argumenttia välitettiin. Teidän on välitettävä tämä tieto itse.
Yleinen tapa on käyttää alussa olevaa lukumääräparametria, kuten kutsussa sum(3, a, b, c).
#include <stdio.h>
#include <stdarg.h>
int sum(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++)
total += va_arg(args, int);
va_end(args);
return total;
}
int main(void) {
printf("%d\n", sum(4, 1, 2, 3, 4));
return 0;
}Sentineliarvon käyttäminen
Toinen tapa merkitä loppu on sentineli: erityinen lopetusarvo, joka kutsujan on annettava, kuten -1 tai NULL.
Toistakaa silmukkaa, kunnes luette sentinelin.
#include <stdio.h>
#include <stdarg.h>
int sum_until_neg(int first, ...) {
va_list args;
va_start(args, first);
int total = first, v;
while ((v = va_arg(args, int)) != -1)
total += v;
va_end(args);
return total;
}
int main(void) {
printf("%d\n", sum_until_neg(10, 20, 30, -1));
return 0;
}Oletusargumenttipromootiot
Vaihtelevat argumentit käyvät läpi oletuspromootiot: char ja short muuttuvat tyypiksi int, ja float muuttuu tyypiksi double.
Lukekaa siis pienet kokonaisluvut aina tyyppinä int ja liukuluvut tyyppinä double käyttämällä va_arg-makroa.
#include <stdio.h>
#include <stdarg.h>
void show_double(int n, ...) {
va_list args;
va_start(args, n);
double d = va_arg(args, double);
printf("%.2f\n", d);
va_end(args);
}
int main(void) {
show_double(1, 3.5f);
return 0;
}va_list-tyypin kopioiminen
Jos tarvitsette argumenttien läpikäyntiä kahdesti, käyttäkää va_copy(dest, src) -kutsua listan kopioimiseen ennen lukemista.
Ette voi käyttää va_list-tyyppistä listaa uudelleen va_end-kutsun jälkeen ilman, että aloitatte sen uudelleen va_start-kutsulla.
#include <stdio.h>
#include <stdarg.h>
void twice(int n, ...) {
va_list a, b;
va_start(a, n);
va_copy(b, a);
printf("%d %d\n", va_arg(a, int), va_arg(b, int));
va_end(a);
va_end(b);
}
int main(void) {
twice(1, 42);
return 0;
}Keskiarvon laskeminen
Yhdistämällä lukumäärämallin liukulukujen lukemiseen voimme laskea vaihtelevina argumentteina välitettyjen lukujen keskiarvon.
#include <stdio.h>
#include <stdarg.h>
double average(int count, ...) {
va_list args;
va_start(args, count);
double sum = 0;
for (int i = 0; i < count; i++)
sum += va_arg(args, double);
va_end(args);
return sum / count;
}
int main(void) {
printf("%.2f\n", average(3, 2.0, 4.0, 6.0));
return 0;
}Pikatarkistus
Testatkaa, miten hyvin ymmärrätte stdarg-makroja.
Kertaus
Opitte vaihtelevien argumenttien mekanismin:
- Ilmoittakaa funktio vähintään yhden nimetyn parametrin jälkeen merkinnällä
.... va_start(list, last)aloittaa käsittelyn,va_arg(list, type)lukee arvon java_end(list)suorittaa siivouksen.- Makrot eivät tiedä argumenttien määrää — käyttäkää lukumääräparametria tai sentineliä.
- Huomioikaa oletuspromootiot: lukekaa pienet kokonaisluvut tyyppinä
intja liukuluvut tyyppinädouble.
Opi C tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 39
- Oppitunnit
- 144
Usein kysytyt kysymykset
Onko oppitunti ”stdarg-makrot” ilmainen?
Kyllä – oppitunnin ”stdarg-makrot” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C Academy-kurssin, päivitä CoddyKit PROhon. C Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”stdarg-makrot”?
va_list, va_start, va_arg. Harjoittelet C Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”stdarg-makrot”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C Academy-oppitunnilla?
Kyllä. Jokainen C Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- stdarg-makrot
- printf-tyyppisten funktioiden kirjoittaminen
- Tyyppiturvallisuuden ongelmat
- Käytännön esimerkkejä