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

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

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

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

Wskaźniki. Informatyka

Stałe, tablice dynamiczne i wielowymiarowe

Wskaźniki. Programowanie Proceduralne 1

Wskaźniki w C. Anna Gogolińska

int tab[5]; tab[1]; ciągły obszar pamięci, w którym umieszczone są elementy tego samego typu macierz [ ] - dwuargumentowy operator indeksowania

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

Programowanie I C / C++ laboratorium 03 arytmetyka, operatory

Języki i metodyka programowania. Wskaźniki i tablice.

> C++ wskaźniki. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki 26 kwietnia 2017

Stałe i zmienne znakowe. Stała znakowa: znak

Techniki Programowania wskaźniki

Lab 9 Podstawy Programowania

DYNAMICZNE PRZYDZIELANIE PAMIECI

> C++ dynamiczna alokacja/rezerwacja/przydział pamięci. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki

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

Tablice deklaracja, reprezentacja wewnętrzna

6 Przygotował: mgr inż. Maciej Lasota

Funkcja (podprogram) void

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

Tablice, funkcje - wprowadzenie

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

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

Tablice, funkcje, wskaźniki - wprowadzenie

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

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

Podstawy Programowania. Specyfikacja funkcji, operacje wejścia i wyjścia na plikach, rekurencja, tablice i wskaźniki

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

Funkcja, argumenty funkcji

wykład II uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - funkcje, tablice i wskaźniki wykład II dr Jarosław Mederski Spis

TABLICE W JĘZYKU C/C++ typ_elementu nazwa_tablicy [wymiar_1][wymiar_2]... [wymiar_n] ;

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

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

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

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 4. Karol Tarnowski A-1 p.

ZASADY PROGRAMOWANIA KOMPUTERÓW

Programowanie w C++ Wykład 4. Katarzyna Grzelak. 19 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 37

Podstawy programowania 1

Część 4 życie programu

Wstęp. do języka C na procesor (kompilator RC51)

Podstawy programowania komputerów

Jzyk C++ cz 3. Jarosław Gramacki Instytut Informatyki i Elektroniki ( $)*)+' *, - ( ' )*'.' '',*/ *, ','*0) 1 / ) %*+ 2'' 2" ( $%%) )'20 )*0) 1 / )

//zmienne globalne int *pa, *pb; //wskaźniki globalne void main(void) { clrscr(); printf("\n podaj wartosc liczby a\n"); scanf("%d",&a); pa=&a;

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

Zmienne i struktury dynamiczne

Język C zajęcia nr 11. Funkcje

Podstawy programowania w języku C++

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

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Programowanie komputerowe. Zajęcia 4

Tablice w argumentach funkcji. Tablicy nie są przekazywane po wartości Tablicy są przekazywane przez referencje lub po wskaźniku

Wykład 4: Klasy i Metody

Język C, tablice i funkcje (laboratorium)

Programowanie I C / C++ laboratorium 02 Składnia pętli, typy zmiennych, operatory

Język C, tablice i funkcje (laboratorium, EE1-DI)

Podstawy programowania w języku C++

main( ) main( void ) main( int argc, char argv[ ] ) int MAX ( int liczba_1, liczba_2, liczba_3 ) źle!

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Język ANSI C. część 11. Jarosław Gramacki Instytut Informatyki i Elektroniki

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

Struktury czyli rekordy w C/C++

tablica: dane_liczbowe

TEMAT : KLASY DZIEDZICZENIE

IX. Wskaźniki.(3 godz.)

Wykład Wskaźniki a tablice jednowymiarowe Arytmetyka wskaźników Dostęp do elementów tablic

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku

Podstawy programowania w języku C++

Wprowadzenie do programowania w języku C

Podstawy programowania w języku C++

Wstęp do Programowania, laboratorium 02

Co nie powinno być umieszczane w plikach nagłówkowych:

Język ANSI C tablice wielowymiarowe

Argumenty wywołania programu, operacje na plikach

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Języki programowania. Przetwarzanie tablic znaków. Część druga. Autorzy Tomasz Xięski Roman Simiński

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

Spis treści JĘZYK C - PRZEKAZYWANIE PARAMETRÓW DO FUNKCJI, REKURENCJA. Informatyka 1. Instrukcja do pracowni specjalistycznej z przedmiotu

