Języki i metody programowania I

Podobne dokumenty
METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Tablice (jedno i wielowymiarowe), łańcuchy znaków

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Globalne / Lokalne. Wykład 15. Podstawy programowania (język C) Zmienne globalne / lokalne (1) Zmienne globalne / lokalne (2)

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Zmienne, stałe i operatory

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wskaźniki. Informatyka

Język C zajęcia nr 11. Funkcje

Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17

Wskaźniki w C. Anna Gogolińska

Lab 9 Podstawy Programowania

Wstęp do Programowania, laboratorium 02

Struktura programu. Projekty złożone składają się zwykłe z różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem.

Podstawy programowania komputerów

Wprowadzenie do programowania w języku C

Wstęp do programowania

Wstęp do programowania

DYNAMICZNE PRZYDZIELANIE PAMIECI

Podstawy programowania skrót z wykładów:

Tablice, funkcje - wprowadzenie

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Wstęp do programowania

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Podstawy programowania w języku C++

Język C++ zajęcia nr 2

Stałe, tablice dynamiczne i wielowymiarowe

Podział programu na moduły

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Funkcje. Spotkanie 5. Tworzenie i używanie funkcji. Przekazywanie argumentów do funkcji. Domyślne wartości argumentów

Argumenty wywołania programu, operacje na plikach

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Programowanie w języku C++

ZASADY PROGRAMOWANIA KOMPUTERÓW

wykład III uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - zarządzanie pamięcią, struktury,

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Wskaznik. Przekazywanie wyniku funkcji przez return. Typy i zmienne wskaznikowe. Zmienna wskazywana. typ * nazwa_wkaznika

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Podstawy programowania w języku C++

KURS C/C++ WYKŁAD 6. Wskaźniki

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

4 Literatura. c Dr inż. Ignacy Pardyka (Inf.UJK) ASK MP.01 Rok akad. 2011/ / 24

Programowanie niskopoziomowe

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny:

Podstawy programowania. Wykład: 7. Funkcje Przekazywanie argumentów do funkcji. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Spis treści WSKAŹNIKI. DYNAMICZNY PRZYDZIAŁ PAMIĘCI W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Zaawansowane programowanie w języku C++ Klasy w C++

Wykład 8: klasy cz. 4

Algorytm. a programowanie -

Zaawansowane programowanie w języku C++ Zarządzanie pamięcią w C++

Szablony klas, zastosowanie szablonów w programach

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

PARADYGMATY PROGRAMOWANIA Wykład 4

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 6. Karol Tarnowski A-1 p.

część 8 wskaźniki - podstawy Jarosław Gramacki Instytut Informatyki i Elektroniki Podstawowe pojęcia

Języki C i C++ Wykład: 2. Wstęp Instrukcje sterujące. dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Wstęp do programowania. Wykład 1

Podstawy programowania. Wykład: 5. Instrukcje sterujące c.d. Stałe, Typy zmiennych c.d. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

5 Przygotował: mgr inż. Maciej Lasota

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy KONSTRUKTORY

Tablice, funkcje, wskaźniki - wprowadzenie

Wykład 4: Klasy i Metody

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Język C++ Różnice między C a C++

Programowanie Obiektowe i C++

Podstawy algorytmiki i programowania - wykład 4 C-struktury

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

Przekazywanie argumentów wskaźniki

Język ludzki kod maszynowy

Wykład 3 Składnia języka C# (cz. 2)

Część 4 życie programu

KURS C/C++ WYKŁAD 8. Deklaracja funkcji informuje komplilator jaką wartość funkcja będzie zwracała i jakiego typu są jej argumenty.

Wskaźniki. Programowanie Proceduralne 1

Kompilator języka C na procesor 8051 RC51 implementacja

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Spis treści WSKAŹNIKI. DYNAMICZNY PRZYDZIAŁ PAMIĘCI W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

C-struktury wykład. Dorota Pylak

Języki programowania obiektowego Nieobiektowe elementy języka C++

Klasy Obiekty Dziedziczenie i zaawansowane cechy Objective-C

Co to jest klasa? Z programistycznego punktu widzenia klasa stanowi typ danych, który odwzorowuje wspólne cechy jakiegoś obiektu.

Zarządzanie pamięcią operacyjną

Spis treści JĘZYK C - WSKAŹNIKI, DYNAMICZNY PRZYDZIAŁ PAMIĘCI. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu

Programowanie obiektowe Wykład 3. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21

Przesłanianie nazw, przestrzenie nazw

4. Tablica dwuwymiarowa to jednowymiarowa tablica wskaźników do jednowymiarowych tablic danego typu.

Wstęp do programowania

ALGORYTMY I STRUKTURY DANYCH

Podstawy programowania. Wykład 9 Preprocesor i modularna struktura programów. Krzysztof Banaś Podstawy programowania 1

Wstęp do wskaźników w języku ANSI C

Programowanie obiektowe w języku C++ dr inż. Jarosław Forenc

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

Transkrypt:

Języki i metody programowania I dr inż. Piotr Szwed Katedra Informatyki Stosowanej C2, pok. 403 e-mail: pszwed@agh.edu.pl http://home.agh.edu.pl/~pszwed/ Aktualizacja: 2013-01-18

9. Struktura programów

Deklaracje W języku C/C++ występują dwa typy deklaracji: Definicje pociągają za sobą przydział pamięci dla zmiennej Referencje informują kompilator o pojawieniu się identyfikatora zmiennej (lub funkcji) określonego typu. Sama definicja występuje później lub w innym module kodu źródłowego. Przykład definicji: int x; Wprowadza identyfikator o nazwie x, przydziela pamięć dla zmiennej. Przykład deklaracji będącej referencją: extern int x; Wprowadza identyfikator o nazwie x, pamięć dla zmiennej nie jest przydzielana. Nastąpi to później lub zmienna pojawi się w innym module. 3

Czas życia (1) Czas życia to okres w trakcie wykonania programu, kiedy zmienna lub funkcja istnieją, czyli jest dla nich przydzielone miejsce w pamięci. Ze względu na czas życia identyfikatory dzielimy na: statyczne (w tym globalne), automatyczne (lokalne). W praktyce, wszystkie funkcje istnieją podczas wykonania programu. Kod funkcji jest załadowany do pamięci w momencie uruchamiania programu i istnieje przez cały czas jego działania (wyjątkiem są dynamicznie linkowane biblioteki DLL). 4

Czas życia (2) Zmienne o statycznym przydziale pamięci Pamięć dla zmiennych statycznych jest zarezerwowana na stałe w trakcie działania programu. Zmienne te są inicjowane wartościami początkowymi tylko raz, przed rozpoczęciem wykonania programu. Jeżeli w momencie definicji zmienna statyczna nie zostanie jawnie zainicjowana, wówczas standardowo nadana jej zostanie wartość 0. Aby zadeklarować zmienną o statycznym przydziale pamięci: Deklarujemy ją poza blokami funkcji, na tym samym poziomie co definicje funkcji; zmienne te nazywane są globalnymi. Używamy słowa kluczowego static 5

Zmienne automatyczne Czas życia (3) Zmiennymi automatycznymi są wszystkie zmienne zadeklarowane wewnątrz funkcji lub wewnątrz instrukcji blokowej, o ile nie są poprzedzone modyfikatorem static. Wszystkie parametry funkcji są również zmiennymi automatycznymi. Czas życia zmiennych automatycznych jest powiązany z wykonaniem instrukcji blokowej... Pamięć dla zmiennych automatycznych jest przydzielana w momencie wejścia do instrukcji blokowej i zwalniana w momencie wykonania ostatniej instrukcji bloku. Zmienne automatyczne powinny być inicjowane przy każdym wejściu do bloku. Jeżeli nie nadamy zmiennej wartości początkowej, wówczas będzie ona miała wartość nieokreśloną. 6

Zmienne automatyczne Czas życia (4) Pamięć dla zmiennych automatycznych przydzielana jest na stosie. Wyjątkiem są zmienne rejestrowe. Zmienne rejestrowe deklarujemy z użyciem słowa kluczowego register. Należy je traktować jako wskazówkę dla kompilatora, aby odwzorowywał zmienną w jeden z wolnych rejestrów procesora, zamiast w komórkę pamięci. Brak jest jednak gwarancji, że żądanie to zostanie zrealizowane. 7

int a=1; // zmienna globalna void f1() int x = 2; Przykład 1 // zmienna lokalna (automatyczna) // zmienna statyczna static int y=0; x--; y++;a*=2; printf("x=%d y=%d a=%d; ", x, y, a) ; int main() f1() ; f1() ; f1() ; return 0; x=1 y=1 a=2; x=1 y=2 a=4; x=1 y=3 a=8; 8

Przykład 2 char*tokenize(char*txt, const char*sep) static char*ptr=0; static char*end=0; char*ret=0; if(txt!=0) ptr = txt; end=txt+strlen(txt); while(ptr<end && *ptr && strchr(sep,*ptr))ptr++; if(ptr>=end *ptr==0 )return 0; ret = ptr; while(ptr<end && *ptr &&!strchr(sep,*ptr))ptr++; while(ptr<end && *ptr && strchr(sep,*ptr))*ptr=0;ptr++; return ret; 9

Przykład 2 (cd) Faza początkowa ustawianie wskaźników ptr i end, pomijanie początkowych separatorów r a z d w a \0 ptr end static char*ptr=0; static char*end=0; char*ret=0; if(txt!=0) ptr = txt; end=txt+strlen(txt); while(ptr<end && *ptr && strchr(sep,*ptr))ptr++; 10

Faza druga wydzielanie symboli Przykład 2 (cd) r a z \0 \0 d w a \0 1 2 3 ret ptr end if(ptr>=end *ptr==0 )return 0; (1) ret = ptr; (2) while(ptr<end && *ptr &&!strchr(sep,*ptr))ptr++; (3) while(ptr<end && *ptr && strchr(sep,*ptr)) *ptr=0;ptr++; return ret; 11

Przykład 2 (cd) Wywołanie int main() char txt[256] = " Ala ma,. kota...i psa "; char*token; for( token=tokenize(txt,".,"); token; token=tokenize(0,".,")) printf("%s\n",token); return 0; Ala ma kota i psa 12

Przydział pamięci dla programu (1) Podczas uruchamiania zapisany na dysku program staje się procesem. Kod programu ładowany do pamięci RAM. Dodatkowo przydzielana jest pamięć dla stosu i sterty. Pamięć programu dzielimy na segmenty. Argumenty programu zmienne środowiskowe stos Wysokie adresy sterta Dane niezainicjowane (BSS) Dane zainicjowane text Zerowane przy uruchamianiu Ładowane przy uruchamianiu Niskie adresy 13

Przydział pamięci dla programu (2) Segment text (kod) Zawiera skompilowany do postaci wykonywalnych rozkazów maszynowych kod funkcji. Nie jest możliwa modyfikacja zawartości segmentu kodu w trakcie działania programu (read-only). Dla bezpieczeństwa umieszczany przy niskich adresach pamięci W przypadku wielodostępu, segment kodu może być dzielony przez różne instancje procesów Segment danych (zainicjowanych) Zawiera zmienne o statycznym czasie życia: globalne i zadeklarowane lokalnie z użyciem modyfikatora static. Obejmuje dane tylko do odczytu (ang. read-only - RO) oraz dane do odczytu i zapisu (ang. read-write - RW) char*ptr="hello world"; // ptr w RW; "Hello world" w RO char tab[]="ala ma kota"; // tab w RW zaincjowane tekstem // "Ala ma kota" int count=0; // count w RW 14

Przydział pamięci dla programu (3) Segment niezainicjowanych danych (BSS) Dane w tym segmencie są zerowane przed rozpoczęciem wykonania programu. Nazwa pochodzi od rozkazu asemblera z 1955 roku block started by symbol, ale niektórzy tłumaczą, jako better save space: segment nie zajmuje miejsca w skompilowanym programie. Do segmentu trafiają zadeklarowane (i zdefiniowane nie extern) zmienne bez jawnej inicjalizacji, np.: static int i; int tab[100000]; // globalna zmienna Segment stosu W starszych architekturach sprzętowych segmenty stosu i sterty rosną w przeciwnych kierunkach i zużywają wolną pamięć. W nowszych mogą być umieszczone w dowolnym miejscu. Na stosie przydzielana jest pamięć dla zmiennych automatycznych (deklarowanych wewnątrz funkcji lub bloków instrukcji) Na stosie przydziela się również pamięć dla formalnych parametrów funkcji Na stosie umieszcza się również wartości zwracane przez funkcje (wybrane) oraz adresy powrotu. 15

Sterta Przydział pamięci dla programu (4) Sterta to potencjalnie największy obszar pamięci dostępnej dla przechowywania danych programu. Zmiennych na stercie nie deklaruje się. Zamiast tego pamięć jest przydzielana dynamicznie w trakcie wykonania programu. Biblioteczne funkcja malloc() lub calloc() przydziela blok pamięci o żądanym rozmiarze i zwraca do niego wskaźnik. Funkcja free() zwalnia pamięć bloku, którego adres jest przekazany przez wskaźnik. W zależności od systemu, sterta może być dzielona przez procesy i dynamicznie ładowane biblioteki. Dzielona pamięć sterty może służyć do komunikacji pomiędzy procesami. W szczególnych implementacjach (systemy wbudowane) sterta może być nieobecna. 16

Przydział pamięci dla programu (4) Ostatnim blokiem są argumenty programu i zmienne środowiskowe Są to dane niemodyfikowalne! Przykład wypisanie argumentów wywołania int main(int argc, char*argv[]) int i; for(i =0;i<argc;i++) printf("%s\n",argv[i]); C:\lib\Dev-Cpp\Project1.exe ala ma 2 koty 17

Przydział pamięci dla programu (5) W systemie operacyjnym zdefiniowane są tzw. zmienne środowiskowe. Jest to zbiór par (klucz, wartość) gdzie nazwie zmiennej (kluczowi) przypisany jest tekst (wartość). Odczytane wartości są również niemodyfikowalne C:\Users\pszwed>echo %TEMP% C:\Users\pszwed\AppData\Local\Temp int main(int argc, char*argv[]) const char * varname="temp"; char*var = getenv(varname); printf("%s=%s\n",varname,var); return 0; temp=c:\users\pszwed\appdata\local\temp 18

Zakres widoczności identyfikatorów (1) Zakres widoczności (ang. scope) identyfikatora jest to obszar programu, w którym można się odwoływać do danego identyfikatora funkcji lub zmiennej. Rozróżnia się następujące zakresy widoczności identyfikatorów: pliku funkcji bloku prototypu funkcji 19

Zakres widoczności identyfikatorów (2) Zakres widoczności: wewnątrz pliku Identyfikator pojawia się poza definicją funkcji lub listą jej parametrów. Identyfikator jest widoczny od momentu jego deklaracji aż do końca pliku (modułu translacji) Nie deklarujemy identyfikatorów globalnych w plikach nagłówkowych! int a =0; void f1() a++; b++; // błąd, zmienna b nie została zadeklarowana int b=0; void f2() a++; b++; f1(); // poprawne, funkcja f1() jest widoczna 20

Zakres widoczności identyfikatorów (3) Zakres widoczności: wewnątrz funkcji Jedynym typem identyfikatora, którego widoczność jest ściśle związana z funkcją jest etykieta instrukcji. Możliwość etykietowania instrukcji jest odziedziczona po niestrukturalnych językach programowania. Etykietowanie instrukcji ma zastosowanie przy użyciu niezalecanej instrukcji goto pozwalającej na przeskok do dowolnego miejsca wewnątrz funkcji. void printsqrt(double x) if(x<0) goto error; printf( %f,sqrt(x)); return; error: printf( error ); 21

Zakres widoczności identyfikatorów (4) Zakres widoczności: wewnątrz bloku instrukcji Blokiem instrukcji nazywany jest ciąg instrukcji pomiędzy nawiasami. Blokiem instrukcji jest: definicja funkcji obszar pomiędzy nawiasem otwierającym i zamykającym wewnątrz funkcji. Identyfikator, którego zakres widoczności jest ograniczony do bloku instrukcji zadeklarowany jest jako element: listy formalnych parametrów funkcji listy zmiennych zdefiniowanych na początku bloku (w C++ w dowolnym miejscu wewnątrz bloku). 22

Zakres widoczności identyfikatorów (4) Właściwości Zmienne, których zakres widoczności ograniczają się do bloku instrukcji są zawsze zmiennymi automatycznymi. Przydziela się im pamięć na stosie w momencie wejścia do bloku. Ich pamięć jest zwalniana w momencie opuszczenia bloku. void f(int x) int y=0; printf("x=%d y=%d", x, y) ; int z=1 ; printf("x=%d y=%d z=%d", x, y, z) ; 23

Zakres widoczności identyfikatorów (5) Przesłanianie W momencie wykonywania bloku instrukcji widoczne są wszystkie identyfikatory zdefiniowane na wyższym poziomie (w pliku, w bloku wyższego poziomu) oraz identyfikatory zadeklarowane w danym bloku. Jeżeli nazwy identyfikatorów pokrywają się, wówczas deklaracje w blokach niższego poziomu przesłaniają deklaracje wyższego poziomu. int x=7; void f() printf( %d\n,x); // wypisze 7 float x=8; printf( %f\n,x); // wypisze 8.00000 x++; printf( %f\n,x); // wypisze 9.00000 printf( %d\n,x); // wypisze 7 24

Zakres widoczności identyfikatorów (6) Zakres widoczności: wewnątrz prototypu W języku C/C++ stosuje się tzw. prototypy funkcji. Prototypy są konstrukcją umożliwiającą podanie typów funkcji, które nie są widoczne w danym miejscu programu, ale które powinny być w nim użyte. /* prototyp (deklaracja) funkcji */ double distance(double, double) ; // postać 1 // lub double distance(double xx, double yy) ; // postać 2 /* definicja funkcji */ double distance(double x, double y) return sqrt(x*x+y*y) ; Zakres widoczności formalnych parametrów funkcji zdefiniowanych w prototypie kończy się w momencie deklaracji. Nazwy parametrów występujących w prototypie są dowolne i nie muszą się pokrywać z nazwami występującymi w definicji funkcji. 25

Moduły Konsolidacja (1) Modułem (jednostką translacji) nazywamy plik źródłowy wraz ze wszystkimi włączonymi plikami nagłówkowymi. W plikach nagłówkowych umieszczamy zazwyczaj: prototypy wyeksportowanych (dostępnych w innych modułach) funkcji deklaracje wyeksportowanych zmiennych (extern) 26

Konsolidacja (2) Odwołania do identyfikatorów spoza modułu Typową praktyką przy budowie programów w C/C++ jest rozmieszczenie kodu w pewnej liczbie plików źródłowych (od kilku do kilkuset). W modułach zazwyczaj korzysta się z zewnętrznych funkcji oraz zewnętrznych zmiennych. Przed odwołaniem się do danego identyfikatora musimy poprzez deklarację poinformować kompilator o jego atrybutach (czy jest zmienną/funkcją, jaki ma typ). Aby odwołać się do funkcji umieszczonej w innym module korzystamy z prototypu funkcji. Aby odwołać się do zewnętrznej zmiennej globalnej stosujemy deklarację extern. Nie możemy odwołać się do zmiennych lokalnych zdefiniowanych wewnątrz funkcji. 27

Przykład src1.h Konsolidacja (3) src2.h int f(double,double); extern int v; int g(int a,int b); extern int w; src1.c #include "src1.h" int f(double x,double y)... int v; #include "src1.h" #include "src2.h" int g(int a,int b) f(1.0,2.0); v=4; int w; src2.c 28

Konsolidacja (4) Ukrywanie identyfikatorów wewnątrz modułu Standardowo, możemy odwoływać się z zewnątrz do wszystkich funkcje i zmiennych globalnych zdefiniowanych wewnątrz modułu. Jest to tzw. zewnętrzna konsolidacja (ang. external linkage). Jeżeli w dwóch różnych modułach pojawiają się definicje funkcji lub zmiennych o tej samej nazwie, wówczas podczas konsolidacji (linkowania) zostanie zasygnalizowany błąd. Chcąc ukryć identyfikator (wyłączyć z procesu linkowania z zewnętrznymi modułami ) stosuje się modyfikator static. Zmienne i funkcje będą dalej widoczne wewnątrz modułu, natomiast wyłączone z globalnego procesu konsolidacji (ang. internal linkage). 29

Przykład src1.c static int x; static void g()... int x1; extern int x2 ; Konsolidacja (5) src2.c static int x; static void g()... int x2; extern int x1 ; void f1() g(); // g() w src1.c x=1; // x w src1.c x2=x;// x2 w src2.c void f2() g(); // g() w src2.c x=1; // x w src2.c x1=x; // x1 w src1.c 30