Język C, C++.

Wprowadzenie do programowania w języku C/C++:
struktura programu,
nazwy i słowa zastrzeżone,
podstawowe typy danych,
struktura funkcji,
stałe, zmienne,
deklaracje,
wyrażenia,
instrukcje we/wy,
operatory,
instrukcje sterujące,
preprocesor,
tablice,
wskaźniki.
Wejście, wyjście w c/C++.

Język C został zdefiniowany w 1972 r. przez Dennisa M Ritchie z Bell Laboratories w New Jersey. Język C jest językiem ogólnego zastosowania. Język w miarę prostoty, niezbyt obszerny, szerokiego zastosowania. Charakteryzuje się także nowoczesnymi strukturami danych i bogatym zestawem operatorów.
C nie jest językiem "bardzo wysokiego poziomu", nie jest nawet "duży", i nie został opracowany dla jakiejś szczególnej dziedziny zastosowań. Brak ograniczeń oraz ogólność powodują, że w wielu przypadkach jest wygodniejszy i bardziej sprawny od innych języków oprogramowania o pozornie większych możliwościach. Można zrobić w nim w miarę wszystko.
Ścisły związek z UNIX - ci sami twórcy.
Tysiące funkcji bibliotecznych. Język C opracował i zrealizował Dennis Ritchie dla systemu operacyjnego UNIX działającego na minikomputerze DEC PDP-11. S
System operacyjny, kompilator C i niemal wszystkie programy usługowe systemu UNIX są napisane w C. Kompilatory języka C tworzy się dla różnych maszyn, łącznie z IMB/370, jednak C nie jest związany z żadnym konkretnym systemem czy sprzętem i łatwo w nim pisać programy, które można uruchamiać bez zmian na dowolnej maszynie, na której język C jest zrealizowany.
Język C funkcjonuje do dziś jako ANSI C.
W latach 80 rozszerzenie - C++ (struktury obiektowe, sprawdzanie wszystkiego).
 Można w nim tworzyć małe programy jak i stosować do komercyjnych zastosowań.
Najbardziej popularny język na świecie (łącznie z C++). Cechuje go elastyczność, nie jest rygorystyczny pod względem sprawdzania - można popełnić wiele nadużyć, wskazana ostrożność (programy ciężko się uruchamia gdy duża elastyczność).  Pascal jako język dydaktyczny jest bardzo hermetyczny i sztywny.

Z punktu widzenia programisty:

W językach wyższego poziomu abstrahujemy od rozkazów wewnętrznych i komórek pamięci

Języki wewnętrzne, maszynowe, algorytmiczne (Pascal, częściowo C), języki czwartej generacji (w tym niektóre języki do tworzenia aplikacji na bazie danych np. SQL)

Więcej operacji elementarnych za pomocą jednej konstrukcji języka wyższej generacji.
W SQL przełożenie o wysokim współczynniku np. 1:10

Program w języku źródłowym (Pascal, C, 4GL Informix...) à Translator à program w innym języku wynikowym (niższego poziomu, np. w języku wewnętrznym)

Strategie tłumaczenia:

Cechy języków programowania:

Język C

Język C pierwotnie miał ułatwiać tworzenie oprogramowania systemowego - UNIX.
UNIX z definicji wyposażony w kompilator C.
Język C można zakwalifikować jako język wysokiego poziomu (1:10 - źródło wynik).
Można również wykonać operacje zastrzeżone dla niskiego poziomu - elementy programowania niskiego poziomu.
Możliwość operowania adresami - operacje na adresach (np. wsk, *wsk, *(wsk+7)). Pozwala to wyeliminować wstawki w języku Asemblera.

Wersje języka C:

Borland C oparty na ANSI C, Microsoft C, Watcom C, Unix C, C++

W języku C podprogramami są funkcje. Zmienne lokalne i globalne.
Łączy cechy wysokiego z możliwościami języka niskiego poziomu.
Język w wysokim stopniu przenośny.
Elastyczność - łagodniej kontroluje zgodność typów - kontrowersyjne, niebezpieczne. Zwięzłość - w Pascalu np. 10 linii, w C - kilka linii.
Ze zwięzłością nie należy przesadzać - trudniej wykryć błąd.

Ogólna struktura programu w języku C

Cechą języka C/C+ jest możliwość budowy programu z wielu modułów.
Modułem może być każdy zbiór zawierający poprawny kod źródłowy.
W pełni poprawny moduł, którego kompilacja zakończy się sukcesem:

int n;

Program w C zbudowany jest z funkcji.
Każda z nich może posiadać parametry oraz określony typ wartości.
Aby można było wygenerować kod wynikowy programu (w DOS, Windows  plik .EXE),
w jednym i tylko w jednym z modułów musi się znaleźć funkcja main, od której rozpocznie się wykonywanie programu. Moduł zawierający funkcję main nazywa się modułem głównym.

Najprostszy wykonywalny program C:

int main(void)

  { 

    return 0;

  }

Po uruchomieniu TC.EXE

Program ten składa się tylko z bezparametrowej funkcji main, której wartość jest typu całkowitego (int).
Ciało funkcji zbudowane jest z instrukcji, które powinny znaleźć się w bloku wyznaczonym nawiasami kwadratowymi.
Funkcja ta zwraca za pomocą instrukcji return wartość zero.

Program TC.EXE – Turbo C

Katalogi Turbo C

Katalog: c:\Tc

 

2011-10-15  15:22    <DIR>          BGI

2011-11-12  15:03    <DIR>          BIN – tu są program, m.in. TC.EXE – środowisko programistyczne, , TCC.EXE – kompilator

2011-10-15  15:22    <DIR>          CLASSLIB

2011-10-15  15:22    <DIR>          DOC

2011-10-15  15:22    <DIR>          EXAMPLES

2011-10-15  15:22    <DIR>          INCLUDE

2011-10-15  15:22    <DIR>          LIB - biblioteki

2011-11-08  10:43    <DIR>          Programy

Menu programu TC.EXE

MenuFile – Plik: opcje: New – Nowy, Open – Otwórz, Save – Zapisz, Save as – Zapisz jako,

Save All – zapisz wszystko, Change dir – zmień katalog,
DOS Shell – okno DOS (exit – wyjście), Quit – wyjście

Menu Edit

Search – szukaj

Run - Uruchom

Compile – Kompiluj
Compile Alt F9 – kompiluj, Make – utwórz, Link – linkuj, Build All – zbuduj wszystko,
Information – informacja, Remove messages – usuń komunikaty (wiadomości)

Debug - debugowanie

Project – Projekt

Options – Opcje

Window – Okno

Help

 

Ustawienia programu - przykładowe: Options, Directories

 

Kompilacja programu:
Po kompilacji programu: Alt C, Compile lub Alt F9 lub F9
utworzy się plik wynikowy P1.EXE w katalogu Output Directory

Uruchomienie programu: Alt R lub Ctrl F9

 

 

Skompiluje się również program w postaci:
main() { }
,
ewentualnie w postaci
void main() { }
lub
void main(void) { }

 

Przykład z Turbo C

// Borland C++ - (C) Copyright 1991 by Borland International

/*         HELLO.C -- Hello, world */

 

#include <stdio.h>

int main()

{

            printf("Hello, world\n");

            return 0;

}

Po uruchomieniu i naciśnięciu Alt F5 – wynik

 

 

Pomoc w programie:

Help, Index, wpisujemy szukane słowo, np. void i naciskamy Enter

 

Ogólna struktura programu w C/C++

Nagłówek programu

#include (włączenia tekstowe)

#define stałe makroinstrukcje

Zmienne globalne

Prototypy funkcji

Funkcja main()

Funkcje pozostałe

W profesjonalnych programach w nagłówku powinna być podana nazwa programu,
dane o autorze, prawa autorskie, przeznaczenie programu, data ostatniej aktualizacji programu, nazwa kompilatora, uwagi odnośnie kompilowania, linkowania, wykonania.

Sekcja #include zawiera specyfikację włączanych plików bibliotecznych oraz własnych

Sekcja #define zawiera definicje stałych i makroinstrukcji

Następne sekcje to zmienne globalne oraz prototypy funkcji.
Muszą wystąpić przed ciałami funkcji, aby w dalszej części programu nie było odwołań do obiektów nieznanych kompilatorowi.
Jeżeli funkcje pozostałe umieszczone byłyby przed funkcją main to specyfikowanie prototypów byłoby zbyteczne.

Włączenia tekstowe #include mogą w zasadzie wystąpić w dowolnym miejscu programu. Zaleca się aby dłuższe funkcje lub grupy funkcji były umieszczane w osobnych plikach.

Podstawowy fragment (element) programu w języku C

main()              /* klamra otwierająca - początek funkcji głównej (jak begin w Pascalu)*/

 {                   /* tu zaczyna się treść programu - w funkcji main()

  /* treść */        

 }                   /* klamra zamykająca - jak end w Pascalu*/

/* - rozpoczęcie komentarza, */ - koniec komentarza

W pisaniu programów rozróżniane są duże i małe litery - np. w main()

Język C/C++ nie ma instrukcji realizujących operacje we/wy.
Do tego celu służą funkcje bibliotek standardowych.
Użycie ich jest niezbędne, gdy trzeba pobrać dane od użytkownika i wysłać je na ekran.

#include <stdio.h>

 

int main(void) // funkcja glowna, brak argumentow, zwraca typ calkowity int

        {

        char imie[20]; // deklaracja tablicy znakow

        int i;  // deklaracja zmiennej calkowitej

 

        printf("\nPodaj swoje imie "); // wydruk na ekran,\n – nowa linia

        gets(imie);   // pobranie zmiennej imie

        puts("Ile masz lat? ");        // wydruk

        scanf("%d",&i);                // pobranie zmiennej typu calkowitego

        printf("\n%s ma %d lat.",imie, i); //wydruk napisu i liczby calkow.

        return 0; // funkcja glowna zwraca 0 – pomyślny koniec

        }

 

Przykłady prostych programów

Przykład prostego programu: prog1.c
Wydruk na ekranie napisu: Dzień dobry (z przejściem kursora do nowej linii)

/* Prog1.c - Program napisany w pliku żródłowym Prog1.c */

#include <stdio.h>  
/* preprocesor - załącz pliku bibliot. standard. stdio.h  */

main()

{

 printf("Dzień dobry\n");  /* printf - drukuj-fragment bibliot. standard */

                           /* \n - znak nowego wiersza */   

}

 

Komentarz w języku C stanowi tekst ograniczony znakami /* i */

 

Inne wersje tego programu:

 

#include <stdio.h>

void main()

 {

  printf("Dzień dobry\n");

 }

 

 

#include <stdio.h>

int  main()

{

 printf("Dzień dobry\n");

 return 0;

 

}

# - preprocesor - wstępny przetwarzacz - uwzględnia dodatkowe rzeczy
#include <stdio.h> - dołączenie nagłówków z biblioteki standardowej (ścieżka domyślnych przeszukowań)
#include "program.h" - dołączenie programu z katalogu aktualnego - podwójne cudzysłowy

Język C/C++ wymaga kompilacji, w wyniku czego tworzy sie plik wykonywalny, binarny, z rozszerzeniem EXE. Nie ma interpreterów do języka C. Skompilować wystarczy raz.

Nie są ważne odstępy w programie. Muszą być całe słowa. Mogą być znaki spacji, nowego wiersza, tabulacji - nieważne ile.
#inlcude  musi być w jednej linii.

Ważne jest projektowanie.
Jedna godzina poświęcona na projektowanie pozwala zaoszczędzić kilka godzin programowania.

Prosty przykład obliczeniowy - obliczenie objętości walca

/********************************************************/

/*  Program  p1a.c                             */

/*  Obliczanie objetosci walca     (wariant startowy)      */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

void main()

 

{

   float promien, wysokosc, objetosc;

 

   promien  = 3.3;

   wysokosc = 44.4;

   objetosc = 3.1415926 * promien * promien * wysokosc;

   printf("Objetosc walca = %f", objetosc);

}

/********************************************************/

Efektem wykonania będzie wydruk na ekranie: Objętość walca=1519.010254

Następny program zawiera za dużo komentarzy

/* poczatek tekstu programu */

/********************************************************/

/*  Program  p1b.c                                   */

/*  Obliczanie objetosci walca (nadmiar komentarzy)   */

/*------------------------------------------------------*/

 

#include <stdio.h>             /* wlaczenie biblioteki */

 

main()                     /* poczatek modulu glownego */   

 

{                                    /* poczatek bloku */

   /* deklaracje zmiennych */

   float promien, wysokosc, objetosc;   

 

   /* nadanie wartosci poczatkowych zmiennym */

   promien  = 3.3;

   wysokosc = 44.4;

 

   /* obliczenie podstawowe */

   objetosc = 3.1415926 * promien * promien * wysokosc;

 

   /* wyprowadzenie wyniku */

   printf("Objetosc walca = %f", objetosc);

 

}                                     /* koniec bloku */

/********************************************************/

/* koniec tekstu programu */

Następny przykład pozbawiony komentarzy ale czytelny:

/* p1c.c */

#include <stdio.h>

 

main()

 

{

   float promien, wysokosc, objetosc;

 

   promien  = 3.3;

   wysokosc = 44.4;

   objetosc = 3.1415926 * promien * promien * wysokosc;

   printf("Objetosc walca = %f", objetosc);

 

Następny przykład jest bardzo zwięzły w zapisie ale mało czytelny:

/*p1d.c*/#include<stdio.h>

main(){float r,h,v;r=3.3;h=44.4;v=3.1415926*r*r*h;printf("V=%f",v);}

Wniosek - brak jak i nadmiar komentarzy nie słuzy czytelnosci programu.

W praktyce stosowane są 2 sposoby umiejscowiana klamer { },
ograniczających sekwencje instrukcji.

1)

