Typy danych - Politechnika Śląska

Transkrypt

Typy danych - Politechnika Śląska
Programowanie komputerów
Jacek Lach
Zakład Oprogramowania
Instytut Informatyki
Politechnika Śląska
Jacek Lach. Programowanie komputerów
Plan
• printf
• Typy danych
Jacek Lach. Programowanie komputerów
Temperatury – wersja 2
#include <stdio.h>
/* print Fahrenheit-Celsius table for fahr = 0,
20, ..., 300; floating-point version, acc. to K&R */
int main()
{
float fahr, celsius;
float lower, upper, step;
lower = 0;
/* lower limit of temperature scale */
upper = 300;
/* upper limit */
step = 20;
/* step size
*/
fahr = lower;
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%3.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
return 0;
}
Definiowanie nazw – krótko
Jacek Lach. Programowanie komputerów
• #define
nazwa
tekst_zastępujący
• Wszystkie wystąpienia nazwy (za wyjątkiem stałych tekstowych i części innych nazw) zostaną zastąpione tekstem_zastępującym • nazwa ma postać identyfikatora
• tekst_zastępujący może być dowolnym ciągiem znaków, niekoniecznie liczb
Wersja 3 – pętla for
#include <stdio.h>
Jacek Lach. Programowanie komputerów
#define LOWER 0
#define UPPER 300
#define STEP 20
/* dolny zakres tabeli */
/* górny zakres
*/
/* krok
*/
/* Wypisywanie tabeli Fahrenheit-Celsius, według K&R */
int main()
{
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32) );
return 0;
}
Instrukcja for
Jacek Lach. Programowanie komputerów
• Instrukcja for organizuje pętlę, jest uogólnieniem while • Wewnątrz nawiasów umieszczane są trzy części oddzielane średnikami:
• inicjalizacja
• warunek
• modyfikacja
• Przykład:
• for(i=0;i<10;i++) {...}
* jako specyfikator precyzji
Jacek Lach. Programowanie komputerów
• Szerokość lub precyzja mogą być zdefiniowane przez gwiazdkę (*). Wtedy określa je następny argument, koniecznie typu int. • Przykład:
printf("%.*f", max, x);
printf – konwersje
Jacek Lach. Programowanie komputerów
•
•
•
•
•
•
•
•
•
•
d,i int; decimal number
o int; unsigned octal number (without a leading zero)
x,X int; unsigned hexadecimal number (without a leading 0x or 0X), using abcdef or
ABCDEF for 10, ...,15.
u int; unsigned decimal number
c int; single character
s char *; print characters from the string until a '\0' or the number of characters
given by the precision.
f double; [­]m.dddddd, where the number of d's is given by the precision (def: 6)
e,E double; [­]m.dddddde+/­xx or [­]m.ddddddE+/­xx, where the number of d's is
given by the precision (default 6).
g, G double; use %e or %E if the exponent is less than ­4 or greater than or equal to the precision; otherwise use %f. Trailing zeros and a trailing decimal point are
not printed.
p void *; pointer (implementation­dependent representation).
% no argument is converted; print a %
printf – sterowanie formatem
Jacek Lach. Programowanie komputerów
%[flagi] [szerokość] [precyzja]
[modyfikator_wielkości] typ_parametru
• Flagi:
• ­ wyrównuje liczbę do lewej (normalnie byłaby wyrównana do prawej)
• + liczba zawsze zaczyna się od znaku "+" (dla dodatnich) lub "­" (dla ujemnych), normalnie znak jest wyświetlany tylko dla liczb ujemnych
printf – sterowanie formatem
Jacek Lach. Programowanie komputerów
%[flagi] [szerokość] [precyzja]
[modyfikator_wielkości] typ_parametru
• Szerokość:
• n określa, ile znaków zostanie wyświetlonych. Jeśli n jest większe od szerokości liczby, to zostanie ona uzupełniona spacjami. Jeśli jest mniejsze to liczba nie zostanie ucięta.
• 0n określa, ile znaków zostanie wyświetlonych. Jeśli n jest większe od szerokości liczby, to zostanie ona uzupełniona zerami. Jeśli jest mniejsze to liczba nie zostanie ucięta.
printf – sterowanie formatem
Jacek Lach. Programowanie komputerów
%[flagi] [szerokość] [precyzja]
[modyfikator_wielkości] typ_parametru
• Modyfikator wielkości:
• l określa, że parametr jest typu long (np. long int to %ld)
• h określa, że parametr jest typu short (np. short int to %hd)
printf – przykłady 0.521
Jacek Lach. Programowanie komputerów
• "[%6.3f]" wyświetli się "[ 0.521]". Liczba 6 oznacza szerokość całej liczby, a nie tylko części przed przecinkiem. Ponieważ szerokość liczby jest równa pięć, to została dodana jedna spacja przed liczbą. • "[%­6.3f]" wyświetli się "[0.521 ]". Jak wyżej, tylko spacja została dodana po liczbie (wyrównanie do lewej). • "[%06.3f]" wyświetli się "[00.521]". Zamiast spacji, zostało dodane zero.
• "[%+6.3f]" wyświetli się "[+0.521]". Oczywiście dla wartości ­0.521 wyświetli się znak minus, nie plus
Jacek Lach. Programowanie komputerów
printf – przykłady
short
s = 1235;
int
i = 12345;
long
l = 12345678;
unsigned u = 65535;
format
wyjście
|%d\%d|
|12345|-12345|
|%8d|%8d|
|
12345| -12345|
|%-8d|%-8d|
|12345
|-12345 |
|%+8d|%+8d|
| +12345| -12345|
|%-+8d|%-+8d|
|+12345 |-12345 |
|%08d|%08d|
|00012345|-0012345|
|% 08d|% 08d|
| 0012345|-0012345|
|%+08d|%+08d|
|+0012345|-0012345|
|%10.8d|%10.8d|
| 00012345| -00012345|
printf – przykłady
Jacek Lach. Programowanie komputerów
short
int
long
unsigned
s
i
l
u
=
=
=
=
1235;
12345;
12345678;
65535;
format
wid = 14;
..."|%*d|\n", wid, i );
wid = 9;
..."|%*d|\n", wid, i );
"|%14ld|%14ld|", l, -l
"|%10hd|,%10hd", s, -s
"|%u|%d|", u, u
|%3ld|
wyjście
|
12345|
|
12345|
|
12345678|...
|
1235|...
|65535|-1|
|12345678|
printf – przykłady
Jacek Lach. Programowanie komputerów
short hex = 0x0b52;
format
wyjście
|%x|
|%X|
|%.4x|
|%04x|
|%10.8X|
|%#x|
|b52|
|B52|
|0b52|
|0b52|
| 00000B52|
|0xb52|
printf – przykłady
Jacek Lach. Programowanie komputerów
short oct = 0571;
format
wyjście
|%o|
|%5o|
|%8.5o|
|571|
| 571|
|
00571|
printf – przykłady
Jacek Lach. Programowanie komputerów
long l = 12345678;
format
wyjście
|%#lo|
|%#lx|
|%#ld|
|057060516|
|0xbc614e|
|12345678|
printf – przykłady
Jacek Lach. Programowanie komputerów
float f = 5.555555;
format
wyjście
|%f|
|%.2f|
|%10f|
|%10.2f|
|%010.2f|
|%-10f|
|%+.2f|
|5.555555|
|5.56|
| 5.555555|
|
5.56|
|0000005.56|
|5.555555 |
|+5.56|
Jacek Lach. Programowanie komputerów
printf – przykłady
double ff = 1234000000.0;
format
wyjście
|%.3e|
|1.234e+09|
|%E|
|1.234000E+09|
|%.3E|
|1.234E+09|
|%12.5e|
| 1.234000e+09|
|%g|
|%g|
|%12g|
|1.234e+09|
|1234|
|
1.234e+09|
1.1
|%.4g|
|%#.4g|
|%.10g|
|1.1|
|1.100|
|3.141592654|
printf – przykłady
Jacek Lach. Programowanie komputerów
char c = 'A";
format
|%c|
|%4c|
|%-4c|
|%04c|
wyjście
|A|
|
A|
|A
|
|
A|
Łańcuchy – precyzja
Jacek Lach. Programowanie komputerów
• ”hello, world” (12 znaków) z dwukropkami
:%s:
:%10s:
:%.10s:
:%-10s:
:%.15s:
:%-15s:
:%15.10s:
:%-15.10s:
:hello, world:
:hello, world:
:hello, wor:
:hello, world:
:hello, world:
:hello, world
:
:
hello, wor:
:hello, wor
:
printf – przykłady
Jacek Lach. Programowanie komputerów
char str[] = "This is all there is.";
format
wyjście
|%s|
|%30s|
|%5s|
|%.5s|
|%-30s|
|%10.2s|
|This
|
|This
|This
|This
|
is all there is.|
This is all there is.|
is all there is.|
|
is all there is.
|
Th|
Strumienie we/wy
• Standardowe wejście: stdin
• Standardowe wyjście: stdout
Jacek Lach. Programowanie komputerów
• Stand. strumień błędów: stderr
• Szczegóły zostaną omówione później
• Normalnie strumienie te są związane z konsolą:
• stdin z klawiaturą
• stdout i stderr z terminalem tekstowym
• Strumienie mogą być przekierowywane
• testapp.exe <dane.txt >wyniki.txt
Wejście znakowe
• Odczytanie pojedynczego znaku lub EOF:
• int getc(FILE *stream);
Jacek Lach. Programowanie komputerów
• powyższa deklaracja nazywana jest prototypem
• Przykład:
• int c;
• c = getc(stdin);
• Dlaczego używamy int dla c zamiast char?
• Czytanie jednego znaku z stdin:
• int getchar(void);
• getchar() działa jak getc(stdin)
Wyjście znakowe
• Zapis pojedynczego znaku do strumienia:
• int putc(int c, FILE *stream);
Jacek Lach. Programowanie komputerów
• Przykład:
• putc(’A’,stdout);
• Zapis pojedynczego znaku do stdout:
• int putchar(int c);
• putchar(’A’) działa jak putc(’A’,stdout)
• Zwracana wartość: wypisany znak
Jacek Lach. Programowanie komputerów
Kopiowanie
#include <stdio.h>
/* kopiowanie wejścia na wyjście:
pierwsza wersja */
main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
return 0;
Kopiowanie
Jacek Lach. Programowanie komputerów
#include <stdio.h>
/* copy input to output; 2nd version */
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;
}
Zliczanie znaków
Jacek Lach. Programowanie komputerów
#include <stdio.h>
/* count characters in input; */
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
return 0;
}
Zliczanie znaków
Jacek Lach. Programowanie komputerów
#include <stdio.h>
/* count characters in input; 2nd
version */
main()
{
double nc;
for (nc = 0; gechar() != EOF; ++nc)
;
printf("%.0f\n", nc);
return 0;
}
Zliczanie wierszy
Jacek Lach. Programowanie komputerów
#include <stdio.h>
/* count lines in input */
main()
{
int c, nl;
nl = 0; /* the number of lines so far */
while ((c = getchar()) != EOF)
if (c == '\n') /* new line found */
++nl;
printf("%d\n", nl);
return 0;
}
Zmienne w pamięci
Jacek Lach. Programowanie komputerów
• Każda zmienna pamiętana jest w pewnym miejscu pamięci ... lub w rejestrze procesora
• Adres zmiennej jest indeksem tej komórki pamięci, w której znajduje się pierwszy bajt zmiennej
• Liczba bajtów zajmowanych przez zmienną zależy od jej typu; operator sizeof informuje o tym rozmiarze: sizeof(type)
Wskaźniki
Jacek Lach. Programowanie komputerów
• Wskaźnik jest adresem, pod którym znajduje się zwykle coś użytecznego
• Definiowanie zmiennej przechowującej adres:
<type> *<variable>
• Przykład:
int *pti; • Pobieranie adresu, pod którym przechowywana jest zmienna: operator &
int x;
pti = &x;
Wskaźniki
int x;
Jacek Lach. Programowanie komputerów
pti = &x;
x = 5;
*pti = *pti + 1; /* teraz x = 6 */
x++;
printf(”%d”,x);
/* 7 */
Wskaźniki ­ dlaczego teraz?
Jacek Lach. Programowanie komputerów
• ...aby przeczytać z wejścia coś bardziej złożonego niż pojedynczy znak
• scanf jest odpowiednikiem printf dla strumienia wejściowego
• udostępnia wiele podobnych konwersji jak printf, ale w przeciwnym kierunku
• Prototyp:
• int scanf(char *format, ...)
• scanf wymaga wskaźników do zmiennych scanf – przykład
Jacek Lach. Programowanie komputerów
#include <stdio.h>
main() {
int x;
printf(” Podaj liczbę: ”);
scanf(”%d”, &x);
printf(”Kwadrat %d wynosi %d\n”, x,
x*x);
return 0;
}
scanf – błędne dane
#include <stdio.h>
main()
Jacek Lach. Programowanie komputerów
{
int a,b;
scanf("%d",&a);
/* abc */
printf("a=%d\n",a);
/* przypadkowa wart. */
scanf("%d",&b);
/* nie czeka! */
printf("b=%d\n",b);
/* znowu przyp. wart. */
return 0;
}
Typy danych
• Jest tylko kilka podstawowych typów danych w C: Jacek Lach. Programowanie komputerów
• char pojedynczy bajt, mogący przechowywać jeden znak z lokalnego zestawu znaków
• int liczba całkowita, zwykle odzwierciedlająca rozmiar słowa maszynowego na danym komputerze
• float liczba zmiennoprzecinkowa pojedynczej precyzji
• double liczba zmiennoprzecinkowa podwójnej precyzji
Typy danych
• Dodatkowo mogą być stosowane kwalifikatory opisujące dodatkowe typy (modyfikacje):
Jacek Lach. Programowanie komputerów
• short i long stosowane do liczb całkowitych
• Słowo int może być opuszczone w takich deklaracjach i zwykle tak się robi
• signed lub unsigned mogą byś stosowane do char i innych typów całkowitych
Typy danych
• short i long s powinny być różnej długości
Jacek Lach. Programowanie komputerów
• int ma zwykle rozmiar wynikający z długości słowa maszyny
• short ma zwykle 16 bitów, int ma 16 bitów lub 32 bity
• Każdy kompilator może obsługiwać inne rozmiary typów całkowitych, zależnie od możliwości sprzętu. Zastrzega się, że short i int mają co najmniej 16 bitów, long co najmniej 32 bity, short jest nie dłuższy niż int, który jest nie dłuższy niż long. Typy danych
Jacek Lach. Programowanie komputerów
• Kwalifikator signed lub unsigned może być zastosowany do char lub innych typów całkowitych
• Liczby unsigned są zawsze nieujemne, podlegają zasadom arytmetyki modulo 2n, gdzie n jest długością zmiennej danego typu w bitach
• Na przykład, jeśli char ma 8 bitów:
• unsigned char mają wartości od 0 do 255, • signed chars mają wartości od ­128 do 127 (w arytmetyce dopełnień do 2)
• Typ char może być signed lub unsigned ­ zależy od maszyny. Znaki drukowalne są zawsze dodatnie. Typy danych
Jacek Lach. Programowanie komputerów
• Typ long double określa liczby zmiennoprzecinkowe o podwyższonej precyzji
• Tak jak w przypadku liczb całkowitych, rozmiary typów zmiennoprzecinkowych są zależne od implementacji
• float, double i long double mogą reprezentować jeden, dwa lub trzy różne rozmiary
• Standardowe nagłówki <limits.h> i <float.h> zawierają stałe symboliczne dla wszystkich tych rozmiarów, wraz z innymi własnościami zależnymi od kompilatora i maszyny
Typy danych – limits.h
#
define CHAR_BIT
8
Jacek Lach. Programowanie komputerów
/* Minimum and maximum values a `signed char' can hold.
# define SCHAR_MIN
(-128)
# define SCHAR_MAX
127
*/
/*
#
/*
#
Maximum value an `unsigned char' can hold. (Minimum is 0.)
define UCHAR_MAX
255
Maximum value an `unsigned int' can hold.(Minimum is 0.) */
define UINT_MAX
4294967295U
/*
#
#
#
#
#
Minimum and maximum values a `signed long int' can hold.
if __WORDSIZE == 64
define LONG_MAX
9223372036854775807L
else
define LONG_MAX
2147483647L
endif
*/
*/
Jacek Lach. Programowanie komputerów
Typy danych – konwersje
• Kiedy operator ma działać na operandach różnych typów, są one konwertowane przy zastosowaniu niewielkiego zbioru reguł.
double x, y;
int k; // Różne typy!
y = x + k;
• Ogólnie, jedynymi automatycznymi konwersjami są takie, które przekształcają typ „mniejszy” w „większy” bez utraty informacji.
Konwersje
• Wyrażenia, które nie mają sensu, są zakazane
Jacek Lach. Programowanie komputerów
• Przykład: użycie float jako indeksu
• Wyrażenia, w których można utracić informację, powodują zgłoszenie ostrzeżenia, ale są dozwolone; przykłady:
• kopiowanie większego typu całkowitego do mniejszego
• przypisanie wartości zmiennoprzecinkowej do zmiennej całkowitej
Konwersje
Jacek Lach. Programowanie komputerów
• Jeśli nie występują operandy unsigned, wystarczający jest następujący zestaw reguł:
• Jeśli jeden z operandów jest typu long double, przekształć drugi na long double.
• W przeciwnym wypadku, jeśli jeden operand jest double, przekształć drugi na double.
• W przeciwnym wypadku, jeśli operand jest float, przekształć drugi na float.
• W przeciwnym wypadku, przekształć char i short na int.
• Potem, jeśli jeden z operandów jest long, przekształć drugi na long.
Wymuszanie konwersji
Jacek Lach. Programowanie komputerów
• Jawna konwersja typu może być wymuszona w wyrażenie przez zastosowanie operatora rzutowania (ang. cast)
• W następującej konstrukcji:
(nazwa_typu) wyrażenie
wyrażenie jest przekształcane na wyrażenie o podanym typie
cels = ((double)5/9) * (fahr­32);
• Konwersje są również wykonywane w wywołaniach funkcji
Stałe
• Stała całkowita taka jak 1234 jest typu int
Jacek Lach. Programowanie komputerów
• Stałe long są zapisywane z przyrostkiem l lub L: 123456789L
• Stałe całkowite bez znaku (unsigned) są zapisywane z przyrostkiem u lub U (ul oznacza unsigned long)
Stałe
• Poprzedzające stałą 0 (zero) oznacza stałą ósemkową
Jacek Lach. Programowanie komputerów
• System ósemkowy: np. 31 oct = 25 dec
• Poprzedzające stałą 0x lub OX oznacza stałą szesnastkową
• Przykład:
• 31 = 037 = 0x1f
• Inny przykład:
• 0XFUL to stała typu unsigned long o wartości dziesiętnej 15
Stałe
Jacek Lach. Programowanie komputerów
• Stała znakowa (character constant) to wartość całkowita, zapisywana jako pojedynczy znak w apostrofach, np. 'x'
• Wartość stałej odpowiada kodowi znaku w lokalnej tablicy kodów
• Przykład:
• '0' ma wartość 48 w kodzie ASCII
Stałe
Jacek Lach. Programowanie komputerów
• Stałe znakowe biorą udział w operacjach arytmetycznych tak jak inne stałe całkowite
• Niektóre znaki mogą być reprezentowane przez specjalne, dwuznakowe sekwencje przykład:
• '\n' (znak nowego wiersza)
• sekwencja, chociaż składa się z dwóch znaków, reprezentuje jeden znak
Stałe
Jacek Lach. Programowanie komputerów
• Dowolna stała o rozmiarze bajtu może być zapisana jako
• '\ooo'
gdzie ooo to jedna to trzech cyfr ósemkowych (0...7)
• lub jako:
'\xhh'
gdzie hh jest jedną lub więcej cyfr szesnastkowych (0...9, a...f, A...F)
Jacek Lach. Programowanie komputerów
Sekwencje specjalne
• \a alert
\' single quote
• \b backspace
\" double quote
• \f form feed
\ooo
• \n newline
\xhh
• \r carriage return
• \t horizontal tab
• \v vertical tab
• \\ backslash
• \? question mark
Przykład
• char b[]="abc";
• b[0]: 'a'
Jacek Lach. Programowanie komputerów
• b[1]: 'b'
• b[2]: 'c'
• b[3]: '\x0'
• (int)b[0]: 97
• (int)b[1]: 98
• (int)b[2]: 99
• (int)b[3]: 0
Przykład
• char b[]="a0\n";
• b[0]: 'a'
Jacek Lach. Programowanie komputerów
• b[1]: '0'
• b[2]: '\n'
• b[3]: '\x0'
• (int)b[0]: 97
• (int)b[1]: 48
• (int)b[2]: 10
• (int)b[3]: 0
Przykład
• char b[]="\nn\n";
• b[0]: '\n'
Jacek Lach. Programowanie komputerów
• b[1]: 'n'
• b[2]: '\n'
• b[3]: '\x0'
• (int)b[0]: 10
• (int)b[1]: 110
• (int)b[2]: 10
• (int)b[3]: 0
Przykład
• char b[]="a\066b";
• b[0]: 'a'
Jacek Lach. Programowanie komputerów
• b[1]: '6'
• b[2]: 'b'
• b[3]: '\x0'
• (int)b[0]: 97
• (int)b[1]: 54
• (int)b[2]: 98
• (int)b[3]: 0
Przykład
• char b[]="\123c";
• b[0]: 'S'
Jacek Lach. Programowanie komputerów
• b[1]: 'c'
• b[2]: '\x0'
• (int)b[0]: 83
• (int)b[1]: 99
• (int)b[2]: 0
Przykład
• char b[]="\567c";
• Błąd!
Jacek Lach. Programowanie komputerów
• Kod > 255
Przykład
• char b[]="\xefgh";
• b[0]: '´'
Jacek Lach. Programowanie komputerów
• b[1]: 'g'
• b[2]: 'h'
• b[3]: '\x0'
• (int)b[0]: 239
• (int)b[1]: 103
• (int)b[2]: 104
• (int)b[3]: 0
Przykład
• char b[]="\x12x\n";
• b[0]: '\x12'
Jacek Lach. Programowanie komputerów
• b[1]: 'x'
• b[2]: '\n'
• b[3]: '\x0'
• (int)b[0]: 18
• (int)b[1]: 120
• (int)b[2]: 10
• (int)b[3]: 0
Stałe i wyrażenia
Jacek Lach. Programowanie komputerów
• Stałe wyrażenie jest wyrażeniem, w którym występują tylko stałe
• Stałe wyrażenie może być obliczone podczas kompilacji, a nie wykonania programu.
Stałe łańcuchowe
Jacek Lach. Programowanie komputerów
• Stała łańcuchowa albo stała tekstowa (lub znakowa) jest ciągiem zera lub więcej znaków otoczonych przez znaki " • Przykład:
• "Jestem łańcuchem znakowym"
• Stałe znakowe mogą być łączone (konkatenowane) podczas kompilacji: • "hello, " "world"
jest równoważne: • "hello, world" Stałe wyliczeniowe
• Wyliczenie jest listą stałych o wartościach całkowitych, np. Jacek Lach. Programowanie komputerów
• enum boolean { NO, YES };
• Pierwsza nazwa w enum ma wartość 0, następna 1 itd., chyba, że zostaną określone inne wartości.
• Jeśli nie wszystkie wartości zostaną podane, to dla nieokreślonych przyjęte zostaną wartości będące kontynuacją ostatniej podanej wartości, jak np.: • enum months {JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
/* FEB = 2, MAR = 3, itd. */
• Nazwy w tym samym i różnych wyliczeniach nie mogą się powtarzać. Wartości mogą się powtarzać.