C Language
Funktionsparametrar
Sök…
Anmärkningar
I C är det vanligt att använda returvärden för att beteckna fel som uppstår; och att returnera data genom användning av vidarebefordrade pekare. Detta kan göras av flera skäl; inklusive att inte behöva tilldela minne på högen eller använda statisk allokering vid den punkt där funktionen anropas.
Använda pekarparametrar för att returnera flera värden
Ett vanligt mönster i C, för att enkelt imitera att returnera flera värden från en funktion, är att använda pekare.
#include <stdio.h>
void Get( int* c , double* d )
{
*c = 72;
*d = 175.0;
}
int main(void)
{
int a = 0;
double b = 0.0;
Get( &a , &b );
printf("a: %d, b: %f\n", a , b );
return 0;
}
Vidarebefordra i matriser till funktioner
int getListOfFriends(size_t size, int friend_indexes[]) {
size_t i = 0;
for (; i < size; i++) {
friend_indexes[i] = i;
}
}
/* Type "void" and VLAs ("int friend_indexes[static size]") require C99 at least.
In C11 VLAs are optional. */
void getListOfFriends(size_t size, int friend_indexes[static size]) {
size_t i = 0;
for (; i < size; i++) {
friend_indexes[i] = 1;
}
}
Här static
inuti []
i funktionsparametern, begär att argumentfältet måste ha minst lika många element som anges (dvs size
). För att kunna använda den funktionen måste vi se till att size
kommer före matrisparametern i listan.
Använd getListOfFriends()
så här:
#define LIST_SIZE (50)
int main(void) {
size_t size_of_list = LIST_SIZE;
int friends_indexes[size_of_list];
getListOfFriends(size_of_list, friend_indexes); /* friend_indexes decays to a pointer to the
address of its 1st element:
&friend_indexes[0] */
/* Here friend_indexes carries: {0, 1, 2, ..., 49}; */
return 0;
}
Se även
Vidarebefordra flerdimensionella matriser till en funktion
Parametrar skickas efter värde
I C passeras alla funktionsparametrar efter värde, så att ändra vad som skickas i callee-funktioner påverkar inte samtalsfunktionernas lokala variabler.
#include <stdio.h>
void modify(int v) {
printf("modify 1: %d\n", v); /* 0 is printed */
v = 42;
printf("modify 2: %d\n", v); /* 42 is printed */
}
int main(void) {
int v = 0;
printf("main 1: %d\n", v); /* 0 is printed */
modify(v);
printf("main 2: %d\n", v); /* 0 is printed, not 42 */
return 0;
}
Du kan använda pekare för att låta callee-funktioner ändra anropsfunktionernas lokala variabler. Observera att detta inte är förbi referens men pekarvärden som pekar på de lokala variablerna passerat.
#include <stdio.h>
void modify(int* v) {
printf("modify 1: %d\n", *v); /* 0 is printed */
*v = 42;
printf("modify 2: %d\n", *v); /* 42 is printed */
}
int main(void) {
int v = 0;
printf("main 1: %d\n", v); /* 0 is printed */
modify(&v);
printf("main 2: %d\n", v); /* 42 is printed */
return 0;
}
Men att returnera adressen till en lokal variabel till callee resulterar i odefinierat beteende. Se Avsluta en pekare till variabel utanför dess livstid .
Ordning på utförande av funktionsparametrar
Ordern för exekvering av parametrar definieras inte i C-programmering. Här kan det köra från vänster till höger eller från höger till vänster. Beställningen beror på implementeringen.
#include <stdio.h>
void function(int a, int b)
{
printf("%d %d\n", a, b);
}
int main(void)
{
int a = 1;
function(a++, ++a);
return 0;
}
Exempel på funktion som returnerar strukt som innehåller värden med felkoder
De flesta exempel på en funktion som returnerar ett värde involverar att tillhandahålla en pekare som ett av argumenten för att låta funktionen ändra det pekade värdet, liknande det följande. Det faktiska avkastningsvärdet för funktionen är vanligtvis någon typ, t.ex. en int
att indikera status för resultatet, oavsett om det fungerade eller inte.
int func (int *pIvalue)
{
int iRetStatus = 0; /* Default status is no change */
if (*pIvalue > 10) {
*pIvalue = *pIvalue * 45; /* Modify the value pointed to */
iRetStatus = 1; /* indicate value was changed */
}
return iRetStatus; /* Return an error code */
}
Men du kan också använda en struct
som ett returneringsvärde som gör att du kan returnera både en felstatus tillsammans med andra värden också. Till exempel.
typedef struct {
int iStat; /* Return status */
int iValue; /* Return value */
} RetValue;
RetValue func (int iValue)
{
RetValue iRetStatus = {0, iValue};
if (iValue > 10) {
iRetStatus.iValue = iValue * 45;
iRetStatus.iStat = 1;
}
return iRetStatus;
}
Denna funktion kan sedan användas som följande exempel.
int usingFunc (int iValue)
{
RetValue iRet = func (iValue);
if (iRet.iStat == 1) {
/* do things with iRet.iValue, the returned value */
}
return 0;
}
Eller så kan det användas på följande sätt.
int usingFunc (int iValue)
{
RetValue iRet;
if ( (iRet = func (iValue)).iStat == 1 ) {
/* do things with iRet.iValue, the returned value */
}
return 0;
}