main()

{

 /* sekwencja instrukcji */

}

 

2)

main() {

/* sekwencja instrukcji */

}

Na czytelność programu wpływa stosowanie wcięć.

Przykłady.

Przeliczenie stopni Fahrenheita na Celsjusza

Wersja 1

/* Program sz2.cpp - komentarz

Przelicza stopnie Fahrenheita na Celsjusza

*/

 

#include <stdio.h>

 

 

void main() /* Poczatek funkcji glownej main - nic nie zwraca*/

{

 /* Definicje zmiennych */

 int tf=0;   /* typ integer  - temp. Fahrenheita*/

 float tc;   /* typ float    - temp Celsjusza */

 

 while (tf <=100)  /* petla - iteracja  tf używana też do sterowania przebiegiem petli */

 {

        tc=(5*(tf-32))/9.0;

        printf("%4d  %6.1f \n",tf,tc);

        tf=tf+10;

 }; /* while */

 

}   /* main */

 

Wersja 2

/* Program sz2a.cpp - bez zmiennej tc

Przelicza stopnie Fahrenheita na Celsjusza

*/

 

#include <stdio.h>

 

 

void main() /* Poczatek funkcji glownej main - nic nie zwraca*/

{

 /* Definicje zmiennych */

 int tf=0;   /* typ integer  - temp. Fahrenheita*/

 

 

 while (tf <=100)  /* petla - iteracja */

 {

        printf("%4d  %6.1f \n",tf,     5*(tf-32)/9.0);

        tf=tf+10;

 }; /* while */

 

}   /* main */

Uwaga! We wzorze (tf-32)*(5/9) - zaokrąglenie 5/9 do liczb całkowitych!. Bezpieczne mnożenie, niebezpieczne dzielenie.

Wersja 3

/* sz2b.c */

#include <stdio.h>

#include <conio.h>

 

main()

 {

  float fahr, celsius;

  int lower, upper, step;

 

  lower =0; /*dolna granica temp*/

  upper=300;

  step=20;

  celsius=lower;

 

  clrscr();

  printf("Zamiana stopni Celsiusza na Fahrenheita\n");

  printf("  Celsjusz      Fahr\n");

 

  while (celsius<=upper) {

    fahr=(9.0/5.0*celsius+32.0);

    printf("%3.0f %20.1f\n",celsius,fahr);

    celsius=celsius+step;

   }

  getch();

  return 0;

 }

Formaty wydruku:

%d, %i

liczba całkowita

%x

w formacie 16 bez znaku

%f, %e, %g

zmiennopozycyjny

%s

string (łańcuch znaków)

%c

znak

%o

ósemkowo

Deklaracja a definicja

Deklaracja - informuje kompilator, że dana nazwa reprezentuje obiekt jakiegoś typu ale nie rezerwuje dla niej miejsca w pamięci. Mówi, że zmienna jest ale nie powołuje jej do życia.

Definicja - wprowadza do programu zmienną i przydziela jej pamięć, powołuje obiekt do życia.

Przykłady deklaracji, które nie są definicjami:
extern int a; int f(int); struct s; typedef int Int;

Zmienna - komórka lub grupa komórek

Podstawowe elementy języka C (każdego praktycznie języka programowania)

Zestaw znaków C:

Nazwy i słowa zastrzeżone (kluczowe, zarezerwowane)

Nazwy służą do identyfikowania elementów programu
(stałych, zmiennych, funkcji, typów danych, itd.).
Nazwa składa się z ciągu liter i cyfr, z tym, że pierwszym znakiem musi być litera.
Znak podkreślenia traktowany jest jako litera.

W języku C rozróżniane są duże i małe litery w identyfikatorach.

Przykład użycia różnych nazw:

/********************************************************/

/*  Program  p6.c                                    */

/*  Obliczanie objetosci walca (rozroznianie nazwy /1)        */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()

 

{

   float promien, wysokosc, objetosc;

   float PROMIEN, WYSOKOSC, OBJETOSC;

 

   promien  = 3.3;   PROMIEN  = 10.;

   wysokosc = 44.4;  WYSOKOSC = 20.;

 

   objetosc = 3.1415926 * promien * promien * wysokosc;

   printf("\nObjetosc walca = %f", objetosc);

 

   OBJETOSC = 3.1415926 * PROMIEN * PROMIEN * WYSOKOSC;

   printf("\nOBJETOSC WALCA = %f", OBJETOSC);

}

/********************************************************/

Efektem wykonania programu są 2 wydruki:

Objetosc walca = 1519.010254

OBJETOSC WALCA = 6283.185059

Użycie odstępu w nazwie jest niedozwolone.
Niektóre implementacje rozpoznają w nazwie do 8 znaków, inne więcej (do 32).

Słowa zastrzeżone

Są to słowa o szczególnym znaczeniu dla języka, których nie wolno używać programiście np. jako nazw zmiennych.

Standardowy zestaw znaków zastrzeżonych języka C:

auto

break

case

char

const

continue

default

do

double

else

enum

extern

float

for

goto

if

int

long

register

return

short

signed

sizeof

static

struct

switch

typedef

union

unsigned

void

volatile

while

Niektóre kompilatory mają niektóre lub cześć z następujących słów kluczowych

ada

asm

entry

far

fortran

huge

near

pascal

Podstawowe typy danych i rozmiary danych

W języku C występuje tylko kilka podstawowych typów danych:

Dodatkowo występuje kilka kwalifikatorów stosowanych z tymi podstawowymi typami. Kwalifikatory short i long odnoszą się do obiektów całkowitych

Typ

Opis

Zakres wartości

Reprezentacja

char (signed char)

pojedynczy znak (np. litera)

-128...127

1 bajt

unsigned char

znak (bez znaku - dodatni)

0...255

1 bajt

short

liczba całkowita krótka

-32768...32767

2 bajty

unsigned short

liczba krótka bez znaku

0...65535

2 bajty

int (signed int)

liczba całkowita

-32768...32767

2 bajty

unsigned int

całkowita bez znaku

0...65535

2 bajty

long (long signed int)

liczba całkowita długa

-2147483648...2147483647

4 bajty

unsigned long (long unsigned int)

j.w. bez znaku

0...4294967295

4 bajty

float

l. rzeczywista

-3.4E-38..-3.4E-38,0,3.4E-38..3..3.4E38

4 bajty

double

l. rzeczywista podwójna

-1.7E308..-1.7E-308,0,1.7E-308..1.7E308

8 bajtów

long double

l. rzecz. długa podwójna

-1E4932..-3.4E-4932,0,3.4E-4932..1.1E4932

10 bajtów

Szczegóły zależne są od konkretnej implementacji kompilatora języka C.

Są jeszcze inne typy danych jak:
void (typ funkcji nie zwracającej wartości),
enum (typ wyliczeniowy) oraz typ wskaźnikowy.

Typ wyliczeniowy (enum) reprezentowany jest na 2 bajtach,
wskaźnikowy na 2 lub 4 (w zależności od modelu pamięci),
void nie jest reprezentowany.

 

Typy, operatory, wyrażenia

Zmienne i stałe są podstawowymi obiektami danych, jakimi posługuje się program. Deklaracje wprowadzają potrzebne zmienne oraz ustalają ich typy i ewentualnie wartości początkowe.
Operatory określają co należy z nimi zrobić.
Wyrażenia wiążą zmienne i stałe, tworząc nowe wartości.

Stałe

W C występują 4 rodzaje stałych:
stałe całkowitoliczbowe,
stałe rzeczywiste,
stałe znakowe
oraz
łańcuchy znaków.
Wartość stałej numerycznej nie może wykraczać poza dopuszczalne granice.

Stałe całkowitoliczbowe

Nazwa

Dozwolony zestaw znaków

Uwagi

Przykłady

Stałe dziesiętne

0..9 + -

Jeśli więcej niż 1 znak, pierwszym nie może być 0

0 1 876 -122 +909

Stałe ósemkowe

0..7 + -

Pierwszą cyfrą musi być 0

0 0111 0777 -0777 +0222

Stałe szesnastkowe

0..9 a..f A..F + -

Pierwszymi znakami muszą być 0x lub 0X

0x 0X1234 0XAFDEC 0xffff

W celu zainicjowania zmiennych typów int i long po znaku równości podajemy całkowitą stałą liczbową. Przykłady:
int l=100;
unsigned k=121;

int la = 0x2ffa;
long i = 25L; /* long */
long unsigned z = 1000lu; /* lub 1000UL */

Stała całkowita, jak np. 1234 jest obiektem typu int.
W stałej typu long na końcu występuje litera l lub L, jak 123456789L.
Stała całkowita nie mieszcząca się w zakresie int jest traktowana jako stała typu long.
W stałych typu unsigned na końcu występuje u lub U,
a końcówka ul lub UL oznacza stałą typu unsigned long.

Stałe rzeczywiste, zwane zmiennoprzecinkowymi reprezentują liczby dziesiętne.
Dozwolony zestaw znaków: 0..9 . + - E e (E lub e reprezentuje podstawę systemu tj. 10)
Uwagi: 1.2*10^-3 można zapisać 1.2E-3 lub 1.2e-3.

Stałe zmiennopozycyjne zawierają albo kropkę dziesiętną (np. 123.4), albo wykładnik e (np. 1e-2) albo jedno i drugie.
Typem stałej zmiennopozycyjnej jest double, chyba, że końcówka stanowi inaczej. Występująca na końcu litera f lub F oznacza obiekt typu float,
a litera l lu L - typu long double.

Przykłady: 0. 2. 0.2 876.543 13.13E13 2.4e-5 2e8

Deklaracja i inicjalizacja zmiennych rzeczywistych - przykłady::

float s=123.16e10; /* 123.16*10^16 */
double x=10.;
long double x=.12398;
double xy=-123.45

Stałe znakowe

Stała znakowa jest liczbą całkowitą; taką stałą tworzy jeden znak ujęty w apostrofy, np. 'x'.
Są to więc pojedyncze znaki zamknięte dwoma apostrofami.
Zestaw dowolnych widocznych znaków ASCII. Wartością jest wartość kodu znaku w maszynowym zbiorze znaków. Np. wartością stałej '0' jest liczba 48 - liczba nie mająca nic wspólnego z numeryczną wartością 0.
Pewne znaki niegraficzne mogą być reprezentowane w stałych znakowych i napisowych przez sekwencje specjalne, takie jak \n (znak nowego wiersza).

Przykłady: 'A' '#' ' '
char a='a';
Znaki z zestawu ASCII o kodach 0 do 31 są znakami sterującymi, niewidocznymi na wydrukach.
Znaki o kodach 0...127 są jednakowe dla wszystkich komputerów bazujących na kodzie ASCII.
Znaki o kodach 128...255 (kod rozszerzony ASCII) mogą się różnić na różnych komputerach.

Escape-sekwencje - sekwencje specjalne

Niektóre znaki "niedrukowalne" mogą być przedstawione w postaci tzw. escape-sekwencji, np. znak nowej linii jako sekwencja \n.
Pierwszym znakiem tej sekwencji jest backslash (\).
Sekwencja specjalna wygląda jak 2 znaki, ale reprezentuje tylko jeden znak

Sekwencja znaków

Wartość ASCII

Znaczenie

\a

7

Sygnał dźwiękowy (BEL)

\b

8

Cofniecie o 1 znak (BS)

\t

9

Tabulacja pozioma (HT)

\v

11

Tabulacja pionowa (VT)

\n

10

Nowa lina (LF)

\f

12

Nowa strona (FF)

\r

13

Powrót karetki (CR)

\"

34

Cudzysłów

\'

39

Apostrof

\?

63

Znak zapytania

\\

92

Backslash

\0

0

Znak pusty (null) - nie jest równoważne stałej znakowej '0'

Stałe napisowe - napisy, łańcuchy znaków (stałe łańcuchowe)

Stała napisowa lub napis jest ciągiem złożonym z zera lub wiecej znaków, zawartym między znakami cudzysłowu, np. "Jestem napisem".
Stała łańcuchowa składa się z ciągu o dowolnej liczbie znaków.
Ciąg ten musi być ograniczony znakami cudzysłowu.
Przykłady:

"Wynik = "     " + 2 mln $"   "Linia nr 1\nLinia nr2"               ""      "A + B =  "

Łańcuchy mogą zawierać escape-sekwencje.
Łańcuchem pustym są same cudzysłowy.
Łańcuch w sposób niejawny jest zakończony znakiem null czyli \0.
Dlatego np. stała znakowa 'K' nie jest równoważna łańcuchowi "K".

Łańcuch znaków (napis) można traktować jako tablicę złożoną ze znaków, uzupełnioną na końcu znakiem '\0'
Taka reprezentacja oznacza, że praktycznie nie ma ograniczenia dotyczącego długości tekstów.
Programy muszą jednak badać cały tekst, by określić jego długość, np. strlen(s) ze standardowej biblioteki.

Przykład:
Napis "Katowice" , który może być zadeklarowany jako tablica jednowymiarowa, której elementami są znaki, np.
char napis[] = "Katowice"

Nr elementu

1

2

3

4

5

6

7

8

9

Napis

K

a

t

o

w

i

c

e

\0

Wartość indeksu

0

1

2

3

4

5

6

7

8

Deklaracja i inicjalizacja łańcuchów - przykłady:

char s[10]="\n\fAndrzeh\x60";
char str[20]={'\n','\f', 'A', 'n', 'd', 'r', 'z', 'e', 'j', '\x60', '\0'};

 

Stałe wyliczeniowe (enumeration constant)