część 9 wskaźniki - c.d Jarosław Gramacki Instytut Informatyki i Elektroniki Przykłady podstawowych wyrażeń ze wskaźnikami

Programowanie w języku C++

Podstawy programowania

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

Programowanie obiektowe w C++ Wykład 12

Wprowadzenie do programowania w języku C

E S - uniwersum struktury stosu

Wykład nr 3. Temat: Wskaźniki i referencje. Edward Morgan Forster

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

Programowanie obiektowe W3

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

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

W dowolnym momencie można zmienić typ wskaźnika.

Podstawy programowania. Wykład Co jeszcze... Przypomnienia, uzupełnienia. Krzysztof Banaś Podstawy programowania 1

Wstęp do programowania obiektowego, wykład 7

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

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

Podstawy programowania w języku C++

1 Wskaźniki. 1.1 Główne zastosowania wskaźników

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:

Transkrypt:

Język ANSI C część 8 wskaźniki - podstawy Jarosław Gramacki Instytut Informatyki i Elektroniki Podstawowe pojęcia najbardziej podstawowe operacje na wskaźnikach int x = 1, y = 2, Tab[10]; int *ip; // czy lepiej pisać int* ip;??? // kilka operacji ip = &x; // ip wskazuje na x y = *ip; // y ma wartość 1 *ip = 0; // x ma wartość 0 ip = &Tab[0]; // ip wskazuje na element Tab[0] ip = Tab; // j.w. ip = &Tab[2]; // wskaźnik na element tablicy o indeksie 2 // również: ip = Tab + 2; adres ip=0x456a667b 0x476c6671 zawartość... x == 1 y == 2 Tab 0 *ip 1 0x456a667b przykładowe wartości adresów wzięte "z głowy" 2

void main() int x = 1, y = 2, Tab[10]; int *ip; int i; ip = &x; // ip wskazuje na x printf("0x%p 0x%p [Dziesietnie: %lu]\n", ip, &x, ip); y = *ip; // y ma wartość 1 *ip = 0; // x ma wartość 0 ip = &Tab[0]; // ip wskazuje na element Tab[0] ip = Tab; // j.w. printf("0x%p 0x%p\n", ip, Tab); ip = &Tab[2]; printf("0x%p 0x%p\n\n", ip, &Tab[2]); for(i=0; i<10; i++) printf("[%d]: 0x%p \n", i, &Tab[i]); ip = NULL; printf("0x%p" ip); c:\temp>project1.exe 0x0022FF6C 0x0022FF6C [Dziesietnie: 2293612] 0x0022FF30 0x0022FF30 0x0022FF38 0x0022FF38 // wartość wskaźnika i adres zmiennej // zmiana wartości wskaźnika [0]: 0x0022FF30 [1]: 0x0022FF34 [2]: 0x0022FF38 [3]: 0x0022FF3C [4]: 0x0022FF40... 0x00000000 // wskaźnik pusty 3 Podstawowe pojęcia najbardziej podstawowe operacje na wskaźnikach // zwiększ obiekt wskazywany przez ip o jeden *ip = *ip + 1; *ip += 1; ++*ip; (*ip)++; *ip++; // zwiększa wskaźnik a NIE wskazywany obiekt // uawga na priorytet i łączność operatorów ++, * // łączność prawostronna, ten sam priorytet *(ip++) // tak wyrażenie *ip++ opracowuje kompilator // (nawiasy wymuszone przez kompilator) 4

Wskaźniki jako argumenty funkcji // przekazywanie przez wartość void Get2Int (int, int); int main (void) int x = 4, y = 5; Get2Int (x, y); printf("first: %d, Second: %d\n, x, y); // 4, 5 void Get2Int (int xx, int yy) xx = 10; yy = 20; printf("first: %d, Second: %d\n, xx, yy); // 10, 20 5 // przekazywanie przez zmienną (przez wskaźnik, przez adres) void Get2Int (int*, int*); int main (void) int x = 4, y = 5; Wskaźniki jako argumenty funkcji Get2Int (&x, &y); printf("first: %d, Second: %d\n, x, y); // 5, -5 void Get2Int (int *px, int *py) *px = *px + 6 - *py; *py = *py - 6 - *px printf("first: %d, Second: %d\n, *px, *py); // 5, -5 w wywołaniu Get2Int (&x, &y); przekazano adresy zmiennych x i y gdzie zostaną umieszczone wyniki działania funkcji Get2Int() przekazanie wskaźnika do funkcji pozwala na ingerencję w zawartość zmiennych utworzonych poza funkcją. zmienne x i y zostały (poprzez ich zadeklarowanie) utworzone i przydzielono im pamięć w funkcji main() 6

