Wskaźniki
Wskaźnik to taki typ, w którym przechowujemy adres komórki, na który on wskazuje, a jednocześnie umożliwia on odczytanie i zmianę zawartości tej komórki.
Wskaźniki muszą być zadeklarowane i w deklaracji musi być podany typ zmiennej, na który on wskazuje.
Wykorzystywany jest tu znak *. I tak:
int k; deklaracja zmiennej typu całkowitego
int *w; deklaracja wskaźnika, który może wskazywać na zmienne typu
całkowitego
w=&k; od tego momentu wskaźnik w wskazuje na komórkę o adresie (&)
gdzie umieszczona jest zmienna k
k==*w wydruk zmiennej k jest równoważny z wydrukiem *w
w==&k wydruk adresu &k jest równoważny z wydrukiem w.
# include <stdio.h>
void main()
{
double k,*w,a,b;
printf("Podaj wartosc k\n");
scanf("%lf",&k);
w=&k;
a=45;
printf("wartosci\n");
printf(" k=%lf\n",k);
printf("*w=%lf\n\n",*w);
printf("adresy\n");
printf("&k=%x\n",&k);
printf(" w=%x\n\n",w);
printf("w+1=%x\n",w+1);
printf(" &a=%x\n\n",&a);
return;
}
#include <stdio.h>
void f(double *);
void main()
{
double *s,k;
s=&k;
f(s);
printf("%lg\n",*s);
printf("%x\n",s);
}
void f(double *p)
{
*p=4.;
}
double *s,k;
Pamięć operacyjna
&k
wskaźnik do double
s=&k;
s=&k
k=śmiecie
wskaźnik do komórki o adresie &k
Jeżeli do komórki o adresie &k wprowadzimy wartość 4 tzn. napiszemy k=4, wtedy: s=&k
Ten sam efekt uzyskamy pisząc: *s=4
w programie przypisano parametr aktualny *s, parametrowi formalnemu *p
Dynamiczna alokacja tablic
Wewnątrz programu tablice deklaruje się dynamicznie przy pomocy funkcji, która rezerwuje dla nich przestrzeń w pamięci. Funkcją tą jest:
malloc(...) - memmory allocation
Parametrem funkcji jest wymiar rezerwowanej przestrzeni pamięci w bajtach równy:
liczbie elementów x wielkość elementu(w bajtach).
Do określenia wielkości elementu posłużyć się można funkcją
sizeof(typ zmiennych)
Wartość podawaną przez funkcję malloc(...) należy przypisać wskaźnikowi do obiektu, odpowiadającemu typowi obiektu, któremu przydziela się pamięć.
Przykład
Dynamiczna deklaracja tablicy jednowymiarowej tabl zawierającej n elementów typu int.
deklarujemy zmienne:
int i, n, *tabl;
...........................
........................... // obliczamy lub przypisujemy wartość
........................... // zmiennej n
tabl=(int*)malloc(n*sizeof (int));
………………….
for (i=0; i<n; ++i)
tabl[i]=.....................//przypisujemy wartości
............................. //kolejnym elementom tablicy
Tablice dwuwymiarowe
Tablicę dwuwymiarową traktować można jak tablicę tablic jednowymiarowych
tabl [nw] [nk]
co można rozumieć jako: tablica tablic Tabl, której elementami są wiersze będące jednowymiarowymi tablicami tabl[nk] - takich tablic jest nw
Z tablicami tabl[i] związane są wskaźniki i stąd tablica tablic tabl musi zawierać wskaźniki do wskaźników ( **)
Przykład
Dynamiczna deklaracja tablicy dwuwymiarowej tabl zawierającej nw
tablic jednowymiarowych zawierających po nk elementów typu double.
deklarujemy zmienne:
int i, nw , nk;
double **tabl; //tablica tablic
int *wtabl //tablica długości wierszy
.........................
......................... //nadawanie wartości zmiennym nw i nk
wtabl=(int*)malloc(nrow*sizeof(int));
for (i=0;i<nrow;++i) wtabl[i]=nw;
tabl=(double**)malloc(nw*sizeof(double*));
for (i=0 ; i<nw; ++i )
tabl[i]=(double*)malloc(nk*sizeof(double));
……………….
for (i=0 ; i<nw; ++i )
for (j=0 ; j<nk; ++j )
tabl[i][j]= ...........//przypisujemy wartości
............................. //kolejnym elementom tablicy
Dynamicznie zajętą pamięć zwraca się koniecznie po wykorzystaniu tablicy:
free(tabl);
tabl(NULL);
Ostatni krok nie jest konieczny, ale zabezpiecza program przed skutkami ponownego zwolnieniu pamięci zajmowanej przez tabl (np. przez gapiostwo)
Dynamiczna deklaracja tablicy n x n. n wczytywane z klawiatury
#include <stdlib.h>
#include <stdio.h>
void AlokacjaTab();
void WartosciTab();
void WydrukTab();
void UwolnienieTab();
// zmienne globalne
int n;
double **ptab; // tablica tablic
int main()
{
printf( "Podaj ilosc wierszy:\n");
scanf( "%d", &n);
AlokacjaTab();
WartosciTab();
WydrukTab();
UwolnienieTab();
return 0;
}
void AlokacjaTab()
{
int i;
ptab = (double**)malloc( n*sizeof(double*));
for ( i=0; i<n; ++i)
ptab[i] = (double*)malloc( n*sizeof(double));
}
void WartosciTab()
{
int i, k;
for ( i=0; i<n; ++i)
for ( k=0; k<n; ++k)
ptab[i][k] = rand() /
(double)RAND_MAX ;
}
void WydrukTab()
{
int i, k;
printf("\n");
for ( i=0; i<n; ++i)
{
for ( k=0; k<n; ++k)
printf( "%6.4f\t",ptab[i][k] );
printf( "\n");
}
printf( "\n");
}
void UwolnienieTab()
{
int i;
for ( i=0; i<n; ++i)
free( ptab[i]);
free( ptab);
ptab = NULL;
}
Struktury
Struktura jest złożonym typem danych określonym jedną nazwą. Struktura grupować może kilka elementów o różnych typach i rozmiarach.
Struktura musi być zadeklarowana np:
struct katalog
{
int numer;
char tytol_ksiazki [50];
char autor [30];
int rok_wyd;
char dzial [20];
};
Powyższa deklaracja struktury nie stanowi definicji obiektu danych. Aby zdefiniować strukturę można użyć poniższego zapisu:
struct katalog
{
int numer;
char tytol_ksiazki [50];
char autor [30];
int rok_wyd;
char dzial [20];
} ksiazki_naukowe;
lub
struct katalog ksiazki_naukowe
Do poszczególnych elementów struktury (do jego składowych) odwoływać się można w następujący sposób:
ksiazki_naukowe.tytul, ksiazki_naukowe.rok_wydania
Tablica może być elementem (w powyższym przykładzie występują tablice znakowe np. autor[30]) oraz struktura może być elementem tablicy np.:
struct katalog ksiazki[40];
Przypisanie wartości poszczególnym elementom struktury odbyć się może w dowolnym miejscu programu np.:
ksiazki[2].tytul="W pustyni i w puszczy";
ksiazki[2].rok_wydania=1975;
itp.
Inicjowanie struktury (jak każdej innej zmiennej) może odbywać się jedynie w miejscu jej zdefiniowania np.:
struct katalog
{
int numer;
char tytol_ksiazki [50];
char autor [30];
int rok_wyd;
char dzial [20];
};
struct katalog ksiazki[5]
{
234
"O czym każdy chłopiec wiedzieć powinien"
"H.Myślicielski"
1999
"Przyrodniczy"
}
Czas
Programy wywołujące funkcje związane z datą i czasem muszą zawierać:
#include <time.h>
Wydruk daty i godziny
#include <stdio.h>
#include <time.h>
int main()
{
struct tm *ptr;
time_t lt;
lt=time(NULL);
ptr=localtime(<);
printf(asctime(ptr));
return 0;
}
Wyznaczenie czasu jaki upłynął pomiędzy instrukcją start=... i end=...
#include <stdio.h>
#include <time.h>
int main()
{
time_t start,end;
long unsigned t;
start=time(NULL);
for (t=0;t<5e8;t++);
end=time(NULL);
printf("Petla zuzyla %lf sekund.\n\n",difftime(end,start));
return 0;
}
Porównanie czasu trwania mnożenia i potęgowania.
#include <stdio.h>
#include <time.h>
#include <math.h>
int main()
{
time_t start,end;
long unsigned t;
double a=5,b;
start=time(NULL);
for (t=0;t<5e7;t++)
b=a*a;
end=time(NULL);
printf("Petla a*a zuzyla %lf sekund.\n\n",difftime(end,start));
start=time(NULL);
for (t=0;t<5e7;t++)
b=pow(a,2);
end=time(NULL);
printf("Petla a^2 zuzyla %lf sekund.\n\n",difftime(end,start));
return 0;
}
Napisać program, który z klawiatury wczytuje współrzędne czterech punktów w przestrzeni. Traktując jeden z tych punktów jako wspólny wyznacza trzy wektory o początku w tym punkcie i oblicza trzy płaskie kąty pomiędzy tymi wektorami. Program poza funkcją main() ma zawierać:
funkcję wczytującą współrzędne punktu
funkcję wyznaczającą współrzędne wektora
funkcję wyznaczającą długość wektora
funkcję wyznaczającą iloczyn skalarny dwóch wektorów
funkcję wyznaczającą kąt pomiędzy dwoma wektorami.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
void wczytaj(int[]);
void wektor(int[],int[],int[]);
double dlug(int []);
int iloczyn(int[],int[]);
double kat(int[],int[]);
void main()
{
int p1[3],p2[3],p3[3],p4[3];
int w1[3],w2[3],w3[3];
double a,b,c,ws;
ws=180/3.1416;
wczytaj(p1);
wczytaj(p2);
wczytaj(p3);
wczytaj(p4);
wektor(p1,p2,w1);
wektor(p1,p3,w2);
wektor(p1,p4,w3);
a=ws*kat(w1,w2);
b=ws*kat(w1,w3);
c=ws*kat(w2,w3);
printf("Katy wynoszą:\n
a=%6.2f b=%6.2f c=%6.2f\n\n",a,b,c);
}
,
void wczytaj(int t[])
{
printf("podaj wspolrzedne punktu\n");
scanf("%d%d%d",&t[0],&t[1],&t[2]);
}
void wektor(int pp[],int pk[],int w[])
{
int i;
for (i=0;i<3;i++)
w[i]=pk[i]-pp[i];
}
double dlug(int w[])
{
int i,d=0;
for (i=0;i<3;i++)
d=d+w[i]*w[i];
return sqrt((double)d);
}
int iloczyn(int wa[],int wb[])
{
int i,s=0;
for (i=0;i<3;i++)
s=s+wa[i]*wb[i];
return s;
}
double kat(int wa[],int wb[])
{
return acos(iloczyn(wa,wb)/
dlug(wa)/dlug(wb));
}
Sortowanie Quicksort oraz bąbelkowe
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void quick(double *,int);
void qs(double *,int,int);
void sort (int, double []);
int main()
{
time_t start,end;
long unsigned t;
double s[50000],s1[50000];
unsigned long int n,i;
n=50000;
for (i=0;i<n;i++)
s[i]=rand()/(double)RAND_MAX;
for (i=0;i<n;i++)
s1[i]=s[i];
start=time(NULL);
quick(s,n);
end=time(NULL);
printf("Sortowanie Quicksort czas %f sekund.\n\n",difftime(end,start));
printf("\n");
start=time(NULL);
sort (n,s1);
end=time(NULL);
printf("Sortowanie babelkowe czas %f sekund.\n\n",difftime(end,start));
printf("\n");
return 0;
}
//sortowanie Quicksort
void quick(double *s,int n)
{
qs(s,0,n-1);
}
void qs(double *s,int lewy,int prawy)
{
register int i,j;
double x,y;
i=lewy; j=prawy;
x=s[(lewy+prawy)/2];
do
{
while ((s[i]<x)&&(i<prawy))i++;
while ((x<s[j])&&(j>lewy))j--;
if(i<=j)
{
y=s[i];
s[i]=s[j];
s[j]=y;
i++;j--;
}
} while (i<=j);
if(lewy<j) qs(s,lewy,j);
if(i<prawy) qs(s,i,prawy);
}
//sortowanie babelkowe
void sort (int n, double tab[])
{
int i,j;
double r;
for (i=0;i<n-1;++i)
for (j=0; j<n-i-1;++j)
if (tab[j]>tab[j+1])
{
r=tab[j];
tab[j]=tab[j+1];
tab[j+1]=r;
}
}
INFORMATYKA WYKŁAD 6 Temat: Język C 8
wielkość
elementów
typ tablicy
k=*s=4
k=śmiecie