krähemann.com

C Tutorial

C programmierä uf Unix ähnliche Betriebssystem

Joël Krähemann

Copyright (C) Joël Krähemann.


Kapitel 1. Iileitig

Inhaltsverzeichnis

Usblick

Usblick

I dem Dokument wird erklährt wiä mor mit dä Programmiersproch C äs Programm schriebt und wiä so äs Programm ufbaut isch ahand vomnä Programm wo inerä Kommandozilä lauft. Diä Dateie wo Verwendändet werdet cham mor au als tarreds und bzippeds Archiv abelade under dem link.

ä C Programm hät d'Dateiendig *.c. I C cha mor Header Dateie vowendä wo dementsprechend d'Dateiendig *.h händ. I Headerdateie cham mor Funktionsdefinitionä, Typdefinitionä, globali Variable und Makros definierä. Sie sind do zum i anderä Dateiä ibundä zwerdä um so d'Definitionä i denä Dateiä sichtbar zmache. C isch ä Typsicheri Programmiersproch, das heisst dä Compiler unterscheidet zwüschä voschiedenä Datetype. Wer ungeduldig isch cha zerst s'Kapitel über s'Kompilierä läse und denn d'Programmbispiel gad laufeloh.

Kapitel 2. Syntax

Inhaltsverzeichnis

Ufbau
Kontext

Ufbau

I C gliederät mo s'Programm i Funktionä, diä wiederum chönd Parameter entgägä neh. Ä Funktion foht mit Wertrückgobä definition a, denn folgt dä Funktionsname, denn i rundä Chlamerä Parameterdefinition, denn dä Programmcode wo mit gschweifte Chlamerä igränzt wird und endet mit dä return awiesig. Funktionsufruef endet mit ämne Semikolon, wobi diä innenand verschachtlet si chönd und nur dä üsserst Funktionsufruef mue mit ämne Strichpunkt abgschlosse si. Parameter sind Variable wo dä Funktion übergeh werdät, wobie vo dä Variable ä Kopie erstellt wird. Falls mo veränderigä a dä Variable i ä Ufrüefende Funktion mit öbercho will, mue mor än Zeiger uf diä Variable übergeh. Kommentar fönd mit /* a und höred mit */ uf. Es giet au eizeiligi Kommentar diä händ am Afang //. Äs Programm started mit dä main Funktion. Diä hät zwei Parameter. Dä erst argc giet ah wiä viel Argument am Programm übergeh worde sind. Dä zweit argv isch äs Array wo alli Argument als Zeichechetti beinhalted.

Kontext

Dä C Compiler arbeitet und übersetzt gwüssi Awisiegä kontextual. Das isch ä so, wiel für unterschiedlichi Problemstelligä s'gliechä Zeiche vowendet wird.

Somit wird jetzt än tüferä Iblick i d'Syntax voschafft. Däbi wird nonig uf d'Bedütig vo dä einzelne Kontext igange, sondern sötti nur än Überblick voschaffe.

S'einzigä Zeiche wo im Kontext interpretiert wird isch *. Zwor eimol als Multiplikation und s'anderä mol als Dereferenzierig. Aber Denn giet's no dä Kontext für diä eckigä Chlammerä []. Innerä Array Deklaration giet's a wiä gross das es isch, z.B. int array[8]; giet a, dass das Array 8 iträg hätt. Aber im Laufzietkontext, wo diä eigentliche Operatione stattfindet, isch äs än Index, z.B. zahl = array[0] + array[1]; addiert s'erste Array Element mit äm zweite und speichert's i dä Variable zahl.

Denn giet's no diä gmischtä Operatorä wo z.B. addiered und gliechsetzed zahl += 8;.

Beispiel 2.1. Kontext

#include <stdio.h>

int
main(int argc, char **argv)
{
  /*
   * Deklarierä vonerä Variable namens zahl vom Datetyp int
   */
  int zahl;
  /*
   * Deklarierä vonerä Variable namens zeiche vom Datetyp char
   */
  char zeiche;
  /*
   * Deklarierä vonerä Variable namens zeichechettä0 vom Datetyp char*
   * S * giet ah, dass es sich um än Zeiger handelt und wird inerä
   * Deklaration immer als Zeigerdefinition interpretiert.
   */  
  char *zeichechette0;
  /*
   * Deklarierä vonerä Variable namens zeichechettä vom Datetyp char*
   * Diä eckigä Chlamerä gebet a, dass es sich um ä Array handelt und
   * innerhalb dävo, isch d'grösse agob.
   */
  char zeichechette1[4];

  /*
   * wenn anerä Variable s'erste Mol än Wert zuegwiesä wird spricht mo
   * vo initialisierä.
   */
  zahl = 1;
  zeiche = 'a';

  /*
   * Do wird ä Speicheradresse i d'Variable zeichechettä0 gschriebe.
   * zeichechettä1 isch eigentlich au ä Variable und schlussendlich
   * sind alles nur Zahle.
   */
  zeichechette0 = zeichechette1;
 
  /*
   * Do wird zeichechettä0 mit äm * dereferenziert, das heisst
   * d'Voänderig gschieht nöd uf dä Variable sondern im Speicher
   * wo dä Pointer druf zeigt.
   * Än Zeiger brucht au Speicher und wird Schlussendlich als Zahl
   * dargstellt und diä Zahl chan mo au voänderä. Das cha au durchus
   * Sinn mache, z.B. dä ganz Speicher abarbeite tuet mor idem mo
   * d'Adresse um eis erhöht (addiert).
   * Bim Derefernzierä tuet mo nöd erhöhe sondern äbä uf dä Speicher
   * zuegriefä wo druf zeigt wird und au nöd dä Zeiger selber manipulierä.
   * Und jetzt zum eigentliche, das ganze hät mit multiplikation nüt z'tue.
   */
  *zeichechette0 = zeiche;

  /*
   * Do wird zerst dä Zeiger um eis erhöht und den derefernziert.
   */
  zeichechette0++;
  *(zeichechette0) = 'b';

  /*
   * Um zeichechettä0 uf diä Ursprünglich Speicheradresse zeig z'loh,
   * setzed mir sie gleich zeichechettä1, wo au än Zeiger isch.
   * Das müe mo, wiel dä Inkrement Operator ++ d'Variable voänderet hät.
   */
  zeichechette0 = zeichechette1;

  /*
   * Ä alternative zu erhöhe vo dä Speicheradresse isch dä zuegriff mittels
   * äm Array Index.
   * Bi dä Deklaratione sind schomol diä eckige Chlamerä uftaucht, döt händs
   * d'Grössi vom Speicherberiech ageh, aber i dem Kontext tuet's dä Zeiger
   * temporär um zwei erhöhe und schriebt in Speicher s'Zeiche c.
   */
  zeichechette0[2] = 'c';

  /*
   * I dem Kontext handelt es sich s'Stärnli um ä Multiplikation.
   * Es werdät drü Zahle multipliziert nämlich: 5, 8 und 2.
   */
  zahl = 2;
  zahl = 5 * 8 * zahl;

  /*
   * Damit das ganze nöd so abstrakt isch gäbä mo dä Inhalt uf äm Bildschirm
   * us.
   */
  zeichechette0[3] = '\0';
  printf(zeichechette0);
  printf("\n\0");

  printf(zeichechette1);
  printf("\n\0");

  printf("zahl = %d\n\0", zahl);

  return(0);
}

      

Kapitel 3. Datetype

Schlüsselwörter

C kennt folgendi Grundtype void, char, short, int, float und double. Diä alli chönd vorgehend unsigned im Code oder i Dä Deklaration stoh ha, das würdi Bedütä, dass dä Typ nur im Positivä Berich liet. Dä Typ Integer (int) cha vorgehend s'Wort long (32 Bit) oder long long (64 Bit) ha. Globali Variable sind i allne Funktione sichtbar und werdät usserhalb vo Funktione definiert. Statischi Variable werdet mit static kennzeichnet. Söttigi Variable verlüred ihren Wert nöd noch äm Funktionsendi. Z'gueter letscht git äs au no Konstante const, sotigi Variable voändered sini Wert niä

Tabelle 3.1. Speicherbelegig

DatetypBitsBeschriebig
char 8 äs einzelns Zeiche, aber eigentlich au ä Ganzzahl
short 16 Ganzzahl
int 32 Ganzzahl
float 32 Flüsskommazahl
double 32 Flüsskommazahl

Mit ämnä Doppelpunkt mit änerä Zahl folgend cha d'Grössi i Bits explizit ageh werdä. int value:1; Das Bispiel definiert ä Variable wo eis Bit beinhalted.

Arrays

Vo allne Datetype cha mor Arrays alegä. Arrays sind Speicherblöck, wo än einheitliche Grundtyp besitzed. int arr[4]; würdi ä Array alegä vom Datetyp Integer, wobie das Array vier Integer beinhaltet. Uf äs Array grieft mo vo 0 a zue und i dem Fall wär 3 dä letscht Index. Arrays chönd beliebig viel Dimensionä ha.

Beispiel 3.1. Arrays

#include <string.h>

int
main(int argc, char **argv)
{
  int matrix[3][3]; // definiert ä zweidimensionals Array
  
  memset(matrix, 0, 9 * sizeof(int)); // setzt alli Arrayiträg uf 0

  return(0);
}

      

Unionä und Strukture

I C giets Unions und Struckturä, wo mit äm Schlüsselwort struct bezugswies union igleitet wird. Unmittelbar däno folgt dä Name vo dä Strucktur oder Union. Bi Unions wird lediglich das Element alloziiert wo am meiste Platz brucht, dodurch loht sich erahne, dass lediglich immer nur eis Element von ärä Union vowendet wird. Struckture hingäge leged so viel Speicher a wiä jedes einzelne Element brucht, dass heisst Element chönd glichzietig vowendät werdä. Optional cha vor äm schlüssende Semikolon än Variable Name stoh. Dä zuegriff uf Struktur- oder Union-Mitglieder gschieht mittels . oder -> bimne Zeiger uf ä Struktur.

Beispiel 3.2. Strukturä

#include <stdlib.h>

struct _StrukturName{
  /*
   * Memberbereich
   */
  int zahl;
}variable_name; // dä Variabläname isch optional

int
main(int argc, char **argv)
{
  struct _StrukturName *variable0; // do wird än Pointer deklariert, wo spöter uf än Speicherbereich zeigt
  struct _StrukturName variable1; // do wird ä Struktur deklariert

  variable_name.zahl = 0;
  
  variable0 = (struct _StrukturName *) malloc(sizeof(struct _StrukturName)); // d'Beschaffig vom Speicher
  variable0->zahl = 1;
  
  variable1.zahl = 2;
 
  return(0);
}

      

Enumerationä

A derä Stell werdet no enum behandelt, wobie das eigentlich kein richtige Datetyp isch, sondern ä Sprochkonstrukt zum automatisch z'nummerierä. Aber es cha trotzdem mit typedef vowendet werdä. Enumerationä werdät au hüfig verwendet, um Bitfelder azlegä, däbi mue mo aber d'Wert selber zuewisä.

Beispiel 3.3. Enumerationä

