Was das calloc(numer of elements, size of elemet) macht:
damit weist man per Hand Speicher für den Pointer zu (der muss ja auf irgendwas zeigen) und setzt den Inhalt (*pointer) auf 0. Es gibt noch die Funktion malloc(...), die lässt aber die Werte im Speicher auf ihrem ursprünglichen (willkürlichen) Wert. Machst du es nicht, dann zeigt der Pointer auf einen willkürlich Speicherbereich - der von anderen Prozessen benutzt werden darf
Zum Schluß muss man wieder free(pointer) machen, ansonst gibt es ein memory-leak. Aber : es wird gefährlich, wenn man free(pointer) zweimal macht (schonmal freigegeben und dann nochmal freigeben

)...
Der Vorteil von selbst zugewiesenem Speicher ist die Möglichkeit, den Speicher dynamisch größer oder kleiner zu machen, wenn man z.b. aus einer Datei lesen will etc. ... Man muss also die größe des Arrays nicht wissen, sondern kann ihn anpassen, wenn nötig.
Das ist in anderen Sprachen nicht nötig, wie Java oder C#, da sollte es automatisch gehen.
Globale Definition von a,b,*erg:
a und b global (
ich meinte was anderes - direkt bei Anfang nach main) zu definieren macht Sinn. Bei *erg sollte ja der Typ von der Operation abhängen. Eine Division ergibt keine ganze Zahl

Wäre dann also eine double.