Ήρθε η ώρα να μιλήσουμε για τις συναρτήσεις. Έχετε ήδη δει κάποιες απ`τις λειτουργίες τους στα προηγούμενα άρθρα, πχ όταν φτιάχναμε την "main", ή όταν καλούσαμε την "getchar()", "printf()", "scanf()" κ.α. Αυτό που είναι πραγματικά οι συναρτήσεις είναι κομμάτια κώδικα ο οποίος κάνει συγκεκριμένα βήματα/εκτελεί συγκεκριμένες εντολές ώστε να παράγει κάτι χρήσιμο. Μπορείτε να χρησιμοποιείτε τις καθιερωμένες/ενσωματωμένες συναρτήσεις της γλώσσας είτε να φτιάχνετε τις δικές σας.

Πρέπει να αναφερθεί ότι μια συνάρτηση μπορεί να επιστρέψει τα πάντα, από ακεραίους, μέχρι πραγματικούς, δείκτες, δομές δεδομένων, ακόμα και τίποτα! Το τελευταίο αναπαριστάται στην C με τη λέξη "void". Ακολουθεί η γενική δομή μιας συνάρτησης:

τύπος_επιστροφής όνομα_συνάρτησης(τύπος1 arg1, τύπος2 arg2, ... , τύποςN argN)
{
    /* Οι δηλώσεις μεταβλητών γίνονται πάντα στην αρχή */

    /* Βάζετε ότι κώδικα θέλετε εδώ */

    return αποτέλεσμα; /* Όλα εκτός του "void" το χρειάζονται */
}

αν δε θέλετε η συνάρτηση να παίρνει παραμέτρους, βάλτε "void" ανάμεσα στις παρενθέσεις όπως "int main(void)". Παρενθέσεις χωρίς τίποτα ενδιάμεσα σημαίνουν για την C ότι η συνάρτηση δέχεται απεριόριστο πλήθος παραμέτρων.

Προσοχή:
Αν καλέσετε την συνάρτησή σας πριν την έχετε ορίσει, η μεταγλώττιση δε σταματάει και ο τύπος επιστροφής εξ ορισμού γίνεται "int". Γι`αυτό, είτε ορίζετε τις συναρτήσεις σας πριν τις καλέσετε, ή δηλώνετε την "παρουσία" τους μέσω μας δήλωσης πρωτοτύπου, έτσι:

τύπος_επιστροφής όνομα_συνάρτησης(τύπος1 arg1, τύπος2 arg2, ... , τύποςN argN);

τα ονόματα των παραμέτρων μπορούν να παραβλεφθούν( μόνο στη δήλωση πρωτοτύπου ).

Επίσης, είναι σημαντικό να θυμάστε ότι η C δεν επιτρέπει να υπάρχουν παραπάνω από μία συναρτήσεις με το ίδιο ακριβώς όνομα.

Ακόμα, όπως και σε άλλες γλώσσες, οι μεταβλητές που δηλώνονται σε μια συνάρτηση είναι τοπικές, δηλαδή μπορώ να έχω μια μεταβλητή με το ίδιο όνομα σε δύο διαφορετικές συναρτήσεις, και δεν θα είναι η ίδια!

Τέλος, κάτι που μπερδεύει πολλούς οι οποίοι έρχονται από άλλες γλώσσες, η C περνάει όλες τις παραμέτρους κατά τιμή, δηλαδή δημιουργεί ένα αντίγραφο της παραμέτρου και το περνάει στη συνάρτηση. Αλλαγές οι οποίες γίνονται μέσα στη συνάρτηση δεν επηρεάζουν τον "έξω κόσμο", δηλαδή ότι συμβαίνει εκτός αυτής της συνάρτησης. Αυτό μπορεί να παρακαμφθεί χρησιμοποιώντας δείκτες( θα αναφερθούν σε άλλο άρθρο, πχ η "scanf()" χρησιμοποιεί δείκτες ).

Τώρα, το γιατί υπάρχουν αυτές οι συναρτήσεις είναι πολύ απλό αν το σκεφτεί κανείς. Ας πούμε ότι έχετε το ίδιο κομμάτι κώδικα και το χρησιμοποιείτε σε 40 διαφορετικά σημεία. Αν θέλατε να αλλάξετε κάτι, δε θα προτιμούσατε να το έχετε σε ένα σημείο ή θα θέλατε να τρέχετε σε 40 διαφορετικά σημεία για να το αλλάξετε;
Κάνει τον κώδικα πιο ευανάγνωστο.
Βοηθάει στη διάσπαση του προγράμματος σε "λογικά κομμάτια", πιο εύκολα επιλύσιμα απ`ότι αν ήταν όλα παστωμένα σε ένα μέρος.

Ας κλείσουμε με ένα παραδειγματάκι:

#include <stdio.h>

double power(double base, int exponent);

int main(void)
{
    double base, result;
    int exponent;
   
    printf("Input a base: ");
    scanf("%lf", &base);
    printf("Input an exponent( integer ): ");
    scanf("%d", &exponent);
   
    result = power(base, exponent);
   
    printf("%g to the power of %d equals %g\n", base, exponent, result);
   
    while (getchar() != '\n');
    getchar();
   
    return 0;
}

/* Επιστρέφει τη base υψωμένη στη exponent */
/* Υπάρχουν πολύ πιο γρήγοροι τρόποι λύσης απ`αυτό,
  αλλά αυτός είναι σίγουρα ο πιο απλός που υπάρχει  */
double power(double base, int exponent)
{
    double result;
    int i;
   
    result = 1.0;
    if (exponent < 0)
    {
        for (i = 0; i < -exponent; i++){
            result *= base;
        }
        result = 1.0/result;
    }
    else
    {
        for (i = 0; i < exponent; i++){
            result *= base;
        }
    }
   
    return result;
}

Όπως πάντα, αντιγράψτε το, μεταγλωττίστε το, τρέξτε το, αλλάξτε του τα φώτα :D, και τα λέμε στο επόμενο άρθρο.