#include <stdio.h>

enum{
  MODUS_0,
  MODUS_1,
  MODUS_2,
  MODUS_3,
};

typedef enum{
  FLAG_1 = 1,
  FLAG_2 = 1 <<  1,
  FLAG_4 = 1 <<  2,
  FLAG_8 = 1 <<  3,
}Flags;

int
main(int argc, char **argv)
{
  printf("%d\n\0", MODUS_0);
  printf("%d\n\0", MODUS_1);
  printf("%d\n\0", MODUS_2);
  printf("%d\n\0", MODUS_3);

  printf("%x\n\0", FLAG_1);
  printf("%x\n\0", FLAG_2);
  printf("%x\n\0", FLAG_4);
  printf("%x\n\0", FLAG_8);

  return(0);
}

      

typedef

typedef wird verwendet um amne Typ än andere Name z'geh und wird üblicherwiis i de Header Dateie agwendet.

Beispiel 3.4. typedef

#include <stdlib.h>

typedef struct _MiniStruktur MiniStruktur;

struct _MiniStruktur{
  int zahl;
  char zeiche;
  char *zeiche_zeiger;
};

int
main()
{
  MiniStruktur *struktur0;
  MiniStruktur *struktur1;

  /* Ufwendigi Schriebwies */
  struktur0 = (struct _MiniStruktur *) malloc(sizeof(struct _MiniStruktur));

  struktur0->zahl = -1;
  struktur0->zeiche = 'a';
  struktur0->zeiche_zeiger = "Nullterminierte String (Zeichechettä)\0";

  /* Verchüerzti Schriebwies dank typedef */
  struktur1 = (MiniStruktur *) malloc(sizeof(MiniStruktur));

  struktur0->zahl = -1;
  struktur0->zeiche = 'b';
  struktur0->zeiche_zeiger = "Zeichechettä mit ämnä Unix-Zeileumbruch (Newline)\nund Nullterminiert\0";

  return(0);
}

      

Typumwandlig (cast)

Typumwandlig i C isch effektiv nur ä Typumwandlig und passiert uf primitiver Ebeni, aber wird au bi Objektcasts igsetzt i dä C Programmbibliothek glib-object. Än Cast ghört eigentlich scho zu dä Operatore, aber wird trotzdem scho do erlütered. Setz dä Typ zu dem du än Cast mache wötsch i rundi Chlamere und dämit isch es scho gscheh.

Beispiel 3.5. Cast

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

/*
 * Definition vo dä BasisStruktur
 */
struct BasisStruktur{
  int zahl;
  double zahl_mit_komma;
};

/*
 * Erwieterigä vo dä BasisStruktur
 */
struct ErweiterungA{
  struct BasisStruktur basis;

  double resultat;
};

struct ErweiterungB{
  struct BasisStruktur basis;

  int resultat;
};

/*
 * Ä Funktion wo vo dä Erwieterigä nüt wüsse wot
 */
void
zeig_mir_zahl(struct BasisStruktur *basis)
{
  printf("%d\n\0", basis->zahl);
}

/*
 * main Funktion
 */
int
main(int argc, char **argv)
{
  struct BasisStruktur *a;
  struct ErweiterungB *b;

  a = (struct BasisStruktur *) malloc(sizeof(struct ErweiterungA));
  a->zahl = -1;
  a->zahl_mit_komma = 2.0;
  ((struct ErweiterungA *) a)->resultat = 3.14;
  
  zeig_mir_zahl(a);

  b = (struct ErweiterungB *) malloc(sizeof(struct ErweiterungB));
  b->basis.zahl = 9;

  zeig_mir_zahl((struct BasisStruktur *) b);

  return(0);
}

      

Kapitel 4. Operatore

Inhaltsverzeichnis

Übersicht

Übersicht

I C giets grundlegendi arithmetischi Operatore für Addition, Subtraktion, Multiplikation und Division. Nebsch denä Operatore giet's au no bitwiesi Operatore Bitwises Oder, Exclusives Bitwises Oder, Bitwises Und und Bitinvertierigs Operator. Däzue chömed no d'Verglichsoperator gleich, ungleich, chliener als, chliener gleich, grösser als und grösser gleich.

Beispiel 4.1. Operatore

#include <stdio.h>

int
main(int argc, char **argv){
  int value;

  /* arithmetischi Operatore */
  value = 0;
  printf("value = 0; // ergiet %d\n\0", value);

  value = 2 + 4;
  printf("value = 2 + 4; // ergiet %d\n\0", value);

  value = 6 - 4;
  printf("value = 6 - 4; // ergiet %d\n\0", value);;

  value = 2 * 3;
  printf("value = 2 * 3; // ergiet %d\n\0", value);

  value = 8 / 2;
  printf("value = 8 / 2; // ergiet %d\n\0", value);

  /* bitwisi Operatorä mit Zahle i hexadezimaler Schriebwiis */
  value = 0x0 | 0xf;
  printf("value = 0x0 | 0xf; // ergiet %x\n\0", value);

  value = 0x1 & 0xf;
  printf("value = 0x1 & 0xf; // ergiet %x\n\0", value);

  value = 0x1 ^ 0xf;
  printf("value = 0x1 ^ 0xf; // ergiet %x\n\0", value);

  /* verglichs Operatorä */
  if(1 != 0) // ist 1 ungleich 0
    printf("1 != 0 ergiet richtig\n\0");

  if(2 == 2) // ist 2 gleich 2
    printf("2 == 2 ergiet richtig\n\0");

  if(2 < 4) // ist 2 kleiner als vier
    printf("2 < 4 ergiet richtig\n\0");

  if(!(2 > 4)) // ist nicht 2 grösser als 4 
    printf("!(2 > 4) ergiet richtig\n\0");

  value = (value + 2 > 1) ? 0: 1;
  printf("%d\n\0", value);

  // Verchnüpfigsoperatore
  if(2 < 4 && 3 == 3) // ist 2 kleiner als 4 und 3 gleich 3
    printf("2 < 4 && 3 == 3) ergiet richtig\n\0");

  if(2 > 4 || 3 == 3) // ist 2 grösser als 4 oder 3 gleich 3
    printf("2 > 4 && 3 == 3) ergiet richtig\n\0");


  return(0);
}


      

Nebscht denä giets au no d'Inkrement und d'Dekrement Operatorä value++ und value--, wo ä Variablä um eis erhöht bezugswiis um eis verchlinerät.

Kapitel 5. Bedingigsawiesigä

Inhaltsverzeichnis

Kontrollstruckture

Kontrollstruckture

I C giet's zwei Kontrollstruckture mit denä mo uf Wohrheit prüefä cha. Zerst aber öppis über Wohrheit: Än Wert isch als richtig definiert, wenn er ungleich 0 isch. Das heisst dä Wert 0 ergiet falsch. Diä erst Möglichkeit isch mit if, else if und else uf wohrheit z'prüefä und diä zweit mit switch und case.

Beispiel 5.1. Bedingigä

#include <stdio.h>

int
main(int argc, char **argv)
{
  int value;

  /*
   * das Bispiel wird immer diä gliech usgob mache, zum anderi Fäll z'erzüge
   * eifach dä variable value än andere Wert geh.
   */
  value = 0;

  /*
   * eini vo dene zwei Bedingig trifft immer i.
   */
  if(value){
    printf("Wenn value\n\0");
  }else if(!value){
    printf("Sust wenn ungleich value\n\0");
  }

  /*
   * Diä Bedingig hät än Fall wo itriet, wenn nüt anders itritt. Hier wärs wenn
   * value chliener als 10 isch
   */
  if(value < 10){
    printf("Wenn value chliener als 10\n\0");
  }else{
    printf("Sust\n\0");
  }
  
  /*
   *
   */
  switch(value){
  case 0:
    printf("Fall 0: Dä Fall tritt ih, wenn value gleich 0 isch und wird nochher Fall 1 au abarbeitä, will kei break awiesig folgt\n\0");
  case 1:
    printf("Fall 1: Dä Fall tritt ih, wenn value gleich 0 oder 1 isch\n\0");
   break;
  case 3:
    printf("Fall 3: Dä Fall tritt ih, wenn value gleich 3 isch\n\0");
    break;
    /*
     * Im folgende case chömed gad zwei Erwieterige, wo dä GNU C Compiler unterstützt:
     * S'einte isch dä Block (diä zwei gschweifte Chlammerä) innerhalb vom case wo
     * d'Funktion printf umschlüsst und s'andere isch dä Beriech wo d'case Bedingig
     * überprüeft.
     */
  case 4 ... 10:
    {
      printf("GNU C Erwieterig:\nFall 4 bis 10: Dä Fall tritt ih, wenn value zwüsched 4 und 10 liet.\0");
    }
    break;
  default:
    printf("Fall Standart: kein anderä Fall wär do iträtä");
  }

  return(0);
}

      

Kapitel 6. Schleifä

Inhaltsverzeichnis

Iterierä

Iterierä

Mit Schleifenä chan mor Struckturä oder Arrays bis ä bestimmti Bedingig itrifft Ablaufe. Äs isch au möglich Benützerigobä z'machä bis zunerä Abbruchsbedingig. Mit dä break awiesig cha mo anärä beliäbigi Stell innerhalb vo dä Schleife abbrächä.

Beispiel 6.1. Iterierä

#include <stdio.h>

int
main(int argc, char **argv)
{
  int i;

  for(i = 0; i < 10; i++){
    printf("%d\n\0", i);
  }
  
  while(i > 0){
    printf("%d\n\0", i);
    
    i--;
  }
  
  do{
    printf("%d\n\0", i);
    i++;
  }while(i < 10);
}

      

Kapitel 7. Sprüng

Inhaltsverzeichnis

Goto

Goto

Mittels sogenannte Labels (Sprungmarke) cham mo i C zumne beliebigä Ort innerhalb vonere Funktion springe. Däbi isch goto s'Schlüsselwort um än Sprung izleitä.

Beispiel 7.1. Goto

#include <stdio.h>

int
main(int argc, char **argv)
{
  goto label0;
  printf("Hallo Welt!\n\0");
 label0:
  printf("Hallo Welt stinkt!\n\0");

  return(0);
}

      

Kapitel 8. Zeiger

Referenzieren und Dereferenzieren

Mit äm kaufmännische Und & cham mo d'Speicheradresse ermittle. Im Gegesatz däzue cham mo mit ä Stärnli * än Pointer (Zeiger) dereferenzierä, das heisst uf diä erst Position zuegriffä. Än Zeiger zeigt also uf ä Speicheradresse.

Bi dä Deklaration vo Zeiger cha mo i dem mo i dä Variable Deklaration am Name äs Sternli voraa setzt *vektor. Vorgängig isch erklärt worde, dass Arrays beliebig viel Dimensione ha chönd, wobie d'Dimensione nur Zeiger uf än wieterä Zeiger isch.

***array3D isch än Zeiger uf än Zeiger uf än Zeiger, also äs drüdimensionals Array.

Kapitel 9. Programmierwerkzüüg

Inhaltsverzeichnis

gcc
ld
pkg-config
make

gcc