Zwracanie z funkcji wyników obliczeń // zwracanie z funkcji jednej wartości int Get2Int (int, int); // wynik jako wartość funkcyjna int main (void) int x = 4, y = 5, result; result = Get2Int (x, y); printf("result: %d\n, result); int Get2Int (int x, int y); int result; result = x + y + 1; return (result); 7 // zwracanie z funkcji więcej niż jednej wartości // użycie np. 3 x return??? int Get2Int (int, int, int*, int*);// status jako wartość funkcyjna // wyniki przez nagłówek funkcji int main (void) int x = 4, y = 5, result1, result2, status; status = Get2Int (x, y, &result1, &result2); printf("results: %d %d\n, result1, result2); Zwracanie z funkcji wyników obliczeń int Get2Int (int x, int y, int *r1, int *r2); int status ; *r1 = x + y; *r2 = x - y; if (*r1 + *r2) > 100 status = 1; else status = 2; return (status); 8

Wskaźniki i tablice int Tab[5]; // int Tab[]; - Błąd!!! int Tab2[] = 1, 2, 3; // deklaracja i inicjalizacja int Tab3[100] = 1, 2, 3; //??? int *pa; // po alokacji pamięci może // "być" tablicą 5-cio elementową pa = &Tab[0]; // lub pa = Tab; pa = &Tab[2]; // pa = Tab[2]. Błąd!!! // teraz do elementów Tab możemy odwoływać się z użyciem pa MyVar = *pa; // trzeci element Tab MyVar = *pa++; // czwarty element Tab Tab: Tab[0] pa pa+2 pa = Tab; Tab[2] = 7; // wpis do elementu o indeksie 2 wartości 7 *(pa + 2) = 7; // j.w. 2[Tab] = 7; // poprawne!!! gdyż *(Tab + 2) == *(2 + Tab) pa[2] = 7; // poprawne 9 czy jednak Tab (nazwa tablicy) i pa (wskaźnik do tablicy Tab) to dokładnie to samo? - NIE! wskaźnik jest zmienną (wskaźnikową) nazwa tablicy jest stałą (wskaźnikową) //... gdzieś w programie Wskaźniki i tablice pa++; pa = Tab; Tab++; Tab = pa; // OK // OK // źle // źle // inny sposób zapamiętania int b = 7; b++; // OK 7++; //??? 7 = b; //??? 10

Specyfikator const specyfikator const NIE zmienia charakteru zmiennej ale uniemożliwia modyfikacje wartości tej zmiennej poprzednio mowa była o różnych charakterach zmiennej (stała i zmienna wskaźnikowa) użycie const w deklaracji tablicy oznacza, że żaden jej element nie może się zmienić const int Tab[] = 1, 4, -7, 88; Tab[2] = 100; // źle? uwaga: wg. normy ANSI C próba zmiany wartości zmiennej zadeklarowanej jako const kończy się w sposób zależny od implementacji! 11 Tablice znakowe char str[] = "ABCD"; // pięć znaków; ABCD + '\0' char str[]; // źle; ile zaalokować pamięci? char str[] = 'A', 'B', 'C', 'D', '\0'; char *pstr = "ABCD"; // wskaźnik wskazuje na stałą napisową! char *pstr2 = str; // wskaźnik wskazuje na zmienną napisową char *bufor; gets (bufor); // źle!!! str: pstr2 pstr: str wskazuje zawsze na ten sam obszar pamięci (jest tzw. stała wskaźnikową). Nie można zmienić wartości str (tak jak nie można na przykład napisać 7++). Można oczywiście napisać : str[2]='x'; pstr (zmienna wskaźnikowa) może zmieniać wartość jak każda zmienna. Może więc wskazywać na cokolwiek Ale uwaga! pstr jest wskaźnikiem zainicjowanym tak, aby wskazywał stałą napisową. Próba zmiany stałej napisowej zakończy się błędem wykonania (pstr[2]='x'; run-time error) ( Według K&R - ma skutek nieokreślony) 12

