Skip to content

Commit

Permalink
przykłady: GLib
Browse files Browse the repository at this point in the history
  • Loading branch information
Wlodek Bzyl committed Jan 9, 2014
1 parent 4fc4096 commit 3dfd779
Showing 1 changed file with 155 additions and 13 deletions.
168 changes: 155 additions & 13 deletions lib/views/notes-adt.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ Linki:

## Struktury

Jak definiujemy struktury?
Jak definiujemy i korzystamy z struktur?

:::c
struct point { /* tutaj `point' to tzw. etykietka struktury */
struct point { /* point to tzw. etykietka struktury */
int x;
int y;
}; /* ważny średnik */

struct point maxpt = { 8, 16 };
struct point minpt;
minpt.x=0; minpt.y=2;
minpt.x = 0; minpt.y = 2;

Zagnieżdżone struktury:

Expand All @@ -49,8 +49,75 @@ Zagnieżdżone struktury:
struct rect screen;
screen.ll.x = 16;

Czasami warto skorzystać z *typedef*
Czasami definując strukturę korzystamy z *typedef*:

:::c
typedef struct point {
int x;
int y;
} point_t;

point_t maxpt;
maxpt.x = 32; maxpt.y = 64;

Ale częściej definujemy **wskaźnik** na strukturę:

:::c
typedef struct point {
int x;
int y;
} *point_t;

point_t maxpt;
maxpt = malloc(sizeof(struct point));
maxpt->x = 128; maxpt->y = 256;

{%= link_to "Przykład", "/struct/struct1.c" %}
w którym użyto powyższych konstrukcji.

Czasami potrzebujemy tablic struktur. Można je zdefiniować na kilka
sposobów:

:::c
struct key {
char *word;
int count;
} keytab[NKEYS];

struct key {
char *word;
int count;
};
struct key keytab[NKEYS];

typedef struct key {
char *word;
int count;
} key_t;
key_t keytab[NKEYS];

Ciekawy przykład zastosowania tablic struktur –
{%= link_to "tablica łącznikowa", "/struct/dtable.c" %}.

Struktury i funkcje – pierwiastki wielomianów:

* {%= link_to "poly1.c", "/struct/poly1.c" %}
* {%= link_to "poly2.c", "/struct/poly2.c" %}
* {%= link_to "poly3.c", "/struct/poly3.c" %}


### Better Structures in C99

Funkcje napisane w języku Python, Ruby
mogą zwracać wiele wartości, a w języku C tylko jedną.
Ale w C możemy zwrócić strukturę, która może składać się
z tylu elementów ile potrzebujemy.

Zilustrujemy to za pomocą tego {%= link_to "przykładu", "/struct/papersize.c" %}.
Kompilujemy go tak:

:::bash
cc -std=c99 -Wall papersize.c


<blockquote>
Expand All @@ -67,31 +134,106 @@ Czasami warto skorzystać z *typedef*
<p class="author">— B. Victor, <a href="http://worrydream.com/Links2013/">Reading Tip #3</a></p>
</blockquote>


## Abstrakcyjne Type Danych (ADT)

Wikipedia: Abstrakcyjne Type Danych.
Zob. tamże definicję stosu (ang. Abstract Data Type; w skrócie ADT)
[Abstract Data Type](http://en.wikipedia.org/wiki/Abstract_data_structure) (w skrócie ADT).
Implementacja *stosu* jako ADT.

Abstrakcyjne Typy Danych służą do oddzielenia interfejsu od implementacji
(ang. *information hiding*).

To oddzielenie osiągamy w C korzystając z nieprzezroczystych struktur danych
(ang. opaque data structures). W pliku nagłówkowym (.h) wpisujemy:
(ang. *opaque data structures*).

W pliku nagłówkowym (*.h*) wpisujemy:

:::c
typedef struct structCDT *structADT;

albo tak
albo

:::c
struct structCDT;

w pliku implementującym ATD (.c) wpisujemy:
W pliku implementującym ADT (*.c*) wpisujemy:

:::c
struct structCDT {
.. definicje pól struktury ..
/* definicje pól */
}

Dlaczego powyższe definicje pozwalają oddzielić interfejs od implementacji?
Dlaczego powyższe definicje nie powodują błędów w trakcie kompilacji?

Dlaczego pozwalają oddzielić interfejs od implementacji?
Jak to „oddzielenie” działa?

Przykład ADT – punkt na płaszczyźnie:

* {%= link_to "definicja", "/adt/point.h" %}
* {%= link_to "implementacja", "/adt/point.c" %}
* {%= link_to "przykład użycia", "/adt/struct3.c" %}

Stos (Stack) to klasyczny przykład, który implementujemy jako ADT:

* {%= link_to "interfejs", "/stack/stack.h" %}
* {%= link_to "implementacja korzystająca z tablic", "/stack/stack1.c" %}
* {%= link_to "j.w. ale bez ograniczenia na wielkość użytej tablicy", "/stack/stack.c" %}
* {%= link_to "implementacja korzystająca z listy łączonej", "/stack/stack2.c" %}
* {%= link_to "symulacja kalkulatora RPN", "/stack/rpn-simulation.c" %} –
*Reverse Polish Notation*

(W kodzie powyżej korzystamy z CSLib.)


### Jeszcze jeden program przykładowy

Struktury odwołujące się do samych siebie – zliczanie wystąpień
wszystkich słów podanych na wejściu

:::c
struct tnode { /* węzeł drzewa */
char *word; /* wskaźnik do tekstu słowa */
int count; /* licznik wystąpień */
struct tnode *left; /* lewy potomek */
struct tnode *right; /* prawy potomek */
};

Uwaga: C nie dopuszcza, aby struktura zawierała w sobie swoje
własne wcielenie. Ale struktura może zawierać wskaźnik do samej siebie.

Wersja opisowa programu zliczającego słowa *fw.pdf*
(zob. rozdział 6.5 w K&R).

Po kompilacji *fw.w*:

:::bash
ctangle fw.w
cc -Wall fw.c -o fw

program *fw* uruchamiamy tak:

:::bash
./fw < fw.w | sort -nr -k1 | head -n 10


## GLib & paths

Biblioteki mogą być zainastalowane w kilku miejscach. Jakich?

Aby się przekonać gdzie została zainstalowana konkretna biblioteka
możemy skorzystać z programu *pkg-config*, np. jeśli

:::bash
pkg-config --libs glib
pkg-config --cflags glib
pkg-config --cflags --libs glib

Tak wygląda kompletny przykład:

:::bash
gcc `pkg-config --cflags --libs glib` -o specific specific.c

Dwa przykłady:

Przykład: {%= link_to "obliczanie długości napisu", "/pointers/str_len.c" %}.
* {%= link_to "hello.c", "/glib/hello.c" %}
* {%= link_to "hash.c", "/glib/hash.c" %}

0 comments on commit 3dfd779

Please sign in to comment.