8.2. C og C++ programmering

Programmeringssproget C og UNIX har traditionelt været tæt knyttet til hinanden, og dette gælder i høj grad også for Linux. Kernen og langt de fleste applikationer er skrevet i C.

GNU C/C++ er en af de allerbedste oversættere på markedet i dag. I modsætning til Windows-verdenen er oversætteren ikke indkapslet i en grafisk brugergrænseflade. Det giver større frihed for den enkelte til at sammensætte et personligt udviklingsmiljø - enten grafisk eller tekstbaseret. Med lidt tilvænning er det også hurtigt at anvende, specielt hvis der skal oversættes meget kode per gang. Der er også den store fordel, at det er standard inden for UNIX-verdenen, hvorfor kode og kompileringsfiler (makefiles) uden problemer kan flyttes, oversættes og eksekveres på andre typer af UNIX-systemer.

8.2.1. Det første C program: HelloWorld

Per tradition er HelloWorld-programmet det første C-program, man skal få til at virke. Programmet skriver en kort tekst (normalt "Hello World", men i dette tilfælde en lidt mere relevant besked) ud på skærmen og afslutter. Indtast følgende (brug emacs, pico eller vi), og gem det som hello.c.

#include <stdio.h>

int main(void)
{
  printf("Linux er sjovt\n");
  return 0;
}

I kataloget, hvor filen er gemt, kan programmet nu oversættes ved at skrive

[daisy@linus daisy]$  gcc -o hello hello.c

C-oversætteren hedder gcc. Den skal her lave en eksekverbar fil med navnet hello, og den skal oversætte og linke ud fra kildeteksten i hello.c.

Det oversatte C-program hello køres ved at skrive navnet i en xterm. For dem, som har C-erfaring, kommer der et par tips nu. En lille sjov ordre er at skrive

[daisy@linus daisy]$  nm hello
Så kan du se, at programmet bl.a. kalder funktionen printf og indeholder en funktion main. Programmet blevet linket med dynamiske links til externe kataloger - dette kan ses ved at skrive ldd hello
[daisy@linus daisy]$  ldd hello
        libc.so.6 => /lib/libc.so.6 (0x40003000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00000000)

At den eksterne funktion printf rent faktisk kommer fra libc, kan ses ved at skrive


[daisy@linus daisy]$  nm /lib/libc.so.6 | grep "printf"

Det var lidt om dynamisk link. Ideen er, at programmet kun indeholder de nødvendige dele. Under udførelsen af programmet bruges nogle af de nævnte eksterne biblioteker. Koden kan også oversættes med alle eksterne funktioner - linket statisk ind.

[daisy@linus daisy]$  gcc -o hello hello.c -static

Bemærk ændringen i filstørrelsen (fra ca. 4 kbytes til over 400 kbytes). Nu vil ldd hello vise, at der ikke er eksterne biblioteker nødvendige for at køre programmet. Nu tilbage til lidt mere simple eksempler.

8.2.2. Det første C++ program

I følgende enkle eksempel ønskes et program, der indlæser to tal, finder det største af de to og skriver dette ud. Omkring C/C++ programmering kan henvises til en af de mange standardbøger om C og C++. Koden er ikke det primære, men kunne se således ud.

#include <iostream.h>

void read2(int&,int&);
void writeMax(int);

int main()
{
  int val1,val2,maxVal;

  read2(val1,val2);
  maxVal = (val1>val2)?val1:val2;
  writeMax(maxVal);

  return 0;
}

void read2(int& v1,int& v2)
{
  cout << "Indtast to heltal ";
  cin >> v1 >> v2;
}

void writeMax(int val)
{
  cout << val
       << " er det største tal\n";
}
Eksemplet gemmes som eks1.c++.

Oversættelse kan ske med en såkaldt makefile, men her sker det ved direkte at kalde oversætteren.

[daisy@linus daisy]$  g++ eks1.c++ -o eks1
Du kan eventuelt lave en fil, hvor der står ordren til at oversætte en fil ud fra variabel. En hurtig måde er direkte at bruge echo funktionen til dette.
[daisy@linus daisy]$  echo "g++ $1.c++ -g -lm -o $1" > mycompile
Koden $1 betyder første argument, hvorfor filen kaldes med første argument lig med C-kodens filnavn. I filen inkluderes debug-information med flaget -g, og matematikbiblioteket linkes med -lm. I dette tilfælde er dette ikke nødvendigt, men normalt vil det være det. Filen er gemt under navnet mycompile, og der skrives
[daisy@linus daisy]$  chmod a+x mycompile
for, at filen kan eksekveres. Nu kan du skrive
[daisy@linus daisy]$  mycompile FILNAVN

Det antages, at kildefilen hedder FILNAVN.c++, og den eksekverbare fil kommer til at hedde FILNAVN.

8.2.3. Oversættelse af flere C-filer med makefiles

Næste eksempel er to filer, hvor den ene kalder funktioner i den anden. I eksemplet, der er C-kode, er det igen det største af to tal, der skal findes og skrives ud.

Følgende fil kan gemmes som ceks2.c.

#include <stdio.h>
#include <math.h>

float v1,v2,retval;

float max(float,float);

int main(void)
{
  v1=sin(2.34);
  v2=tan(4.4);

  retval=max(v1,v2);

  printf("Af %f og %f er %f stoerst\n",v1,v2,retval);
  return 0;
}

