do druku
Transkrypt
do druku
Typy całkowite ( unsigned signed ) Pierwsza kolumna określa rodzaj arytmetyki. Zawsze jest ona modulo 2n (gdzie n — liczba bitów), ale • w przypadku unsigned zakres [0 . . 2n ) • w przypadku signed zakres [−2n−1 . . 2n−1 ) char short × int long long long Druga kolumna odpowiada za liczbę bajtów (po 8 bitów) przeznaczonych na wartość danego typu. Na Sigmie: char — 1 short — 2 int — 4 long — 8 long long — 8 Na innych (w tym na moim) bywa inaczej. . . Wykład 2. TYPY, str. 2 Typy całkowite 5 3 4 • zawsze taka sama arytmetyka modulo 2n , gdzie n — liczba bitów 2 6 ■ 1 + 7 • czerwony punkt widzenia odpowiada unsigned 1 rysunek dla n = 4 2 14 = − 3 − = 3 1 12 = −4 −5 6 11 = − = 10 1 1 ❘ 1 5 = − 7 + − 9= 0 8 = −8 • zielony punkt widzenia odpowiada signed • „znakowość” nie ma wpływu na wyniki działań, ale wpływa na wyniki porównań i na postać wydruku • domyślnie (jeśli niczego nie napiszemy) przyjmuje się signed Typy całkowite „Znakowość” wpływa na wyniki porównań #include<stdio.h> int main() { for (unsigned short n=32766; n<32768; n++) printf("%i\n", n); return 0; } drukuje dwie liczby 32766 32767 #include<stdio.h> int main() { for (signed short n=32766; n<32768; n++) printf("%i\n", n); return 0; } zapętla się na drukowaniu liczb z przedziału [−32768 . . 32768) 215 = 32768 Wykład 2. TYPY, str. 4 Typy całkowite „Znakowość” wpływa na postać wydruku Np. w typie short: 65535 = −1 (bo 216 = 65536) Jeśli unsigned , to zostanie wydrukowane 65535 , jeśli signed , to zostanie wydrukowane -1 . Typy całkowite Domyślnie (jeśli niczego nie napiszemy) przyjmuje się signed . char jest typem całkowitym, liczb jednobajtowych (8-bitowych). Zawiera więc • liczby z przedziału [0 . . 128) odpowiadające podstawowemu alfabetowi ASCII — np. zapis ’A’ oznacza liczbę 65 ; • liczby z przedziału [−128 . . 0) odpowiadające rozszerzeniu alfabetu ASCII zależnemu od kodowania — np. w Latin-2 zapis ’Ą’ oznacza liczbę −95 ; • w typie unsigned char w Latin-2 zapis ’Ą’ oznacza liczbę 161 = −95 + 256 . int main() { char c = getchar(); printf("%i\n", c); return 0; } int main() { unsigned char c = getchar(); printf("%i\n", c); return 0; } Wykład 2. TYPY, str. 6 Typy całkowite Zakresy short int bity zasięg czyli ok. 16 [−215 . . 215 ) 32 tys. MAŁO! int 32 [−231 . . 231 ) 2 mld może być za mało na liczenie zysków dużej firmy long long 64 [−263 . . 263 ) 9 trln za mało dla nowoczesnych programów szyfrujących Typy rzeczywiste — zmiennopozycyjne Wcześniej niż ENIAC! Pierwszy binarny programowalny komputer z wbudowanymi działaniami zmiennopozycyjnymi: Z3, zbudowany przez Konrada Zuse w 1941 (Berlin). Funkcjonował na elektromagnetycznych przekaźnikach, więc nie był jeszcze w pełni elektroniczny. Reklamowany jako nadający się do „badań ras ludzkich” oraz „cech dziedzicznych”; używany do obliczeń numerycznych przy badaniu szkodliwych wibracji skrzydeł samolotów. W 1943 zniszczony w alianckim nalocie bombowym na Berlin. Wykład 2. TYPY, str. 8 Typy rzeczywiste — zmiennopozycyjne Język C ma trzy typy rzeczywiste: znak cecha mantysa nadmiar float 1 8 23 32 (= 4 bajty) double 1 11 52 64 (= 8 bajtów) long double 1 15 64 48 długość słowa 128 (= 16 bajtów) Tak jest na Sigmie, na innych (w tym na moim) bywa inaczej. . . Wydłużenie mantysy o 1 bit powoduje 2-krotne zwiększenie precyzji. Wydłużenie cechy o 1 bit powoduje ?-krotne zwiększenie zasięgu. Wydłużenie cechy o 1 bit powoduje zwiększenie zasięgu do kwadratu. Zapis stałych liczbowych w programie 1234 1234L 12345678901 1234U 1234UL 0123 0X123 0X1FC 0XFUL ’a’ 123.4 1e-2 123.4F 1e-2F 123.4L 1e-2L : : : : : : : : : : : : : : : : całkowita (int) długa (long) długa (long) — bo w int się nie mieści całkowita bez znaku długa bez znaku całkowita (int) ósemkowa, równa (1 ∗ 8 + 2) ∗ 8 + 3 = 83 całkowita (int) szesnastkowa, równa (1 ∗ 16 + 2) ∗ 16 + 3 = 291 całkowita (int) szesnastkowa, równa (1 ∗ 16 + 15) ∗ 16 + 12 = 508 długa bez znaku (int) szesnastkowa, równa 15 znakowa (char) równa 97 rzeczywista (double) rzeczywista (double), równa 0.01 rzeczywista krótka (float) rzeczywista krótka (float) rzeczywista długa (long double) rzeczywista długa (long double) Wykład 2. TYPY, str. 10 Zapis stałych liczbowych w programie Jeszcze o stałych znakowych (char): ’a’ = 97 ’0’ = 48 itp. — wg numeracji ASCII. Stałymi znakowymi mogą być dowolne czarne „czcionki” ujęte w pojedyncze apostrofy. Ponadto stałymi znakowymi są ’ ’ : znak spacji ’\n’ : znak nowej linii ’\t’ : znak tabulacji ’\0’ : znak końca napisu ’\′ ’ : znak apostrofu ’\”’ : znak cudzysłowu ’\\’ : znak \ . . . i jeszcze inne. . . Przykład: M Co wydrukuje komenda printf("\\\’\""); ? Odp.: \’" Deklaracje zmiennych w typach prostych Wszystkie typy proste w C: • całkowite, • rzeczywiste, • wskaźniki (o nich będzie później), • nowe, zdefiniowane przez programistę (i o nich będzie później). Deklaracje zmiennych: typ zmienna; Ale można je też łączyć ze sobą i z inicjalizacją: Przykład: M • int i, poczatek =-1; deklaracje połączone; zmienna poczatek zainicjalizowana; • int rok = 365*24*3600; inicjalizatorem nie musi być gotowa liczba; • char zn = ’c’; deklaracje zmiennych znakowych też można inicjalizować; • long long poczlatek = -1; zmienne poczatek i poczlatek należą do różnych typów. Wykład 2. TYPY, str. 12 Typy nieproste Konstrukcje prowadzące do typów nieprostych: • tablice, • struktury. Deklaracje zmiennych tablicowych: • indeksy tablicy — zawsze całkowite liczone od zera • wartości tablicy — dowolne Przykład: M • int a[4] = {1, 1, 1, 1}; tablica całkowita a długości 4 inicjalizowana jedynkami; • double chwile[365][24][3600]; tablica rzeczywista trójwymiarowa. Typy nieproste Typowy błąd: pisanie poza tablicą #include<stdio.h> void druk_tab . . . int main() { char tab[2][3]; Wydruk: for (int i=0; i<2; i++) for(int j=0; j<3; j++) tab[i][j] = ’A’; druk_tab(2,3,tab); printf("\n"); tab[0][3] = ’B’; druk_tab(2,3,tab); A A A A A A A B A A A A W wierszu 0 nie ma znaku 3. B zostaje wstawione w inne miejsce. return 0; } Wykład 2. TYPY, str. 14 Tablice znaków — napisy • deklaracja: char napis[DUZO] = "Hokus pokus"; • w pamięci komputera: napis : 0 1 2 3 4 5 6 7 8 9 10 11 ’H’ ’o’ ’k’ ’u’ ’s’ ’ ’ ’p’ ’o’ ’k’ ’u’ ’s’ ’\0’ • komenda: napis[2] = napis[ 8] = ’p’; napis[3] = napis[ 9] = ’l’; napis[4] = napis[10] = ’a’; • w pamięci komputera: napis : 0 1 2 3 4 5 6 7 8 9 10 11 ’H’ ’o’ ’p’ ’l’ ’a’ ’ ’ ’p’ ’o’ ’p’ ’l’ ’a’ ’\0’ • napis wydrukowany: "Hopla popla" Tablice znaków — napisy W pliku nagłówkowym string.h są deklaracje funkcji przydatnych do działań na napisach. Np.: #include<stdio.h> #include<string.h> nowy : 0 #define DUZO 30 2 3 4 5 6 7 8 9 10 11 6 7 8 9 10 11 7 8 9 10 11 ✒ int main() { char hokus[DUZO] = "Hokus", nowy [DUZO]; strcpy(nowy, hokus); strcat(nowy, " "); strcat(nowy, "pok"); 1 ’H’ ’o’ ’k’ ’u’ ’s’’\0’ nowy : 0 ✯ 1 2 3 4 5 ’H’ ’o’ ’k’ ’u’ ’s’ ’ ’’\0’ nowy : ✲ 0 1 2 3 4 5 6 ’H’ ’o’ ’k’ ’u’ ’s’ ’ ’ ’p’ ’o’ ’k’’\0’ printf(" %s\n", nowy); Wydruk: return 0; Hokus pok } Wykład 2. TYPY, str. 16 Tablice znaków — napisy W pliku nagłówkowym string.h są deklaracje funkcji przydatnych do działań na napisach. strlen(źródło) strcpy(cel, źródło) strcat(cel, źródło) : długość : kopiowanie : konkatenacja (łączenie) strcmp(źródło 1, źródło 2) : porównanie alfabetyczne < 0 jeśli źródło 1 wcześniejsze, = 0 jeśli równe, > 0 jeśli źródło 2 wcześniejsze memcpy(cel+n, źródło, k) : kopiowanie k pierwszych znaków z źródło do cel począwszy od n-tego Tablice znaków — napisy hokus : 0 #include<stdio.h> #include<string.h> #define DUZO 30 int main() { char hokus[DUZO] = "Hokus"; 1 2 3 4 5 6 7 8 9 10 11 6 7 8 9 10 11 6 7 8 9 10 11 ’H’ ’o’ ’k’ ’u’ ’s’’\0’ ✒ hokus : 0 1 2 3 4 5 ’H’ ’o’ ’k’ ’u’ ’s’’\0’ ✯ hokus : 0 memcpy(hokus+2, "plama", 3); printf(" %s\n", hokus); return 0; } q 1 2 3 4 5 ’H’ ’o’ ’p’ ’l’ ’a’’\0’ Wydruk: Hopla Wykład 2. TYPY, str. 18 Struktury Tablica — dużo numerowanych pól tego samego typu. Struktura — kilka nazwanych pól różnych typów. typedef struct { char nazwa[DUZO]; double x, y; } miejsce; Definicja nowego typu danych złożonego z pól podanych typów o podanych nazwach: nazwa ✒ ciąg znaków miejsce Gdansk; strcpy(Gdansk.nazwa, "Gdansk"); Gdansk.x=0; Gdansk.y=0; y x ✻ ✼ liczba rzeczywista liczba rzeczywista nazwa ”Gdansk” y x 0 0 Struktury #include<stdio.h> #include<string.h> #define DUZO 30 typedef struct { char nazwa[DUZO]; double x, y; } miejsce; • sama definicja typedef... nie wprowadza żadnych nowych zmiennych int main() { miejsce Centrum = {"Glowne Miasto", 0, 0}; miejsce Wrzeszcz = {"Wrzeszcz", -2.4, 2.5}; miejsce MojDom = { "Srodek", (Centrum.x + Wrzeszcz.x)/2, (Centrum.y + Wrzeszcz.y)/2 }; printf(" %s jest w (%lf, %lf).\n", MojDom.nazwa, MojDom.x, MojDom.y); return 0; } • nowe zmienne wprowadzają deklaracje takie jak miejsce Centrum... • dostęp do pól takiej zmiennej daje kropka: zmienna pole . Wykład 2. TYPY, str. 20 Struktury #include<stdio.h> typedef struct { double rea, ima; } zespol; zespol dod_zesp(zespol z1, zespol z2) { zespol pom; pom.rea = z1.rea + z2.rea; pom.ima = z1.ima + z2.ima; return pom; } int main() { zespol pierwsza = {4.0, 2.0}, druga = {-2.0, 4.0}; printf(" suma: %.2lf + i*%.2lf\n", dod_zesp(pierwsza,druga).rea, dod_zesp(pierwsza,druga).ima); return 0; } • nowo zdefiniowany typ strukturalny może stanowić typ wynikowy funkcji Zagnieżdżanie • • • • struktury tablice w struktury tablice w w strukturach, strukturach, w tablicach, tablicach typedef struct { char nazwisko[30]; char imie[30]; int rok_urodz; } osoba; typedef struct { osoba kto; int pensja; } pracownik; pracownik kartoteka[200]; — wszystkie są dostępne i działają • kartoteka[12] — 12-ty pracownik • kartoteka[12].pensja — pensja 12-tego pracownika • kartoteka[12].kto — 12-ty pracownik (jako osoba) • kartoteka[12].kto.rok urodz — rok urodzenia 12-tego pracownika • kartoteka[12].kto.imie — imię 12-tego pracownika • kartoteka[12].kto.imie[5] — 5-ta litera imienia 12-tego pracownika