Stałe wyliczeniowe tworzą zbiór stałych o określonym zakresie wartości. Wyliczenie jest listą wartosci całkowitych, np.
enum boolean {NO, YES};
Pierwsza nazwa na liście wyliczenia ma wartość 0, następna 1 itd., chyba że nastąpi jawnie podana wartość.

Przykłady:

enum KOLOR {CZERWONY, NIEBIESKI, ZIELONY, BIAŁY, CZARNY}

KOLOR staje się nazwą wyliczenia, powstaje nowy typ. Do CZERWONY zostaje przypisana wartośc 0, do niebieski 1, zielony 2 itd. Każda stała wyliczeniowa ma wartość całkowitą. Jeśli specjalnie się nie określi, to pierwsza stała przyjmie wartość 0, druga 1 itd.

enum KOLOR {red=100, blue, green=500, white, black=700};

red przyjmie wartość 100, blue 101, green 500, white 501, black 700

enum escapes{BELL='\a', BACKSPACE='\b', TAB='\t', NEWLINE='\n', VTAB='\v', RETURN='\r'};

enum months {JAN=1, FEB, MAR, APR , MAY, JUL, AUG, SEP, OCT, NOV, DEC};

(luty jest 2-gi itd.)

Stałe symboliczne - makrodefinicje

Stała symboliczna jest nazwą przedstawiającą inną stałą - numeryczną, znakową lub tekstową. Definicję stałej symbolicznej umożliwia instrukcja #define:

#define NAZWA tekst

gdzie NAZWA jest nazwą stałej symbolicznej, a tekst jest związanym z tą nazwą łańcuchem znaków

Przykłady:

Makrodefinicje proste:

#define identyfikator <ciąg-jednostek-leksykalnych>

#define PI 3.14159

#define TRUE 1

#define FALSE 0

#define NAPIS1 Siemianowice

#define IMIE "Andrzej"          (puts(IMIE) rozwija w tekst puts("Andrzej")

#define IMIE_I_NAZWISKO IMIE+"Zalewski"       rozwinięcie daje tekst "Andrzej + Zaleski"

#define WCZYTAJ_IOSTREAM_H #include <iostream.h>    

 

Makrodefinicje parametryczne

#define identyfikator(idPar1, idPar2,...) ciąg_jedn_leksykalnych

#define ILORAZ(a,b) ((a)/(b)) - makrodefinicja ILORAZ - parametry w nawiasach!

#define SUMA(a,b) ((a)+(b))

W trakcie kompilacji nazwy stałych symbolicznych są zastąpione przez odpowiadające im łańcuchy znaków.
Ułatwia to parametryzację programu, a także umożliwia zastępowanie często niewygodnych w pisaniu sekwencji programu, tworzenie makrodefinicji, tworzenie własnych dialektów języka, czy nawet języków bezkompilatorowych (na bazie kompilatora C).

Przykład z walcem, z zastosowaniem pseudoinstrukcji #define

/********************************************************/

/*  Program  p8.c                                    */

/*  Obliczanie objetosci walca        ( #define )    */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

#define PI        3.1415926

#define PROMIEN   3.3

#define WYSOKOSC 44.4

#define WYNIK    printf("Objetosc walca = %f", objetosc)

 

main()

 

{

   float promien, wysokosc, objetosc;

 

   promien  = PROMIEN;

   wysokosc = WYSOKOSC;

   objetosc = PI * promien * promien * wysokosc;

   WYNIK;

}

/********************************************************/

Wynik programu:
Objętość walca = 1519.010254

Dzięki #define program jest bardziej czytelny.
Stała PI może być użyta wielokrotnie, wartości danych są widoczne na początku.

Użycie dużych liter jako nazwy stałej symbolicznej nie jest obowiązkowe ale zalecane.

Zmienne

Zmienną nazywamy nazwę (identyfikator) reprezentującą określony typ danych.
W chwili rozpoczęcia pracy programu zmienna powinna posiadać nadaną wartość początkową (nie powinna być przypadkowa).
W trakcie pracy programu wartości zmiennych ulegają zwykle zmianom.
Należy przewidzieć zakres zmienności tych zmiennych.

W języku C wszystkie zmienne muszą być zadeklarowane przed ich użyciem, zwykle na początku funkcji przed pierwszą wykonywaną instrukcją.
Deklaracja zapowiada właściwości zmiennych.
Składa się ona z nazwy typu i listy zmiennych, jak np.
int fahr, celsius;

W języku C oprócz podstawowych typów: char, short, int, long, float, double
występują także
tablice, struktury, unie, wskaźniki do tych obiektów oraz funkcje zwracające ich wartości.

W przypadku zmiennych nalezy zwrócić uwagę na 2 zasadnicze rzeczy:

Przykład ilustrujacy ten problem

/********************************************************/

/*  Program  p9.c                                    */

/*  Obliczanie objetosci walca        ( zmienne )    */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

#define PI        3.1415926

#define PROMIEN   3.3

#define WYNIK    printf("Objetosc walca = %f", objetosc)

 

main()

 

{

   float promien, wysokosc, objetosc;

   int i;

 

   promien  = PROMIEN;

   objetosc = PI * promien * promien * wysokosc;   /* uwaga */

   WYNIK;

   i=40000;                                      /* uwaga */

   printf("\ni = %i ", i);

}

/********************************************************/

Efekt wykonania:

Objetosc walca = 0.000000

i = -25536

Objętość walca jest równa 0, bo nie została zainicjalizowana zmienna 'wysokosc' - przez domniemanie kompilator przyjął 0. Na wydruku i widać, że nastąpiło przekroczenie dopuszczalnego zakresu zmiennej 'i' typu int.

Zmienne mogą być automatyczne oraz zmienne zewnętrzne.
Zmienne automatyczne pojawiają się i znikają razem z wywołaniem funkcji.
Zmienne zewnętrzne to zmienne globalne, dostępne przez nazwę w dowolnej funkcji programu.

Zmienna zewnętrzna musi być zdefiniowana dokładnie jeden raz na zewnątrz wszystkich funkcji - definicja przydziela jej pamięć. Taka zmienna musi być też zadeklarowana w każdej funkcji, która chce mieć do niej dostęp. Można to zrobić albo przez jawną deklarację extern, albo niejawnie przez kontekst.
Jeśli definicja zmiennej zewnętrznej pojawia się w pliku źródłowym przed użyciem zmiennej w konkretnej funkcji, to nie ma potrzeby umieszczania w tej funkcji deklaracji extern.

Deklaracje

Deklaracje umożliwiają wyspecyfikowanie grup zmiennych określonego typu.
Większość kompilatorów dopuszcza nadanie wartości początkowej zmiennej w deklaracji (inicjalizację).

Wszystkie zmienne muszą być zadeklarowane przed użyciem.
W deklaracji określa się typ, a następnie wymienia jedną lub kilka zmiennnych tego typu, np.

int lower, upper;
char c, line[1000];

W deklaracjach można nadawać zmiennym wartości początkowe, np.

char esc='\';
int i=0;
float eps=1.0e-5;
int limit=MAXLINE+1;

Jeśli zmienna nie jest automatyczna, to jej wartość początkową nadaje się tylko raz - jakby przed rozpoczęciem programu; jej inicjatorem musi być wyrażenie stałe.
Zmiennym automatycznym jawnie określone wartości początkowe nadaje się za każdym razem przy wywołaniu funkcji lub przy wejściu do zawierającego je bloku.
Zmiennym zewnętrznym i statycznym przez domniemanie nadaje się wartość pocz. zero. Zmienne automat. bez jawnie określonej wartości pocz. mają wartości przypadkowe (śmiecie).

Kwalifikator const mówi, że wartość zmiennej będzie stała.

const double e=2.71828182;
const char mas[]="Uwaga:";

Deklarację const można stosować również do tablicowych paramentów funkcji, by wskazać, że funkcja nie może zmieniać tablicy:

int strlen(const char[]);

Przykład programu z deklaracjami zmiennych. Niektórym nadano wartości początkowe.

Przykład programu z deklaracjami zmiennych. Niektórym nadano wartości początkowe.

/********************************************************/

/*  Fragment p10.c             Turbo C  2.0           */

/*                (dozwolone deklaracje elementarne) */

/*------------------------------------------------------*/

 

main()

 

{

   /* Komentarz  (znaczenie slow kluczowych)

 

      typy danych:  char     - znak (bajt),

                   int      - liczba calkowita,

                   float    - liczba rzeczywista,

                   double   - liczba rzeczywista podwojna,

 

      modyfikatory: short    - krotki,

                   long     - dlugi,

                   signed   - ze znakiem,

                   unsigned - bez znaku                 */

 

   /* --- typy znakowe --------------------------------- */

   char                 c1  ='k';

   signed char          c2  ='\123';

   unsigned char        c3  ='\xAB';

 

   /* --- tablice znakow ------------------------------- */

   char           tekst[]   = "Katowice";

   unsigned char   teKst[30] = "Taki sobie teKst to jest!";

 

 

   /* --- typy liczb calkowitych ----------------------- */

   int                  i1  = 0;

   signed int           i2  =-32767;

   unsigned int          i3;

   signed               i4  = 32767;

   unsigned             i5  = 32767;

   short                i6  = 3;

   signed short          i7  =-3;

   unsigned short      i8  = 44;

   short int            i9  = 22;

   signed short int      i10 =-555;

   unsigned short int  i11 = 1;

   long                 i12 = 11111;

   signed long          i13 =-1;

   unsigned long         i14;

   long int             i15 = 22222;

   signed long int       i16;

   unsigned long int     i17;

 

 

   /* --- typy liczb rzeczywistych --------------------- */

   float                r1 =-3.4E38;

   signed float          r2 = 3.4E38;

   unsigned float        r3 = 5.5E38;

   long float           r4 = 1.7E308;

   double               r5 = 1.7e308;

   long double           r6 = 1.1e4932;

   float               r7 = 1234.56789;

 

   /*  dalsza ( robocza ) czesc programu ... */

}

/********************************************************/

W deklaracji typu text[]="... " kompilator sam sobie dobiera długość pola tablicy, dbając też, by ostatnim znakiem był null (\0).
W przypadku deklaracji explicite, np. text[20]="...", gdy łańcuch będzie dłuższy od 20 to nastąpi jego obcięcie, a gdy będzie krótszy, to niewykorzystane miejsca zostaną wypełnione albo znakami pustymi albo po znaku \0 będą wartości przypadkowe (nieistotne).

Operatory arytmetyczne

Wyrażenia 2-argumentowe: +, -, *, / oraz operator dzielenia modulo %

Dzielenie całkowite obcina cześć ułamkową wyniku.

Przykład:

int x,y, a=5, b=2;

x=a/b;            /* w wyniku x otrzyma wartość 2 */

y=a%b;            /* y => 1  - reszta z dzielenia */

x % y daje w wyniku resztę dzielenia x przez y.
Operatora % nie można stosować do danych typu float i double.

Operatory jednoargumentowe:
+,  -.

Dwuargumentowe operatory + i - mają ten sam priorytet, niższy od *, /, %, który z kolei jest niższy od priorytetu jednoargumentowych. operatorów + i -.
Operatory arytmetyczne są lewostronnie łączne.

Relacje i operatory logiczne

Operatory relacji: >  >=   <  <=  (mają ten sam priorytet)
Operatory przyrównania:  == (równe)   !=  (różne)  (priorytet niższy)
Operatory logiczne: && (and)  i  ||  (or) 

Wyrażenia

Wszystko co zwraca wartość jest wyrażeniem.
Wyrażeniem może być samodzielny element, np. liczba, stała, zmienna.
Może to być też kombinacja w/w elementów połączonych znakami operatorów, np. arytmetycznych lub logicznych.

Przykłady:

Instrukcje

Instrukcje są to fragmenty tekstu programu (zwykle linie), które powodują jakąś czynność komputera w trakcie wykonywania programu.

Instrukcje można podzielić na grupy:

·                Instrukcje grupujące (złożone) - ograniczone klamrami { },
 np.
{
  a=3;
  b=2.2;
  p=a*b;
  printf("Pole=%f",p);
}

 

Przykład instrukcji złożonej (grupującej)

/********************************************************/

/*  Program  p11.c                                */

/*  Obliczanie objetosci walca   ( instrukcja bloku )     */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

#define PI           3.1415926

#define PROMIEN      3.3

#define WYSOKOSC    44.4

#define KRYTERIUM 1500.0

#define WSP          2.2

#define WZOR_OBJETOSC  PI * promien * promien * wysokosc

 

main()

 

{

   float promien, wysokosc, objetosc;

 

   promien  = PROMIEN;

   wysokosc = WYSOKOSC;

   objetosc = WZOR_OBJETOSC;

   printf("Objetosc walca = %f", objetosc);

 

   if (objetosc > KRYTERIUM)

     {

       float  objetosc,  promien = PROMIEN * WSP;

 

       objetosc = WZOR_OBJETOSC;

       printf("\nObjetosc walca = %f  (lokalna)", objetosc);

     }

 

   printf("\nObjetosc walca = %f", objetosc);

}

/********************************************************/

Efekt wykonania programu:

Objetosc walca = 1519.010254

Objetosc walca = 7352.010742  (lokalna)

Objetosc walca = 1519.010254

Wejście i wyjście programu

Do podstawowych funkcji języka C, umożliwiających komunikację z otoczeniem należą:

dla operacji wejścia: getchar, gets, scanf;

dla operacji wyjścia: putchar, puts, printf;

W DOS, wyniki wysyłane na ekran mogą być przy pomocy znaku potoku wysłane do pliku lub na drukarkę.
Np. p11 > Wynik.txt (do pliku)
p11 > PRN (na drukarkę)

Funkcja putchar: int putchar(int)

