#include <stdio.h> int x; int main() { printf("\"Litwo, %d Ojczyzno moja\"\n",x); return 0; }
Wstawianie znaków w tekście:
\n - nowy wiersz
\a - wywołuje dźwięk;
\b - powoduje wymazanie pojedynczego znaku (backspace);
\\ - wstawia znak \;
\? - wstawia znak zapytania;
\ ' - wstawia znak ' ;
\" - wstawia znak cudzysłowu
specyfikatory konwersji (z ang. Conversion specifiers)
%d %i Decimal signed integer.
%o Octal integer.
%x %X Hex integer.
%u Unsigned integer.
%c Character.
%s String. See below.
%f double
%e %E double.
%g %G double.
%p pointer.
%n Number of characters written by this printf.
Zmienne
Data Type Memory (bytes) Range Format Specifier short int 2 -32,768 to 32,767 %hd unsigned short int 2 0 to 65,535 %hu unsigned int 4 0 to 4,294,967,295 %u int 4 -2,147,483,648 to 2,147,483,647 %d long int 4 -2,147,483,648 to 2,147,483,647 %ld unsigned long int 4 0 to 4,294,967,295 %lu long long int 8 -(2^63) to (2^63)-1 %lld unsigned long long int 8 0 to 18,446,744,073,709,551,615 %llu signed char 1 -128 to 127 %c unsigned char 1 0 to 255 %c float 4 %f double 8 %lf long double 12 %Lf
#include <stddef.h>
size_t
Unsigned integral type of the result of the sizeof operator.
#include <stdbool.h>
zmienna boolowska
Stałe
stałą literalną (literal constant)
Stała literalna to po prostu wartość wpisana w kod programu.Przykład:
godzina = 60:
stałą symboliczną (symbolic constan t):
#define Naszaliczba 13
Innym sposobem deklaracji stałej jest użycie słowa kluczowego const, np.:
const int Naszaliczba 13;
Scanf() - funkcje wejścia
Wczytuje z klawiatury i przydziela do zmiennych, zmienna z & (adres) jeśli %d (dla %s bez &)
#include <stdio.h> int Wiek; int main() { scanf("%d", &Wiek); printf("Masz %d lat", Wiek); return 0; }
Instrukcja warunkowa IF
#include <stdio.h> int x, y; int main() { printf("Podaj pierwsza liczbe: \n"); scanf("%d", &x); printf("Podaj druga liczbe: \n"); scanf("%d", &y); if (x>y) printf("Liczba %d jest wieksza\n", x); else { printf("Liczba %d jest wieksza lub rowna ", y); printf("liczbie %d\n", x); } return 0; }
Znak == wchodzi w skład grupy operatorów porównania. Pozostałe z nich to:
> - większość,
< - mniejszość,
>= - większość lub równość,
<= - mniejszość lub równość,
!= - różne.
Inna grupa operatorów to operatory logiczne:
AND (symbol: && ) - iloczyn logiczny wyrażeń,
OR (symbol: || ) - suma logiczna wyrażeń,
NOT (symbol: ! ) - zaprzeczenie wyrażenia.
Przykład IF z operatorami logicznymi:
#include <stdio.h> int a, b, c, d; int main() { printf("Podaj pierwsza liczbe: \n"); scanf("%d", &a); printf("Podaj druga liczbe: \n"); scanf("%d", &b); printf("Podaj trzecia liczbe: \n"); scanf("%d", &c); if (a > c && b > a) { d = a*b*c; printf("Dokonano mnozenia wartosci "); printf("trzech zmiennych, iloczyn: %d\n", d); } if (b < c || b < a) { d = b/a; printf("Dokonano dzielenia wartosci "); printf("zmiennej b przez a, iloraz: %d\n", d); } if ((c > a && b != 5) || (b > c && a != 0)) { d = a+b+c; printf("Dodano wartosci wszystkich trzech "); printf("zmiennych, suma: %d\n", d); } return 0; }Operator iloczynu (&&) ma większy priorytet od operatora sumy ( 11 ) , dlatego działanie iloczynu dwóch wyrażeń oddzielone zostało za pomocą dodatkowych nawiasów.
Operatory przypisania
x += 3 Operator powoduje dodanie do wartości zmiennej x liczby 3
x *= 9 Operator powoduje pomnożenie wartości zmiennej x przez 9
x /= 2 Operator powoduje podzielenie wartości zmiennej x przez 2
x -= 4 Operator powoduje odjęcie 4 od wartości zmiennej x
x += y*9 Przykładowa operacja przypisania powoduje dodanie do wartości zmiennej x iloczynu wartości zmiennej y i liczby 9 (x = x+y*9)
Funkcje
Prototyp - wstępna deklaracja funkcji (zakończony średnikiem w przeciwieństwie do funkcji!)
Każda funkcja, która zwraca wartość, musi być wywoływana przy jednoczesnym przypisaniu danej wartości pewnej zmiennej globalnej. (tu x globalne czyli inicjacja przed main)
x = MojaFunkcja (zmiennal. zmienna2 );
W przypadku funkcji, które nie zwracają żadnej wartości (void) mechanizm wywołania ogranicza się tylko do wpisania nazwy danej funkcji oraz (opcjonalnie) przyjmowanych argumentów.
#include <stdio.h>
long MojaFunkcja( int x, int y ); int liczba1, liczba2; long wynik; int main() { printf("Podaj pierwsza liczbe: \n"); scanf("%d", &liczba1); printf("Podaj druga liczbe: \n"); scanf ("%d", &liczba2); wynik = MojaFunkcja(liczba1, liczba2); printf("Iloczyn dwoch liczb: %ld\n", wynik); return 0; } long MojaFunkcja (int x, int y) { long z; z = x*y; return z; }
Pętle
pętla for
#include <stdio.h> int n; int main() { for (n=0; n<10; n++) printf("Kocham lato \n"); return 0; }
zerowanie elementów tablicy pętlą for
#include <stdio.h> int tablica[40]; int licznik; int main() { for (licznik=0; licznik < 40; licznik++) tablica[licznik] = 0; printf("Tablica zostala wyzerowana\n"); return 0; }
albo przypisanie co piątemu elementowi zera:
for (n=0; n<100; n += 5)
albo, wyjdź jeśli podana wartość nie mieści się w zakresie 1 6
if (sr_ucz < 1 || sr_ucz > 6)
exit(0);
pętla nieskończona
#include <stdio.h> unsigned int liczba : unsigned long suma : int main ( ) { for ( ; ; ) { printf ( " Podaj dodatnia liczbe z zakresu " ); printf ( " 2 - 65535 , wpisz 1 . aby zakonczyc\ n " ) ; scanf( "%u", &liczba ); if (liczba == l ) break; else suma +=liczba; } printf( " Suma wszystkich wpisanych liczb " ); printf( "wynosi : %lu\n", suma ); return O : }
pętla while
#include <stdio.h> int licznik; int main() { licznik = 25; while (licznik <=200) { printf( "Licznik: %d \n", licznik ); licznik++; } return 0; }program policzy od 25 do 200
pętla nieskończona typu while:
while(1) /* zawsze prawda */
Instrukcja switch
#include <stdio.h> int wartosc; int main() { printf("Wpisz wartosc od 1-3: "); scanf("%d", &wartosc); switch (wartosc) { case 1: { printf("Wpisales 1"); break; } case 2: { printf("Wpisales 2"); break; } case 3: { printf("Wpisales 3"); break; } default: { printf("Cos ty wpisal...?"); } } return 0; }
Tablice wielowymiarowe
przykład 4 klasy po 5uczniów:
float MojaSzkola [ 4] [5]
#include <stdio.h> float MojaSzkola[4][5]; int licz1, licz2; int main() { for (licz1 = 0; licz1 < 4; licz1++) { for (licz2 = 0; licz2 < 5; licz2++) { printf("\n\nWpisz srednia ocen %d-ego ", licz2+1); printf("ucznia %d-ej klasy: ", licz1+1); scanf("%f", &MojaSzkola[licz1][licz2]); } } for (licz1 = 0; licz1 < 4; licz1++) { for (licz2 = 0; licz2 < 5; licz2++) { printf("\n\nSrednia ocen %d-ego ucznia\n ", licz2+1); printf("%d-ej klasy wynosi: %f\n", licz1+1, MojaSzkola[licz1][licz2]); } } return 0; }
Wskazniki
deklaracja:
int *wskaznik;
wskaznik=&zmienna;
#include <stdio.h> int Ola; int *Zbychu; int main() { Ola = 180; Zbychu = &Ola; printf("Wzrost Oli: %d \n", Ola); printf("Wzrost Oli wg. Zbycha: %d \n", *Zbychu); printf("Adres Oli: %p \n", &Ola); printf("Adres Oli wg.Zbycha: %p \n", Zbychu); return 0; }czyli:
Ola = 180
*Zbychu=180
ale:
&Ola= adres xxx dlatego %p (pointer)
Zbychu=adres xxx dlatego %p (pointer)
nazwa zadeklarowanej tablicy użyta bez nawiasów jest wskaźnikiem do tej tablicy !!!
int tablica [20]
tablica == &tablica [0];
dlatego:
#include <stdio.h> int Moja_Tablica[20]; int *wskaznik; int main() { Moja_Tablica[0] = 5; wskaznik = Moja_Tablica; printf("1-y element tablicy zawiera wartosc:%d \n", *Moja_Tablica); printf("1-y element tablicy zawiera wartosc:%d \n", *wskaznik); printf("1-y ADRES tablicy zawiera wartosc:%p \n", Moja_Tablica); printf("1-y ADRES tablicy zawiera wartosc:%p \n", wskaznik); return 0; }i wynik mamy:
5
5
adres
adres
to samo:
wskaznik=Moja_Tablica
wskaznik = &Moja_Tablica[0];
przykład przekazania tablicy do funkcji jako parametru:
podaj 5 liczb i za pomocą funkcji znajdz maximum
rozmiar podany jako stała (dzięki temu mamy zmienna rozmiaru i możemy podać ją jako parametr)
w szukaniu maximum, za pomocą zmiennej z minimalna wartością porównywaną do kolejnych
#include <stdio.h> #define rozm 5 int tab[rozm]; int licznik; int maks(int x[], int y); int main() { for (licznik = 0; licznik < rozm; licznik++) { printf("Wprowadz wartosc z zakresu: "); printf("-32000 do 32000 \n"); scanf("%d", &tab[licznik]); } printf("Najwieksza wartosc: %d\n", maks(tab, rozm)); return 0; } int maks( int x[], int y ) { int licz; int maksimum = -32000; for (licz = 0; licz < y; licz++) { if (x[licz] > maksimum) maksimum = x[licz]; } return maksimum; }
Przykłady tworzenia tablic
int* tab1[3]; // statyczna tablica 3 wskaźników int* tab2 = new int [3]; // "dynamiczna tablica" 3 int-ów int** tab3 = new int* [3]; // "dynamiczna tablica" 3 wskaźników
Znaki
Char Znak ; /* deklaracja zmiennej typu char */
Znak = ' a ' ; /* przypisanie wartosci (znaku) koniecznie w ' ' */
dla typów char istnieją dwa specyfikatory konwersji (z ang. Conversion specifiers) :
%d - dla liczb kodu ASCII
%c - dla znaków im odpowiadających
Łańcuchy znaków
jeśli zdeklarujemy tak:
char zdanie[ 4] ;
jedyny sposób przypisania to:
zdanie [0] = 'd' ;
zdanie [1] = 'o' ;
zdanie[2] = ' m' ;
zdanie[3] = ' y ' ;
zdanie[4] = ' \0 ' /*znak końca zdania */
dlatego najlepiej przypisywać podczas deklaracji:
char zdanie [ ] = "programowanie";
Długość łańcucha i znak końca zdania zostaną przypisanie automatycznie.
Istnieje również możliwość użycia łańcuchów znaków bez konieczności korzystania z tablic tylko ze wskaźników:
char *a = "programowanie";
Można również użyć funkcji :
STRCPY(wsk, "tekst");
przykład w strukturach
Wyświetlanie łańcucha:
puts(zdanie);
albo
printf("$s",zdanie);
Wyświetlanie jednego znaku z łańcucha:
printf("Teraz wyswietlimy znak drugi:%c",*(zdanie+1));
Pobieranie znaków prosto z klawiatury:
gets(zdanie);
albo
scanf("%s",zdanie); (zwykle czytanie scanf wymagało & -scanf("%d",&zmienna); ale nie tu!)
By to zadziałało zdanie musiało mieć określoną wielkość podczas deklaracji - char zdanie[200];
Dostępna jest jeszcze jedna funkcja, której można używać do wpisywania danych:
fgets()
Podobnie jak scanf() pobiera ona argument będący wskaźnikiem typu char, jednak — w odróżnieniu od scanf() — wymaga ona także określenia maksymalnej długości wprowadzanego łańcucha: (W scanf również można opcjonalnie podać ilość czytanych znaków scanf("%5s",zdanie);
fgets (zdanie, sizeof(zdanie), stdin); /* można podać wielkośc liczbą, stdin czyta z klawiatury*/
fgets nie potrafi czytać innych danych, tylko łańcuchów, tylko 1 bufor, ale potrafi wczytać łańcuch ze spacjami!
Zapis z klawiatury w miejscu okreslonego znaku łacucha np 3 z kolei:
scanf("%c",zdanie+2); (zamiana %s na %c bo czytamy nie łańcuch a jeden char)
Alokacja pamięci pod wskaźnik
Można zadeklarować wskaźnik któremu nie przypiszemy od razu żadnego łańcucha znaków.
Wtedy trzeba zaalokować pamieć na przyszłe przypisanie za pomocą malloc <stdlib.h>
void *malloc (rozmiar);
Funkcja malloc zwraca wskaźnik do zarezerwowanego bloku, dzięki void może zwracać do każdego rodzaju zmiennych.Gdy za mało ram zwróci 0.
przykład rezerwacji pamięci wraz z reakcją jeśli pamięci brakuje:
#include <stdlib.h> #include <stdio.h> int main() { char *lancuch; if ((lancuch = (char*)malloc(200)) == NULL) { printf( "Za malo pamieci!!! Sorry...\n"); exit(1); } printf("Operacja przydzielenia pamieci "); printf("zostala pomyslnie zakonczona!\n" ); return 0; }
czyli można zadeklarować tak:
char lancuch[200];
albo wskaźnikiem
char *lancuch;
lancuch=malloc(200);
inicjacja dla int (które ma więcej niż 1 bajt):
int *tablica;
tablica=(int *)malloc( 50*sizeof(int) )
Obliczanie liczby znaków w łańcuchu:
size_t a; /* size_t to deklaracja int ale o dowolnej wielkości bitowej 1 2 4 bity */
a=strlen(zdanie);
Przykład, funkcja pobiera 2 łańcuchy jako argumenty, sprawdza który dłuższy i zwraca WSKAŹNIK do dłuższego
#include <stdio.h> char bufor1[]="krotszy"; char bufor2[]="dluuuuzszy"; char *funkcja(char x[], char y[]); //prototyp funkcji zakonczony ; int main() { printf( "Dluzszy lancuch znakow: %s\n", funkcja( bufor1, bufor2 )); //wywolanie return 0; } char *funkcja(char x[], char y[] ) //*funkcja bo zwraca WZKAŹNIK { size_t a, b; a = strlen(x); b = strlen(y); if ( a > b ) return x; else return y; }
Co ważne przekazywanie tablicy jako argumentu do funkcji np tak jak tu: funkcja (char x[], char []);
przekazuje wskaźnik!
Dlatego trzeba zastosować strlen by określić długość a nie sizeof (ta zwróci tylko 4 bity długość int)
Zastosowania wskaźników
1 Przekazywanie przez wskaźnik zmiennej jako argumentu funkcji
przekazywanie przez wartość (kopia zmiennej):
int funkcja ( int x )
wywołanie:
y=funkcja(x);
Przy przekazywaniu zmiennej x do funkcji funkcja nie można zmienić jej wartości.
przekazywanie przez wskaźnik:
int funkcja ( int *x)
y = funkcja (&x);
Teraz wszelkie operacje wewnątrz funkcji zmieniają wartość zmiennej x !!!
przykład:
#include <stdio.h>
void wartosc( int x ); void wskaznik(int *x); int main() { int x = 1; wartosc(x); printf("Wartosc x po wywolaniu funkcji wartosc: %d\n", x); wskaznik(&x); printf("Wartosc x po wywolaniu funkcji wskaznik: %d\n", x); return 0; } void wartosc( int x ) { x++; } void wskaznik(int *x) { (*x)++; }wynik
przez wartość 1 czyli x się nie zmienił
przez wskaźnik 2 czyli funkcja zmieniła argument który otrzymała
2 Dynamiczny przydział pamięci
zapytaj o wielkosc pamięci i taką przydziel
przykład
#include <stdio.h> #include <stdlib.h> int main() { int *kontener; int n; printf("Podaj mozliwa ilosc bimbru do sprzedazy w litrach: "); scanf("%d", &n); if (kontener = (int *)malloc(sizeof(int)*n)) printf("Przygotowalem kontener o wielkosci %d\n", n); else printf("Nie mam takiego kontenera, nie bedzie dzisiaj imprezy, sorry!"); free(kontener); return 0;pamiętaj scanf gdy czyta%d potrzebuje &zmienna !
3 Operacje arytmetyczne na wskaźnikach
Wskaźnik można przypisać do innego wskaźnika w poniższy sposób :·
int x = 0 ;
int *ptr1=&x ;
int *ptr2 = ptrl ;
Porównanie wskaźników jest głównie wykorzystywane w celu sprawdzenia, który wskaźnik wskazuje na dalszy element w pamięci. Dobrym przykładem jest implementacja odwrócenia łańcucha znaków za pomocą wskaźników (operacje arytmetyczne na wskaźnikach )
#include <stdio.h> #include <string.h> void odwrocenie (char *s); int main() { char ciag_znakow[20] = "Rychu ma bimber"; odwrocenie(ciag_znakow); printf("Ciag znakow po odwroceniu: %s\n", ciag_znakow); return 0; } void odwrocenie(char *s) { char *wsk = s + strlen(s)-1; char temp; for (;wsk>s;wsk--,s++) { temp = *s; *s = *wsk; *wsk = temp; } }pętla for nie zawiera w ogóle początkowego przypisania (for ( ; wsk>s ;wsk--,s++) ponieważ niepotrzebna Ci jest zmienna indeksująca) oraz zawiera inkrementacje dwóch wskaźników naraz (wsk - oraz s++) .
wersja z indeksowaniem tablic:
void odwrocenie_tab(char *s) { int i,j; char temp; j = strlen(s)-1; for (i=0; i<j; j--, i++) { temp = s[i]; s[i] = s[j]; s[j] = temp; } }
gdzie jest różnica
2 przykłady :
int i=0;
while (i<rozmiar_tablicy)
{
*wskaźni k++=1; // Uwaga! operacja rownowazna z *wskaznik = 1; wskaznik++;
i++;
}
ORAZ
int i=0;
while (i<rozmiar_tablicy)
{
tablica[i]=1;
i++;
}
wersja ze wskaźnikiem dużo szybsza
(zapis tablica[i] jest równoznaczny z tablica +i *sizeof(int ) czyli mnożenie, które jest wolniejsze )
wersja jeszcze szybsza na wskaźnikach (bez int)
int *ptr=tablica; do *wskaznik=1; while (wskaznik++<=tablica+rozmiar_tablicy)
Obliczanie długości łańcucha własna funkcją:
#include <stdio.h> int moj_strlen(char *s); int main() { char str[50]; printf("Podaj lancuch znakow: "); scanf("%s", str); printf("\nDlugosc lancucha znakow: %d", moj_strlen(str)); return 0; } int moj_strlen(char *s) { int i = 0; while (*s !='\0') { s++; i++; } return i; }Długość tablicy można wyciągnąć poleceniem sizeof(tablica),
zapytanie sizeof(wskaźnik) wskaże jednak tylko ...wielkość zmiennej 2,4 8 bitów.
Sizeof pokazuje długość z ostatnim znakiem kończącym wiersz więc ma dl+1 i pokazuje długość CAŁEJ tablicy a nie wpisanego tekstu kończącego się na NULL.
Jeśli mamy zadeklarowaną długość 200 pokaże 200 dlatego lepiej użyć strlen bo pokazuje realną długość tekstu a nie długość możliwych danych.
Struktury
są grupą zmiennych zebranych razem pod wspólną nazwą. Ponadto w strukturach można przechowywać zmienne różnego typu, a nawet całe tablice oraz inne struktury. Struktury definiujemy w następujący sposób:
struct wiek_kotka {
int bury_kotek;
int krasy_kotek;
};
Deklaracja struktury:
1 sposób:
struct wiek_kotka {
int bury_kotek;
int krasy_kotek;
} koci_wiek, ludzki_wiek; /* deklaracja */
2 sposób:
struct wiek_kotka {
int bury_kotek;
int krasy_kotek;
};
struct wiek_kota koci_wiek, ludzki_wiek; /*deklaracja*/
Miejsce w pamięci zostanie przydzielone dopiero po zadeklarowaniu instancji struktury.
Przypisanie wartości elementom struktury:
koci_wiek.bury_kotek = 40 ;
koci_wiek.krasy_kotek = 30 :
ludzki _wiek.bury_kotek = 4 :
ludzki_wiek.krasy_kotek = 3 :
Można jednocześnie zadeklarować i przypisać wartości:
struct wiek_kotka {
int bury_kotek;
int krasy_kotek;
} koci_wiek ={4,3};
Program wyświetlający datę wykorzystujący struktury: Przykład wykorzystania funkcji STRCPY
#include <stdio.h> #include <string.h> struct data { char dzien[20]; char miesiac[20]; int rok; } d_data; int main() { strcpy(d_data.dzien, "poniedzialek"); strcpy(d_data.miesiac, "styczen"); d_data.rok = 2001; printf("%s, %s, %d", d_data.dzien, d_data.miesiac, d_data.rok); return 0; }Do tablicy(łańcucha znaków) nie mozna przypisać łańcucha znaków(możliwe tylko podczas definicji tablicy np char dzien[20]="poniedzialek" ) Później należny to zrobić kopiując znak po znaku lub użyć gotowej funkcji
STRCPY() <string.h>
Pierwszym argumentem takiej funkcji jest wskaźnik do łańcucha, do którego chcemy skopiować łańcuch znaków przekazany jako drugi argument.
Przykład2 - struktura w strukturze
W powyższym przykładzie elementami struktury są inne struktury.
Struktury takie deklaruje się wewnątrz definicji głównej struktury "struct dane".
#include <stdio.h> struct adres { char ulica[30]; int nr_domu; char miasto[40]; }; struct data { int rok; char miesiac[20]; char dzien[20]; }; struct dane { char imie[20]; char nazwisko[30]; struct adres moj_adr; struct data u_data; } MojeDane; int main() { printf("\nPodaj imie: "); scanf("%s", MojeDane.imie); printf("\n\nPodaj nazwisko: "); scanf("%s", MojeDane.nazwisko); printf("\n\nPodaj adres: "); printf("\n\tUlica: "); scanf("%s", MojeDane.moj_adr.ulica); printf("\n\tNumer domu: "); scanf("%d", &MojeDane.moj_adr.nr_domu); printf("\n\tMiasto: "); scanf("%s", MojeDane.moj_adr.miasto); printf("\n\nPodaj date urodzenia: "); printf("\n\tRok (np.1990): "); scanf("%d", &MojeDane.u_data.rok); printf("\n\tMiesiac (slownie): "); scanf("%s", MojeDane.u_data.miesiac); printf("\n\tDzien (slownie): "); scanf("%s", MojeDane.u_data.dzien); printf("\n\n\nTwoje Dane: \n"); printf("\n%s\n%s\n%s\n%d\n%s\n%d\n%s\n%s", MojeDane.imie, MojeDane.nazwisko, MojeDane.moj_adr.ulica, MojeDane.moj_adr.nr_domu, MojeDane.moj_adr.miasto, MojeDane.u_data.rok, MojeDane.u_data.miesiac, MojeDane.u_data.dzien); return 0; }
Higher order functions in C
#include <stdio.h> #include <stdlib.h> char *rot(char* strng); //funkcje ktore beda wywolywane przez funkcje oper char* selfieAndRot(char* strng); //tworzenie typu ktory zwraca char*, przyjmuje tez char* a nazywa sie generic_func_t typedef char* (*generic_func_t) (char*); char* oper(generic_func_t f, char* s) { //Higher order functions zmienna f typu stworzonego powyzej return f(s); }
Programowanie w języku C. Żwiczenia
R5 -103
Struktury ze wskaźnikami
Wskaźniki do funkcji
Preprocesor
https://tohtml.com
Bred3