C langage

This is the programming language to know before programming with FreeFem++.

A lot of tutorials exists for this programming language (in french sorry but more tutorials exist in english):

There are hundreds tutorial on this subject, so do not hesitate looking for more information.

A preliminary advice Avoid programming in C on Windows, prefer a Unix system (like MacOS) or a Linux system (like Ubuntu). Indeed, programming on Windows requires an emulator such MingW, while Unix and Linux have very powerful compilers often integrated into the distribution. Finally, Linux distributions are free, so enjoy it.

Some rules

C is a complied language, so he needs a compiler to run. Each line of a C project ends with a ;.

Data types

  • int : integers

  • float : floating (real number)

  • double : double precision floating

  • char : characters

Prefixes unsigned, short and long are applicable to these datatypes. You can also create your own datatype using the keywork typedef.

First example: Hello world!

Open your favorite text editor and write this code in the file hello_world.c.

#include <stdio.h>

int main(int argc, char *argv[]){
    /*I write Hello World !!*/
    printf("Hello world !!\n");
    return 0;
}

Several things about this code:

  • stdio.h is a library. Libraries are very useful in C, they include functions that do not require to be coded. We include it in our program with the command #include <stdio.h> Here, this library is used to access the printf function.

  • The main function is the master function, it is mandatory in C, this is the only function that is executed. It returns an integer and takes an integer parameter and a list of strings (we will see later their utility).

  • A comment is written between / et /. All inside will not be taken into account by the compiler. It is advisable to put comments to explain what is the function, for you or for other people, to understand your code (even one month later).

  • The printf function allows a screen display of a string. \n for a newline.

  • The main function returns the value 0 (which means no worries), if all is good.

We will now compile the code and run it. On linux system, open the terminal and type:

make main

Now type:

./main

And miracle, the terminal displays Hello world !!

Hello world !!

In fact, many things have happened with the make command. The main.c file was converted in the main.o file and then in the executable file main (there is gcc behind it!). We run the main executable using the command ./main.

We can also define a function that write Hello World !! and call them directly in the main function.

#include <stdio.h>

/*My Hello World !! function*/
void hello_world(void){
    printf("Hello world !!\n");
}

/*My main function*/
int main (int argc, char *argv[]){
    /*Call of my function*/
    hello_world();
    return 0;
}

The hello_world function takes no parameters and returns nothing (void). The result is the same as the preceding code.

Pointers

Pointers in C are really important. This is a variable that contains the address of another variable! What is this? To use dynamic structures, but do not worry this is quite simple.

Before do this, I invite you to learn more about the scope of variables and the transition parameter values.

For example an array of doubles.

#include <stdio.h>
#include <stdlib.h>

void main(void){
int i, N = 10;
double *d = NULL;
d = (double*)malloc(N*sizeof(double));
for (i = 0; i < N; i++){
    d[i] = i+1;
}
for (i = 0; i < N; i++){
    printf("%f\n", d[i]);
}
free(d);
d = NULL;
}
  • At first, we need a new library in this code: stdlib.h (that contains malloc).

  • We define our main function as a no parameters and return function (it is one of the possibility of the main function).

  • We define a pointer d who is a double *, understand a pointer on a double array.

  • We allocate memory to this pointer with the malloc keyword. Here, we allocate a N size memory that can represent a table. The pointer d gives the first element of the table address.

  • This table is filled by a loop (here a for loop but others exist…​).

  • We display the table values (%f for display doubles, et \n for a newline…​).

  • We only delete memory for d.

  • We put d to NULL to delete completely the object.

After compiling and run, we have the following result:

1.000000
2.000000
3.000000
4.000000
5.000000
6.000000
7.000000
8.000000
9.000000
10.000000

There is 10 lines managed by our pointer.

Structure definition

We will define a variable type very useful, the vector. We want to have the size of the vector and these components. We will therefore use the notion of structure.

#include <stdio.h>
#include <stdlib.h>

typedef struct {int length; double *val;} vector;

vector* New_vector(int length){
    vector *v = (vector*)malloc(sizeof(vector));
    v->length = length;
    v->val = (double*)malloc(length*sizeof(double));
    return v;
}

void View_vector(vector *v){
    int i;
    printf("vector of length %d :\n", v->length);
    for (i = 0; i < v->length; i++){
        printf("%f\n", v->val[i]);
    }
}

void Free_vector(vector **v){
    free((*v)->val);
    (*v)->val = NULL;
    free(*v);
    *v = NULL;
}

int main(void){
    int i, N = 10;
    vector *v = New_vector(N);
    for (i = 0; i < N; i++){
        v->val[i] = i+1;
    }
    View_vector(v);
    Free_vector(&v);
    return 0;
}
  • We define a new structure vector with the keywords typedef and struct.

  • The first function is used to create a new vector. We allocate memory for the structure and for the table’s values val. Access to a structure field is trought if we have pointer on the structure (v→val), by . otherwise (v.val).

  • The second function is used to display the contents of a vector. It displays the length and the components of the vector.

  • The third function is to release a vector. It i a bit special but very effective. It frees the array of double, put NULL and did the same for he structure. You will notice that the input parameter is a double pointer, or a pointer to pointer.

  • Finally, the main function, which creates, displays, release the vector and return the value 0 (there is still another possible configuration for the main function). For liberation, which takes a double pointer as parameter, we give the address of the pointer to the vector structure with &.

We have a similar result to an array of double, but more generic and easier to use, once coded.

Read and write a file

We will now read and write files, and to do this we will use …​ pointers.

#include <stdio.h>
#include <stdlib.h>

int main(void){
    int i;
    FILE *file = NULL;
    file = fopen("test_file.txt", "w");
    if (file){
        fprintf(file, "Hello\n");
        fprintf(file, "How are you?\n");
        fprintf(file, "Good bye!\n");
        fclose(file);
    }
    else{
        return -1;
    }
    file = fopen("test_file.txt", "r");
    if (file){
        char *text = (char*)malloc(256*sizeof(char));
        printf("I read:\n");
        for (i = 0; i < 6; i++){
            fscanf(file, "%s", text);
            printf("%s\n", text);
        }
        free(text);
        fclose(file);
    }
    else{
        return -1;
    }
    return 0;
}
  • We used the FILE structure, already define in stdio.h.

  • We open the file with the fopen keyword, "w" for write and "r" for read (there are other options).

  • if the file is opened, we write in it. Otherwise, it returns a -1 instead of the 0 which allows us to know that there is an error during execution.

  • We now opens the same file for reading, and if it is open we read the content.

  • The scanf function stops whenever space is encountered, but there are other read functions (fgets, …​).

  • We return 0 if everything went well.

I read:
Hello
How
are
you?
Good
bye!

We read all the content of the file.

There are many aspects of C that we have not addressed here then do not hesitate to consult other more specific tutorials. Now that you know to master the C language broadly, we will speak about the C++ language.