Funkcja wysyła na zewnątrz (do standardowego strumienia wyjściowego stdout, standardowo na ekran0 pojedynczy znak
Funkcja (makro) zwraca wartość wypisanego znaku lub EOF (jako sygnał błędu).

Przykład:

/********************************************************/

/*  Program  p12.c                                    */

/*                            ( putchar )            */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

#define SPACJA 32

 

main()

{

  char napis[] = "ABCDEFGHIJKLMNOPQRS...";

  int znak = 73;

 

  /* wyprowadzanie pojedynczych znakow

     przy pomocy funkcji  putchar   */

 

  putchar('\n');     putchar(znak);     putchar(SPACJA);

  putchar(55);       putchar(SPACJA);   putchar('Z');

  putchar(SPACJA);   putchar('\066');   putchar(SPACJA);

  putchar('\x3A');   putchar('\n');     putchar(napis[0]);

  putchar(SPACJA);   putchar(napis[4]); putchar(SPACJA);

  putchar(znak+'\066'-52);              putchar('\n');

}

/********************************************************/

Wynik:

I 7 Z 6 :

A E K

Funkcja puts: int puts(const char *s);

Wysyła łańcuch s do standardowego strumienia wyjściowego (stdout) i dołącza znak końca wiersza.
W przypadku powodzenia operacji wartość jest nieujemna, w przeciwnym wypadku EOF.

/********************************************************/

/*  Program  p13.c                                    */

/*                            ( puts )               */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

#define NOWA_LINIA putchar('\n')

 

main()

{

  char napis[] = "ABCDEFGHIJKLMNOPQRS...";

 

  /* wyprowadzanie pojedynczych linii tekstu

     przy pomocy funkcji  puts            */

 

  NOWA_LINIA; puts(napis); NOWA_LINIA;

  puts("To jest praktyczna funkcja");

  puts("\066\067\x2B\x2A itd.");

}

/********************************************************/

Wynik:

ABCDEFGHIJKLMNOPQRS...

 

To jest praktyczna funkcja

67+* itd.

Funkcja printf

Wyprowadza wynik przetwarzania w różnych formatach.

printf (łańcuch, lista argumentów)
int printf(const char *format,...)

Przykład:

/********************************************************/

/*  Program  p14.c                                    */

/*                            ( printf  /1/ )        */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()

{

  int  k = 21101;  /* liczba dziesietna */

 

  printf("\nk(_10) = %i   k(_8) = %o    k(_16) = %X", k, k, k);

 

 

}

/********************************************************/

Wynik:

k(_10) = 21101   k(_8) = 51155    k(_16) = 526D

Formaty realizowane przez funkcję printf (znaki typu w łańcuchach formatujących)

Typ danych - znak typu w formacie

Argument wejściowy

Format wyjściowy

Przykład

Liczba

%d, %i

int

liczba całkowita ze znakiem

%u

unsigned int

l. całk. ze bez znaku

%o

int

ósemkowa

%x

int

szestnastkowa bez znaku, małe litery a..f

%X

int

j.w. będą duże litery A..F

%f

float/double

l. zmiennoprzecinkowa: [-]nnnn.mmmmm

%e

float/double

j.w. w postaci [-].nnnne[+-]mmm

%E

-"-

j.w. ze znakiem E

%G

-"-

jak %f lub %E, mniejsza liczba znaków

ZNAK lub ŁAŃCUCH

%c

char (znak)

pojedynczy znak

%s

char * - wskaźnik łańcucha

łańcuch znaków, aż do napotkania bajtu zerowego \0

WSKAŹNIK

%n

int *

Liczba dotychczas wysłanych znaków

%p

pointer - wskaźnik

argument w postaci wskaźnika, co zależy od modelu pamięci (segm:offs lub offs)- liczba 16-wa

Przykłady:

/********************************************************/

/*  Program  p15.c                                   */

/*                            ( printf  /2/ )        */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()

{

  float  a,b,c;

 

    a=153.67789;    b=2.33E-2;   c = a * b;

 

    printf(" %f  razy  %E  wynosi:  %f ", a,b,c);

}

/********************************************************/

Wynik:

 153.677887  razy  2.330000E-02  wynosi:  3.580695

/********************************************************/

/*  Program  p16.c                                    */

/*                            ( printf /3/ )         */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()

{

  char napis[] = "ABCDEFGHIJKLMNOPQRS...";

  int  znak = 73;

 

  /* wykonanie tego samego co w przykladach

     p12.c i p13.c  przy pomocy funkcji  printf              */

 

  /* p12.c */

  printf("\n%c %c %c %c %c \n%c %c %c\n",

   znak,55,'Z','\066','\x3A',napis[0],napis[4],znak+'\066'-52);

 

  /* p13.c */

  printf("\n%s\nTo jest praktyczna funkcja\n%c%c%c%c itd.",

   napis,'\066','\067','\x2B','\x2A');

}

/********************************************************/

Wynik:

I 7 Z 6 :

A E K

 

ABCDEFGHIJKLMNOPQRS...

To jest praktyczna funkcja

67+* itd.

/********************************************************/

/*  Program  p17.c             ( Turbo C 2.0 )        */

/*                            ( printf  /4/ )        */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()  /* zagadnienie dokladnosci */

{

  double  a=153.67789;

  int     k=22799;

  int     m=-500;

  int     *p;     /* wskaznik */

  char    c='M';

  char    napis[]="Lepsze C od B lub P    ";

 

  p=&k;

  printf("\n format  %%d   %d", k);

  printf("\n format  %%i   %i", m);

  printf("\n format  %%u   %u", k);

  printf("\n format  %%o   %o", k);

  printf("\n format  %%x   %x", k);

  printf("\n format  %%X   %X", k);

  printf("\n format  %%f   %f", a);

  printf("\n format  %%e   %e", a);

  printf("\n format  %%E   %E", a);

  printf("\n format  %%g   %g", a);

  printf("\n format  %%G   %G", a);

  printf("\n format  %%c   %c", c);

  printf("\n format  %%s   %s", napis);

  printf("\n format  %%p   %p", *p);

  printf("\n ------------------------");

  printf("\n "); printf(napis);

}

/********************************************************/

Wynik:

 format  %d   22799

 format  %i   -500

 format  %u   22799

 format  %o   54417

 format  %x   590f

 format  %X   590F

 format  %f   153.677890

 format  %e   1.536779e+02

 format  %E   1.536779E+02

 format  %g   153.678

 format  %G   153.678

 format  %c   M

 format  %s   Lepsze C od B lub P

 format  %p   654C:590F

 ------------------------

 Lepsze C od B lub P

Użyty w łańcuchach formatu zapis %% reprezentuje pojedynczy "widzialny" znak procentu.

Pełny zapis instrukcji formatu printf:

% [Pole znaku] [Szerokość] [.Dokładność] [Modyfikator] Typ danych

%[flagi][szerokość][.precyzja][F|N|h\l|L]znak-typu

Wszystkie sekwencje formatujące zaczynają się od znaku %. Kolejne elementy określają:

Zapisy w nawiasach kwadratowych są opcjonalne i nie muszą wystąpić

Pole znaku (znaki flag):

'+'  '-'   '#'  ' ' (spacja)   0 (zero)

- wyprowadzony ciąg znaków będzie wyrównany lewostronnie
+ znak ma być wydrukowany (- lub +)

Flagi w sekwencjach formatujących

Flaga

Co określa

-

Justuje lewostronnie wartość, umieszczając z prawej strony odpowiednią ilość spacji

+

Jeśli wyświetlana jest liczba ze znakiem, wówczas zostanie przed nią umieszczony znak + lub -, w zależności od wartości

spacja

Jeśli wartość jest nieujemna, zamiast plus wyświetlana będzie spacja, w przypadku wartości ujemnych -

#

Wpływ tego znaku zależy od tego, z jakim znakiem typu jest związany - tabela poniżej

 

Typ danych

Reakcja, gdy występuje znak #

c, s, d, i, u

Nie wpływa

%o

Przy wartościach dodatnich na początku zostanie dopisany znako 0

%x, %X

Wszystkie liczby będą przedstawione z 0x lub 0X

%e, %E, %f

Również w przypadku braku miejsc znaczacych dziesiętnych, po przecinku będzie kropka dzies.

%g, %G

Odpowiednio jak dla %e i %E, ale będą widoczne nieznaczące zera

Specyfikator precyzji rozpoczyna się znakiem kropki, który oddziela go od pozostałych elementów sekwencji formatującej

Specyfikatory precyzji (dokładności) - zagadnienie dokładności obliczeń

Specyfikator dokładności

Precyzja - znaczenie

nie podano

Domyslne precyzje:
- 1 dla znaków typu d, i, o, u, x, X
- 6 dla typu e, E, f
- wszystkie znaczące cyfry dla typu g i G

.0

Dla znaków typu d, i, o, u, x, X przyjmowana jest precyzja d domysla. Dla e, E, f nie jest drukowana kropka dziesiętna. Liczby całkowite o wartosci zero nie będą drukowane

.n

Drukowane będzie n znaków lub cyfr dziesiętnych. Może nastąpić obcięcie lub zaokrąglenie

*

Lista argumentów zawiera wartość określającą precyzję.

Specyfikator szerokości - określa minimalną szerokość dla wartości wyjściowej.

Specyfikatory szerokości pola

Specyfikator szerokości pola

Wpływ na formatowane dane

n

Drukowanych jest przynajmniej n znaków. Jeśli wartość zajmuje mniej niż n znaków, umieszczone będą dodatkowe spacje, z lewej lub prawej strony (jeśli ustawiono odpowiednią flagę)

0n

Drukowanych jest przynajmniej n znaków. Jeśli znaków drukowanych jest mniej niż n to nastąpi wypełnienie zerami z lewej strony

*

Szerokość pola znajdzie się w argumencie poprzedzającym argument, z którym związana jest dana sekwencja

Modyfikatory rozmiaru argumentów - zawierają dodatkową informację o typie argumenów wejściowych. Jedna z liter: F, N, h, I

Modyfikator

Działanie

F

Przekazanie wskaźnika typu far. Argument zostanie potraktowany jako daleki wskażnik - używany ze znakami typu p, s, n

N

Przekazanie wskaźnika typu near. Argument będzie traktowany jako wskaźnik bliski. Nie stosować w modelu huge.

h

Oznacza przekazanie danej typu short int. Argument traktuje się jako short int dla znaków typu d, i, o, u, x, X

l

Oznacza przekazanie danej typu long int względnie double.

L

Argument traktowany jako long double dla znaków typu e, E, f, g, G

Przykłady:

/********************************************************/
/* Program p18.c ( Turbo C 2.0 ) */
/* ( printf /5/ ) */
/*------------------------------------------------------*/

#include <stdio.h>

main() /* wybrane formaty */
{
double a=153.67789, b=153. ;
int k=22799;
int m=-500;
int *p; /* wskaznik */
char c='M';
char napis[]="Lepsze C od B lub P ";

p=&k;
printf("\n format %%#-+8d %#-+8d", k);
printf("\n format %%#-+8i %#-+8i", m);
printf("\n format %%#- 8u %#- 8u", k);
printf("\n format %%#-+8o %#-+8o", k);
printf("\n format %%#-+8x %#-+8x", k);
printf("\n format %%#-+8X %#-+8X", k);
printf("\n format %%#020.8f %#020.8f", a);
printf("\n format %%# 20.8e %# 20.8e", a);
printf("\n format %% +20.8E % +20.8E", b);
printf("\n format %% +20.8g % +20.8g", a);
printf("\n format %% +20.8G % +20.8G", b);
printf("\n format %% +20.8c % +20.8c", c);
printf("\n format %%.20s %.20s", napis);
printf("\n format %%24p %24p", *p);
printf("\n ---------------------------------------");
printf("\n%44.*s",30,napis);
m=printf("\n\n123456789 123456789 123456789 123456789 1\n");
printf("\n\"Wynik\" poprzednio wykonanej instrukcji");
printf("\np r i n t f wynosi %i znaki \n", m);
}
/********************************************************/

Wynik:

 format  %#-+8d   +22799

 format  %#-+8i   -500

 format  %#- 8u   22799

 format  %#-+8o   054417

 format  %#-+8x   0x590f

 format  %#-+8X   0X590F

 format  %#020.8f   00000000153.67789000

 format  %# 20.8e         1.53677890e+02

 format  % +20.8E        +1.53000000E+02

 format  % +20.8g             +153.67789

 format  % +20.8G                   +153

 format  % +20.8c                      M

 format  %.20s   Lepsze C od B lub P

 format  %24p                  10B4:590F

 ---------------------------------------

                     Lepsze C od B lub P

 

123456789 123456789 123456789 123456789 1

 

"Wynik" poprzednio wykonanej instrukcji

p r i n t f   wynosi  44  znaki

/********************************************************/

/*  Program  p19.c             ( Turbo C 2.0 )        */

/*                            ( printf  /6/ )        */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()  /* zapisy rownowazne, dynamiczny format */

{

  double  a=153.22;

  char    napis[]="Wszystko dobre co nie jest niedobre ";

  int     i,j;

 

  printf("\n%.9s", napis);

  printf("\n%.*s", 9, napis);

  i=9;   printf("\n%.*s", i, napis);

  i=14;  printf("\n%.*s", i, napis);

  i=21;  printf("\n%.*s", i, napis);

 

  printf("\n a = %#09.3f", a);

  printf("\n a = %#0*.3f", 9, a);

  printf("\n a = %#0*.*f", 9, 3, a);

  i=9; j=3;

  printf("\n a = %#0*.*f", i, j, a);

  i=20; j=8;

  printf("\n a = %#0*.*f", i, j, a);

}

/********************************************************/

Wynik:

Wszystko

Wszystko

Wszystko

Wszystko dobre

Wszystko dobre co nie

 a = 00153.220

 a = 00153.220

 a = 00153.220

 a = 00153.220

 a = 00000000153.22000000

/********************************************************/

/*  Program  p20.c                                   */

/*  Obliczanie objetosci walca   ( wieksza dokladnosc ) */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

#define PI           3.1415926

#define PROMIEN      3.3

#define WYSOKOSC    44.4

 

main()

{

 { float promien, wysokosc, objetosc;

 

   promien  = PROMIEN;  wysokosc = WYSOKOSC;

   objetosc = PI * promien * promien * wysokosc;

   printf("\nObjetosc walca = %f", objetosc);

 }

 { double promien, wysokosc, objetosc;

 

   promien  = PROMIEN;  wysokosc = WYSOKOSC;

   objetosc = PI * promien * promien * wysokosc;

   printf("\nObjetosc walca = %f", objetosc);

 }

}

/********************************************************/

Wynik:

Objetosc walca = 1519.010254

Objetosc walca = 1519.010288

/********************************************************/

/*  Program  p21.c                                   */

/*  Obliczanie objetosci walca   ( wieksza dokladnosc ) */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

#define PI           3.1415926

#define PROMIEN      3.3

#define WYSOKOSC    44.4

 

main()

{

   double promien, wysokosc, objetosc;

 

   promien  = PROMIEN;

   wysokosc = WYSOKOSC;

   objetosc = PI * promien * promien * wysokosc;

   printf("\nObjetosc walca = %f", objetosc);

   printf("\nObjetosc walca = %E", objetosc);

   printf("\nObjetosc walca = %g", objetosc);

   printf("\nObjetosc walca = %15.10f", objetosc);

   printf("\nObjetosc walca = %25.20f", objetosc);

 

}

/********************************************************/

Wynik:

Objetosc walca = 1519.010288
Objetosc walca = 1.519010E+03
Objetosc walca = 1519.01
Objetosc walca = 1519.0102875816
Objetosc walca = 1519.01028758159987000000

Funkcja getchar

int getchar(void)

Funkcja odczytuje znak ze standardowego strumienia wejściowego (stdin) i zwraca go po dokonaniu konwersji bez rozszerzenia znakowego. Funckja przy każdym wywołaniu podaje następny znak z wejścia lub EOF, gdy napotkała koniec pliku. W przypadku błędu lub końca zbioru wartością funkcji jest EOF. Stała symboliczna EOF jest zdefiniowana w nagłówku <stdio.h.. Jej wartoscią jest na ogół -1, ale e testach należy używać EOF.
Zadaniem funkcji jest wprowadzenie pojedynczego znaku do pamięci komputera. Syntaktycznie postać funkcji jest następująca:
c = getchar(); gdzie c jest typu char.
Po każdym wywołaniu funkcja getchar pobiera ze strumienia znaków następny znak i wraca z jego zawartością. Zawartością zmiennej jest następny znak z wejścia.

Przykłady:

#include <stdio.h>

 

/* przepisz wejscie na wyjście, wersja 1 */

main()

{

 int c;

 c = getchar(); /* przeczytaj znak */

 

 while (c != EOF) /* dopóki znak nie jest znakiem konca pliku (Ctrl Z) */

  {

        putchar(c);  /* wypisz przeczytany znak */

        c=getchar(); /* przeczytaj nastepny znak */

  }

}

Funkcja scanf

int scanf(const char * format, ...)

Funkcja scanf jest wejściowym odpowiednikiem funkcji printf . Wczytuje znaki ze standardowego wejścia, interpretuje zgodnie ze specyfikacjami w argumencie format i zapamiętuje wyniki w miejscach określonych przez argumenty, np.

int i, j;
scanf("%d%d", &i, &h);
spowoduje, ze ze standardowego wejścia zostaną pobrane 2 liczby całkowite (sekwencje formatujące %d i %d), których wartość zostanie umieszczona w zmiennych "i" i "j".

Syntaktycznie funkcja scanf ma definicję:

scanf(łańcuch formatu, lista argumentów)

Przykład: Obliczenie objętości walca:

/************************************************************/

/*  Program  p24.c                                       */

/*  Obliczanie objetosci walca        ( scanf /1/ )         */

/*----------------------------------------------------------*/

 

#include <stdio.h>

 

#define PI  3.1415926

 

main()

{

  float promien, wysokosc, objetosc;

 

  printf("\n----- Program oblicza objetosc walca -----");

  printf("\n----- Podaj dane wejsciowe: \n");

  printf("\npromien  = ");

  scanf("%f", &promien);

  printf("wysokosc = ");

  scanf("%f", &wysokosc);

  objetosc = PI * promien * promien * wysokosc ;

  printf("\nObjetosc walca = %f", objetosc);

}

/************************************************************/

Wyniki:

----- Program oblicza objetosc wal
----- Podaj dane wejsciowe:

promien = 3.3
wysokosc = 44.4

Objetosc walca = 1519.010254

Liczby 3.3 i 44.4 zostały wprowadzone z klawiatury. Każdy łańcuch znaków reprezentujacy liczbę, musi być zakoczony ENTER.

Uproszczona wersja w.w. programu - brak zmiennej objętość:

/************************************************************/

/*  Program  p24b.c                                      */

/*  Obliczanie objetosci walca        ( printf /8/ )        */

/*----------------------------------------------------------*/

 

#include <stdio.h>

 

#define PI  3.1415926

 

main()

{

  float promien, wysokosc;

 

  printf("\n----- Program oblicza objetosc walca -----");

  printf("\n----- Podaj dane wejsciowe: \n");

  printf("\npromien  = ");

  scanf("%f", &promien);

  printf("wysokosc = ");

  scanf("%f", &wysokosc);

  printf("\nObjetosc walca = %f",PI*promien*promien*wysokosc);

}

/************************************************************/

Instrukcja formatu dla funkcji scanf:

% [*] [Szerokość] [Modyfikator1] [Modyfikator2] Typ danych

Znaczenie opcji:

Typ danych (znak formatu)

Typ argumentu

Format wejściowy - dana wprowadzana

LICZBA

%d

int *

liczba całkowita dziesiętna, całkowita ze znakiem

%D

long *

liczba całkowita dzies. ze znakiem

%i

int *

liczba dzies., ósemkowa, 16-wa, całkowita, ze znakiem

%l

long *

j.w.

%u

unsigned *

liczba całkowita, dziesiętna, bez znaku

%U

unsigned long *

liczba całk. dziesiętna, bez znaku

%o

int *

liczba ósemkowa ze znakiem

%O

long *

j.w.

%x

int *

liczba 16-wa całkowita

%X

long *

j.w.

%f

float *

liczba zmiennoprzecinkowa

%e

float *

j.w.

%E

float *

j.w.

ZNAKI (znak lub łańcuch znaków)

%c

char *

pojedynczy znak

%s

char tab[n]

łańcuch aż do bajtu zerowego

WSKAŹNIK

%n

brak

liczba już wczytanych znaków zapamiętana we wskaźniku typu (int *)

%p

far * / near *

wskaźnik do dowolnego obiektu, jako liczba 16-wa, bliski (ofs) lub daleki (seg:ofs)

/********************************************************/

/*  Program  p27.c                                    */

/*                            ( scanf /3/ )          */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()  /* to samo co w przyk. p22.c i p23.c  */

{

   char znak, linia[80];

 

   scanf("%c",   &znak);     /* p22.c */

   printf("%c\n", znak);

   scanf("%s",   linia);     /* p23.c */

   printf("%s",  linia);

}

/********************************************************/

Program poniższy pokazuje możliwość filtrowania znaków:

/********************************************************/

/*  Program  p28.c                                    */

/*                             ( scanf /4/ )          */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()  /* filtrowanie znakow */

{

   char linia[80];

 

   scanf("%[a-zABC]",linia);

   printf("%s",  linia);

}

/********************************************************/

Przykładowy wynik:

alinaABOLa
alinaAB

Instrukcja scanf pozwala tu na wprowadzenie wszystkich małych liter a-z oraz wybranych liter A, B, C. Wprowadzony łańcuch zostanie obcięty przed znakiem nie należacym do zbioru podanego.

Inne możliwe filtry:

Operatory i wyrażenia

Do wykonania obliczeń zmieniających dane w informacje, niezbędne są operatory. Operator to symbol mówiący komputerowi, jak ma przetwarzać dane.

Operatory, z punktu widzenia liczby argumentów dzielimy na dwuargumentowe i jednoargumentowe.

a op b - op jest operatorem 2-argumentowym, np. a+b; a*b; a/b; a%b;

op a - op jest operatorem jednoargumentowym, np. -a; -(a+b); !a

Można je pogrupować wg cech funkcjonalnych na grupy:

Operatory arytmetyczne

Operatory arytmetyczne można podzielić na 3 grupy:

operatory inkrementacji i dekrementacji: --Op, ++Op, Op--, Op++

operatory addytywne: "+" i "-"

operatory multiplikatywne: "*', "/", "%"

Operatory te używane są do wykonywania działań matematycznych.

Operatory addytywne i multiplikatywne:

Operator

Funkcja

Wyrażenie

Operandy

Przykład

Wynik

+

Dodawanie

Op1+Op2

Op1 i Op2 są typu arytmetycznego
Op1 typu całk, Op2 wskaźnik
Op1 wskaźn, Op2 całkowity

int a=9; int b=2, c; c=a+b;

c=11

-

Odejmowanie

Op1-Op2

Op1 i Op2 są typu arytmet.
Op1 i Op2 są wskaźnikami tego samego typu
Op1 jest wskaźnikiem, Op2 typu całkowitego

int a=9; int b=2, c; c=a-b;

c=7

*

Mnożenie

Op1*Op2

Op1 i Op2 typów arytmet.

int a=9; int b=2, c; c=a*b;

c=18

/

Dzielenie

Op1 / Op2

-"-

int a=9; int b=2, c; c=a/b;

c=4

%

Reszta z dzielenia liczb całkowitych - modulo

Op1 % Op2

Op1 i Op2 typów całkowitych

int a=9; int b=2, c; c=a%b;

c=1

Brak jest operatora potęgowania (realizuje to funkcja biblioteczna pow)

Jeżeli dzielimy zmienne lub liczby całkowite przy pomocy operatora /, to wynik zawsze bedzie liczbą całkowitą. Z operatora % korzystamy do obliczenia reszty z dzielenia liczb całkowitych.

Przykład wykorzystujący operatory arytmetyczne:

/********************************************************/
/*  Program  p29.c                                    */
/*                      ( operatory arytmetyczne )           */
/*------------------------------------------------------*/
 
#include <stdio.h>
 
main()
{
  int    k = 20,  m = 3,    i;
  float  x = 7.5, y = 1.5,  z;
 
  printf("\n k=20,  m=3      (int)");
  printf("\n---------------------------");
  i = k + m;
  printf("\n k + m = %i ", i);
  i = k - m;
  printf("\n k - m = %i ", i);
  i = k * m;
  printf("\n k * m = %i ", i);
  i = k / m;
  printf("\n k / m = %i ", i);
  i = k % m;
  printf("\n k %% m = %i ", i);
  printf("\n");
  printf("\n x=7.5,  y=1.5   (float)");
  printf("\n---------------------------");
  z = x + y;
  printf("\n x + y = %6.2f ", z);
  z = x - y;
  printf("\n x - y = %6.2f ", z);
  z = x * y;
  printf("\n x * y = %6.2f ", z);
  z = x / y;
  printf("\n x / y = %6.2f ", z);
  printf("\n---------------------------");
  i = k*x + (m+k+1)/y ;
  printf("\n k*x + (m+k+1)/y  = %i    (int)", i);
  z = k*y + (x+k+1.)/m ;
  printf("\n k*y + (x+k+1.)/m = %6.2f (float)", z);
}
/********************************************************/
 Wynik wykonania:
k=20,  m=3      (int)
---------------------------
 k + m = 23
 k - m = 17
 k * m = 60
 k / m = 6
 k % m = 2
 
 x=7.5,  y=1.5   (float)
---------------------------
 x + y =   9.00
 x - y =   6.00
 x * y =  11.25
 x / y =   5.00
---------------------------
 k*x + (m+k+1)/y  = 166    (int)
 k*y + (x+k+1.)/m =  39.50 (float)
 

Operatory porównania - relacyjne

Operatory relacyjne pozwalają stwierdzić, czy między operandami zachodzi dana relacja. Jeżeli relacja jest prawdziwa, to jej wartością jest true (prawda, wartość 1), a jeżeli fałszywa, to jej wartością jest false (wartość 0). Operator sprawdzenia róności to "==" (operator przypisania to "=").

Operator

Znaczenie

Relacja

Opis

Przykład

< 

Mniejszy

Op1<Op2

Op1 mniejsze niż Op2

int a,b,wyn;
a=10; b=3;
wyn = a<b; // zostanie przypisana wartość 0 (false)

<=

Mniejszy lub równy

Op1 <= Op2

Op1 mniejsze równe Op2

wyn = a<=b; // 0

> 

Większy

Op1 > Op2

Op1 większe niż Op2

wyn = a>b; // 1 (true)

>=

Większy lub równy

Op1 >= Op2

wyn = a>= b; //1

==

Równy - równe

Op1 == Op2

Op1 równe Op2

wyn = a == b; // 0

!=

Nierówny - różne

Op1 != Op2

Op1 różne od Op2

wyn = a != b; //1

Operandy Op1 i Op2 w powyższych relacjach muszą spełniać jedną z 2 reguł:

Operandy wyrażeń z operatorem równości == lub różnosci powinny spełnaić w.w. właściwości lub jedną z poniższych:

Uwaga! Operator równości jest często mylony z operatorem przypisania =

if (a=1) - przypisanie, wartością wyrażenia jest 1, czyli prawda, zamiast

if (a==1) - porównanie, wartością wyrażenia jest prawda, jeśli a równa się 1 lub fałsz gdy nie.

Kilka przykładów:

int k=1; m=2; n=3;

Wyrażenie

Interpretacja

Wartość

m<n

prawda

1

(k+m)>=n

prawda

1

(m-k)>n

fałsz

0

n>=3

prawda

1

k != m

prawda

1

k == 2

fałsz

0

(m+2) <= k

fałsz

0

 

Operatory logiczne

W języku C/C++ wartość logiczna prawda to liczba całkowita różna od zera, zaś fałsz to zero (całkowite)

Operator

Znaczenie

Wyrażenie

Opis

Przykład

&&

Koniunkcja - logiczne AND (i) /iloczyn

Op1 && Op2

Koniunkcja Op1 i Op2

int k=1, m=2, n=3;
((k+m)>=n) && (m==1) // 0

||

Alternatywa - logiczne OR (lub) /suma log.

Op1 || Op2

Alternatywa Op1 i Op2

((m-k)>n) || (m==2) //1

!

Negacja - logiczne NOT (nie)

!Op1

Negacja Op1

!(k>n) //1

Operandy Op1 i Op2 muszą być skalarami, zaś wartość wyrazenia logicznego jest zawsze typu int.

Wartości wyrażeń logicznych (f - fałsz/ false, t - prawda/false)

Op1

Op2

Op1 && Op2

Op1 || Op2

!Op1

f

f

f

t

t

f

t

f

t

t

t

f

f

t

f

t

t

t

t

f

if (x != 0) to samo co if (x)

if (y == 0) równoważne if (!y)

Przykład (Zalewski, Programowanie w C i C++ ..., str 131):

#include <stdio.h>

#define TRUE 1

#define FALSE 0

 

typedef int BOOL;

 

BOOL czy_w_przedziale(double x, double s, double t, BOOL domkniety)

{

  if ((x<t && x>s && !domkniety) || (x<=t && x>=s && domkniety))

        return TRUE;

  else return FALSE;

}

 

int main(void)

{

 double x, s=5, t=20;

 printf("\nPodaj liczbe: ");

 scanf("%lf",&x);

 if (czy_w_przedziale(x,s,t,TRUE))

  printf("\nLiczba %lf nalezy do przedzialu <%lf, %lf>",x,s,t);

 else

  printf("\nLiczba %lf nie nalezy do przedzialu <%lf, %lf>",x,s,t);

 return 0;

}

Przykładowy wynik :

Podaj liczbe: 3

Liczba 3.000000 nie nalezy do przedzialu <5.000000, 20.000000>

Przykład z walcem - promień ma być w przedziale (2, 3.3), a wysokosć w przedziale (4.50, 5.50), dodatkowo H/r ma być w przedziale [2.11,2.42] lub w [2.58, 2.95], objętość walca C <= 100 - walec jest DOBRY

/*************************************************************/

/*  Program  p30.c                                        */

/*  Ocena jakosci walca            ( operatory logiczne )    */

/*-----------------------------------------------------------*/

 

#include <stdio.h>

 

#define PI    3.1415926

/* parametry narzucone przez kryterium:

   P1  - promien minimalny

   P2  - promien maksymalny

   H1  - wysokosc minimalna

   H2  - wysokosc maksymalna

   hp  - stosunek wysokosci do promienia

   HP1 - dolna granica hp  (zakres pierwszy)

   HP2 - gorna granica hp  (zakres pierwszy)

   HP3 - dolna granica hp  (zakres drugi)

   HP4 - gorna granica hp  (zakres drugi)

   V   - objetosc maksymalna                  */

 

#define  P1    2.00

#define  P2    3.30

#define  H1    4.50

#define  H2    5.50

#define  HP1   2.11

#define  HP2   2.42

#define  HP3   2.58

#define  HP4   2.95

#define  V   100.00

 

main() /* kryterium jakosci walca */

{

 float promien, wysokosc, hp, objetosc;

 

 scanf("%f %f", &promien, &wysokosc);

 hp = wysokosc / promien;

 objetosc = PI * promien * promien * wysokosc;

 if

    (((promien  >  P1) && (promien  <  P2)) &&

     ((wysokosc >= H1) && (wysokosc <= H2)) &&

     (((hp>=HP1) && (hp<=HP2)) || ((hp>=HP3) && (hp<=HP4))) &&

      ( objetosc <= V ))

   {

     printf("\n------ Walec jest DOBRY dla:");

     printf("\npromien=  %5.2f, wysokosc=%5.2f",promien,wysokosc);

   }

 printf("\nobjetosc=%6.2f, hp=     %6.2f",objetosc,hp);

}

/**************************************************************/

2.30

5.40

 

------ Walec jest DOBRY dla:

promien=   2.30, wysokosc= 5.40

objetosc= 89.74, hp=       2.35

 

Operatory bitowe

Bitowe operatory logiczne działają na uporządkowanym ciągu bitów (0,1) i pozwalają na manipulowanie bitami. Za pomocą tych operatorów można realizować funkcje logiczne OR, AND, EXOR, NOT.

Operator

Znaczenie

Wyrażenia

Przykłady

&

Bitowa koniunkcja (AND)

Op1 & Op2

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

|

Bitowa alternatywa (OR)

Op1 | Op2

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

^

Bitowa różnica symetryczna (XOR)
Suma modulo 2

Op1 ^ Op2

0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 0
1 ^ 1 = 1

~

Bitowa negacja

~Op1

~0 = 1
~1 = 0

<< 

Przesunięcie w lewo

Op1 << Op2

Przesuń Op1 w lewo o Op2 bitów

>> 

Przesunięcie w prawo

Op1 >> Op2

Przesuń Op1 w prawo o Op2 bitów

Operandy Op1 i Op2 muszą być typu całkowitego. Użycie operatorów bitowych powoduje wykonanie operacji logicznych na wszystkich parach odpowiadających sobie bitów.

Przykład:

/********************************************************/

/*  Program  p31.c                                    */

/*                          ( operatory bitowe )     */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()

{

  unsigned int   k = 0x5555,  m = 0x3333,   i;

 

  printf("\n k = %#x    m = %#x  ", k, m);

  printf("\n------------------------------");

  i = k & m;

  printf("\n k & m   = %#x ", i);  /* wydruk z początkowym )x */

  i = k | m;

  printf("\n k | m   = %#x ", i);

  i = k ^ m;

  printf("\n k ^ m   = %#x ", i);

  i = ~ m;

  printf("\n   ~ m   = %#x ", i);

  i = k << 3;

  printf("\n k << 3  = %#x ", i);

  i = k >> 2;

  printf("\n k >> 2  = %#x ", i);

  printf("\n------------------------------");

}

/********************************************************/

Wydruk wyników:

 k = 0x5555    m = 0x3333

------------------------------

 k & m   = 0x1111

 k | m   = 0x7777

 k ^ m   = 0x6666

   ~ m   = 0xcccc

 k << 3  = 0xaaa8

 k >> 2  = 0x1555

------------------------------

 

Operatory przypisania

Instrukcją przypisania jest trójka elementów zapisana jako:

identyfikator operator_przypisnia wyrażenie

Operator

Przykład zapisu

Zapis równoważny

=

a = b

a = b

+=

a += b

a = a + b

-=

a -= b

a = a - b

*=

a *= b

a = a * b

/=

a /= b

a = a / b

%=

a %= b

a = a % b

<<=

a <<= b

a = a << b

>>=

a >>=b

a = a>>b

&=

a &= b

a = a & b

^=

a ^= b

a = a ^ b

|=

a |= b

a = a | b

Przykłady:

double x, y, x;
x = y = z = 1.01;

c += d + e; // równoważne: c = c + d + e;

Przykłady:

double x, y, x;
x = y = z = 1.01;

c += d + e; // równoważne: c = c + d + e;

Przykład programu wykorzystującego operatory przypisania:

/********************************************************/

/*  Program  p32.c                                    */

/*                      ( operatory przypisania )            */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()

{

  int    k = 5,  m = 3,  i;

 

  printf("\n wartosci poczatkowe:  k=%i, m=%i, i=?",k,m);

  printf("\n------------------------------------------");

  printf("\n  operacja         wynik  ");

  printf("\n------------------------------------------");

  i = m;

  printf("\n ( i = m   )       i = %i ", i);

  i += k;

  printf("\n ( i += k  )       i = %i ", i);

  i -= k;

  printf("\n ( i -= k  )       i = %i ", i);

  i *= k;

  printf("\n ( i *= k  )       i = %i ", i);

  i /= k;

  printf("\n ( i /= k  )       i = %i ", i);

  i <<= 3;

  printf("\n ( i <<= 3 )       i = %i ", i);

  i >>= 2;

  printf("\n ( i >>= 2 )       i = %i ", i);

  i &= k;

  printf("\n ( i &= k  )       i = %i ", i);

  i ^= k;

  printf("\n ( i ^= k  )       i = %i ", i);

  i |= k;

  printf("\n ( i |= k  )       i = %i ", i);

  i %= k;

  printf("\n ( i %%= k  )       i = %i ", i);

  printf("\n-----------------------------------------");

}

/********************************************************/

Wydruk wyników:

 wartosci poczatkowe:  k=5, m=3, i=?

------------------------------------------

  operacja         wynik

------------------------------------------

 ( i = m   )       i = 3

 ( i += k  )       i = 8

 ( i -= k  )       i = 3

 ( i *= k  )       i = 15

 ( i /= k  )       i = 3

 ( i <<= 3 )       i = 24

 ( i >>= 2 )       i = 6

 ( i &= k  )       i = 4

 ( i ^= k  )       i = 1

 ( i |= k  )       i = 5

 ( i %= k  )       i = 0

-----------------------------------------

Operatory unarne (jednoargumentowe)

W grupie tej wystepują 3 operatory:

Operatory ++ i -- są szczególnie charakterystyczne dla języka C. Przykładami zapisu mogą być: ++i, --i, i++, i--.

Zapisowi i++ lub ++i odpowiada równoważny zapis i = i + 1. Zapisowi i-- lub --i odpowiada i = i-1. Należy pamiętać, że wyrażenia ++i oraz i++ są różne. Operacja: ++i zwiększa wartość zmiennej i o 1 przed jej użyciem, natomiast i++ zwiększa wartość zmiennej i o 1 po uzyciu jej poprzedniej wartości.

Operatory zwiększania lub zmniejszania o 1 jest wykonywana przez większość procesoró w jednym rozkazie, dlatego w języku C są oddzielne operatory pozwalajace na wykonanie tych operacji.

Operator

Dekrementacja

Inkrementacja

przedrostkowy

--Op

++Op

przyrostkowy

Op--

Op++

Operand Op musi być typu arytmetycznego lub wskaźnikowego i jednocześnie musi stanowić l-wartość (zmieniana jest więc wartość zmiennej).

Przykład przed- i przyrostkowych operatorów inkrementacji::

int m=3; n=1; r;
r=(m++) + (++n)

/* r=3+(1+1) = 5; m=m+1=4; */

r = (++m) + (++n) /* m=m+1=4; n=n+1=2; r=(3+1) + (1+1) = 6; */

Istotę różnicy między ++i a i++ oraz --i a i-- ilustruje też poniższy program:

/********************************************************/

/*  Program  p33.c                                    */

/*                          ( operatory unarne )     */

/*------------------------------------------------------*/

 

#include <stdio.h>

 

main()

{

  int   i=5 ;

 

  printf("\n----------------");

  printf("\n  i = %i ",   i  );

  printf("\n  i = %i ", ++i  );

  printf("\n  i = %i ",   i  );

  printf("\n  i = %i ",   i++);

  printf("\n  i = %i ",   i  );

  printf("\n  i = %i ", --i  );

  printf("\n  i = %i ",   i  );

  printf("\n  i = %i ",   i--);

  printf("\n  i = %i ",   i  );

  printf("\n  i = %i ",  -i  );

  printf("\n----------------");

}

/********************************************************/

Wydruk wyników:
----------------
i = 5
i = 6
i = 6
i = 6
i = 7
i = 6
i = 6
i = 6
i = 5
i = -5
----------------

Instrukcja printf("\n i = %i", ++i) jest równoważna sekwencji instrukcji: i=i+1; printf("\n i = %i",i);
natomiast instrukcja printf("\n = %%i", i++); jest równoważna sekwencji instrukcji: printf("\n i =%i",i); i=i+1;.

Jeszcze 2 zapisy: a =-b; oraz a -= b;
Pierwszy zapis dotyczy minusa unarnego (zmiany znaku liczby: a= (-b)), zapis drugi - operacji odejmowania: a = a-b;

Operator rozmiaru - sizeof

 

Operator sizeof może być używany w jeden ze sposobów:

Rezultatem jest liczba całkowita, określająca rozmiar argumentu w bajtach.
Jeśli Op jest tablicą, to zwracany jest całkowity rozmiar pamięci zajmowany przez wszystkie jej elementy. W związku z tym liczba elementów tablicy równa się sizeof (tab) / sizeof (tab[0]). Jeśli Op jest strukturą lub unią, zwracana jest całkowita wielkość obszaru pamięci przez nią zajmowanego.
Typ wartosci pobrania rozmiaru nosi nazwę size_t i jest zdefiniowany m.in. w stdio.h jako unsigned int.

Przykład programu z użyciem sizeof:

/********************************************************/

/*  Program p34.c              Turbo C  2.0          */

/*                          ( operator  sizeof )      */

/*------------------------------------------------------*/

#include <stdio.h>

main()

{

   char                 c1;

   char         tekst[]  = "Turbo C jak Turbo-Jetta",

                napis[80]= "Jaki komputer taki pan ";

   int                  i1;

   short int            i2;

   long int             i3;

   float                r1;

   long float           r2;

   double               r3;

   long double           r4;

   int                 *p;

 

   printf("\n Turbo C 2.0  (reprezentacja) ");

   printf("\n============================= ");

   printf("\n Typ         Liczba bajtow    ");

   printf("\n----------------------------- ");

   printf("\n char        :  %2i ", sizeof(char));

   printf("\n int         :  %2i ", sizeof(int));

   printf("\n short int   :  %2i ", sizeof(short int));

   printf("\n long  int   :  %2i ", sizeof(long  int));

   printf("\n float       :  %2i ", sizeof(float));

   printf("\n long float  :  %2i ", sizeof(long float));

   printf("\n double      :  %2i ", sizeof(double));

   printf("\n long double :  %2i ", sizeof(long double));

   printf("\n pointer     :  %2i ", sizeof p);

   printf("\n----------------------------- ");

   printf("\n tekst       :  %i ", sizeof tekst);

   printf("\n napis       :  %i ", sizeof napis);

   printf("\n zmienna r4  :  %i ", sizeof r4);

   printf("\n============================= ");

}

/********************************************************/

Wydruk:

 Turbo C 2.0  (reprezentacja)

=============================

 Typ         Liczba bajtow   

-----------------------------

 char        :   1

 int         :   2

 short int   :   2

 long  int   :   4

 float       :   4

 long float  :   8

 double      :   8

 long double :  10

 pointer     :   2

-----------------------------

 tekst       :  24

 napis       :  80

 zmienna r4  :  10

=============================

Dla deklaracji tekst[] kompilator zadeklarował tyle miejsca, ile potrzeba so zmieszczenia napisu. Dla deklaracji tab[80] kompilator zarezerwował dokładnie 80 bajtów, mimo, że faktycznie łańcuch jest krótszy.

Operator sizeof jest szczególnie pożyteczny przy dynamicznie określanych rozmiarach pamięci dla różnych typach danych.

Przykład 2 (Zalewski str. 139):

#include <stdio.h>

struct PUNKT

{

 double x,y; /* 2 * 8 bajtów = 16 bajtów */

 int t[10];  /* 10 * 2 bajty = 20 bajtów */

};

 

int main(void)

 {

  double tab[10];

  printf("\nRozmiary:\nTablicy: %d\nTypu float: %d\nStruktury PUNKT: %d",

                         sizeof tab,

                         sizeof (float),

                         sizeof (struct PUNKT));

  printf("\nPrzypadek szczególny: rozmiar = %d",sizeof puts("Andrzej"));

  return 0;

 }

Wynik:

Rozmiary:
Tablicy: 80
Typu float: 4
Struktury PUNKT: 36
Przypadek szczególny: rozmiar = 2

Rozmiar tablicy tab wynosi 80, co odpowiada 10 elementom po 8 bajtów, rozmiar typu float - 4, rozmiar struktury PUNKT - 36. Interesującą ciekawostką jest ostatnie użycie operatora sizeof, które daje wartość 2. Wynika to z faktu, że wartości standardowej funkcji puts są typu int. Ponieważ wyrażenie nie jest obliczane, więc funkcja puts nie zostanie wywołana.

Operator konwersji - jednoargumentowy operator rzutowania (cast)

 

Operator konwersji, zwany również operatorem rzutowania pozwala na jawne przekształcenie typów danych.

Zapis operatora rzutowania: (nazwa typu) wyrażenie

Wyrażenie jest przekształcane wg reguł dla typu określonego przez nazwę typu.

Przykład:
int a;
a=2;
(double)a; /* typ operandu zmienia się na typ podany w nawiasie - tu double */

Przykład programu z operatorami konwersji:

/********************************************************/

/*  Program p35.c                                    */

/*                        ( operator konwersji )     */

/*------------------------------------------------------*/

 

#include <stdio.h>

#include <math.h>

 

main()

{

   char                 c = 'k';

   int                  i = 70;

   float                f = 345.6789;

 

   printf("\n Wartosci poczatkowe:  ");

   printf("\n c = \'%c\';  i = %i;  f = %8.4f;", c ,i, f);

   printf("\n-------------------------------------");

   printf("\n Konwersja           Wynik           ");

   printf("\n-------------------------------------");

   printf("\n (int)    c          %i ", (int)    c      );

   printf("\n (float)  c          %f ", (float)  c      );

   printf("\n (double) i          %f ", (double) i      );

   printf("\n (char)   i          %c ", (char)   i      );

   printf("\n (double) i+2000     %f ", (double) i+2000 );

   printf("\n (int)    f          %i ", (int)    f      );

   printf("\n sqrt((double) c)    %f ", sqrt((double) c));

   printf("\n-------------------------------------");

}

/********************************************************/

Wydruk wyników:

 Wartosci poczatkowe:

 c = 'k';  i = 70;  f = 345.6789;

-------------------------------------

 Konwersja           Wynik

-------------------------------------

 (int)    c          107

 (float)  c          107.000000

 (double) i          70.000000

 (char)   i          F

 (double) i+2000     2070.000000

 (int)    f          345

 sqrt((double) c)    10.344080

-------------------------------------

Operator konwersji daje możliwośc doraźnego przekształcenia wartości zmiennej określonego typu dla potrzeb bieżących bez naruszania rzeczywistej wartosci tej zmiennej. Argumentem funckcji sqrt jest liczba typu double uzyskana do dokonaniu konwersji kodu całkowitoliczbowego litery k

Wyciąg (skrócona wersja) ww. programu:

#include <stdio.h>

main()

{

 char c='k';

 int i=70;

 printf("k= %d, i= %d\n",c,i);

 printf("k= %c   %%d = %d   (int) c = %d\n",c,c,(int) c);

 printf("i= %d   %%c = %c   (char) i = %c\n",i,i, (char) i);

 getchar();

}

Wydruk:

k= 107, i= 70

k= k   %d = 107   (int) c = 107

i= 70   %c = F   (char) i = F

 

Operator warunkowy ?

Wyrażenie z użyciem operatora warunkowego:

Op1 ? Op2: Op3;

wyrażenie_warunkowe ? wyrażenie_na_tak: wyrażenie_na_nie;

Operator warunkowy (?:) pozwala zapisać w bardziej zwartej formie pewne konstrukcje programowe wymagające użycia instrukcji if.

Np.
z = (a>b)? a:b; /* z=max(a,b) */

Równoważny zapis:

Dla C:

if (a>b) z=a; else z=b;

Dla Pascala:

if a>b then z:=a else z:=b;

W operatorze warunkowym operand Op1 musi być skalarem, zaś operatory Op2 i Op3 muszą spełniać jedną z zasad:

W pierwszej kolejności obliczna jest wartość Op1. Jeśli jest niezerowa (prawda), obliczana jest wartość Op2, a Op3 ignorowane; w przeciwnym razie (Op1 = 0) obliczna jest wartość Op3 a Op2 pomijane. Uzyskana wartość operandu Op2 lub Op3 staje się wartością wyrażenia warunkowego.

Przykłady:

1) Typowe zastosowanie - funkcja max