Diä eifachst verwendig vom GNU Compiler isch `gcc quelltext.c -o binäri_datei`. Objekt händ normalerwies dä Suffix "*.o", aber dä cha mo bi dä usführbar Datei au weg loh.

ld

Fals mo voschiedeni Objektdateie hät wo vonenand abhänged mue mo diä bevor mo s'Programm laufeloh cha mitenand volinkä dä Befehl däzue isch `ld -o usführbari_datei objekt0.o objekt1.o ... -lm`. Das Bispiel vo vorher hät au no ä volinkig mit dä Mathebibliothek erstellt -lm. Alternativ zum Befehl `ld` cha mo au `gcc` vowende um dä linker ufzrüefä, was viel eifacher isch.`gcc -o binäri_datei objekt0.o objekt1.o ... -lm`

pkg-config

`pkg-config` isch äs Programm mit dem include und library Pfäd usgeh werdä chönd. Äs folgend zwei Befehl, d'library und d'include Pfäd vo glib-2.0. glib isch ä Bibliothek einigi nützlichi Strukturä, sowiä Funktione zum manipuliere vo dene Strukture beinhaltet (eifach oder doppelt glinkti Listä, threads, ...).

Beispiel 9.1. Simple

pkg-config --libs glib-2.0
pkg-config --cflags glib-2.0

      

