Sök…


Jämförelse av bokstavlig och variabel

Anta att du jämför värde med någon variabel

if ( i  == 2) //Bad-way
{
    doSomething;
}

Anta nu att du har misstagat == med = . Då tar det din söta tid att räkna ut det.

if( 2 == i) //Good-way
{
    doSomething;
}

Då, om ett lika tecken oavsiktligt lämnas ut, kommer kompilatorn att klaga över ett "försök att tilldela bokstavligen." Detta skyddar dig inte när du jämför två variabler, men varje liten bit hjälper.

Se här för mer info.

Lämna inte parameterlistan för en funktion tom - använd tom

Anta att du skapar en funktion som inte kräver några argument när den kallas och du står inför dilemmaet för hur du ska definiera parameterlistan i funktionsprototypen och funktionsdefinitionen.

  • Du har valet att hålla parameterlistan tom för både prototyp och definition. Därmed ser de ut precis som det anrop som du behöver.

  • Du läser någonstans att en av användningarna av nyckelordet tomrum (det finns bara ett fåtal av dem), är att definiera parameterlistan med funktioner som inte accepterar några argument i deras samtal. Så detta är också ett val.

Så, vilket är rätt val?

SVAR: Använd nyckelordet ogiltigt

ALLMÄN RÅD: Om ett språk tillhandahåller vissa funktioner som du kan använda för ett speciellt syfte är du bättre att använda den i din kod. enum till exempel enum istället för #define makron (det är för ett annat exempel).

C11 avsnitt 6.7.6.3 "Funktionsdeklaratorer", punkt 10, anger:

Det speciella fallet med en namngiven parameter av typen void som det enda objektet i listan anger att funktionen inte har några parametrar.

Punkt 14 i samma avsnitt visar den enda skillnaden:

... En tom lista i en funktionsdeklarator som är en del av en definition av den funktionen anger att funktionen inte har några parametrar. Den tomma listan i en funktionsdeklarator som inte ingår i en definition av den funktionen anger att ingen information om antalet eller typer av parametrar tillhandahålls.

En förenklad förklaring tillhandahållen av K&R (s. 72-73) för ovanstående saker:

Dessutom, om en funktionsdeklaration inte innehåller argument, som i
double atof(); , det anses också för att inget ska antas om atof argument; all parameterkontroll är avstängd. Denna speciella betydelse av den tomma argumentlistan är avsedd att tillåta äldre C-program att kompilera med nya kompilatorer. Men det är en dålig idé att använda den med nya program. Om funktionen tar argument, förklara dem; om det inte krävs några argument, använd void .

Så det här är hur din prototyp ska se ut:

int foo(void);

Och det är så funktionsdefinitionen ska vara:

int foo(void)
{
    ...
    <statements>
    ...
    return 1;
}

En fördel med att använda ovanstående, intill int foo() typ av deklaration (dvs. utan att använda nyckelordet tom ), är att kompilatorn kan upptäcka felet om du kallar din funktion med ett felaktigt uttalande som foo(42) . Den här typen av uttalande om funktionssamtal orsakar inte några fel om du lämnar parameterlistan tom. Felet skulle passera tyst, oupptäckt och koden skulle fortfarande köras.

Detta innebär också att du bör definiera huvudfunktionen main() så här:

int main(void)
{
    ...
    <statements>
    ...
    return 0;
}

Observera att även om en funktion definierad med en tom parameterlista inte tar några argument ger den inte en prototyp för funktionen, så kompilatorn kommer inte att klaga om funktionen därefter kallas med argument. Till exempel:

#include <stdio.h>

static void parameterless()
{
    printf("%s called\n", __func__);
}

int main(void)
{
    parameterless(3, "arguments", "provided");
    return 0;
}

Om den koden sparas i filen proto79.c kan den sammanställas på Unix med GCC (version 7.1.0 på macOS Sierra 10.12.5 som används för demonstration) så här:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -pedantic proto79.c -o proto79
$

Om du sammanställer med strängare alternativ får du fel:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -pedantic proto79.c -o proto79 
proto79.c:3:13: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
 static void parameterless()
             ^~~~~~~~~~~~~
proto79.c: In function ‘parameterless’:
proto79.c:3:13: error: old-style function definition [-Werror=old-style-definition]
cc1: all warnings being treated as errors
$

Om du ger funktionen den formella prototypen static void parameterless(void) , ger sammanställningen fel:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -pedantic proto79.c -o proto79 
proto79.c: In function ‘main’:
proto79.c:10:5: error: too many arguments to function ‘parameterless’
     parameterless(3, "arguments", "provided");
     ^~~~~~~~~~~~~
proto79.c:3:13: note: declared here
 static void parameterless(void)
             ^~~~~~~~~~~~~
$

Moral - se alltid till att du har prototyper och se till att din kompilator berättar när du inte följer reglerna.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow