Podstawy Programowania Wykład.docx

(417 KB) Pobierz

3 pytania

1 pytanie to funkcja z tablicami nie używając nawiasów kwadratowych. Kopiowanie tablic. Podstawowy wzór języka C.

2 pytanie deklaracja wskaźnika

3 pytanie to teoretyczne… coś o wskaźnikach, wszystko szczegółowo podać… kiedy operacje mają sens itp.

Pełna odpowiedź daje ocenę dostateczną.

 

 

 

Wskaźnik jest zmienną lub stałą zawiarającą adres innej zmiennej. Najczęściej są czterobajtowe.

              Operator wyłuskania (*). Jego argumentem jest jakieś wyrażenie wskaźnikowe (jest to takie, które po policzeniu staje się wskaźnikiem)

              *wsk <- definicja operatora wyłuskania

 

+ -> na początku nie było go w C. Podobno nic nie robi, ale może zepsuć program. Zwraca on wartość, a nie zmienną A.

- -> negacja arytmetyczna

 

A – zmienna

+A – jest wartością tej zmiennej

 

*wsk <- Tryb podstawowy

Int *wsk;              <- deklaracja wskaźnika wsk

 

Kkp rysunek

Int zm;

Int *wsk = &zm

Int **wsk1; <- będzie typu podstawowego (przez to że są dwa wsk?)

Jak wskaźniki mają zerową wartość to znaczy że na nic nie wskazują. Jak ma wartość przypadkową to nie możemy na co wskazują?

 

Operator pobrania adresu

 

Operator pobrania adresu zwraca adres. Np. zbada zm i zwróci jej adres.  Możemy go wstawić do wskaźnika.

Wsk = & zm;

Znaczek – & ? ^^

& zm; <- nie może być stała, musi być jakaś zmienna. Zmienne mają adres a stałe nie mają

*wsk=1000; <- nie zmieni wsk. Zmieni zmienną zm.   <->               zm=1000;

Wsk1 =&wsk;

**wsk1;   <- dwie gwiazdki będzie to samo co zm.   <->                            zm = 2000;

We wskaźniki nie można przyjmować wartości? Sami nie możemy tych wartości sami wymyślać. Wartości całkowitych. Z wyjątkiem 0. Zero możemy sobie sami wpisać

 

Int tab[10];

TUTAJ MA BYĆ TA CHORA TABELKA ^^

Int *wsk=& tab[0];

++wsk;  <- zamiast 4001 będzie 4004

wsk=wsk+2

Skalowanie wskaźników polega na tym że jeżeli do wskaźnika dodajemy liczbę całkowitą. To ta liczba jest mnożona przez długoś elementu na który wskazuje wskaźnik i dopiero ta pomnożona liczba jest dodawana do adresu.

Przykład: wsk=wsk+2

 

Jest także wskaźnik typu „pustego”?

void*wsk <- wskazuje na typ nieokreślony, nie można z niego wyłuskać oraz nie można nic dodawać. Kompilator nie wie jaka jest długoś elementu.

Char*wsk <- do tego podobno można dodawać

 

Dodając liczby całkowite musimy sami sprawdzać aby nie wyjść poza adres/wielkość tablicy. Żeby się nie znaleźć z adresem poza tablicą. System ani kompilator nie będą nam sprawdzać ^^.

NIE MOŻNA DODAWAĆ JAKICHKOLWIEK LICZB DO WSKAŹNIKÓW, można tylko zero.

WSK=1
NIE MOŻEMY PRZEKROCZYĆ TABLICY

Jeżeli za bardzo przekroczymy tablice to możemy wejść na adresy systemu operacyjnego? Czy coś takiego. Dopisać….

 

Przyrównywanie i inne operacje na wskaźnikach:

 


Wsk++

Wsk—

Wsk+n

Wsk-n


 


Wsk==0

Wsk!=0

Wsk==wsk1

Wsk!=wsk1


 

!wsk // gdy wskaźnik jest równy 0

!!wsk // gdy wskaźnik jest różny od zera

 

Można porównywać wskaźniki ze sobą np. wsk > wsk1 lub takie jak >= < <=

Wskaźniki można między sobą odejmować wsk – wsk1

 

Jest także operacja np.

Double *wsk;

Int z;

Wk=&z;                                          <- Nie da się

Wsk=(double*)&z;              <- Jest to tak zwane rzutowanie wskaźników

*wsk=15;

*(int*)wsk=15;                            // wyłuskane z? Wartość 15 będzie w zmiennej z.

 

Wsk=(double*)1; <- tak się podobno da.

 

Podstawowy wzór języka C

*(wsk+1)=wsk[i];

Operator wyłuskania = [i] <- pobranie elementu z tablicy

Tu są 3x równa się xD. To znaczy 3 kreski. Że są równoważne

 

Rezerwowanie tablicy int tab[10] <- zadeklarowaliśmy tablice o wielkości 10. 40 bajtów zarezerwowanych

Int tab[10];

C:\Users\ShadowUS\Desktop\IMG_3706.JPG

Tab jest uważane za stały wskaźnik.

Są modyfikatory 0, 1, 2. Są liczbami całkowitymi.

Tab[0] <- 4 bajty

Bierzemy adres tab[0] i wyłuskujemy 4 bajty z niego?