/* C++ - Operator warunkowy - funkacja max */

 

#include <iostream.h>

 

 

void main()

{

 int max(int, int);

 int a, b, m;

 char c;

 cout << "Program wyznacza max 2 liczb\n";

 cout << "Podaj 2 liczby calkowite oddzielone spacja: ";

 cin >> a >> b;

 m=max(a,b);

 cout << "Max liczb " << a << " i " << b << " wynosi " << m;

 cout << "\nNacisnij cos";

 cin >> c;

}

 

int max(int i, int j)

{

 return i > j? i: j;

}

Wynik:

Program wyznacza max 2 liczb

Podaj 2 liczby calkowite oddzielone spacja: 4 7

Max liczb 4 i 7 wynosi 7

Nacisnij cos

2) Użycie operatora warunkowego zamiast instrukcji warunkowej:

if (a<10)

     d=b=20;

else

     d=c=30;

To samo działanie z operatorem warunkowym:

d = a<10? b=20: c=30;

3) W przypadku większej liczby przypisań można użyć operatora warunkowego w połączeniu z wyliczeniowym (przecinek), np.

 if (a<10)

  {

    x=12; y=13;

  }

 else

  {

    a=1; x=14; y=15;

  }

Można napisać:

 a<10? x=12, y=13: a=1, x=14, y=15;