Følgende fil kan gemmes som cfkt.c.

float max(float f1,float f2)
{
  float f3;

  if (f1>f2)
    f3=f1;
  else
    f3=f2;

  return f3;
}

Koden kan oversættes ved hjælp af GNU C-oversætteren gcc. Brug man gcc for at få hjælp de mange muligheder.

[daisy@linus daisy]$  gcc -o ceks2 ceks2.c cfkt.c -lm

En langt mere elegant metode er at lave en makefile. Herefter skrives blot make, og C-oversætteren vil kun oversætte de filer, der er nye i forhold til objektfilerne. Makefiles kan også anvendes til at styre oversættelse generelt såsom af LaTeX-kode. En makefile (med navnet Makefile) kunne være følgende.

# Makefile til GNU C-oversætteren - dette er en kommentar
# I dette eksempel oversættes to filer.
# ceks2.c og cfkt.c oversættes til exefilen ceks2

# Navn paa oversaetter = gcc
CC = gcc

# Navn paa eksekverbar fil
OUTPUT   = ceks2

# Kilde fil navne
sources  = ceks2.c \
           cfkt.c

# Automatisk navngivning af objektfiler, hvor  .c bliver til .o
OBJS        = $(sources:.c=.o)

# Compilerflag: Maximal optimering -O2 og debug information -g
CFLAGS      = -O2 -g

#Linkerflag: Inkluderer math-bibliotek med -lm !!!!
LDFLAGS      = -lm

# Foelgende linje checker om en .o fil er nyere end den eksekverbare fil. Hvis
# dette er tilfaeldet, linkes disse. Dvs. kun nye elementer oversættes.
$(OUTPUT): $(OBJS)
	$(CC) $(CFLAGS) -o $(OUTPUT) $(OBJS) $(LDFLAGS)

Bemærk, at der skal stå en tabulator foran de linjer, der skal eksekveres, såsom den sidste. Der må ikke anvendes mellemrum.

Når makefilen er skrevet, kan programmet oversættes ved at skrive

[daisy@linus daisy]$  make
i det bibliotek, hvor makefilen findes. En makefile kan være meget lang og indeholde mange regler.

8.2.4. GNU debuggeren og DDD

Til GNU C/C++ findes en tekst-baseret debugger (gdb), som virker fint sammen med oversætteren. Hvis alle filer er oversat med flaget -g, kan man kalde debuggeren ved at skrive gdb FILNAVN, hvor FILNAVN er navnet på den eksekverbare fil.

Man kan vise (display) enkelte variable eller strukturer. Du kan sætte breakpoints og meget andet, men det hele er tekstbaseret. Programmet gdb kan med fordel kaldes fra editoren Emacs ved at skrive Meta-x gdb (Meta=Alt). Så fås en delt skærm med debugger og kode, der kører sammen. Du kan i en xterm skrive man gdb for at få muligheder for debuggeren. Ved fejl kan det anbefales at oversætte kode uden optimering, dvs. fjern -O2 ved oversættelse, idet man således ikke får fjernet overflødige variable og lignende, som så ikke kan vises med debuggeren.

Ønsker du at anvende en grafisk debugger, kan du med fordel installere ddd, der anvender gdb, men giver en fuldt professionel grafisk brugerflade til debugging af C, C++, Java og Fortran kode. Specielt lækkert er, at man nemt kan følge indholdet af strukturer, tabeller og simple variable. DDD kan downloades fra http://www.cs.tu-bs.de/softech/ddd

8.2.5. KDevelop

Der er ved at komme integrerede udviklingsmiljøer til Linux, som det kendes fra f.eks. Visual C++ til Windows. Man kan købe Code Warrior til Linux og projekter Code Crusader er også godt på vej (men Code Crusader er ikke så godt designet).

Et spændende helt nyt program er KDevelop til KDE.

Ambitionsniveauet er meget højt, og til trods for at det er den første beta version, som er blevet testet her, så ser det positivt ud.

Som det ses på Figur 8-3, så er der der ligheder med Visual C++ fra Microsoft. Man kan nemt overskue alle filer, klasser, strukturer og variable i projektet. Der er god support for at oversætte, debugge (ser det ud til), og revisionskontrol er direkte integreret. Dette er baseret på CVS. Der er mulighed for integreret dokumentationsmuligheder baseret på SGML.

En ting, som er et meget stort plus ved KDevelop i forhold til Visual C++ er at alle projekt filer er tekst-baserede, dvs. man kan se alt med en almindelig tekst-editor og rette hvis man har noget specielt, der skal ind. KDevelop laver i øvrigt selv standard makefiles, så man kan oversætte programmerne udenfor GUI miljøet. Med andre ord, så er KDevelop en naturlig overbygning på GNU værktøjerne, uden at disse erstattes. KDevelop følger ikke med f.eks. Red Hat endnu, men kan downloades fra projektets hjemmeside http://www.kdevelop.org.

8.2.6. Bøger om C-programmering under Linux

Der findes mange bøger om C-programmering på UNIX-systemer. Vi nøjes her med at nævne et par stykker, som vi synes er gode:

Fælles for de tre nævnte bøger er, at de henvender sig til læsere, der allerede er godt inde i C som programmeringssprog. Hvis du har brug for at lære C fra grunden, findes der utroligt mange bøger at vælge mellem. Prøv som udgangspunkt at tage et kig på disse to (den første er en klassiker):