Ho una struttura chiamata State che contiene tutte le variabili per il programma. Invece di essere modificato direttamente dalle funzioni, è il valore restituito. Ecco alcuni codici:
#define USERNAME_LENGTH 20
#define MAX_NUMBEROFUSERS 64
#include <string.h>
#include <stdio.h>
struct User {
char name[USERNAME_LENGTH +1];
int id;
};
struct State {
int numberOfUsers;
struct User users[MAX_NUMBEROFUSERS];
};
// create a new instance of state, called "_";
struct State _;
// function for returning the state with a new user in it
struct State newUser() {
struct State state = _;
char name[USERNAME_LENGTH +1];
sprintf(name, "test username #%d", state.numberOfUsers);
struct User newUser;
newUser.id = state.numberOfUsers;
memset(newUser.name, 'Users are:
test username #0
test username #1
test username #2
test username #3
test username #4
test username #5
test username #6
test username #7
test username #8
test username #9
10 users total.
', USERNAME_LENGTH +1);
memcpy(newUser.name, name, USERNAME_LENGTH);
state.users[state.numberOfUsers] = newUser;
state.numberOfUsers++;
return state;
}
int main() {
while (_.numberOfUsers < 10) {
_ = newUser();
}
printf("Users are:\n");
for (int i=0; i<_.numberOfUsers; i++) {
printf("%s\n", _.users[i].name);
}
printf("%d users total.\n", _.numberOfUsers);
return 0;
}
Output:
newUser(const char* username) {...}
Come puoi vedere, l'intero stato viene trasmesso finché il programma non termina. La funzione newUser () copia lo stato in una variabile locale che viene modificata e quindi restituita. Ho scelto di non passare lo stato come argomento alla funzione, perché volevo essere in grado di passare altri argomenti, se necessario, come ad esempio:
#define USERNAME_LENGTH 20
#define MAX_NUMBEROFUSERS 64
#include <string.h>
#include <stdio.h>
struct User {
char name[USERNAME_LENGTH +1];
int id;
};
struct State {
int numberOfUsers;
struct User users[MAX_NUMBEROFUSERS];
};
// create a new instance of state, called "_";
struct State _;
// function for returning the state with a new user in it
struct State newUser() {
struct State state = _;
char name[USERNAME_LENGTH +1];
sprintf(name, "test username #%d", state.numberOfUsers);
struct User newUser;
newUser.id = state.numberOfUsers;
memset(newUser.name, 'Users are:
test username #0
test username #1
test username #2
test username #3
test username #4
test username #5
test username #6
test username #7
test username #8
test username #9
10 users total.
', USERNAME_LENGTH +1);
memcpy(newUser.name, name, USERNAME_LENGTH);
state.users[state.numberOfUsers] = newUser;
state.numberOfUsers++;
return state;
}
int main() {
while (_.numberOfUsers < 10) {
_ = newUser();
}
printf("Users are:\n");
for (int i=0; i<_.numberOfUsers; i++) {
printf("%s\n", _.users[i].name);
}
printf("%d users total.\n", _.numberOfUsers);
return 0;
}
Domanda: Penso che sia abbastanza interessante, ma è pratico? Il compilatore (GCC) può ottimizzare per questo tipo di stile quasi funzionale?
Riesco a vedere il vantaggio di tenere esplicitamente traccia dello stato del programma, ma ne vale la pena?