4) Przykład: Ustalenie ceny walca w zależności od objętości:

/*************************************************************/

/*  Program  p36.c                                        */

/*  Ustalenie ceny walca           ( operator warunkowy )    */

/*-----------------------------------------------------------*/

#include <stdio.h>

 

#define PI    3.1415926

 

/*  C1  - cena dla objetosci mniejszej od V1

    C2  - cena dla objetosci miedzy  V1 a V2

    C3  - cena dla objetosci wiekszej  od V2  */

 

#define  V1    300.0

#define  V2    500.0

#define  C1    1000

#define  C2    2500

#define  C3    1200

 

main()

{

 float promien, wysokosc, objetosc;

 int   cena;

 

 scanf("%f %f", &promien, &wysokosc);

 objetosc = PI * promien * promien * wysokosc;

 

 cena = (objetosc < V1) ? C1 : (objetosc > V2 ? C3 : C2 ) ;

 

 printf("\nobjetosc=%6.2f,  cena=%4i ",objetosc,cena);

}

/*************************************************************/

Wydruk:

1.22 3.50

 

objetosc= 16.37,  cena=1000

 

Operator przecinkowy/wyliczeniowy , (koma)

Wyrażenie wyliczeniowe ma postać:

Op1, Op2, ..., Opn

gdzie Opi, (i=1..n) są operandami dowolnych typów.

Opracowanie tego wyrażenia polega na obliczeniu wartości kolejnych operandów, począwszy od Op1, a skończywszy na Opn. Typ i wartość całego wyrażenia określa operand Opn.

W C++ wynik wyrażenia wyliczeniowego jest l-wartością. Poprawne jest więc wyrażenie: (a+=b, c-=d, c*=a)++.

Przykład:

int n=10, i=2, k=4, wynik;
wynik=(n-=i, k+=2, i*=5):

W wyniku obliczenia powyższego wyrażenia zmienne uzyskają następujące wartości:
n = n-i = 10-2=8
k = k+2 = 4+2=6
i = i*5 = 2*5=10 (ostatni operand)
wynik = wartość ostatniego operandu, czyli 10

Operator przecinkowy stosowany jest m.in. w instrukcjach for, np. do sterowania równoległego 2 indeksami, a także w wywołaniach funkcji. Stosując wyrażenia wyliczeniowe w wywołaniach funkcji należy pamiętać o użyciu nawiasów, np.:
func(i, (i+=k, k++), j); - funkcja otrzymuje tylko 3 parametry.

Przykład programu z operatorem przecinkowym:

/*************************************************************/

/*  Program  p37.c                                        */

/*                               ( operator przecinkowy )    */

/*-----------------------------------------------------------*/

 

#include <stdio.h>

#include <math.h>

 

main()

{

   int  i, j;

 

   printf("\n    i     j    sqrt(i)    sin(j)");

   printf("\n----------------------------------- ");

   for (i=0, j=10; j>=0; i++, j--)

     printf("\n   %2i    %2i    %6.3f    %6.3f",i,j,

            sqrt((double) i), sin((double) j) );     /* argument w radianach */

 

   printf("\n----------------------------------- ");

}

/*************************************************************/

Wydruk:

    i     j    sqrt(i)    sin(j)

-----------------------------------

    0    10     0.000    -0.544

    1     9     1.000     0.412

    2     8     1.414     0.989

    3     7     1.732     0.657

    4     6     2.000    -0.279

    5     5     2.236    -0.959

    6     4     2.449    -0.757

    7     3     2.646     0.141

    8     2     2.828     0.909

    9     1     3.000     0.841

   10     0     3.162     0.000

-----------------------------------

Operatory wskazywania

Operator adresu & i odwołania do zmiennej wskazywanej *

Operator pobrania adresu &

W przypadku &Op - operand Op musi być identyfikatorem funkcji lub l-wartością, która nie jest polem bitowym i nie została zadeklarowana ze specyfikatorem register (nie można pobrać adresu zmiennej przechowywanej w rejestrze). Użycie operatora pobrania adresu w odniesieniu do funkcji jest zbędne.

Operator odwołania do zmiennej wskazywanej * (operator adresowania pośredniego)

W wyrażeniu *Op, operand Op musi być wskaźnikiem. Wartością wyrażenia jest zmienna wskazywana przez Op (czyli l-wartość), zaś jego typ zgodny z typem wskazywanym operandu. Jeśli Op jest wskaźnikiem funkcji, wartość wyrażenia określa wskazywaną funkcję. Wartość wyrażenia jest nieokreślona w 2 przypadkach:

Przykład:

#include <stdio.h>

 

void main()

{

 int i=10, *pi;

 pi = &i;

 printf("Adres pi=&i = %p  *pi= %d  i= %d\n",pi, *pi, i);

 *pi=20;

 printf("Adres pi=&i = %p  *pi= %d  i= %d",pi, *pi, i);

 getchar();

}

Wydruk:

Adres pi=&i = 4A27:2222  *pi= 10  i= 10

Adres pi=&i = 4A27:2222  *pi= 20  i= 20

Przykład na operatory & i * oraz tablice

#include <stdio.h>

 

int main(void)

