C Language
Iteration Uttalanden / loopar: för, medan, gör-medan
Sök…
Syntax
- / * alla versioner * /
- för ([expression]; [expression]; [expression]) one_statement
- för ([uttryck]; [uttryck]; [uttryck]) {noll eller flera uttalanden}
- medan (uttryck) one_statement
- medan (uttryck) {noll eller flera uttalanden}
- gör en_statement medan (uttryck);
- gör {en eller flera uttalanden} medan (uttryck);
- // sedan C99 utöver formuläret ovan
- för (deklaration; [uttryck]; [uttryck]) one_statement;
- för (deklaration; [uttryck]; [uttryck]) {noll eller flera uttalanden}
Anmärkningar
Iteration statement / loopar ingår i två kategorier:
- huvudstyrd iterationsmeddelande / slingor
- fotkontrollerade iterationsförklaringar / slingor
Huvudstyrd Iteration-uttalande / slingor
for ([<expression>]; [<expression>]; [<expression>]) <statement>
while (<expression>) <statement>
for ([declaration expression]; [expression] [; [expression]]) statement
Fotreglerad Iteration-uttalande / slingor
do <statement> while (<expression>);
För slinga
För att köra ett kodblock om igen, kommer öglor in i bilden. for
loopen ska användas när ett kodblock ska utföras ett fast antal gånger. För att till exempel fylla en matris med storlek n
med användaringångarna måste vi utföra scanf()
i n
gånger.
#include <stddef.h> // for size_t
int array[10]; // array of 10 int
for (size_t i = 0; i < 10; i++) // i starts at 0 and finishes with 9
{
scanf("%d", &array[i]);
}
På detta sätt scanf()
-funktionssamtalet n
gånger (10 gånger i vårt exempel), men skrivs bara en gång.
Här variabeln i
är slingan index, och det är bäst förklaras som presenteras. Typen size_t
( storlekstyp ) ska användas för allt som räknas eller slingas genom dataobjekt.
Detta sätt att förklara variabler inuti for
är endast tillgänglig för kompilatorer som har uppdaterats till C99-standarden. Om du av någon anledning fortfarande sitter fast med en äldre kompilator kan du förklara slingindexet före for
loop:
#include <stddef.h> /* for size_t */
size_t i;
int array[10]; /* array of 10 int */
for (i = 0; i < 10; i++) /* i starts at 0 and finishes at 9 */
{
scanf("%d", &array[i]);
}
Medan slinga
En while
slinga används för att exekvera en bit kod medan ett villkor är sant. while
slingan ska användas när ett kodblock ska utföras ett varierande antal gånger. Exempelvis får den visade koden användarinmatningen, så länge användaren sätter in nummer som inte är 0
. Om användaren sätter in 0
, är villkoret medan inte längre sant så exekveringen kommer att lämna slingan och fortsätta till någon efterföljande kod:
int num = 1;
while (num != 0)
{
scanf("%d", &num);
}
Do-While-slinga
Till skillnad från for
och while
slingor, do-while
slingor kontrollera sanningen om tillståndet i slutet av slingan, vilket innebär att do
blocket kommer att köras en gång och sedan kontrollera tillståndet för while
längst ner i blocket. Vilket innebär att en do-while
loop alltid kommer att köras minst en gång.
Exempelvis får denna do-while
slinga nummer från användaren tills summan av dessa värden är större än eller lika med 50
:
int num, sum;
num = sum = 0;
do
{
scanf("%d", &num);
sum += num;
} while (sum < 50);
do-while
slingor är relativt sällsynta i de flesta programmeringsstilar.
Struktur och styrflöde i en for-loop
for ([declaration-or-expression]; [expression2]; [expression3])
{
/* body of the loop */
}
I en for
loop har loop-villkoret tre uttryck, alla valfria.
- Det första uttrycket,
declaration-or-expression
, initialiserar slingan. Det körs exakt en gång i början av slingan.
Det kan antingen vara en deklaration och initialisering av en slingvariabel eller ett generellt uttryck. Om det är en deklaration begränsas omfattningen av den deklarerade variabeln av for
påståendet.
Historiska versioner av C tillåts endast ett uttryck här, och förklaringen av en slinga variabel måste placeras före for
.
- Det andra uttrycket,
expression2
, är testvillkoret . Det körs först efter initieringen. Om villkoret ärtrue
, kommer kontrollen in i slingans kropp. Om inte, förflyttas den till utanför öglets kropp i slutet av öglan. Därefter kontrolleras detta villkor efter varje körning av kroppen samt uppdateringsförklaringen. När det ärtrue
flyttar kontrollen sig tillbaka till början av slingans kropp. Villkoret är vanligtvis avsett att vara en kontroll av antalet gånger slingans kropp körs. Detta är det primära sättet att gå ut från en slinga, det andra sättet att använda hoppsatser . - Det tredje uttrycket,
expression3
, är uppdateringsmeddelandet . Det körs efter varje exekvering av slingans kropp. Det används ofta för att öka en variabel med antalet gånger som loopkroppen har utfört, och denna variabel kallas en iterator .
Varje instans av exekvering av slingkroppen kallas en iteration .
Exempel:
for(int i = 0; i < 10 ; i++)
{
printf("%d", i);
}
Utgången är:
0123456789
I exemplet ovan exekveras först i = 0
, initialiserar i
. Därefter kontrolleras villkoret i < 10
, vilket utvärderar att vara true
. Styrningen kommer in i slingans kropp och värdet på i
skrivs ut. Därefter förflyttas kontrollen till i++
, uppdaterar värdet på i
från 0 till 1. Därefter kontrolleras tillståndet igen, och processen fortsätter. Detta fortsätter tills värdet på i
blir 10. Därefter utvärderar villkoret i < 10
false
, varefter kontrollen flyttas ur slingan.
Oändliga öglor
En slinga sägs vara en oändlig slinga om kontrollen kommer in men aldrig lämnar slingans kropp. Detta händer när testtillståndet i slingan aldrig utvärderas till false
.
Exempel:
for (int i = 0; i >= 0; )
{
/* body of the loop where i is not changed*/
}
I exemplet ovan initialiseras variabeln i
, iteratorn, till 0. Testvillkoret är initialt true
. i
ändras dock inte någonstans i kroppen och uppdateringsuttrycket är tomt. Därför kommer i
att förbli 0, och testvillkoret kommer aldrig att utvärderas till false
, vilket leder till en oändlig slinga.
Antagande att det inte finns några hopputtalanden, ett annat sätt som en oändlig slinga kan bildas är genom att uttryckligen hålla villkoret sant:
while (true)
{
/* body of the loop */
}
I en for
loop är tillståndsuppgiften valfri. I detta fall är villkoret alltid true
vakuum, vilket leder till en oändlig slinga.
for (;;)
{
/* body of the loop */
}
Men i vissa fall tillståndet skulle hållas true
avsiktligt med avsikt att avsluta slingan med hjälp av en hopp uttalande som break
.
while (true)
{
/* statements */
if (condition)
{
/* more statements */
break;
}
}
Loop Unrolling och Duff's Device
Ibland kan den raka fram-slingan inte vara helt inne i slingkroppen. Detta beror på att slingan måste grundas av vissa påståenden B. Därefter börjar iterationen med några påståenden A , som sedan följs av B igen innan du slingar.
do_B();
while (condition) {
do_A();
do_B();
}
För att undvika potentiella klipp / klistra in problem med att upprepa B två gånger i koden, kan Duff's Device användas för att starta slingan från mitten av while
kroppen, med hjälp av en switch-sats och falla genom beteende.
switch (true) while (condition) {
case false: do_A(); /* FALL THROUGH */
default: do_B(); /* FALL THROUGH */
}
Duff's Device uppfanns faktiskt för att implementera rullning av slingor. Föreställ dig att använda en mask på ett minnesblock, där n
är en signerad integrerad typ med ett positivt värde.
do {
*ptr++ ^= mask;
} while (--n > 0);
Om n
alltid kunde delas med 4, kan du enkelt rulla upp detta som:
do {
*ptr++ ^= mask;
*ptr++ ^= mask;
*ptr++ ^= mask;
*ptr++ ^= mask;
} while ((n -= 4) > 0);
Men med Duff's Device kan koden följa detta rullande formspråk som hoppar till rätt plats mitt i slingan om n
inte kan delas med 4.
switch (n % 4) do {
case 0: *ptr++ ^= mask; /* FALL THROUGH */
case 3: *ptr++ ^= mask; /* FALL THROUGH */
case 2: *ptr++ ^= mask; /* FALL THROUGH */
case 1: *ptr++ ^= mask; /* FALL THROUGH */
} while ((n -= 4) > 0);
Denna typ av manuell avrullning krävs sällan med moderna kompilatorer, eftersom kompilatorns optimeringsmotor kan rulla upp slingor för programmerarens räkning.