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