{

 int tab[3], *ptr=tab;

 int (*p)[]=&tab, i;

 

 ptr[0]=5;

 *(ptr+1)=10;

 (*p)[2]=2;

 

 for (i=0; i<3; i++)

  printf("\nTab[%d]=%d",i,tab[i]);

 

 return 0;

}

Wydruk:

Tab[0]=5

Tab[1]=10

Tab[2]=2

Przykład na operatory & i * z funkcjami

Wersja 1

#include <stdio.h>

 

int func(int i);

 

 

 

int main(void)

{

 int (*pf1)(int)=func, (*pf2)(int);

 // int i;

 pf2=*pf1;

 

 printf("%d\n",pf1(10));

 printf("%d\n",(*pf2)(20));

 return 0;

 

}

 

int func(int i)

{

 return i*i;

}

Wersja 2 - z typedef

#include <stdio.h>

 

int func(int i);

 

typedef int (*PFUNC)(int);

 

void main(void)

{

 PFUNC pf1=func, pf2;

 

 pf2=*pf1;

 

 printf("%d\n",pf1(10));

 printf("%d\n",(*pf2)(20));

 

}

 

int func(int i)

{

 return i*i;

}

Wydruk:

100

Operatory wyboru składowej . ->

W celu odwołania się do skłądowych struktury, unii lub klasy (w C++) należy posłużyć się jednym z operatorów wyboru skłądowej:

Op.identyfikator_składowej

Op->identyfikator_składowej

Operator . (kropka) umożliwia odwołanie do składowej struktury, unii lub klasy (C++) określonej przez operand Op, operator -> (minus, większe) zaś odwołanie do skłądowej struktury, unii lub klasy (C++) wskazywanej przez operand Op.

Wartość i typ wyrażenia są określone typem i wartością składowej, do której nastąpiło odwołanie. Wartość wyrazeń jest l-wartością, jeśli l-wartością jest operand Op.

Przykład:

#include <iostream.h>

 

struct PUNKT

{

 double x,y;

};

 

void main()

{

 struct PUNKT P, *pPt;

 P.x=P.y=10.5;

 cout << "P.x= " << P.x << " P.y=" << P.y << '\n';

 pPt= &P;

 pPt->x=12.5;

 pPt->y=13.5;

 cout << "P.x= " << P.x << " P.y=" << P.y << '\n';

 cout << "pPt->x=" << pPt->x << " pPty->y=" <<  pPt->y;

}

Wydruk:

P.x= 10.5 P.y=10.5

P.x= 12.5 P.y=13.5

pPt->x=12.5 pPty->y=13.5

 

 

 

 

 

 

 

 

W językach tych powstają aplikacje dla różnych systemów operacyjnych, w tym m.in. dla Windows, Unix, Linux, MacOS, BeoS.

Do pisania programów można wykorzystywać edytory narzędzi programistycznych jak:
Borlanda: Turbo C, Borland C, Borland C++ Builder
Microsoft Visual C++,
Dev C++, CodeBlocks

Można użyć dowolnego edytora tekstowego zapisującego pliki w postaci czystego kodu ASCII,  typu Notatnik, Edit lub np. Notepad, który pozwala sprawdzać składnię i podkolorowuje odpowiednio tekst po wybraniu języka.

Do kompilacji można użyć środowiska programistycznego Borland C++  Compiler 5.5.

Kompilator ten jest darmowy, generuje 32-bitowy kod dla Windows, zawiera tylko niezbędne narzędzia uruchamiane z linii poleceń, jest prosty w instalacji i konfiguracji.

Najlepiej zainstalować w C:\BCC55. W katalogu tym są podkatalogi: BIN, INCLUDE, LIB, HELP, EXAMPLES.

Pliki konfiguracyjne w katalogu C:\BCC55\BIN

Zawartość plików

Plik BCC32.cfg

-I"c:\Bcc55\include"

-L"c:\Bcc55\lib"

Plik ILINK32.cfg  - składa się z jednej linii

-L"c:\Bcc55\lib"

Można też  dodać katalog C:\BCC%%\BIN do ścieżki wyszukiwania – dopisać w wierszu poleceń PATH=%PATH%;C:\BCC55\BIN  

Kompilacja programów przy pomocy BCC32:

Bcc32 program.c  lub  bcc32 program cpp

Program Turbo C – TC.EXE, kompilator TCC.exe

-IC:\TC\INCLUDE

-LC:\TC\LIB

 

 

 

Objaśnienia:

Instrukcja #include poleca kompilatorowi dołączyć do programu plik stdio.h (tzw. pseudonagłówkowy),
w którym zawarta jest m.in. definicja funkcji printf.
Bardzo często używa się też innych plików pseudonagłówkowych, np.  conio.h, math.h itp.
Wszystkie pliki *.h zawarte w nawiasach <>  znajdują się w podkatalogu INCLUDE.
Druga linijka z main zawiera rozpoczęcie funkcji głównej programu czyli main().
Nagłówek void main() to inaczej void main(void)
 void przed mian oznacza, że funkcja nie zwraca żadnego wyniku. (void )w nawiasie po main oznacza brak parametrów programu.

 

Deklaracja funkcji main może mieć inne formy, np.

int main() - funkcja w wyniku swojego działania zwróci wartość typu int i nie pobiera żadnych parametrów przy rozpoczęciu działania.

int main(void) - inny zapis, ale znaczenie takie samo jak wyżej

main() - jeszcze inny zapis, ale znaczenie takie samo jak wyżej

float main() - w tym przypadku wynikiem działania funkcji będzie typ float.

int main(int argc, char *argv[])

                                                      

Po linii z main zaczyna się nawiasem klamrowym otwierającym {
 ciało (treść) funkcji głównej i kończy na końcu nawiasem zamykającym }

Wewnątrz funkcji głównej jest instrukcja printf, powodująca wyświetlenie na ekranie  tekstu, będącego jej parametrem (tekst w nawiasach w cudzysłowie).

Instrukcje kończymy średnikiem.

Po skompilowaniu czarny ekran i zaraz znika i dlatego trzeba dokonać modyfikacji programu.

Uruchamiamy edytor Edit lub notatnik, zapisujemy plik pod inną nazwą, np. p1a.c i modyfikujemy

 

// program p1a.c

// to jest komentarz w jednej linii

/* to jest też komentarz, może mieć kilka linii, dłuższy, ograniczony */

#include <stdio.h>  // dołączenie pliku nagłówkowego z biblioteki systemowej

// potrzebny do wywołania instrukcji printf 

#include <conio.h>        // dołączenie pliku conio.h do funkcji getch() i clrscr()

int  main()           //funkcja główna main

{  // początek main

   clrscr();             // kasowanie ekranu

   printf("Nazwisko Imie: Pierwszy program w C – zmodyfikowany ");

   printf("\nNacisnij jakis klawisz  ");

   getch();             // czeka na jakiś klawisz

   return 0;        // funkcja główna zwraca 0 przy pomyślnym wyniku zakończenia

}              // koniec funkcji głównej main

 

Kompilacja: BCC32  p1a.c – w wyniku program skompilowany p1a.exe

Po uruchomieniu: p1a

 

W programie wprowadzono funkcje clrscr() – kasowanie ekranu oraz getch() – program czeka na naciśnięcie dowolnego klawisza. Definicje tych funkcji są w pliku conio.h, dlatego jest on dopisany w dyrektywie #include <conio.h>/

Zamiast getch() , można zastosować getchar() lub while(!kbhit())

\n to znak specjalny – powoduje przejście do nowej linii.
 Podobnie \t – tabulacja, \a – sygnał dźwiękowy.

Komentarze – oznaczone // - jednolinijkowy
 oraz oznaczone /*    komentarz */ - dłuższe, mogą zawierać  wiele linii
Kompilator nie czyta komentarzy, stosuje się dla wyjaśnienia programu.

 

Podsumowanie

// program p1d.c

#include <stdio.h> 

#include <conio.h>

int  main() 

{ 

   clrscr();

   printf("Program p1d.c - podsumowanie\n");

   printf("\nProgramy w C i C++ maja rozszerzenie c oraz cpp\n");

   printf("Na poczatku programu #include i pliki z definicjami instrukcji\n");

   printf("np. #include <stdio.h> do funkcji printf(), conio.h do clrscr()\n");

   printf("\nDeklarujemy funkcje main(), np. int main() \n");

   printf("Cialo funkcji main() jest w nawiasach {  }\n");

   printf("W ciele funkcji glownej wypisujemy wszystkie instrukcje (zakonczone srednikiem) \n");

   printf("Mamy 2 rodzaje komentarzy: //  - jednoliniowy oraz /*  wieloliniowy */\n");

   printf("\nAby zatrzymac pracc programu, uzywamy funkcji getch(); lub getchar(); \n");

   printf("Do czyszczenia ekranu szuzy funkcja clrscr();. \n");

   printf("Na koncu funkcji main jest return 0; - co funkcja zwraca\n");

   printf("W programie mozemy uzywac tzw. znakow specjalnych, np. \\n - nowa linia. \n");

   printf("\nNacisnij cos  ");

   getchar();

   return 0;   

 

 

 

TYPY ZMIENNYCH I WZORCE KONWERSJI

Zmienne służą do tego, aby zapamiętać sobie tymczasową wartość (którą potem można zmienić w każdej chwili według potrzeby).

Typy zmiennych:

Operatory

Operacje arytmetyczne przypominają konwencjonalny matematyczny zapis. Również kolejność działań jest identyczna jak w matematyce.

Najczęściej używane operatory:

+, -, *, /, =

dodawanie, odejmowanie, mnożenie, dzielenie, operator przypisania

%

reszta z dzielenia (odpowiada operacji modulo)

++, --

inkrementacja i dekrementacja

!

negacja

<, >

mniejsze, większe

<=, >=

nie większe, nie mniejsze

&&, ||

i, lub (logicznie)

==

równe

+=, -=, *=, /=

połączenie operatorów przypisania i innych

 

Inkrementacja jest to proces zwiększenia zmiennej o 1,
a dekrementacja zmniejszenia o 1.
Zmienną a możemy inkrementować na dwa sposoby:

a=a+1;       - sposób tradycyjny
a++;           - sposób krótszy, w języku C/C++

 

Język C/C++

Sposób tradycyjny (też w C/C++)

a+=10;

a=a+10;

b-=30;

b=b-30;

a*=20;

a=a*20;

b/=5;

b=b/5;

 

Programy przy zastosowaniu typów zmiennych i  operacji matematycznych. możemy zabrać się za pisanie następnego programu.
Najprostszym przykładem użycia zmiennych jest prosty kalkulator.
Program, który poprosi nas o wpisanie dwóch liczb i wykona na nich podstawowe działania matematyczne: zsumuje je, odejmie, pomnoży i podzieli.
Na początku program musi wczytać dwie liczby:

//Program p2a.c

// Wczytuje 2 liczby całkowite I wyświetla na ekranie

#include <stdio.h>

#include <conio.h>

Int main ()

{

        int a,b; //deklaracja zmiennych a i b

        clrscr();

        printf("Podaj liczbe a: ");

        scanf("%d",&a); // wczytanie liczby a

        printf("Podaj liczbe b: ");

        scanf("%d",&b);  // wczytanie liczby b

        printf("Wpisane liczby a i b : %d, %d.\n",a,b);

        printf("\nNacisnij Enter ");

        getch(); // czekanie na Enter

        return 0 ;

}

Typ int (integer) oznacza, że zmienna może przyjmować wartości całkowite z zakresu +/- 32767.  Jeżeli zamierzamy używać w programie dużych liczb wtedy zamiast typu int używamy typu long. Kompilator już wie, że w kodzie programu będą pojawiać się zmienne a i b i wie ile pamięci musi zarezerwować na ich przechowanie.

Następnie wypisujemy na ekranie komunikat, który prosi nas o wpisanie liczby.
Program zatrzyma się w tym miejscu i będzie czekał dotąd, aż napiszemy liczbę i zatwierdzimy je ENTERem.
Funkcja scanf() służy do odczytu wprowadzonych danych z klawiatury
Wzorzec konwersji określa typ zmiennej, którą wpiszemy z klawiatury lub wypiszemy na ekranie.

Poniższa tabela przedstawia deklaracje zmiennych określonego typu, odpowiednie dla nich wzorce konwersji oraz przykłady ich użycia:

Typ zmiennej

Deklaracja

Wzorzec

Postać funkcji scanf()

Postać funkcji printf()

liczba całkowita

int A

%d

scanf("%d",&A);

printf("Liczba A wynosi: %d",A);

liczba rzeczywista

float B

%f

scanf("%f",&B);

printf("Liczba B wynosi: %f",B);

ciąg znaków

char *C

%s

scanf("%s",&C);

printf("Łańcuch ma postać: %s",C);

pojedynczy znak

char D

%c

scanf("%c",&D);

printf("Znak D to: %c",D);

 
 
Program zmodyfikowany, wykonujacy podstawowe obliczenia matematyczne
 

//Program p2b.c

#include <stdio.h>

#include <conio.h>

int main()

{

int a,b; //deklaracja zmiennych całkowitych a i b

int suma,roznica,iloczyn;

float iloraz;

clrscr();

printf("Prosty kalkulator\n");

printf("\nPodaj liczbe a: ");

scanf("%d",&a);

printf("Podaj liczbe b: ");

scanf("%d",&b);

 

suma=a+b;

roznica=a-b;

iloczyn=a*b;

iloraz=(float)a/(float)b; // operator rzutowania w dzieleniu

 

printf("\nWyniki dzialan:\n");

printf("\nSuma:    %d  ",suma);

printf("\nRoznica: %d  ",roznica);

printf("\nIloczyn: %d  ",iloczyn);

printf("\nIloraz:  %f  ",iloraz);

 

getch();

return 0 ;

}