// przekaż do funkcji tablicę int GetTab ( int* ); to nawet sugeruje, że tablica jest // lub przekazywana przez wartość!!! // int GetTab ( int[] ); // int GetaTab ( int A[] ); identyfikator zbędny w prototypie // int GetaTab ( int A[7] ); rozmiar jest tu zbędny int main (void) int Tab[]=1,2,3,4,5,6,7, suma; Tablice jako parametry funkcji sizeof(tab) == 28 (7 x 4) Tab jest typu int(*)[7] (wskaźnik do tablicy 7-miu int-ów) suma = GetTab ( Tab ); // źle: suma = GetTab( &Tab ); // dobrze: suma = GetTab( &Tab[0]); // dobrze: suma = GetTab( &Tab[-3]);??? // dobrze: suma = GetTab( &Tab[2]); podtablica // dobrze: suma = GetTab( Tab + 2 ); podtablica int GetTab (int *ptr); int suma;??? for (i=0; i < 6; i++) // lepiej wymiar przekazać z miejsca wywołania // for (i=0; i < sizeof(ptr); i++) // źle: sizeof(ptr) == 4; zawsze! suma += ptr[i]; // lub: suma += *(ptr + i); return (suma); 13 Pointer / offset notation int main() int b[] = 10, 20, 30, 40 ; int *bptr = b; int i; int offset; printf( "\npointer / offset notation\n" ); for ( offset = 0; offset < 4; offset++ ) printf( "*( bptr + %d ) = %d\n", offset, *( bptr + offset ) ); c:\temp>project1.exe Pointer / offset notation *( bptr + 0 ) = 10 *( bptr + 1 ) = 20 *( bptr + 2 ) = 30 *( bptr + 3 ) = 40 14

Pointer subscript notation int main() int b[] = 10, 20, 30, 40 ; int *bptr = b; int i; int offset; Pointer subscript notation printf( "\npointer subscript notation\n" ); for ( i = 0; i < 4; i++ ) printf( "bptr[ %d ] = %d\n", i, bptr[ i ] ); Pointer subscript notation bptr[ 0 ] = 10 bptr[ 1 ] = 20 bptr[ 2 ] = 30 bptr[ 3 ] = 40 15 Zwracanie z funkcji wskaźnika long *function1 (long* pay); int main(void) long your_pay = 30000L; long *old_pay = &your_pay; long *new_pay = NULL; przykład dosyć sztuczny new_pay = function1( old_pay ); printf("\nold pay = $%ld", *old_pay); printf(" New pay = $%ld\n", *new_pay); long *function1(long *pay) *pay += 10000L; return pay; c:\temp>project1.exe Old pay = $40000 New pay = $40000 wyjaśnij to 16

Zwracanie z funkcji wskaźnika popracuj z debugerem 17 Zwracanie z funkcji wskaźnika ustawienia do wygodnego debugowania 18

Zwracanie z funkcji wskaźnika... int main(void) long your_pay = 30000L; long *old_pay = &your_pay; long *new_pay = NULL; printf("0x%p, 0x%p, 0x%p\n\n", &your_pay, old_pay, new_pay); printf("0x%p, 0x%p\n\n", &old_pay, &new_pay); Tylko czy potrzebujemy znać adresy wskaźników? NIE, wystarczą nam ich WARTOŚCI!!! new_pay = function1( old_pay ); printf("0x%p, 0x%p\n\n", new_pay, &new_pay); long *function1(long *pay) printf("0x%p, 0x%p\n\n", pay, &pay); *pay += 10000L; return pay; 0x0022FF4C, 0x0022FF4C, 0x00000000 0x0022FF48, 0x0022FF44 0x0022FF4C, 0x0022FF30 Contents your_pay 30000 *old_pay 0x0022FF4C *new_pay *pay Address 0x0022FF4C 30000 wypełnij pozostałe wartości 0x0022FF4C, 0x0022FF44 19