Elektronika Schematy Projekty DiY
Nawigacja  
  Home
  Elektronika Projekty
  Linki dla ELEKTRONIKA
  Programy do projektowania PCB
  Programy
  Wyślij mi wiadomość E-mail
  LOGOWANIE
  Kanał na YouTube
  Pilot - KODY
  ANKIETA
  RADIO
Za zamieszczone tu materiały NIE ODPOWIADAM !
Progry w C
lol

Język C

Definicje zmiennych i deklaracje
Stałe
Operatory
Wyrażenia
Instrukcje
Tablice i wskaźniki
Struktury
Inicjowanie zmiennej
Funkcje
Argumenty funkcji main

 

 

Definicje zmiennych i deklaracje

Zmienne muszą być zdefiniowane przed użyciem. Dostępne są następujące podstawowe typy danych:

Typ Definicja Typowy rozmiar
char zmienna znakowa 1 bajt
short int liczba znakowa krótka 2 bajty
int liczba całkowita zależy od realizacji
long int liczba całkowita długa 4 bajty
float liczba zmiennoprzecinkowa 4 bajty
double liczba zmiennoprzecinkowa o podwójnej precyzji 8 bajtów
long double liczba zmiennoprzecinkowa długa zależy od realizacji np. 80 bitów
unsigned char zmienna znakowa bez znaku 1 bajt
unsigned int liczba całkowita bez znaku zależy od realizacji

Podane są rozmiary najczęściej używane, ale programista powinien sprawdzić rozmiar dla używanego kompilatora.

Występują jeszcze inne typy danych:
- tablica, czyli wielokrotne wystąpienie identycznych zmiennych;
- struktura, czyli grupa powiązanych zmiennych; mogą być różnych typów;
- wskaźnik, czyli zmienna zawierająca adres innej zmiennej;
- unia, czyli dwie lub więcej zmiennych zajmujacych w pamięci to samo miejsce;
- dane wyliczeniowe (enum), czyli zmienne o ograniczonym zbiorze dopuszczalnych wartości;
- ciąg znaków (łańcuch), czyli tablica zmiennych znakowych typu char, zakończona znakiem NULL.

Dodatkowe typy danych, oparte na podanych powyżej, można zdefiniować korzystając ze specyfikatora typedef. Różnica między definicją danych a deklaracją danych polega na tym, że definicja danych rezerwuje miejsce w pamięci na dane, a deklaracja nie.

Zmienne zdefiniowane lub zadeklarowane poza funkcjami są dostępne od miejsca zdefiniowania aż do końca pliku źródłowego. Zmienne zdefiniowane wewnątrz funkcji są dostępne jedynie wewnątrz tych funkcji, w których zostały zdefiniowane. Zmienne zdefiniowane wewnątrz instrukcji złożonych (bloków) są dostępne jedynie wewnątrz tych instrukcji złożonych, w których zostały zdefiniowane.

Zmienne mogą należeć do jednej z czterech klas:
- static - pamięć dla nich jest rezerwowana statycznie na początku programu;
- auto - pamięć dla nich jest rezerwowana dynamicznie, gdy funkcja jest wykonywana i jest zwalniana, gdy kończy się wykonanie funkcji (jest to domyślna klasa pamięci dla zmiennych definiowanych wewnątrz funkcji);
- extern - pamięć dla nich jest rezerwowana w innym pliku; odwołanie rozstrzyga konsolidator;
- register - są zapamiętywane w rejestrach, o ile jest to możliwe;

 

Stałe

Stałe są określane w tekście programu następująco:

Typ Składnia Przykład
char otoczona apostrofami 'a'
ciąg znaków otoczona cudzysłowami "abc"
liczba ósemkowa zaczyna się 0 (zerem) 0377
liczba szesnastkowa zaczyna się 0x 0x3ef
long int kończy się l lub L 123L
float z kropką dziesiętną lub w notacji naukowej 3.24 lub 3.2E-4
double jak double  

 

Operatory

operator opis operatora przykład
operatory nawiasowe i selektorowe
() wywołanie funkcji getc(stdin)
[] odwołanie do elementu tablicy k[17]
-> selekcja pola struktury lub unii wskazywanej przez wskaźnik wsu -> pole
. odwołanie do elementu struktury su.c
operacje jednoargumentowe
! negacja logiczna !1 daje 0
!0 daje 1
~ uzupełnienie do jedynki lub negacja bitowa ~0x7f
+ plus jednoargumentowy +n
- minus jednoargumentowy -n
++ preinkrementacja
lub postinkrementacja
++i
i++
-- dekrementacja --i lub i--
* wkazanie pośrednie (wyłuskanie) *p_k
& adres elementu &n
sizeof rozmiar zmiennej lub typu sizeof(j*z) lub sizeof(k) lub sizeof(float)
(typ) zmiana typu (int) frac

Przykłady
j=++i <==> i=i+1;
j=i; j=i++ <==> j=i; i=i+1;

operator opis operatora przykład
operatory multiplikatywne
* mnożenie i*j
/ dzielenie i/j
% dzielenie modulo i%j
operatory addytywne
+ dodawanie i+j
- odejmowanie i-j
operatory przesunięć bitowych
<< pzesunięcie bitowe w lewo i<<2
>> pzesunięcie bitowe w prawo i>>2
operatory porównań
< mniejszy niż i<j
<= mniejszy lub równy i<=j
> większy niż i>j
>= większy lub równy i>=j
== równy if (i==5)
!= nierówny if (i!=5)
operatory bitowe dwuargumentowe
& bitowy iloczyn logiczny (AND) c&033
^ bitowa suma modulo 2 (XOR) c^0317
| bitowa suma logiczna c|0333
operatory logiczne dwuargumentowe
&& iloczyn logiczny (AND) i==5 && j==6
|| suma logiczna (OR) i==5 || j==6
operator warunkowy
?: wybór jednego z dwóch wyrażeń max=(i>j?i:j)
operatory przypisań
= proste przypisanie i=7
*= mnożenie, potem przypisanie i*=3 czyli i=i*3
/= dzielenie, potem przypisanie i/=4
%= dzielenie modulo, potem przypisanie i%=4
+= dodawanie, potem przypisanie i+=5
-= odejmowanie, potem przypisanie i-=5
&= iloczyn bitowy, potem przypisanie i&=0333
^= suma mod 2, potem przypisanie i^0317
|= suma logiczna, potem przypisanie i|=0117
<<=
>>=
przesunięcie w lewo (w prawo), potem przypisanie i<<=2
i>>=3
operator wyliczenia
, oblicznenie i odrzucenie func (j, (i=2, i+4), k)

 

Wyrażenia

Wyrażenie może przyjąć jedną z następujących postaci:
- nazwa zmiennej,
- wywołanie funkcji,
- nazwa tablicy,
- stała,
- nazwa funkcji,
- odwołanie do elementu struktury,
- odwołanie do elementu tablicy,
- jedna z powyższych postaci z nawiasami i operatorami.

 

Instrukcje

Wyrażenie zakończone średnikiem jest uważane za instrukcję. Na przykład: i+1 jest wyrażeniem, podczas gdy i+1; jest instrukcją. Oto przykłady innych instrukcji:
; instrukcja pusta
if (wyrazenie) instrukcja
if (wyrażenie) instrukcja1 else instrukcja2
while (wyrażenie) instrukcja
do instrukcja while (wyrażenie);
for (wyrażenie1; wyrażenie2; wyrażenie3) instrukcja
break;
switch (wyrażenie_całkowitoliczbowe) {case stała1: instrukcja1 break; case stała2: instrukcja2 break; . . . . default: instrukcja break;}
continue;
goto
etykieta;
return;
return wyrażenie;

 

Tablice i wskaźniki

Wskaźnik jest to zmienna zawierająca adres innej zmiennej. W języku C wskaźniki mają określony typ, to znaczy, że standardowo definiuje się je jako wskaźniki do zmiennej określonego typu, np:
char *c - wskaźnik do zmiennej typu znakowego
int *p - wskaźnik do zmiennej typu całkowitego
char *argv[] - wskaźnik do tablicy, której elementami są ciągi znaków.
Definicja int *p_k określa zmienną p_k jako wskaźnik do zmiennej całkowitej, natomiast wyrażenie *p_k oznacza "zmienna wskazywana przez p_k" . W przypadku wskaźników dopuszcza się tylko proste operacje arytmetyczne. Do wskaźnika można dodać (lub od niego odjąć) tylko liczbę całkowitą, ale nie są dopuszczalne operacje w zasadzie bezsensowne, takie jak dodawanie wskaźników, dzielenie wskaźnika przez liczbę całkowitą itp.

Tablica jest to ciąg zmiennych tego samego typu zajmujących ciągły obszar w pamięci. Na przykład definicja int k[10] określa tablicę dziesięciu liczb całkowitych, o nazwach od k[0] do k[9]. Zauważmy, że w języku C pierwszy element tablicy ma numer 0. W języku C nazwa tablicy (bez nawiasu kwadratowego) jest rozumiana nie jako wartość pierwszego elementu tablicy, lecz jako jej adres. Tak więc wyrażenie p_k = k ustawia tak p_k , aby wskazywał on pierwszy element tablicy k. Jeżeli p_k wskazuje element k[0], to p_k + 1 wskazuje element k[1]. Tak więc inkrementacja wskaźnika nie zwiększa go o jeden bajt, ale o jeden element. Innymi słowy, istnieją dwie metody odwoływania się do elementu tablicy - przez użycie indeksu w tablicy (np. k[3]) lub odpwiednio zdefiniowanego wskaźnika (np. *(p_k + 3) ).

Przykłady:
char c[5] = {'a','b','c','d',''} - definiuje tablicę znakową typu char o nazwie c, złożoną z 5 elementów, której przypisano wartości początkowe od 'a' do 'd' i zakończono znakiem końca ciągu znaków
char *string = c - definiuje zmienną string jako wskaźnik do zmiennej typu char i nadaje jej wartość początkową c, tak aby wskazywała tablicę c
int *p[4] - definiuje tablicę 4 wskaźników do liczb całkowitych
int (*p[4]) () - definiuje tablicę 4 wskaźników do funkcji, dających w wyniku liczby całkowite
int k[3] [4] - definiuje tablicę dwuwymiarową o rozmiarze 3x4: k[0][0], k[0][1], k[0][2], k[0][3] k[1][0], k[1][1], k[1][2], k[1][3] k[2][0], k[2][1], k[2][2], k[2][3]

