Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane Stałe Oprócz zmiennych w programie mamy też stałe, które jak sama nazwa mówi, zachowują swoją wartość przez cały czas działania programu. Można je definiować na dwa sposoby: a) dyrektywa #define schemat: #DEFINE nazwa wartość //bez średnika na końcu #define LICZBA 12 #define PI 3.14159 #define KOMUNIKAT Wystąpił błąd w programie!!! W ten sposób stałe deklarujemy zazwyczaj w sekcji nagłówkowej programu. b) modyfikator const schemat: const typ nazwa=wartość; //średnik jest! const int LICZBA=12; const float PI=3.14159; Źródła nie podają, czy da się w ten sposób deklarować stałe łańcuchy znaków. Co dalej ze stałymi: int wynik = LICZBA * 2; //do zmiennej wynik trafi wartość 24 float objetosc = (4*PI*r*r*r)/3 //i mamy objętość kuli o promieniu r, r to zmienna char znaki[liczba]; //można użyć do deklaracji Operacja LICZBA=25; zakończy się błędem, gdyż LICZBA to stała, a nie zmienna! Zmienne znakowe deklarujemy korzystając z typu char, a inicjujemy korzystając z apostrofów. ( ) Np. char znak; lub razem: char znak= a ; znak= a ; Łańcuchy znaków Łańcuchy znaków są to inaczej tablice znaków zakończone znakiem: \0, którego przy wyświetlaniu nie widać, i którego zazwyczaj sami nie wpisujemy. Przy inicjacji, wywołaniach funkcji i innych sytuacjach korzystamy z cudzysłowów. (" ")
Np. łańcuch "Jestem tekstem" jak widzi go program (od wewnątrz)... 74 101 115 116 101 109 32 116 101 107 115 116 101 109 0...... J e s t e m t e k s t e m \0... 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 (w górnym wierszu kody ASCII, w dolnym numery komórek) Deklaracja zmiennych łańcuchów znaków: a) jako tablica znaków: char tekst1[20]; b) za pomocą wskaźnika: char *tekst; Przypisanie wartości zmiennym tego typu: a) jeśli deklarujemy jako tablica //20-elementowa tablica znaków //wskaźnik na pierwszy znak, na początek łańcucha znaków 1) char tekst= Łańcuch znaków //tak można 2) chat tekst={ Ł, a, ń, c, u, c, h,, z, n, a, k, ó, w, \0 } \\tak można ale to niepraktyczne, bo długie i musimy pamiętać o znaku \0 na końcu 3) char tekst[20]; tekst= Jakiś tekst //tak nie można!!!, zamiast tego trzeba użyć funkcji, np. b) jeśli deklarujemy jako wskaźnik tekst= Imię i nazwisko ; //memcpy(tekst, Jakiś tekst,12); //tak można, nie ma problemów O operacjach na łańcuchach, a także o tablicach więcej informacji już niebawem. Znak a łańcuch Zapis A oznacza znak. Jeden znak. Dokładnie jeden znak. Zapis A oznacza łańcuch znaków, czyli dokładnie dwa znaki: A i \0. Wprowadzanie i wyprowadzanie łańcuchów znaków a) wyjście sformatowane funkcja printf(). Funkcja służy do wyprowadzania sformatowanych łańcuchów znaków na standardowe wyjście (ekran). int printf(const char *format,...) Parametr format wskazuje tzw. łańcuch formatujący. Jak każdy inny łańcuch jest on zakończony znakiem \0. Niektóre sekwencje znaków są jednak specyficznie traktowane. Są one zastępowane odpowiednio danymi znajdującymi się w parametrach nieustalonych (oznaczonych w definicji przez... ). Np. char *imie= Jan ;
int wiek=30; printf( %s ma %d lat.,imie,wiek); spowoduje wyświetlenie napisu Jan ma 30 lat.. Sekwencja formatująca określona jest następująco: %[flagi][szerokość][.precyzja][f N h l L]znak-typu Specyfikator typu Znak typu Argument wejściowy Postać wyjściowa Liczby całkowite d, i o u x X Liczby zmienno-przecinkowe e E f g G c s % znak wskaźnik łańcucha żaden dziesiętna ze znakiem ósemkowa bez znaku dziesiętna bez znaku szesnastkowa bez znaku, małe litery (a,b,c,...) szesnastkowa bez znaku, duże litery (A,B,C,...) [-]d.ddd...e[+/-]ddd przed przecinkiem jedna cyfra, liczba cyfra po przecinku równa precyzji, wykładnik co najmniej dwie cyfry j.w., ale duża litera E, zamiast małej [-]ddd.ddd..., gdzie liczba cyfr po przecinku jest równa precyzji liczba będzie wyświetlana w postaci e lub f w zależności od zadanej precyzji j.w., ale z dużą literą E zamiast małej pojedynczy znak znaki łańcucha aż do napotkania znaku \0 drukuje znak % Specyfikator precyzji Specyfikator Precyzja nie podano Przyjmowane są następujące domyślne precyzje: - 1 dla znaków typu d,i,o,u,x,x - 6 dla znaków typu e,e,f - wszystkie znaczące cyfry dla znaków typu g i G - łańcuchy są drukowane do pierwszego znaku \0.0 Dla znaków typu d,i,o,u,x,x przyjmowana jest precyzja d domyślna; dla e,e,f nie jest drukowany przecinek dziesiętny; liczby całkowite o wartości zero nie są w ogóle drukowane.n Drukowane będzie n znaków lub cyfr dziesiętnych; jeżeli wartość wymaga większej liczby znaków nastąpi obcięcie lub zaokrąglenie Specyfikator szerokości Specyfikator Wpływ na formatowane dane n Drukowanych jest przynajmniej n znaków; jeśli wartość zajmuje mniej niż n znaków, zostaną umieszczone dodatkowe spacje 0n Drukowanych jest przynajmniej n znaków; jeśli wartość ma mniej niż n znaków, zostanie ona wypełniona zerami z lewej strony
b) wejście sformatowane funkcja scanf(). Funkcja służy do pobierania sformatowanych danych ze standardowego wejścia (klawiatury). int scanf(const char *format,...) Parametr format wskazuje łańcuch formatujący określający typy wprowadzanych danych. Wprowadzane dane są określone przez zmienne zawarte w parametrach nieustalonych (oznaczonych w definicji przez... ). Odwołanie do zmiennych odbywa się za pomocą referencji, czyli poprzez wskazanie adresu tej zmiennej w pamięci (znak & ), chyba, że zmienna jest typu wskaźnikowego (łancuch znaków też). Np. int zmienna1, zmienna2; scanf( %d%d,&zmienna1,&zmienna2); Spowoduje zczytanie z klawiatury dwóch liczb ch i umieszczenie ich w zmiennych zmienna1 i zmienna2. Sekwencja formatująca określona jest następująco: %[*][szerokość][f N h l L]znak-typu Specyfikator typu Znak typu Dana wprowadzana Liczby całkowite d, D o, O i, I u, U x, X dziesiętna ósemkowa dziesiętna, ósemkowa, szesnastkowa dziesiętna bez znaku szesnastkowa Liczby rzeczywiste e, E, f, g, G zmiennoprzecinkowa C s znak łańcuch znaków c) PRZYKŁAD: wczytaj nazwy pięciu samochodów, ich pojemność, standard (wysoki lub niski) i cenę. Wyświetl to na ekranie w odpowiedni sposób: Nazwa Standard Pojemność Cena najdłuższej nazwy) 7 znaków) 10 znaków, z precyzją jednej cyfry po przecinku) 10 znaków) d) wprowadzanie i wyprowadzanie niesformatowanych łańcuchów znaków 1) Funkcja gets() służy do odczytania z klawiatury łańcucha znaków, zakończonego znakiem końca wiersza [Enter]. W łańcuchu mogą być spacje. char *gets(char *napis)
łańcuch umieszczony zostaje w zmiennej napis. 2) Funkcja puts() służy do wyprowadzania na ekran łańcuchów znaków. Na końcu łańcucha dołączany jest znak końca wiersza int puts(const char *napis) Wywołanie: char *napis1, *napis2; gets(napis1); napis2= Test ; puts(napis2); e) wprowadzanie i wyprowadzanie pojedynczych znaków 1) Funkcja getchar() służy do odczytania z klawiatury pojedynczego znaku. int getchar(void) 2) Funkcja putchar() służy do wyprowadzania na ekran pojedynczego znaku. int putchar(const int c) Wywołanie: char znak1, znak2; znak1 = getchar(); znak2= a ; putchar(znak2);