Mit äm Substitutionszeiche (`) igfasst, chan mit Bash (Standardkommandoziileprogramm uf GNU/Linux), library und include Pfäd direkt uf einerä Zeilä notiert werdä.

Beispiel 9.2. Substitution

gcc -o personalien_konsole personalien.o konsole.o `pkg-config --libs glib-2.0`

      

make

`make` isch äs Programm zum sammle und usfüäre vo Compiler ufrüef. D'Datei mue Makefile heisse, damit sie `make` findet. Ä Bispiel Makefile Datei chönti so usgseh:

Beispiel 9.3. Makefile

CC = gcc

SOURCES = $(wildcard *.[ch])

OBJECTS = konsole.o personalien.o

personalien_konsole: $(OBJECTS)
	$(CC) -g -o personalien_konsole $(OBJECTS) -ldl

.c.o: $(SOURCES)
	$(CC) -g -c $< -o $@

      

Immenä Makefile sind das vorem : targets (Ziel) wo us dä Kommandozielä ufgruefe werde chönd. `make clean` würdi alli Binär Dateie lösche.

Kapitel 10. Personalien Programm

Header Datei - personalien

Als erstes schriebä mo ä header Datei wo äs Makro besitzt, än Typ Personalien definiert und ä Enumeration definiert. Druff folgt ä Struktur und ä deklaration vo zwei Funktione. Alles wo do i därä Header Datei definiert oder deklariert wird, cha überall vowendet werde wo diä Header Datei mittels #include "personalien.h" (falls im Glieche Vozeichnis) ibunde wird. Oder suscht mit <personalien/personalien.h> falls äm Compiler mitteilt worde isch wo sich diä izubindende Dateie befindet z.B. `gcc -g -c personalien.c -o personalien.o -I/home/benutzername/sources/`.

Beispiel 10.1. personalien.h

#ifndef __PERSONALIEN_H__
#define __PERSONALIEN_H__

typedef struct _Personalien Personalien;

typedef enum{
  PERSONALIEN_M  = 1,
  PERSONALIEN_W  = 1 <<  1,
}PersonalienFlags;

struct _Personalien
{
  unsigned int flags;

  char *vorname;
  char *nachname;
  char *strasse;
  int hausnummer;
  char *ort;
  int postleitzahl;
  char *email;
  int telefon_nummer;
};

void personalien_zeige(Personalien *personalien);

Personalien* personalien_neu();

#endif /*__PERSONALIEN_H__*/

      

Programmcode - personalien

Beispiel 10.2. personalien.c

#include "personalien.h"

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

void personalien_init();

void
personalien_init(Personalien *personalien)
{
  personalien->flags = 0;
  personalien->vorname = NULL;
  personalien->nachname = NULL;
  personalien->strasse = NULL;
  personalien->hausnummer = 0;
  personalien->ort = NULL;
  personalien->postleitzahl = 0;
  personalien->email = NULL;
  personalien->telefon_nummer = 0;
}

void
personalien_zeige(Personalien *personalien)
{
  fprintf(stdout, "%s\n%s\n%s\n%d\n%s\n%d\n%s\n%d\n\0",
	  personalien->vorname,
	  personalien->nachname,
	  personalien->strasse,
	  personalien->hausnummer,
	  personalien->ort,
	  personalien->postleitzahl,
	  personalien->email,
	  personalien->telefon_nummer);
}

Personalien*
personalien_neu()
{
  Personalien *personalien;

  personalien = (Personalien *) malloc(sizeof(Personalien));
  personalien_init(personalien);

  return(personalien);
}

      

Header Datei - konsole

Beispiel 10.3. konsole.h

#ifndef __KONSOLE_H__
#define __KONSOLE_H__

#include <stdio.h>

#include "personalien.h"

typedef struct _Konsole Konsole;

struct _Konsole
{
  Personalien *personalien;
  char *name;
  FILE *datei;
};

#endif /*__KONSOLE_H__*/

      

Programmcode - konsole

Beispiel 10.4. konsole.c

#include "konsole.h"

#include <stdlib.h>

void konsole_init(Konsole *konsole);
void konsole_neue_personalien(Konsole *konsole);
void konsole_zeige_personalien_nach_index(Konsole *konsole, int index);
void konsole_zeige_personalien_nach_feld(Konsole *konsole, int nth, char *text);

void
konsole_init(Konsole *konsole)
{
  konsole->personalien = personalien_neu();
  konsole->name = NULL;
  konsole->datei = NULL;
}

void
konsole_neue_personalien(Konsole *konsole)
{
  int wert;
  char *zeichenkette;

  /* zerst s'erfassä vo dä Datä */
  printf("enter firstname: \0");
  zeichenkette = (char *) malloc(256 * sizeof(char));
  scanf("%s\0", zeichenkette);
  konsole->personalien->vorname = zeichenkette;

  printf("enter surname: \0");
  zeichenkette = (char *) malloc(256 * sizeof(char));
  scanf("%s\0", zeichenkette);
  konsole->personalien->nachname = zeichenkette;

  printf("enter street: \0");
  zeichenkette = (char *) malloc(256 * sizeof(char));
  scanf("%s\0", zeichenkette);
  konsole->personalien->strasse = zeichenkette;

  printf("enter housenumber: \0");
  scanf("%d\0", &wert);
  konsole->personalien->hausnummer = wert;

  printf("enter city: \0");
  zeichenkette = (char *) malloc(256 * sizeof(char));
  scanf("%s\0", zeichenkette);
  konsole->personalien->ort = zeichenkette;

  printf("enter postcode: \0");
  scanf("%d\0", &wert);
  konsole->personalien->postleitzahl = wert;

  printf("enter email: ");
  zeichenkette = (char *) malloc(256 * sizeof(char));
  scanf("%s\0", zeichenkette);
  konsole->personalien->email = zeichenkette;

  printf("enter telephone number: ");
  scanf("%d\0", &wert);
  konsole->personalien->telefon_nummer = wert;

  /* jetzt chunt s'schrieb vo dä Datä i d'Datei */
  fprintf(konsole->datei, "%s\n\0", konsole->personalien->vorname);
  fprintf(konsole->datei, "%s\n\0", konsole->personalien->nachname);
  fprintf(konsole->datei, "%s\n\0", konsole->personalien->strasse);
  fprintf(konsole->datei, "%d\n\0", konsole->personalien->hausnummer);
  fprintf(konsole->datei, "%s\n\0", konsole->personalien->ort);
  fprintf(konsole->datei, "%d\n\0", konsole->personalien->postleitzahl);
  fprintf(konsole->datei, "%s\n\0", konsole->personalien->email);
  fprintf(konsole->datei, "%d\n\0", konsole->personalien->telefon_nummer);
  fflush(konsole->datei);
}

void
konsole_zeige_personalien_bei_index(Konsole *konsole, int index)
{
  Personalien personalien;
  unsigned int i;

  fseek(konsole->datei, 0, SEEK_SET);
  
  for(i = 0; i < index; i++){
    fscanf(konsole->datei, "%s\n%s\n%s\n%d\n%s\n%d\n%s\n%d\n\0",
           &konsole->personalien->vorname,
           &konsole->personalien->nachname,
           &konsole->personalien->strasse,
           &konsole->personalien->hausnummer,
           &konsole->personalien->ort,
     	   &konsole->personalien->postleitzahl,
    	   &konsole->personalien->email,
    	   &konsole->personalien->telefon_nummer);
  }
}

void
konsole_zeige_personalien_bei_feld(Konsole *konsole, int nth, char *text)
{
  Personalien personalien;
  char *separator = "  -------  ";
  int return_value;

  fseek(konsole->datei, 0, SEEK_SET);
  
  while(!0){
    return_value = fscanf(konsole->datei, "%s\n%s\n%s\n%d\n%s\n%d\n%s\n%d\n\0",
			  &konsole->personalien->vorname,
			  &konsole->personalien->nachname,
			  &konsole->personalien->strasse,
			  &konsole->personalien->hausnummer,
			  &konsole->personalien->ort,
			  &konsole->personalien->postleitzahl,
			  &konsole->personalien->email,
			  &konsole->personalien->telefon_nummer);
    
    switch(nth){
    case 0:
      if(!strcmp(konsole->personalien->vorname, text)){
	fprintf(stdout, "%s\n\0", separator);
	personalien_zeige(konsole->personalien);
	fprintf(stdout, "%s\n\0", separator);
      }
      break;
    case 1:
      if(!strcmp(konsole->personalien->nachname, text)){
	fprintf(stdout, "%s\n\0", separator);
	personalien_zeige(konsole->personalien);
	fprintf(stdout, "%s\n\0", separator);
      }
      break;
    case 2:
      if(!strcmp(konsole->personalien->strasse, text)){
	fprintf(stdout, "%s\n\0", separator);
	personalien_zeige(konsole->personalien);
	fprintf(stdout, "%s\n\0", separator);
      }
      break;
    case 3:
      if(konsole->personalien->hausnummer == atoi(text)){
	fprintf(stdout, "%s\n\0", separator);
	personalien_zeige(konsole->personalien);
	fprintf(stdout, "%s\n\0", separator);
      }
      break;
    case 4:
      if(!strcmp(konsole->personalien->ort, text)){
	fprintf(stdout, "%s\n\0", separator);
	personalien_zeige(konsole->personalien);
	fprintf(stdout, "%s\n\0", separator);
      }
      break;
    case 5:
      if(konsole->personalien->postleitzahl == atoi(text)){
	fprintf(stdout, "%s\n\0", separator);
	personalien_zeige(konsole->personalien);
	fprintf(stdout, "%s\n\0", separator);
      }
      break;
    case 6:
      if(!strcmp(konsole->personalien->email, text)){
	fprintf(stdout, "%s\n\0", separator);
	personalien_zeige(konsole->personalien);
	fprintf(stdout, "%s\n\0", separator);
      }
      break;
    case 7:
      if(konsole->personalien->telefon_nummer == atoi(text)){
	fprintf(stdout, "%s\n\0", separator);
	personalien_zeige(konsole->personalien);
	fprintf(stdout, "%s\n\0", separator);
      }
      break;
    }
  }
}

int
main(int argc, char **argv)
{
  Konsole *konsole;
  char *zeichenkette;
  int wert;

  konsole = (Konsole *) malloc(sizeof(Konsole));
  konsole_init(konsole);

  /*
   * Falls du `gcc` unter Windows vowändisch, söttisch
   * diä folgendi Zeilä uskommentierä, das erlaubt
   * dir mittels scanf än 256 Zeichä lange String uszläsä.
   * Sötteds meh si, passiert än Bufferoverflow und
   * s'Programm stürzt ab! Beachte, das Strings Nullterminiert
   * si mönd!
   * Bufferoverflows werdet däzue vowendet i System izbrechä.
   */
  zeichenkette = (char *) malloc(256 * sizeof(char));


  if(argc == 1){
    konsole->datei = fopen("default\0", "w+\0");
  }else if(argc == 2){
    konsole->datei = fopen(argv, "a+\0");
  }else
    printf("the konsole takes at most 1 argument\n\0");

  while(!0){
    printf("> \0");
    scanf("%256[^\n]%*[^\n]\0", zeichenkette);
    getchar();

    if(!strncmp(zeichenkette, "quit\0", 4))
      break;
    else if(!strncmp(zeichenkette, "new\0", 3))
      konsole_neue_personalien(konsole);
    else if(!strncmp(zeichenkette, "show\0", 4)){
     main0:

      fprintf(stdout, "[0] - index\n\0");
      fprintf(stdout, "[1] - firstname\n\0");
      fprintf(stdout, "[2] - surname\n\0");
      fprintf(stdout, "[3] - street\n\0");
      fprintf(stdout, "[4] - house number\n\0");
      fprintf(stdout, "[5] - city\n\0");
      fprintf(stdout, "[6] - post code\n\0");
      fprintf(stdout, "[7] - email\n\0");
      fprintf(stdout, "[8] - telephone number\n\0");
      fprintf(stdout, "[9] - exit");
      fprintf(stdout, "enter number: \0");

      scanf("%d\n\0", &wert);

      switch(wert){
        case 0:
          fprintf(stdout, "enter index: \0");
          scanf("%d\n\0", &wert);
          konsole_zeige_personalien_bei_index(konsole, wert);
          break;
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
          fprintf(stdout, "enter search criteria: \0");
          scanf("%s\0", &zeichenkette);
          konsole_zeige_personalien_bei_feld(konsole, wert - 1, zeichenkette);
          break;
        case 9:
          break;
        default:
          fprintf(stdout, "you didn't enter a number between 0 and 9\n\0");
          goto main0;
	  }
    }else
      fprintf(stdout, "enter \"quit\", \"new\" or \"show\"\n");
  }

  fclose(konsole->datei);
  free(konsole->personalien);
  free(konsole);

  return(0);
}

      

Kapitel 11. Strings

deklarierä und initialisiere

Strings oder au Zeichechettä gnannt werdet verwendet um eifache Text darzstellä. Strings sind i C än zämmehängende Speicher vo Zeiche, sprich äs Character-Array. Diä wiederum händ dä Datetyp char.

Strings sötted generell nullterminiert sii. So än String macht mor mittels dä Escape-Sequenz '\0', aber grundsätzlich sötti mor sich nöd druf verloh das er konform isch und eigentlich nur diä Stringfunktione vowendä, wo d'Längi als Parameter entgägä nämed.

Im folgende Bispiel werdet diä voschiedene Erstelligsarte für Strings ufzeigt.

Beispiel 11.1. strings.c

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

/* Deklaration und Initialisierig */
char string0[] = {
  'H',
  'e',
  'l',
  'l',
  'o',
  ',',
  '\n',
  '\0',
};

char *string1 = "how are you?\n\0";

char string2[15];

int ascii_ziffer_0 = 48;
char *string3 = NULL;

/* Main-Funktion */
int
main(int argc, char **argv)
{
  char *string3_i;
  int i;
  char ziffer;

  /* Ufruef vo dä printf Funktion zur Usgob vo dä Variable string0 */
  printf(string0);

  /*
   * Dä folgendi Programmcode giet au än String uf dä Konsole us.
   * Diä Schleife wird abgarbeited bis im String d'Escape-Sequenz '\0'
   * uftritt.
   * Innerhalb vo dä Schleife wird d'Funktion putc ufgruefä. Diä giet äs
   * Zeiche inne Datei us und i dem Fall isch d'Datei diä global Variable stdout.
   * D'Datei "/dev/stdout" isch i Unix artige Betriebssystem für konsolebasierti
   * Textusgob.
   */
  for(i = 0; string1[i] != '\0'; i++){
    putc(string1[i], stdout);
  }
  
  /* Ufruef vo dä fprintf Funktion zur Usgob vo dä Variable string2 */
  string2[0] = 'G';
  string2[1] = 'n';
  string2[2] = 'u';
  string2[3] = '\'';
  string2[4] = 's';
  string2[5] = ' ';
  string2[6] = 'N';
  string2[7] = 'o';
  string2[8] = 't';
  string2[9] = ' ';
  string2[10] = 'U';
  string2[11] = 'n';
  string2[12] = 'i';
  string2[13] = 'x';
  string2[14] = '\0';
 
  fprintf(stdout, string2);
  printf("\n\0");

  /*
   * Dä Speicher vo string3 wird zur Laufziet mittels malloc beschaffe.
   * Diä Variable isch zuvor mit äm NULL Pointer initialisiert worde, aber 
   * nochdem dä Speicher alloziiert worde isch chömmer dä Speicher mit Date
   * fülle.
   * I dem Bispiel mit dä Zahle 0 bis 9 und dä Escape Sequenz '\0' am Schluss.
   * UTF-8 isch abwärtskompatible zum ASCII Zeichesatz, aber falls än andere
   * Zeichesatz vowendet wird giet das Bispiel sehr worschienlich 10 anderi Zeiche
   * us.
   */
  string3 = (char *) malloc(11 * sizeof(char));
  
  for(string3_i = string3, ziffer = ascii_ziffer_0; string3_i <= string3 + 10; string3_i++, ziffer++){
    *string3_i = ziffer;
  }
  
  string3[10] = '\0';
  printf(string3);
  printf("\n\0");
  
  /* programm Endi */
  return(0);
}

      

Kapitel 12. Stringfunktione

Inhaltsverzeichnis

Übersicht
strings.h
string.h

Übersicht

strings.h

int strcasecmp(const char *s1, const char *s2);

Zeichechetti uf gliechheit überprüfe ohne Rücksichtnahm uf Gross- und Chliischriebig.

int strncasecmp(const char *s1, const char *s2, size_t n);

Die erste n Zeiche vonere Zeichechetti uf gliechheit überprüfe ohne Rücksichtnahm uf Gross- und Chliischriebig.

char* index(const char *s, int c);

S'erste Uftrettä vom Zeiche c inere Zeichechettä.

char *rindex(const char *s, int c);

S'letschte Uftrettä vom Zeiche c inere Zeichechettä.

string.h

char *strcat(char *dest, const char *src);

Hängt ein String an andere a.

char *strchr(const char *s, int c);

Suecht imne String noch äm erste vorkomme vomne Zeiche c.

int strcoll(const char *s1, const char *s2);

Überprüeft zwei Strings uf gliechheit, wobie diä momentan Locale verwendet wird.

char *strcpy(char *ziil, const char *quellä);

Kopiert ein String inne andere String.

size_t strcspn(const char *s, const char *reject);

Suecht nochem erste vorkomme vordefinierter Zeiche, wobi reject enthaltet Zeiche wo nöd vorcho dörfed.

char *strdup(const char *s);

Dupliziert än String.

char *strfry(char *string);

Füllt än String mit züäfällige Zeiche.

size_t strlen(const char *s);

Gibt längi vomnä String zrugg.

char *strncat(char *dest, const char *src, size_t n);

Hängt n zeich vomne String an än andere a.

char *strncpy(char *ziil, const char *quellä, size_t n);

Kopiert n Zeiche vo einem String i än andere.

char *strpbrk(const char *s, const char *accept);

Suecht nochem erste vorkomme vordefinierter Zeiche, wobi accept enthaltet Zeiche wo vorcho dörfed.

char *strrchr(const char *s, int c);

Findet s'letschtä vorkomme vom Zeiche c.

char *strsep(char **stringp, const char *delim);

Findet s'erste Token i stringp und delimitiert es mit delim und giet än Pointer uf s'erste Vorkomme vom Token zrugg.

size_t strspn(const char *s, const char *accept);

Suecht nochem erste vorkomme vordefinierter Zeiche, wobi accept enthaltet Zeiche wo vorcho dörfed.

char *strstr(const char *haystack, const char *needle);

suecht noch ämnä Substring (än String im String)

char *strtok(char *s, const char *delim);

Extrahiert Tokens vomne String, wobie delim begrenzt d'Uswahl.

size_t strxfrm(char *dest, const char *src, size_t n);

Nicht dokumentiert.

Kapitel 13. Formatierti I-/Usgob

Inhaltsverzeichnis

Übersicht
stdio.h
stdarg.h

Übersicht

stdio.h

int fgetc(FILE *stream);

Zeiche usemne Stream läsä.

char *fgets(char *s, int size, FILE *stream);

Ä Zeile usemne Stream läsä.

int getc(FILE *stream);

Zeichebasierti Iigob usemne Stream.

int getchar(void);
Zeichebasierti Iigob ufem Terminal.

char *gets(char *s); (veraltet)

Zeile us dä Standardiigob läsä.

int ungetc(int c, FILE *stream);

Stream um äs Zeiche zruggsetze.

int printf(const char *format, ...);

Formatierti Usgob uf Standardusgob.

int fprintf(FILE *stream, const char *format, ...);

Formatierti Usgob in Stream.

int sprintf(char *str, const char *format, ...);

Formatierti Usgob in än String.

int snprintf(char *str, size_t size, const char *format, ...);

Formatierti Usgob in än String unter berücksichtigung vo dä String längi.

stdarg.h

int vprintf(const char *format, va_list ap);

Variadict printf.

int vfprintf(FILE *stream, const char *format, va_list ap);

int vsprintf(char *str, const char *format, va_list ap);

Variadict sprintf.

int vsnprintf(char *str, size_t size, const char *format, va_list ap);

Variadict snprintf.

Kapitel 14. Mathe

Ileitig

Damit mo d'Mathe Bibliothek vowende cha mue mo näbed ä include vo math.h au no am Linker mitteile mittels -lm als Parameter bim ufruef vom Compiler. Äs folged Usschnitt us dä Header-Datei math.h

Konstante

Konstante us dä Mathematik befindet sich i math.h.

Beispiel 14.1. math.h

#if defined __USE_BSD || defined __USE_XOPEN
# define M_E            2.7182818284590452354   /* e */
# define M_LOG2E        1.4426950408889634074   /* log_2 e */
# define M_LOG10E       0.43429448190325182765  /* log_10 e */
# define M_LN2          0.69314718055994530942  /* log_e 2 */
# define M_LN10         2.30258509299404568402  /* log_e 10 */
# define M_PI           3.14159265358979323846  /* pi */
# define M_PI_2         1.57079632679489661923  /* pi/2 */
# define M_PI_4         0.78539816339744830962  /* pi/4 */
# define M_1_PI         0.31830988618379067154  /* 1/pi */
# define M_2_PI         0.63661977236758134308  /* 2/pi */
# define M_2_SQRTPI     1.12837916709551257390  /* 2/sqrt(pi) */
# define M_SQRT2        1.41421356237309504880  /* sqrt(2) */
# define M_SQRT1_2      0.70710678118654752440  /* 1/sqrt(2) */
#endif

      

Konstante - GNU Erwieterig

Diä vorhergehende Konstante sind nöd adequat für berechnige mit long double Variable.

Beispiel 14.2. math.h

#ifdef __USE_GNU
# define M_El           2.7182818284590452353602874713526625L  /* e */
# define M_LOG2El       1.4426950408889634073599246810018921L  /* log_2 e */
# define M_LOG10El      0.4342944819032518276511289189166051L  /* log_10 e */
# define M_LN2l         0.6931471805599453094172321214581766L  /* log_e 2 */
# define M_LN10l        2.3025850929940456840179914546843642L  /* log_e 10 */
# define M_PIl          3.1415926535897932384626433832795029L  /* pi */
# define M_PI_2l        1.5707963267948966192313216916397514L  /* pi/2 */
# define M_PI_4l        0.7853981633974483096156608458198757L  /* pi/4 */
# define M_1_PIl        0.3183098861837906715377675267450287L  /* 1/pi */
# define M_2_PIl        0.6366197723675813430755350534900574L  /* 2/pi */
# define M_2_SQRTPIl    1.1283791670955125738961589031215452L  /* 2/sqrt(pi) */
# define M_SQRT2l       1.4142135623730950488016887242096981L  /* sqrt(2) */
# define M_SQRT1_2l     0.7071067811865475244008443621048490L  /* 1/sqrt(2) */
#endif

      

Übersicht

Runde

double ceil(double x);

Ufrunde.

float ceilf(float x);

Ufrunde.

long double ceill(long double x);

Ufrunde.

double floor(double x);

Abrunde.

float floorf(float x);

Abrunde.

long double floorl(long double x);

Abrunde.

double round(double x);

Runde.

float roundf(float x);

Runde.

long double roundl(long double x);

Runde.

Exponentialfunktione

double exp2(double x);

Zweierpotenz.

float exp2f(float x);

Zweierpotenz.

long double exp2l(long double x);

Zweierpotenz.

double exp(double x);

Potenz zur Basis der eulerschen Zahl.

float expf(float x);

Potenz zur Basis der eulerschen Zahl.

long double expl(long double x);

Potenz zur Basis der eulerschen Zahl.

double sqrt(double x);

Quadratwurzel.

float sqrtf(float x);

Quadratwurzel.

long double sqrtl(long double x);

Quadratwurzel.

Logarithme

double log(double x);

Natürlicher Logarithmus.

float logf(float x);

Natürlicher Logarithmus.

long double logl(long double x);

Natürlicher Logarithmus.

double log2(double x);

Zweier Logarithmus.

float log2f(float x);

Zweier Logarithmus.

long double log2l(long double x);

Zweier Logarithmus.

double log10(double x);

Zehner Logarithmus.

float log10f(float x);

Zehner Logarithmus.

long double log10l(long double x);

Zehner Logarithmus.

Kreisfunktione

double sin(double x);

Sinus.

float sinf(float x);

Sinus.

long double sinl(long double x);

Sinus.

double cos(double x);

Cosinus.

float cosf(float x);

Cosinus.

long double cosl(long double x);

Cosinus.

double tan(double x);

Tangens.

float tanf(float x);

Tangens.

long double tanl(long double x);

Tangens.

Kapitel 15. Kommentär

Inhaltsverzeichnis

Gtk-Doc

Gtk-Doc

Dä folgendi Code isch äs interaktivs Konsoleprogramm, wo ä Primfaktorzerlegig macht, um dä GGT und s'KGV z'berechne. Unteranderem chömed au spezielli Kommentar vor, wo mit GTK-Doc i Docbook XML umgwandelt werdä cha. Docbook XML isch konvertierbar i voschiedensti Format, wiä PDF, Postscript, HTML, ... Mit därä Notation chönd API-Referenze erstellt werdä.

Beispiel 15.1. Primzahle

/* prim_factors
 * Copyright (C) 2012 Joël Krähemann
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <strings.h>

/**
 * is_prim:
 * @x ein Integer
 * Returns: 1 wenn es eine Primzahl ist, sonst 0.
 *
 * Ermittelt, ob die zahl @x eine Primzahl ist.
 */
int
is_prim(int x)
{
  int i;

  if (x == 2){
    return(1);
  }
  
  for (i = 3; i <= sqrt(x); i += 2){
    if (x % i == 0){
      return 0;
    }
  }

  return 1;
}

/**
 * prim_factors:
 * @x ein Integer
 * @factors ein Zeiger auf einen Zeiger, in dem die Faktoren gespeichert werden
 * @count ein Zeiger auf einen Integer, der die Anzahl Faktoren enthalten wird
 */
void
prim_factors(int x, int **x_factors, int *count)
{
  int *factors;
  int current_x;
  int i, n_factors;

  if(x < 2){
    *x_factors = NULL;
    *count = 0;
  }

  current_x = x;

  factors = NULL;
  n_factors = 0;

  for (i = 2; current_x != 0 && current_x - i != 0; ){
    if(!is_prim(i)){
      i++;
      continue;
    }

    if ((current_x % i) == 0){
      current_x /= i;

      n_factors++;
      factors = (int *) realloc(factors, n_factors * sizeof(int));
      factors[n_factors - 1] = i;
    }else{
      i++;
    }
  }

  if(current_x != 0){
    n_factors++;
    factors = (int *) realloc(factors, n_factors * sizeof(int));
    factors[n_factors - 1] = i;
  }

  *x_factors = factors;
  *count = n_factors;
}


/**
 * ggt:
 * @a ein Integer
 * @b ein Integer
 * Returns: Gibt den GGT zurück.
 *
 * Ermittelt den grössten gemeinsamen Teiler der beiden Zahlen @a und @b.
 */

int
ggt(int a, int b)
{
  int result;
  int *a_prims, *b_prims;
  int count_a, count_b;
  int i0, i1;

  if(a == b){
    return(a);
  }

  result = 1;

  prim_factors(a, &a_prims, &count_a);
  prim_factors(b, &b_prims, &count_b);

  i0 = 0;
  i1 = 0;

  while(i0 < count_a && i1 < count_b){
    if(a_prims[i0] == b_prims[i1]){
      result *= a_prims[i0];

      i1++;
    }else if(a_prims[i0] > b_prims[i1]){
      while(i1 < count_b && a_prims[i0] > b_prims[i1]){
	i1++;
      }
    }

    i0++;
  }

  if (result == 1 && (a != 1 || b != 1)){
    result = 1;
  }else if(result == a && (b % a != 0)){
    result = 1;
  }else if (result == b && (a % b != 0)){
    result = 1;
  }

  return(result);
}

/**
 * kgv:
 * @a ein Integer
 * @b ein Integer
 * Returns: Gibt das KGV zurück.
 *
 * Ermittelt das kleinste gemeinsame Vielfache der beiden Zahlen <paramref name="a"/> und <paramref name="b"/>.
 */
int
kgv(int a, int b){
  int result;
  int *a_prims, *b_prims;
  int count_a, count_b;
  int i0, i1;

  result = 1;

  prim_factors(a, &a_prims, &count_a);
  prim_factors(b, &b_prims, &count_b);

  i0 = 0;
  i1 = 0;

  while(i0 < count_a && i1 < count_b){
    if(a_prims[i0] == b_prims[i1]){
      result *= a_prims[i0];
      
      i0++;
      i1++;
    }else if(a_prims[i0] > b_prims[i1]){
      while(i1 < count_b && a_prims[i0] > b_prims[i1]){
	result *= b_prims[i1];

	i1++;
      }
    }else{
      result *= a_prims[i0];
      i0++;
    }
  }

  while(i0 != count_a){
    result *= a_prims[i0];

    i0++;
  }

  while(i1 < count_b){
    result *= b_prims[i0];

    i1++;
  }

  if(result == 1 && (a != 1 || b != 1)){
    result = 0;
  }

  return (result);
}

/**
 * write_line_and_read_int:
 * @message Die Nachricht, die vor der Zahlen eingabe erscheint (z.B. Zahl 1:).
 * Returns: Gibt eine int Zahl zurück.
 *
 * Gibt die Nachricht @message auf dem Bildschirm aus. Dann
 * liest es von der Standardeingabe bis ein Enter Schlag geschieht.
 * Die oberen zwei Befehle werden ausgeführt, bis eine gültig Integer Zahl eingegeben wurde.
 */
int
write_line_and_read_int(char *message)
{
  int a;
  int successfully_readed;

  a = 0;
  successfully_readed = 0;

  while(successfully_readed != 1){
    printf(message);
    successfully_readed = scanf("%d\0", &a);
  }

  return (a);
}


void
main(int argc, char **argv)
{
  char *command;
  int a, b;
  int result;
  int successfully_readed;

  printf("Hallo, das ist das Bruch Programm.\n\0");
  printf("Hiermit können Sie den GGT oder das KGV berechnen lassen.\n\0");

  command = malloc(1024 * sizeof(char));
  successfully_readed = 0;

  while(!0){
    bzero(command, 1024);
    
    printf("Geben Sie \"GGT\" oder \"KGV\" mit ihrer Tastatur ein.\n\0");
    printf("Sie werden dann aufgefordert zwei Zahlen einzugeben!\n\0");
    printf("Oder geben Sie \"beenden\" ein, um das Programm zu schliessen.\n\0");
    
    while(successfully_readed != 1){
      printf("> \0");
      successfully_readed = scanf("%s\0", command);
    }

    successfully_readed = 0;

    if(!strcmp("beenden\0", command)){
      break;
    }else if(!strcmp("KGV\0", command)){
      printf("Sie werden nun aufgefordert zwei Zahlen einzugeben Bestätigen Sie jede Zahl mit Enter.\n\0");

      a = write_line_and_read_int("Zahl 1: \0");
      b = write_line_and_read_int("Zahl 2: \0");
      
      result = kgv(a, b);
      
      printf("Das KGV von %d und %d beträgt: %d\n\0", a, b, result);
    }else if (!strcmp("GGT", command)){
      printf("Sie werden nun aufgefordert zwei Zahlen einzugeben Bestätigen Sie jede Zahl mit Enter.\n\0");
      
      a = write_line_and_read_int("Zahl 1: \0");
      b = write_line_and_read_int("Zahl 2: \0");

      result = ggt(a, b);
      
      printf("Der GGT von %d und %d beträgt: %d\n\0", a, b, result);
    }else{
      printf("Tut mir leid, habe Ihre Eingabe nicht verstanden.\n\0");
    }
  }
  
  printf("Aufwiedereingeben!\n\0");
}

      

Kapitel 16. Gtk+

Inhaltsverzeichnis

Offscreen rendering

Offscreen rendering

draw_wave.c screenshot

Das Bispiel vowendet sin und cos Funktione um sie graphisch mittels cairo und Gtk+-2.0 darzstellä. Links isch än Screenshot vo dem Fenster wo das Programm erzügt. Was viellicht nöd gad so offesichtlich isch, isch dass cairo für RGB24 Farbe nöd wiä erwarted 3 Byte alegt, sondern 4 Byte langi Felder.

A därä Stell wird zum erste mol mit Gtk+ uf Fensterebeni gschaffet. Setzt aber vorus, dass pkg-config und d'Entwicklerdateie vo Gtk+ installiert sind.

Zum compiliere folgendes im Terminal usführe: gcc draw_wave.c -o draw_wave `pkg-config --libs --cflags gtk+-2.0` -lm

Das Programm cha mit folgendem Befehl i dä Bash (Kommandoziilä) gstarted werdä: ./draw_wave

Beispiel 16.1. GdkPixbuf - Sinus & Cosinus zeichne

/* draw_wave
 * Copyright (C) 2012 Joël Krähemann
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <gtk/gtk.h>
#include <math.h>
#include <stdlib.h>

static cairo_surface_t *sine_surface = NULL;
static cairo_surface_t *cosine_surface = NULL;

static unsigned int RED_PIXEL = 255 << 16;
static unsigned int GREEN_PIXEL = 255 << 8;
static unsigned int BLUE_PIXEL = 255;
static unsigned int WHITE_PIXEL;

static int STRIDE;

void
window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
  /* leave main loop */
  gtk_main_quit();
}

void
sine_drawing_area_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
  GdkWindow *window;
  cairo_t *cr;

  /* create cairo context */
  window = gtk_widget_get_window(widget);
  cr = gdk_cairo_create(window);

  /* do painting */
  cairo_set_source_surface(cr, sine_surface, 0, 0);
  cairo_surface_mark_dirty(sine_surface);
  cairo_paint(cr);
}

void
cosine_drawing_area_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
  GdkWindow *window;
  cairo_t *cr;

  /* create cairo context */
  window = gtk_widget_get_window(widget);
  cr = gdk_cairo_create(window);

  /* do painting */
  cairo_set_source_surface(cr, cosine_surface, 0, 0);
  cairo_surface_mark_dirty(cosine_surface);
  cairo_paint(cr);
}

void
putpixel(unsigned char *data, int x, int y, unsigned long int pixel)
{
  int bpp = 4; // STRIDE / 400;
  /* Here p is the address to the pixel we want to set */
  unsigned char *p = data + y * STRIDE + x * bpp;

  switch(bpp) {
  case 1:
    *p = pixel;
    break;

  case 2:
    *(unsigned short int *)p = pixel;
    break;

  case 3:
      p[0] = pixel & 0xff;
      p[1] = (pixel >> 8) & 0xff;
      p[2] = (pixel >> 16) & 0xff;
    break;

  case 4:
    *(unsigned long int *)p = pixel;
    break;
  }
}

void
draw_sine(cairo_surface_t *surface)
{
  unsigned char *data;
  double value;
  int offset;
  int i;

  data = cairo_image_surface_get_data(surface);

  for(i = 0; i < 400; i++){
    value = sin(((double) i / 400.0) * 2.0 * M_PI - M_PI) * 100.0;
    

    putpixel(data, i, 100 + (int) floor(value), WHITE_PIXEL);
  }

  cairo_surface_flush(surface);
}

void
draw_cosine(cairo_surface_t *surface)
{
  unsigned char *data;
  double value;
  int offset;
  int i;

  data = cairo_image_surface_get_data(surface);

  for(i = 0; i < 400; i++){
    value = cos(((double) i / 400.0) * 2.0 * M_PI + M_PI) * 100.0;

    putpixel(data, i, 100 + (int) floor(value), WHITE_PIXEL);
  }

  cairo_surface_flush(surface);
}

int
main(int argc, char **argv)
{
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *sine_drawing_area;
  GtkWidget *cosine_drawing_area;

  gtk_init(&argc, &argv);

  WHITE_PIXEL = RED_PIXEL | GREEN_PIXEL | BLUE_PIXEL;

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(G_OBJECT(window), "delete-event\0",
		   G_CALLBACK(window_delete_event), NULL);

  vbox = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(window),
		    vbox);
  /* sine related */
  sine_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 400, 200);
  STRIDE = cairo_image_surface_get_stride(sine_surface);

  draw_sine(sine_surface);

  sine_drawing_area = gtk_drawing_area_new();
  gtk_drawing_area_size(GTK_DRAWING_AREA(sine_drawing_area), 400, 200);
  gtk_box_pack_start(GTK_BOX(vbox),
		     sine_drawing_area,
		     FALSE, FALSE,
		     0);
  g_signal_connect(G_OBJECT(sine_drawing_area), "expose_event\0",
		   G_CALLBACK(sine_drawing_area_expose_event), NULL);

  /* cosine related */
  cosine_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 400, 200);

  draw_cosine(cosine_surface);

  cosine_drawing_area = gtk_drawing_area_new();
  gtk_drawing_area_size(GTK_DRAWING_AREA(cosine_drawing_area), 400, 200);
  gtk_box_pack_start(GTK_BOX(vbox),
		     cosine_drawing_area,
		     FALSE, FALSE,
		     0);
  g_signal_connect(G_OBJECT(cosine_drawing_area), "expose_event\0",
		   G_CALLBACK(cosine_drawing_area_expose_event), NULL);

  /* show all widgets */
  gtk_widget_show_all(window);

  /* enter main loop */
  gtk_main();

  return(0);
}

      

Kapitel 17. Posix Threads

Inhaltsverzeichnis

Iileitig
Übersicht
pthread.h

Iileitig

Threads sind gliechziitigi Handligsabläuf. Wenn mo än thread erstellt lauft diä Funktion wo pthread_create übergeh worde isch gliechziitig zu därä Funktion wo än Erstellt hät. Um Threads z'synchronisiere brucht mo Mutices. Komplexeri synchronisierigs Reglene lönd sich mit Barriers oder Conditional-Locks erstelle.

Übersicht

pthread.h

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

Thread erzüge.

void pthread_exit(void *retval);

Thread beende.

int pthread_join(pthread_t thread, void **retval);

Uf än Thread warte, bis er beendet isch.

pthread_t pthread_self(void);

Dä eigini Thread ermittle.

int pthread_cancel(pthread_t thread);

Än Thread beende.

int pthread_detach(pthread_t thread);

Än Thread als glöst markiere.

int pthread_attr_init(pthread_attr_t *attr);

Äs Thread Attribut initialisiere.

int pthread_attr_destroy(pthread_attr_t *attr);

Äs Thread Attribut freigeh.

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

Än Mutex initialisiere.

int pthread_mutex_destroy(pthread_mutex_t *mutex);

Än Mutex freigeh.

int pthread_mutex_lock(pthread_mutex_t *mutex);

Än Mutex sperre.

int pthread_mutex_unlock(pthread_mutex_t *mutex);

Än Mutex entsperre.

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

Ä Condition initialisiere.

int pthread_cond_destroy(pthread_cond_t *cond);

Ä Condition freigeh.

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

Warte uf e Condition mit ziitlicher Limitte.

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

Warte uf e Condition.

int pthread_cond_broadcast(pthread_cond_t *cond);

Alli Threads ufwecke wo uf Condition warted.

int pthread_cond_signal(pthread_cond_t *cond);

Ufwecke vo einem Thread wo uf Condition warted.

int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count);

Än Barrier initialisiere.

int pthread_barrier_destroy(pthread_barrier_t *barrier);

Än Barrier freigeh.

int pthread_barrier_wait(pthread_barrier_t *barrier);

Warte uf Barrier.

Referenz


Übersicht

#include <unistd.h>

int access(const char *pfad, int modus);
      

Beschriebig

access überprüeft d'Dateirecht und öb ä Datei existiert. Giet 0 zrugg bi Erfolg und -1 wenn än Fähler uftritt.

Tabelle 2. access Modus

MakroBeschriebig
R_OK öb d'Datei läsbar isch
W_OK öb i d'Datei gschriebä werdä cha
X_OK öb d'Datei usführbar isch
F_OK öb d'Datei existiert

Tabelle 3. access Fähler

WertBeschriebig
EACCES Zuegriffsrecht sind verweigered wordä oder s'sueche innerhalb vom Verzeichnispfad isch verweigered wordä
ELOOP z'viel symbolische Links sind uftaucht bim uflöse vom Pfad
ENAMETOOLONG dä Pfadname isch z'lang
ENOENT ä Komponente im Pfad existiert nöd
ENOTDIR ä Komponente im Pfad isch kei Verzeichnis
EROFS Read-Only Dateisystem
EFAULT dä Pfadname zeigt usserhalb vom zuegriefbare Adressruum
EINVAL modus isch falsch ageh wordä
EIO Igob/Usgob Fehler isch ufträtte
ENOMEM dä Kernel hä zwenig Speicher
ETXTBSY schriebzuegriff uf ä momentan usgführts Programm isch volangt wordä


Übersicht

#include <stdlib.h>

double atof(const char *zeichächettä);
      

Beschriebig

atof konvertiert ä Zeichächettä zumnä double


Übersicht

#include <stdlib.h>

int atoi(const char *zeichächettä);
      

Beschriebig

atoi konvertiert ä Zeichächettä zumnä int


Übersicht

#include <stdlib.h>

long atol(const char *zeichächettä);
      

Beschriebig

atol konvertiert ä Zeichächettä zumnä long


Übersicht

#include <stdlib.h>

long long atoll(const char *zeichächettä);
      

Beschriebig

atoll konvertiert ä Zeichächettä zumnä long long


Übersicht

#include <unistd.h>

int chdir(const char *pfad);
      

Beschriebig

chdir wechslät s'Arbeitsverzeichniss. Bimnä Fähler giets -1 zrugg susch 0.

Tabelle 4. chdir Fähler

WertBeschriebig
EACCES Zuegriffsrecht sind verweigered wordä oder s'sueche innerhalb vom Verzeichnispfad isch verweigered wordä
EFAULT dä Pfadname zeigt usserhalb vom zuegriefbare Adressruum
EIO Igob/Usgob Fehler isch ufträtte
ELOOP z'viel symbolische Links sind uftaucht bim uflöse vom Pfad
ENAMETOOLONG dä Pfadname isch z'lang
ENOENT ä Komponente im Pfad existiert nöd
ENOMEM dä Kernel hä zwenig Speicher
ENOTDIR ä Komponente im Pfad isch kei Verzeichnis


Übersicht

#include <math.h>

double ceil(double x);
      

Beschriebig

ceil rundät ä Flüsskommazahl uf diä nögst grösser Zahl uf


Übersicht

#include <sys/stat.h>

int chmod(const char *path, mode_t mode);
      

Beschriebig

chmod ändert Dateirächt

Tabelle 5. chmod Modus

MakroBeschriebig
S_ISUID Benutzer ID setzä
S_ISGID Gruppe ID setzä
S_ISVTX chläbriges Bit
S_IRUSR läsä vom Besitzer
S_IWUSR schriebä vom Besitzer
S_IXUSR usführä vom Besitzer
S_IRGRP läsä vo dä Gruppä
S_IWGRP schriebä vo dä Gruppä
S_IXGRP usführä vo dä Gruppä
S_IROTH läsä vo dä anderä
S_IWOTH schriebä vo dä anderä
S_IXOTH usführä vo dä anderä

Tabelle 6. chmod Fähler

WertBeschriebig
EACCES Zuegriffsrecht sind verweigered wordä oder s'sueche innerhalb vom Verzeichnispfad isch verweigered wordä
EFAULT dä Pfadname zeigt usserhalb vom zuegriefbare Adressruum
EIO Igob/Usgob Fehler isch ufträtte
ELOOP z'viel symbolische Links sind uftaucht bim uflöse vom Pfad
ENAMETOOLONG dä Pfadname isch z'lang
ENOENT ä Komponente im Pfad existiert nöd
ENOTDIR ä Komponente im Pfad isch kei Verzeichnis
EPERM diä effektiv UID stimmt nö mit därä vo dä Datei überein und dä Prozess isch nöd privilegiert.
EROFS Read-Only Dateisystem


Übersicht

#include <unistd.h>

int chown(const char *pfad, uid_t besitzer, gid_t gruppä);
      

Beschriebig

chown ändert dä Besitzer vonerä Datei. Bi Erfolg giets 0 und bimnä Fähler -1 zrugg.

Tabelle 7. chown Fähler

WertBeschriebig
EACCES Zuegriffsrecht sind verweigered wordä oder s'sueche innerhalb vom Verzeichnispfad isch verweigered wordä
EFAULT dä Pfadname zeigt usserhalb vom zuegriefbare Adressruum
ELOOP z'viel symbolische Links sind uftaucht bim uflöse vom Pfad
ENAMETOOLONG dä Pfadname isch z'lang
ENOENT ä Komponente im Pfad existiert nöd
ENOMEM dä Kernel hä zwenig Speicher
ENOTDIR ä Komponente im Pfad isch kei Verzeichnis
EPERM diä effektiv UID stimmt nö mit därä vo dä Datei überein und dä Prozess isch nöd privilegiert.
EROFS Read-Only Dateisystem


Übersicht

#include <stdio.h>

int clearerr(FILE datestrom);
      

Beschriebig

clearerr fähler vomne Datestrom zrugsetzä.


Übersicht

#include <unistd.h>

int close(int dateideskriptor);
      

Beschriebig

close schlüst än Dateideskriptor, wo vorher mit open göffnet wordä isch. Giet 0 zrugg wenn kein Fähler ufträte isch und susch -1.

Tabelle 8. close Fähler

WertBeschriebig
EBADFD dateideskriptor isch kein gültige offenä Dateideskriptor
EINTR dä close Ufruef isch vomnä Signal unterbrochä worde
EIO Igob/Usgob Fehler isch ufträtte


Übersicht

<sys/types.h>
<dirent.h>

int closedir(DIR *vozeichnis_zeiger);
      

Beschriebig

closedir schlüsst ä Vozeichniss

Tabelle 9. closedir Fähler

WertBeschriebig
EBADFD dateideskriptor isch kein gültige offenä Dateideskriptor


Übersicht

#include <math.h>

double cos(double x);
      

Beschriebig

cos berechnet dä Cosinus i Bogämass und giet än wert zwüschäd 1 und -1


Übersicht

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int creat(const char *pfadname, mode_t modus);
      

Beschriebig

creat erschafft ä neui Datei und giet dä neu Dateideskriptor zrugg. creat isch s'gliche wiä open mit O_CREAT|O_WRONLY|O_TRUNC als Parameter für modus


Übersicht

#include <math.h>

double exp2(double x);
      

Beschriebig

exp2 berechnet d'Potenzä zur Basis vo 2


Übersicht

#include <math.h>

double exp(double x);
      

Beschriebig

exp berechnet d'Potenzä zur Basis vo dä eulersche Zahl e ≈ 2.718281828459

Da ax = ex * ln(a) gilt, cha mo jedi beliäbigi Potenz mit därä Funktion berechnen

double basis;
double exponent;
double potenz;

potenz = exp(exponent * log(basis));
    

Übersicht

#include <stdio.h>

int fclose(FILE *datestrom);
      

Beschriebig

fclose schlüst än Datestrom, wo vorher mit fopen göffnet wordä isch. Giet 0 bi erfolg und EOF bimnä Fähler zrugg.

Tabelle 10. fclose Fähler

WertBeschriebig
EBADFD dateideskriptor isch kein gültige offenä Dateideskriptor


Übersicht

#include <stdio.h>

int feof(FILE *datestrom);
      

Beschriebig

feof überprüeft ob s'Endi vo datestrom erreicht wordä isch. 0 als Rückgobewert entspricht falsch und ungleich 0 entspricht wohr. Um d'Agob vom Endi ufzhebä bitte clearerr benütze.


Übersicht

#include <stdio.h>

int ferror(FILE *datestrom);
      

Beschriebig

ferror überprüeft ob än Fähler ufträtä isch. 0 als Rückgobewert entspricht falsch und ungleich 0 entspricht wohr. Um d'Agob vomne Fähler ufzhebä bitte clearerr benütze.


Übersicht

#include <stdio.h>

int fflush(FILE *datestrom);
      

Beschriebig

fflush schriebt dä Zwüschespeicher vomnä Datestrom i d'Datei. Wenn NULL als Argument übergeh wird, schriebts dä Zwüschespeicher vo allne offenä Usgobestreams.

Tabelle 11. fflush Fähler

WertBeschriebig
EBADFD dateideskriptor isch kein gültige offenä Dateideskriptor


Übersicht

#include <stdio.h>

int fgetpos(FILE *datestrom, fpos_t position);
      

Beschriebig

fgetpos ermittlät d'Position im Datestrom. Isch ä alternativi Schnittstell zu ftell mit SEEK_SET als Parameter.


Übersicht

#include <stdio.h>

FILE *fopen(const char *pfad, int modus);
      

Beschriebig

fopen öffnet än Datestrom. Giet än FILE-Zeiger zrugg, aber bimne Fehler NULL.

Öffnet ä Datei wo durch pfad ageh wird und vobindet diä mit ämnä Datestrom. Wenn dä nümmä länger brucht wird sötti dä mit fclose gschlosse werdä

Tabelle 12. fopen Modus

StringBeschriebig
r öffnet ä Textdatei im läsä Modus. Dä Datestrom wird uf dä Afang vo dä Datei gsetzt
r+ öffnet d'Datei zum läsä und schriebä. Dä Datestrom wird uf dä Afang vo dä Datei gsetzt
w d'Datei wird uf ä längi vo 0 gsetzt oder neu erstellt zum schriebä. Dä Datestrom wird uf dä Afang vo dä Datei gsetzt
w+ Öffnet zum läsä und schriebä. D'Datei wird erstellt falls sie nöd existiert, susch wird sie kürzt. Dä Datestrom wird uf dä Afang vo dä Datei gsetzt
a Öffnet zum ahängä. D'Datei wird erstellt falls sie nöd existiert. dä Datestrom wird uf s'Endi vo dä Datei gsetzt
a+ Öffnet zum ahängä und läsä. D'Datei wird erstellt falls sie nöd existiert. Dä Zeiger zum läsä wird uf dä Afang gsetzt, aber gschriebä wird immer am Endi vo dä Datei.

Tabelle 13. fopen Fähler

WertBeschriebig
EINVAL dä modus isch ungültig

Cha diä gliechä Fähler wiä malloc setzä

Cha diä gliechä Fähler wiä open setzä


Übersicht

#include <stdio.h>

int fprintf(FILE *datestrom, const char *format, ...);
      

Beschriebig

fprintf Schriebt formatiert in än Datestrom. Giet d'Azahl usgebeni Zeiche zrugg ohni s'folgende '\0', falls än Fähler uftritt giet's än negative Wert zrugg. Siehe printf für s'format Argument.


Übersicht

#include <unistd.h>

pid_t fork(void);
      

Beschriebig

fork erzügt än Chindprozess. Bi Erfolg erhaltet dä elterlich Prozess dä PID vom chind Prozess und 0 für s'Chind als Rückgobe wert. Bimne Fähler giet's -1 zrugg.

Tabelle 14. fork Fähler

WertBeschriebig
EAGAIN fork cha nöd gnüegend Speicher alloziierä um diä elterliche "page tables" z'kopierä und ä "task Strucktur" z'alloziierä für s'Chind.
EAGAIN Es isch nöd möglich gsi än neue Prozess z'erstellä, wil äm Ufrüefer sis RLIMIT_NPROC Ressourcelimit erreicht isch.
ENOMEM dä Kernel hä zwenig Speicher
ENOSYS fork wird uf derä Plattform nöd unterstützt


Übersicht

#include <stdio.h>

size_t fread(void *zeiger, size_t grössi, size_t azahl, FILE *datestrom);
      

Beschriebig

fread binäre Datestrom input. Giet d'Azahl erfolgrich gläseni Iträg zrugg.


Übersicht

#include <stdlib.h>

void free(void *ptr);
      

Beschriebig

free Speicher freigeh.


Übersicht

#include <stdio.h>

int fscanf(FILE *datestrom, const char *format, ...);
      

Beschriebig

fscanf liest formatiert userä Datei. für format siehe scanf


Übersicht

#include <stdio.h>

int fseek(FILE *datestrom, long offset, int von_wo);
      

Beschriebig

fseek positioniere vomne Datestrom. Rückgob vo 0 bi Erfolg und -1 bi Misserfolg.

Tabelle 15. fseek Modus

MakroBeschriebig
SEEK_SET relativ zum afang
SEEK_CUR relativ zur momentanä Position
SEEK_END relativ zum endi

Tabelle 16. fseek Fähler

WertBeschriebig
EBADFD datestrom isch kein positionierbare Strom.
EINVAL von_wo isch nöd SEEK_SET, SEEK_CUR oder SEEK_END gsi


Übersicht

#include <stdio.h>

int fsetpos(FILE *datestrom, fpos_t *position);
      

Beschriebig

fsetpos setzt d'Position im Datestrom. Isch ä alternativi Schnittstell zu fseek mit SEEK_SET als Parameter.


Übersicht

#include <stdio.h>

long ftell(FILE *datestrom);

      

Beschriebig

ftell ermittlät d'Position im Datestrom.


Übersicht

#include <stdio.h>

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
      

Beschriebig

fwrite binäre Datestrom output. Giet d'Azahl erfolgrich glschriebeni Iträg zrugg.


Übersicht

#include <unistd.h>

char* getcwd(char *zwüschäspeicher, size_t grössi);
      

Beschriebig

getcwd ermittlät s'momentane Arbeitsverzeichniss. Kopiert än absolutä Pfad vom momentane Arbeitsverzeichniss is Argument zwüschespeicher. Bi Erfol giets dä Pfad als Zeichechetti zrugg, susch NULL.

Tabelle 17. getcwd Fähler

WertBeschriebig
EACCES s'sueche innerhalb vom Verzeichnispfad isch verweigered wordä
EFAULT zwüschäspeicher zeigt uf ä schlächti Adresse.
EINVAL zwüschäspeicher isch NULL
ENAMETOOLONG dä nullterminiert Pfadname überschrieted PATH_MAX bytes.
ENOENT s'momentane Arbeitsverzeichnis isch glöscht worde
ERANGE zwüschäspeicher isch z'chli um dä absoluti Pfad z'speichere


Übersicht

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);
      

Beschriebig

getpid ermittlät d'Prozess ID


Übersicht

#include <math.h>

double log(double x);
      

Beschriebig

log berächnet dä natürlich Logarithmus


Übersicht

#include <sys/types.h>
#include <unistd.h>

off_t lseek(int datei_deskriptor, off_t offset, int von_wo);
      

Beschriebig

lseek positioniert läsä und schriebä Zeiger. Giet Position i Azahl Bytes vom Afang us zrugg bi Erfolg, bimne Fähler -1.

Tabelle 18. lseek von wo

Von woBeschriebig
SEEK_SET vom Afang us plus offset Azahl Bytes
SEEK_CUR relativ zur momentanä Position
SEEK_END vom Endi us plus offset Azahl Bytes

Tabelle 19. lseek Fähler

WertBeschriebig
EBADFD datei_deskriptor isch kein Offene Dateizeiger
EINVAL von_wo isch nöd SEEK_SET, SEEK_CUR oder SEEK_END gsi
EOVERFLOW s'resultierende offset cha vo off_t nöd dargestellt werdä
ESPIPE datei_deskriptor isch an ä pipe, socket, or FIFO bundä


Übersicht

#include <stdlib.h>

void* malloc(size_t size);

      

Beschriebig

malloc Speicher beschaffe. Giet än Zeiger uf dä beschaffeni Speicher zrugg, aber bimne Fähler NULL.


Übersicht

#include <string.h>

void* memcpy(void *ziil, const void *quellä, size_t n);
      

Beschriebig

memcpy kopiert n bytes vo quellä noch ziil


Übersicht

#include <string.h>

void* memmove(void *ziil, const void *quellä, size_t n);
      

Beschriebig

memmove kopiert n bytes vo quellä noch ziil. D'Speicheradresse chönd sich überlappe


Übersicht

#include <time.h>

int nanosleep(const struct timespec *aforderig, struct timespec *verbliebend);
      

Beschriebig

nanosleep hochuflösendä schlof. Loht än Prozess oder än Thread aforderig lang schlofä. Fals dä Ufruäf vomnä Signal unterbroche wird, enthaltäd verbliebend diä restlich Ziit. Giet 0 bi Erfolg zrugg, falls än Fähler oder dä Ufruef vomne Interrup unterbroche worde isch -1.

Tabelle 20. nanosleep Fähler

WertBeschriebig
EFAULT Probleme mit kopieren von Daten vom Userspace
EINTR die Pause wurde von einem Signal unterbrochen und die verbleibende Schlafzeit isch i verbliebend gspeichert
EINVAL dä Wert vo tv_nsec liet nöd im Berich zwüsched 0 und 999999999 oder isch negativ gsi


Übersicht

#include <sys/types.h>

#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pfadname, int flags);

int open(const char *pfadname, int flags, mode_t modus);
      

Beschriebig

open öffnet und möglicherwies erstellt ä Datei oder Grät. Giet dä neu Dateideskriptor zrugg, bimne Fähler -1.

Tabelle 21. open flags

WertBeschriebig
O_APPEND d'Datei wird zum Ahänge göffnet, dä Dateizeiger isch uf s'Endi gsetzt
O_ASYNC ermögliche signalbasierti Igob/Usgob
O_CLOEXEC vermeide vo "race conditions" während än Thread än Dateideskriptor öffnet und zur selbä Ziit än andere Thread fork und execve ufrüeft
O_CREAT wenn d'Datei nöd existiert wird sie erstellt
O_DIRECT versuecht dä Cacheeffekt z'minimierä
O_DIRECTORY falls pfadname kei Verzeichnis isch söll dä Ufruef nöd glinge
O_EXCL sicherstelle, dass d'Datei erstellt wird - wird mit äm Flag O_CREAT benützt und falls d'Datei bereits existiert, wird dä Ufruef nöd glinge
O_LARGEFILE erlaube Datei z'öffne wo vo off_t nöd dargstellt werde chönd, aber vo off64_t
O_NOATIME tuet verhinderä, dass diä letscht Zuegriffsziit nöd aktualisiert wird
O_NOCTTY falls pfadname sich uf äs Terminal beziät, wird das Terminal nöd zum Prozess sis kontrollierende Terminal
O_NOFOLLOW falls pfadname än Link isch, wird's nöd erfolgrich sii
O_NONBLOCK oder O_NDELAY wenn möglich wird d'Datei im nicht blockendä Modus göffnet
O_SYNC synchroni Igob/Usgob, d.h. d'Funktion chert erst zrugg, wenn d'Date physikalisch uf d'Harware gschriebä isch
O_TRUNC löscht dä Inhalt vo dä Datei

Tabelle 22. open Modus

WertBeschriebig
S_IRWXU läsä, schriebä und usführä vom Besitzer
S_IRUSR läsä vom Besitzer
S_IWUSR schriebä vom Besitzer
S_IXUSR usführä vom Besitzer
S_IRWXG läsä, schriebä und usführä vo dä Gruppä
S_IRGRP läsä vo dä Gruppä
S_IWGRP schriebä vo dä Gruppä
S_IXGRP usführä vo dä Gruppä
S_IRWXO läsä, schriebä und usführä vo dä anderä
S_IROTH läsä vo dä anderä
S_IWOTH schriebä vo dä anderä
S_IXOTH usführä vo dä anderä

Tabelle 23. open Fähler

WertBeschriebig
EACCES dä volangti Zuegriff isch nöd erlaubt oder s'sueche innerhalb vom Verzeichnispfad isch verweigered wordä
EEXIST pfadname existiert bereits und O_CREAT und O_EXCL sind benutzt wordä
EFAULT pfadname zeigt usserhalb vom zuegriefbare Adressruum
EFBIG siehe bei EOVERFLOW


Übersicht

#include <sys/types.h>

#include <dirent.h>

DIR* opendir(const char *name);
      

Beschriebig

opendir öffnet ä Vozeichnis


Übersicht

#include <stdio.h>

int printf(const char *format, ...);
      

Beschriebig

printf bildschirmusgob vonerä Zeichechettä nochäm entsprechendä Format

Tabelle 24. printf Format

WertBeschriebig
d, i s'Argument wird zumnä vorzeichebehaftä dezimal Wert konvertiert
u s'Argument wird zumnä vorzeichelosä dezimal Wert konvertiert
o s'Argument wird zumnä vorzeichelosä oktal Wert konvertiert
x, X s'Argument wird zumnä vorzeichelosä hexadezimal Wert konvertiert
e, E exponentialschriebwies vomenä Wert i dä Form [-]d.ddde+-dd
f, F s'double Argument wird grundet und zumenä dezimal Wert konvertiert
c s'Argument wird als vorzeichelosäs Zeichä interpretiert
s s'Argument wird als Zeichechettä interpretiert
% usgob vom Zeichä %


Übersicht

#include <unistd.h>

ssize_t read(int deskriptor, void *puffer, size_t azahl);
      

Beschriebig

read vomenä Dateideskriptor läsä


Übersicht

#include <dirent.h>

struct dirent *readdir(DIR *dirp);
      

Beschriebig

readdir äs Verzeichnis usläsä


Übersicht

#include <stdio.h>

int rename(const char *alte_pfad, const char *neuä_pfad);
      

Beschriebig

rename ändert dä name oder dä Platz vonerä Datei


Übersicht

#include <unistd.h>

int rmdir(const char *pfad_name);
      

Beschriebig

rmdir äs Verzeichniss loschä


Übersicht

#include <stdio.h>

int scanf(const char *format, ...);
      

Beschriebig

scanf formatierts Iläsä vo dä Standartigob

Tabelle 25. scanf Format

WertBeschriebig
l i kombination mit %c
d entspricht ämenä vorzeichebehaftetä dezimal Wert
o entspricht ämenä vorzeichelosä oktal Wert
u entspricht ämenä vorzeichelosä dezimal Wert
x, X entspricht ämenä vorzeichelosä hexadezimal Wert
f entspricht ämenä double wert
s entspricht änerä Sequenz vo nicht Leerschläg
c entspricht einäm Zeichä


Übersicht

#include <unistd.h>

unsigned int sleep(unsigned int sekundä);
      

Beschriebig

sleep loht dä ufrüefendi Prozess für d'agebeni Sekundä schlofä


Übersicht

#include <math.h>

double sqrt(double x);
      

Beschriebig

sqrt berächnet d'Quadratwuerzel vo x


Übersicht

int stat(const char *pfad, struct stat *buf);
      

Beschriebig

stat Dateistatus ermittlä


Übersicht

#include <string.h>

int strcmp(const char *s1, const char *s2);
      

Beschriebig

strcmp zwei Zeichechettä mitänand verglichä


Übersicht

#include <string.h>

char* strcpy(char *ziil, const char *quellä);
      

Beschriebig

strcpy kopiert ä Zeichechettä vo quellä noch ziil samt äm abschlüssende Null Byte ('\0')


Übersicht

#include <string.h>

int strncmp(const char *s1, const char *s2, size_t n);
      

Beschriebig

strncmp vergliecht diä erstä n Zeichä


Übersicht

#include <string.h>

char* strncpy(char *ziil, const char *quellä, size_t n);
      

Beschriebig

strncpy kopiert n Bytes vo quellä noch ziil


Übersicht

#include <string.h>

char* strstr(const char *heuhaufen, const char *nadel);
      

Beschriebig

strstr ä Zeichächettä innerä anderä Zeichächettä suechä


Übersicht

#include <math.h>

double tan(double x);
      

Beschriebig

tan berächnet dä Tangens vo x, dä Rückgobewert isch i Bogämass


Übersicht

#include <unistd.h>

int unlink(const char *pfadname);
      

Beschriebig

unlink löscht än Dateisystemitrag. Wenn's dä letscht link uf ä Datei isch und kein Prozess d'Datei göffnet hät, wird sie glöscht.


Übersicht

#include <unistd.h>

int usleep(useconds_t usec);
      

Beschriebig

usleep loht dä ufrüefendi Prozess für mindestens usec Microsekunde schlofä


Übersicht

#include <unistd.h>

ssize_t write(int datei_deskriptor, const char *puffer, size_t azahl);
      

Beschriebig

write i ä Dateideskriptor azahl Bytes vom Puffer schriebä