Nazwa tablicy jest stałą mającą znaczenie jej pierwszego elementu. W tablicach wielowymiarowych, jak tablica powyżej, stała k jest adresem elementu k[0][0] (zmiennej. Stała k[0] jest adresem pierwszego elementu pierwszego wiersza tablicy, to jest k[0][0]. Stała k[1] jest adresem pierwszego elementu drugiego wiersza tablicy, to jest k[1][0] itd.

Wskaźniki do zmiennych używane są także w innych sytuacjach:
1. Sytuacje, w których wymagania na rozmiar pamięci nie da się określić w chwili kompilacji i pamięć musi być przydzielona dynamicznie. Nie zawsze bowiem wiadomo dokładnie, jak duża tablica jest potrzebna i dynamiczny przydział pamięci z użyciem np. funkcji malloc i free pozwala optymalizować wykorzystanie pamięci.
2. Umożliwienie funkcjom modyfikowanie zmiennych, które są dla nich niewidoczne. W języku C funkcja może zmodyfikować wartość zmiennej, której nie widzi, pod warunkiem, że widzi wskaźnik do niej, jeżeli ten wskaźnik został zdefiniowany globalnie lub jest jednym z argumentów funkcji.

Przykład
int i; int k;
funkc(&i, k); - wywołanie funkcji
void func(j, n) - definicja funkcji
{
int *j; int n;
*j = 1; - nadanie i wartości 1
n = *j; - nie ma wpływu na k
}

 

Struktury

Struktura (słowo kluczowe w postaci struct) jest to zbiór logicznie powiązanych zmiennych różnych typów, odpowiadających rekordowi w języku Pascal. Struktury można określić na jeden z trzech sposobów:

1. struct complex
{
double real;
double imaginery;
}

Zadeklarowano tu strukturę o nazwie complex, ale nie zdefiniowano żadnej zmiennej. Definicje podane poniżej są poprawne pod warunkiem, że odbywają się w zasięgu powyższej deklaracji:
struct complex c1;
struct complex *c1;
struct complex *func();
struct complex c[2];

2. struct
{
double real;
double imaginery;
} c;

Zadeklarowano tu nie nazwaną strukturę i zdefiniowano pojedynczą zmienną tego typu. Ponieważ ta struktura nie ma oznacznika, nie jest więc możliwe zdefiniowanie innych zmiennych lub wskaźników do struktury tego typu.

3. struct complex
{
double real;
double imaginery;
} c[2];

Zadeklarowano tu strukturę o nazwie complex i zdefiniowano tablicę dwóch zmiennych typu struct complex. Definicje i deklaracje podane dla pierwszego przykładu są także tutaj dopuszczalne pod warunkiem, że znajdują się w zasięgu tej deklaracji.

Elementami struktury mogą być zmienne dowolnego typu. Wskaźnik do deklarowanej struktury może być zdefiniowany jako jeden z jej elementów. Taka właściwość nosi nazwę autoreferencji struktury.
struct node
{
struct node *parent;
struct node *right_child;
struct node *left_child;
char c;
};

Do poszczególnych elementów struktury można się odwoływać w różny sposób. Przy podanych niżej deklaracjach i definicjach:
struct complex
{
double real;
double imaginery;
} c;
struct complex *p_c = c;

Wyrażenie p_c jest wskaźnikiem do struktury c.
Wyrażenia
- c.real
- (*p_c).real
-p_c -> real
odnoszą się do zmiennej real w strukturze c.

 

Inicjowanie zmiennej

Definicja zmiennej może także zawierać nadanie jej wartości poczatkowej (inicjowanie). Składnia jest następująca:
- dla zmiennych prostych definicja = wyrażenie;
- dla agregatów (struktur i tablic) definicja = {lista_wartości_początkowych};
Unie i agregaty klasy auto nie mogą być inicjowane. Wyrażenie musi być stałą lub wynikiem jego obliczenia musi być stała albo adres poprzednio zadeklarowanej zmiennej (ewentualnie przesunięty o stałą wartość). Lista_wartości_początkowych jest listą wartości dla elementów agregatu, oddzielonych przecinkami, w kolejności rosnących numerów tych elementów. Zmienne klasy auto lub register mogą dodatkowo być inicjowane za pomocą wyrażeń zawierających wywołanie funkcji lub za pomocą poprzednio zdefiniowanych lub zadeklarowanych zmiennych, gdyż inicjuje się podczas wykonywania programu, a nie podczas kompilacji. W przypadku inicjowania agregatu, jeśli liczba elementów w liście wartości początkowych jest mniejsza niż liczba elementów agregatu, to pozostałym elementom agregatu nadaje się wartość zero. Tablicy znakowej można nadać wartość początkową za pomocą ciągu znaków.

Przykłady
int i = 3;
int k[4] = { 0, 4, 6, 9};
int k[] = {5, 10, 8};
int m[4] = {1,2};
int n[4][3] = { {1,2,3}, {4,5,6} }; - definiuje następującą tablicę:
n[0][0] = 1 n[0][1] = 2 n[0][2] = 3
n[1][0] = 4 n[1][1] = 5 n[1][2] = 6
n[2][0] = 0 n[2][1] = 0 n[3][2] = 0
int n[4][3] = { 1,2,3, 4,5,6 }; - definiuje taką samą tablicę, jak poprzednio
int q[4][3] = { {1}, {2}, {3}, {4} }; - definiuje tablicę 2-wymiarową w następujący sposób:
q[0][0] = 1 q[1][0] = 2
q[2][0] = 3 q[3][0] = 4
Pozostałym elementom tablicy nadaje się wartość zero.

Instrukcja char *ostrzeżenie = "Uważaj na zakrętach" definiuje ciąg znaków tak duży, aby zmieścił się w nim tekst, stanowiący jego wartość początkową, łącznie zkończącym każdy ciąg znaków znakiem ''.

Instrukcja
struct
{
char *słowo;
int licznik;
} start [4] = { "witaj", 0, "żegnaj", 0 };

definiuje tablicę 4 struktur, przy czym pierwszym pierwszym dwóm elementom tablicy (strukturom) nadaje się następujące wartości:
start[0].słowo = "witaj"
start[0].licznik = 0
start[1].słowo = "żegnaj"
start[1].słowo = 0
Pozostałym elementom struktury przypisuje się wartość zero.

 

Funkcje

We wszystkich plikach źródłowych, które są kompilowane i konsolidowane w celu utworzenia programu wynikowego, tylko jedna funkcja może nosić nazwę main. Pierwsza wykonywana instrukcja instrukcja w programie jest też pierwszą wykonywalną instrukcją w main.

W języku C wszystkie funkcje znajdują się na tym samym poziomie składniowym; nie można definiować funkcji wewnątrz funkcji. Co więcej, wszystkie funkcje we wszystkich plikach tworzących program oraz wszystkie funkcje w bibliotekach dołączonych przez konsolidatorsą widoczne dla wszystkich pozostałych funkcji. Jedynym wyjątkiem jest funkcja określana jako static; jej widoczność jest ograniczona do pliku źródłowego, w którym została zdefiniowana.

Funkcja może być wywoływana z argumentami, które są przekazywane przez wartość. W języku C nie występuje wywołanie przez nazwę, gdyż wywołana funkcja otrzymuje kopię argumentu i nie jest w stanie zmienić wartości oryginalnej zmiennej. Wyjątek stanowią argumenty będące tablicą; w tym wypadku przekazuje się wskaźnik do tablicy, a nie samą tablicę, ponieważ - jak zauważyliśmy wcześniej - przez nazwę tablicy rozunie się jej adres. W niektórych wersjach języka C jest możliwe wywołanie struktury przez nazwę.

Funkcja nie może modyfikować wartości swoich argumentów (z wyjątkiem dwóch wypadków wywołania przez nazwę omówionych wyżej). Mimo to funkcja może modyfikować wartość zmiennej niewidocznej dla niej, jeśli widzi ona adres tej zmiennej jako swój argument albo jako zmienną globalną.

Funkcja może zwracać wynik za pomocą instrukcji return. Jeśli funkcja nie zwraca żadnego wyniku poprzez swoją nazwę, to w nagłówku funkcji podaje się modyfikator void. Możliwe jest przekazanie jako argumentu funkcji nazwy innej funkcji, zwanej "wskaźnikiem do funkcji". Ciało funkcji, to jest definicje, deklaracje i instrukcje, musi być zawarte w nawiasach klamrowych.

Przykłady deklaracji funkcji

deklaracja znaczenie
int f() f jest funkcją dającą w wyniku liczbę całkowitą
int *f() f jest funkcją dającą w wyniku wskaźnik do zmiennej całkowitej
int (*) f() f jest wskaźnikiem do funkcji dającej w wyniku liczbę całkowitą
int (*f[4])() f jest tablicą 4 wskaźników do funkcji dających w wyniku liczby całkowite

Przykład - funkcja zwracająca długość tekstu
int długość (t)
char *t;
{
int n;
for (n = 0; *t != ''; t++)
{++n;}
return n;
}

Wywołanie:
char *tekst="ola ma kota";
printf ("dlugość tekstu = % d, długość(tekst));

 

Argumenty funkcji main

W wielu systemach operacyjnych funkcja main akceptuje dwie zmienne:
- int argc - liczbę całkowitą pokazującą liczbę argumentów w wierszu poleceń przy wywoływaniu programu (łącznie z nazwą programu),
- char *argv[ ] - wskaźnik do tablicy ciągów znakowych, zawierających argumenty z wiersza poleceń; alternatywnie argv może być zadeklarowany jako **argv, jeśli programiście ta postać bardziej odpowiada.

Przykład

Jeśli program został wywołany z systemu operacyjnego za pomocą następującego wiersza poleceń:
program abc def 6
to argc wynosi 4, a argv jest tablicą 4 znaków: arg[0] = "program" arg[1] = "abc" arg[2] = "def" arg[3] = "6"

Standardowa postać programu do przeglądania argumentów funkcji main (oprócz pierwszego, który jest zawsze nazwą programu) ma postać:
main (argc, argv)
int argc;
char **argv;
{while (--argc > 0)
{ ... *( ++argv ) ... }}

   



Zrobić ćwiczenie 10 i 12 z laborek ( za tydzień kolos MiTP )


Linki linux:

Poradnik


LINK Ścig

 
Ankieta  
 

Czy podoba ci się ta strona?
TAK
NIE
TROCHĘ
NIEWIEM
NIE MAM ZDANIA

(Pokaż wyniki)


 
Unitra DIORA WS 442  
   
Latarka LED  
   
Geostat  
 
IP
 
Dzisiaj było 20 odwiedzającyna tej stronie.
This website was created for free with Own-Free-Website.com. Would you also like to have your own website?
Sign up for free