Tab[1] to 4 bajty dalej położone. *(Tab+1) do adresu tab dodajemy jedynkę. Wykonywane jest skalowanie wskaźników, jeden jest mnożony przez 4. Więc do adresu tab będą dodane 4 bajty. Nastąpi wyłuskanie i będą to te 4 bajty.

 

Int z;

Int *wsk=&z;

Te na dole są identyczne!! Te 3 na dole ^^. To chyba przypisywanie liczby

*wsk=150;

*(wsk+0)=150

Wsk[0]=150;

z=150; <- to też jest to samo. Tylko łatwiejsze

 

Deklarowanie wskaźników związanych z tablicami:

Tablica 10 wskaźników

*tab[k]

Int *tab[10]; <- deklaracja tego wskaźnika na tablicy. Czy jakoś takoś.

(*wsk)[k]         *wsk[k] <- to drugie zabrałoby nam k przed wyłuskaniem. Chuj wi co to znaczy

Int (*wsk)[20]; <- 20 elementowa

Int(*wsk1)[60] <- wsk1 jako tablica 60 elementowa

Wzór int(*wsk[)]

 

Tablica 10 wskaźników

RYSUNEK TEGO GÓWNA ŚMIESZNEGoC:\Users\ShadowUS\Desktop\dfdfdfdfdfd.jpg

 

*tab[2] == tb[0]

Tutaj kolumny są różnej długości. Kolumna 2 ma długość 50, kolumna też ma jakąś długość… pozostałe kolumny nie istnieją?

 

Int tb[50]

Tab[2]=&tb[0];

Jedno zadanie będzie polegało na napisaniu prostej funkcji bez użycia nawisów kwadratowych. To chyba na kolos? Musimy znać obie formy

 

Czy to jest wskaźnik? Nie jest bo nie ma operatora wyłuskania…

Int fun(int,int);

Aby uzyskać wskaźnik do funkcji o znaneym prototypie. Należy zastąpić w nim nazwę funkcji przez (* nazwa_wskaźnika)

Np. int (*wsk)(int, int);

FUNKCJA WSK - Int *wsk (int,int)  <- priorytet nawiasów jest większy…. Gwiazdka jest operatorem o jeden priorytet mniejszym. Mamy funkcje *wsk i ta funkcja ma dwa parametry całkowite a później zwraca wskaźnik do int’a. To nie jest wskaźnik.

 

Inne przykłady deklaracji:

Zamiast t była nazwa funkcji int nazwa()

Int (*t[12])();  <- tablica wskaźników. Funkcja t[i] jest jakimś wskaźnikiem. Jak jest wyłuskanie to uzyskujemy funkcje bez parametrów i zwraca int. Jeżeli mamy coś takiego to należy oczekiwać na to t[i] możemy podstawić adres funkcji. Jeżeli mamy int fun(); to możemy podstawić adres przez t[i]=&fun; lub t[i]=fun;

 

Double (*(*t)())();  <- A CHUJ NIE WIEM CO ON TU GADA!

Gwiazdka musi być użyta do nazwy…

 

 

To jest odwrotne do tego na górze! To na dole nie jest już wskaźnikiem gdyż * ma priorytet niższy niż nawiasy okrągłe. Jest to deklaracja jakieś funkcji fun

Double (*fun())();

 

 

ZADANIE KURWA!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Zadeklarować tablice 10 wskaźników. Do funkcji całkowitych mających dwa parametry int i double*.

int (*tab[10])(int, double*); <- nikt nam nie zabierze tablicy.. później () aby nikt nam tego wszystkiego nie zabrał.

 

Zadeklaruj wskaźnik do tablicy 10 wskaźników do funkcji całkowitych…

int (*tab[10])(int, double*); <- tab zastępujemy przez wskaźnik

czyli

int(*(*wsk)[10])(int, double*);

 

int fun1(int, int);

int fun2(int, int);

 

int main()

{

int(*wsk)(int, int);

if(getch()==’+’) wsk=fun1;               <- jeżeli napisze + to pod wsk podstawimy adres funkcji fun1

else wsk=fun2;                                          <- jeżeli coś innego to podstawi się adres fun2

printf(„%d”), wsk(3,5));                            <- tutaj robimy użycie wsk

 


int fun1(int a, int b)

{
return a+b;
}

 

Int fun2(int a, int b)

{

Return a*b;

}

 


W programie wielokrotnie musi robić zamianę dwóch zmiennych… No więc… doszedł wniosku że tyle razy ma to zamieniać więc pomyślał że zrobi sobie fuknkcję, która sama to będzie robić. Przez zmienną tymczasową. I napisał sobie funkcję.

Void swap(int *a, int *b)

{

Int temp;

Temp=*a;

*a=*b;

*b=temp;

}

 

Void main()

{

Int=5, y=7;

Swap(&x,&y);

Printf(„%d, x);

}

 

Tablice dynamiczne

Int ile, *tab;                             <- deklaracja tablicy, zmienna ile pokazuje ile danych będzie potrzebnych do przebiegu.

Scanf(„%d”, &ile);               <- przypisanie wielkości tablicy

tab=(int*)calloc(ile, sizeof(int)); LUB    tab=(int*)malloc(uke*suzeif(int));

if może być używane do wyrażeń wskaźnikowych

if(!tab)

{

printf(„Out of memory”);

Exit(1);  <- exit 1 oznacza zakończenie niepoprawne, a exit 0 oznacza zakończenie poprawni

}

Tab[ind]    0 <= ind <i le

! też może być przy wsk...

Zgłoś jeśli naruszono regulamin