PODSTAWY INFORMATYKI
PODSTAWY INFORMATYKI
Wykład 2
Język C
Literatura
Literatura:
1. Kernighan B.W., Ritchie D.M., Język ANSI C, WNT, Warszawa
1994.
2. Stroustrup B., Język C++, WNT, Warszawa 1994.
3. Eckel B., Thinking in C++ (Edycja polska), Helion 2002.
4. Grębosz Jerzy, Symfonia C++ t. I-III, Oficyna Kallimach, Kraków 1999.
5. Wróblewski Piotr, Język C++ dla programistów, Helion, Gliwice 1994.
6. Zalewski Andrzej, Programowanie w językach C i C++ z
wykorzystaniem pakietu Borland C++, Nakom, Poznań 1995.
Strony WWW:
1.
- darmowe książki Bruce'a Eckel'a.
2.
- C/C++ User Journal, informacje dla
programistów
w C/C++.
3.
- ciekawa strona na temat języka C+
+.
Słowa kluczowe
auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default goto sizeof volatile
do if static while
Pierwszy program w C
#include <stdio.h>
main()
{
printf("Hello, world\n");
return 0;
}
Elementy programu w
języku C
• Program w C, niezależnie od rozmiaru,
składa się z funkcji i zmiennych
• Funkcja zawiera instrukcje
określające, jakie operacje
obliczeniowe mają zostać wykonane
• Zmienne przechowują wartości
stosowane podczas obliczeń
Zmienne
• Zmienne przechowują wartości
• Zanim zmienna zostanie użyta,
musi zostać zadeklarowana
• Typy
podstawowe:
– char
– int
– float
– double
• Specyfikatory:
– short
– long
– unsigned
Deklaracje i zmienne
• Składnia deklaracji:
<typ> <nazwa_zmiennej>
• Nazwa zmiennej jest identyfikatorem
• Identyfikatory:
– składają się ze znaków alfanumerycznych
i znaku podkreślenia
– nie mogą zaczynać się cyfrą
– odróżniane są małe od wielkich liter
• Zmiennym można przypisywać
wartości i używać ich w wyrażeniach
Sterowanie: pętla
while
while (warunek) {
...
}
• Wartościowany jest warunek w nawiasach.
• Jeśli jest spełniony, wykonywane jest tzw.
ciało funkcji (instrukcje w nawiasach
klamrowych).
• Sterowanie powraca to wartościowania
warunku -jest ponownie wartościowany itd..
• Kiedy warunek okaże się fałszywy, sterowanie
przechodzi do następnej instrukcji po pętli.
Formatowane wyjście:
funkcja
printf
• printf
może wypisywać wartości
różnych typów: teksty, liczby
całkowite, zmiennoprzecinkowe,
znaki i inne.
int x;
x = 5;
printf(”example: %d+1=%d\n”,x,x+1);
Problem do
rozwiązania: konwersja
temperatur
Fahrenheit Celsjusz
• Gabriel Daniel Fahrenheit wprowadził
skalę temperatur w 1714 r.
• Anders Celsius, wprowadził inną skalę
w 1742 r.
• Wzór przeliczający temperaturę:
T[Celsjusz] = (5/9) ·(T[Fahrenheit] - 32)
• Potrzebna jest tabelka wartości
Pierwsza wersja
/* print Fahrenheit-Celsius table
for fahr = 0, 20, ..., 300, acc. to K&R */
int main()
{
int fahr, celsius;
int lower, upper, step;
lower = 0; /* dolna granica tabeli */
upper = 300;
/* górna granica */
step = 20;
/* krok */
fahr = lower;
while (fahr <= upper) {
celsius = 5 * (fahr-32) / 9;
printf("%d\t%d\n", fahr, celsius);
fahr = fahr + step;
}
return 0;
}
Wyniki:
0 -17
20 -6
40 4
60 15
80 26
100 37
120 48
140 60
160 71
180 82
200 93
220 104
240 115
260 126
280 137
300 148
Często stosowane z funkcją
printf
konwersje
%d
print as decimal integer
%6d
print as decimal integer, at least 6 characters wide
%f
print as floating point
%6f
print as floating point, at least 6 characters wide
%.2f
print as floating point, 2 characters after decimal point
%6.2f
print as floating point, at least 6 wide and 2 after decimal point
Druga wersja:
zmiennoprzecinkowa
#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;
}
Wyniki:
0 -17.8
20 -6.7
40 4.4
60 15.6
... tutaj
pozostała
część tabeli ...
280 137.8
300 148.9
Definiowanie nazw -
krótko
#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
Trzecia wersja: pętla
for
#include <stdio.h>
#define LOWER
0
/* dolny zakres tabeli
*/
#define UPPER 300
/* górny zakres
*/
#define STEP 20
/* 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
• 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=i+1) {...}
* jako specyfikator
szerokości i/lub precyzji
• 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
- sterowanie
formatem
%[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 - c.d.
%[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 - c.d.
%[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 wydruku
0.521
"[%6.3f]”
"[%-6.3f]”
"[%06.3f]”
"[%
+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ą.
• wyświetli się "[0.521 ]". Jak wyżej, tylko
spacja została dodana po liczbie
(wyrównanie do lewej).
• wyświetli się "[00.521]". Zamiast spacji,
zostało dodane zero.
• wyświetli się "[+0.521]". Oczywiście dla
wartości -0.521 wyświetli się znak
minus, nie plus.
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
short s = 1235;
int i = 12345;
long l = 12345678;
unsigned u = 65535;
format wyjście
wid = 14;
..."|%*d|\n", wid, i ); | 12345|
wid = 9;
..."|%*d|\n", wid, i ); | 12345|
"|%14ld|%14ld|", l, -l | 12345678|...
"|%u|%d|", u, u |65535|-1|
|%3ld| |12345678|
printf
- przykłady
short hex = 0x0b52;
format wyjście
|%x| |b52|
|%X| |B52|
|%.4x| |0b52|
|%04x| |0b52|
|%10.8X| | 00000B52|
printf
- przykłady
short oct = 0571;
format wyjście
|%o| |571|
|%5o| | 571|
|%8.5o| | 00571|
printf
- przykłady
long l = 12345678;
format wyjście
|%#lo| |057060516|
|%#lx| |0xbc614e|
|%#ld| |12345678|
printf
- przykłady
float f = 5.555555;
format wyjście
|%f| |5.555555|
|%.2f| |5.56|
|%10f| | 5.555555|
|%10.2f| | 5.56|
|%010.2f| |0000005.56|
|%-10f| |5.555555 |
|%+.2f| |+5.56|
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.23400e+09|
printf
- przykłady
char c = ‘A’;
format wyjście
|%c| |A|
|%4c| | A|
|%-4c| |A |
|%04c| | A|
Precyzja a łańcuchy
:%s: :hello, world:
:%10s: :hello, world:
:%.10s: :hello, wor:
:%-10s: :hello, world:
:%.15s: :hello, world:
:%-15s: :hello, world :
:%15.10s: : hello, wor:
:%-15.10s: :hello, wor :
Wypisanie tekstu ”hello, world” (12 znaków) z
dwukropkami
printf
- przykłady
char str[] = "This is all there is.";
format wyjście
|%s| |This is all there is.|
|%30s| | This is all there is.|
|%5s| |This is all there is.|
|%.5s| |This |
|%-30s| |This is all there is. |
|%10.2s| | Th|
Typy danych i rozmiary
• Jest tylko kilka podstawowych typów danych w
C:
– 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
• Dodatkowo z powyższymi mogą być stosowane
kwalifikatory opisujące dodatkowe typy:
– 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 i rozmiary
- c.d.
• short
i
long
s powinny być różnej długości
• 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 i rozmiary
- c.d.
• 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 2
n
, 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
char
s 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 i rozmiary
- c.d.
• Typ
long
double
określa liczby zmienno-
przecinkowe 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
Stałe
• Stała całkowita taka jak 1234 jest typu
int
• 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)
• Poprzedzające stałą 0 (zero) oznacza stałą ósemkową
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 - c.d.
• 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 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
Sekwencje specjalne
\a
alert (bell)
character
\\
backslash
\b backspace
\?
question mark
\f formfeed
\'
single quote
\n newline
\" double quote
\r carriage return \ooo octal number
\t horizontal tab
\xhh
hexadecimal
number
\v vertical tab
Stałe i wyrażenia
• 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
• Stała łańcuchowa albo stała tekstowe
(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.
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 nazwet różnych wyliczeniach nie mogą
się powtarzać. Wartości mogą się powtarzać.
Operatory logiczne
&
logiczny operator
AND
|
logiczny operator
OR
!
logiczny operator
NIE
^ logiczne XOR
Operatory logiczne
przykład
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int i; i=100;
printf("wartosc poczatkowa i:%d\n",i);
i=i^21987;
printf("i po pierwszym XOR:%d\n",i);
i=i^21987;
printf("i po drugim XOR:%d\n",i);
system("pause");
return 0;
}
/*WYNIK:
wartosc poczatkowa
i:100
i po pierwszym
XOR:21895
i po drugim XOR:100
*/
Operatory arytmetyczne
• +, -, *, /, %
• Przykład:
rok przestępny jest rokiem, którego numer
jest podzielny przez 4, ale nie przez 100,
chyba, że jest podzielny przez 400 - wtedy jest
przestępny.
if ((year%4 == 0 && year%100 != 0) || year%400 == 0)
printf("%d to rok przestępny\n", year);
else
printf("%d nie jest przestępny\n", year);
Operatory relacji
• Porównywanie wartości:
> >= < <=
• Badanie równości:
== !=