Explorați Cărți electronice
Categorii
Explorați Cărți audio
Categorii
Explorați Reviste
Categorii
Explorați Documente
Categorii
Filtrare
Commanda head - afiseaza primele linii ale unui fisier
Comanda tail - afiseaza ultimele linii
Optiuni pt tail: "-n" care ne permite sa spunem ca vrem doar ultimele 'n' linii
Ex: daca vreau ultimele 3 linii, fac "tail -n3" si numele fisierului si am ultimele 3.
Comanda grep - putem specifica liniile pe care vrem sa le vedem
Optiuni comanda grep: "-v" pt a indeparta toate liniile care contin cuvantul cautat
Comanda sort
EX 04: Scrieti o linie de comanda care afiseaza adresele MAC ale masinii voastre. Fiecare
adresa va fi urmata de retur de linie.
ifconfig | grep "ether " | cut -d " " -f 2
Zi2:
C
What is a computer?
-CPU
-Some RAM
-Some devices
Transformam codul C pe care il scriem in limbaj masina, care va fi apoi executat de
procesor (compileaza)
In memoria RAM datele (binare) se reprezinta in grupuri de cate 8 biti, adica octeti.
Tipuri de date in C: char, unsigned char, unsigned short, int, unsigned int ,long long,
unsigned long long, *(pointer)
Structura programului-un ansamblu de functii
Din ce e compusa o functie - instructiuni si var locale
Declarare functie
Tabloul(array): un sir, o serie de elemente de acelasi tip, repetate in memorie. Se
declara: tipul, numele, paranteza patrata deschisa
Structuri de date: ne permit sa definim de fapt o reprezentare a unui obiect in memorie.
O structura se defineste: cuvantul cheie struct, numele structurii, acolada deschisa,
declaratia componenetelor structurii, acolada inchisa si punct si virgula.
Blocul e alcatuit dintr-o acolada deschisa, o serie de declaratii de variabile locale pt acel
bloc, o serie de instructiuni si o acolada inchisa.
Expresia este ceva urmat de punct si virgula si care efectueaza un calcul, o evaluare
numerica
Structuri de control: permit controlul modului de derulare al unei serii de instructiuni in
interiorul unui bloc.
Sunt o serie de calcule care dau un rezultat.
Expresiile sunt o serie de calcule care dau un rezultat. Ex: evaluare numerica - se
evalueaza direct la
valoarea lor, deci compilatorul va face in asa fel incat sa
reprezinte valoarea rezultatului.
Variabilele - cand scriem numele unei variabile, aceasta va returna valoarea ei.
Ex: b[18] va evalua cu valoarea de-al 19-lea element din tablou.
Apelul la o functie: pt a face un apel la o functie, scriem numele functiei si
parametrii trimisi intre paranteze. Compilatorul va face in asa fel incat va apela functia,
iar valoarea rezultata este cea returnata de functie.
Atribuirile: de ex: a=42
Comparatorii: sunt operatori a caror evaluare va rezulta intr-o valoare
Operatori
Operatorul sizeof: scriem sizeof si un tip de variabila si va returna marimea acestei
variabile in memorie
Pointer: este o variabila ca si celelalte dar care in loc sa contina o valoare, va contine
adresa unei alte variabile sau in orice caz o adresa de date.
Un pointer catre ceva, indica numele, contine adresa unei date.
Cum se declara: se declara incepand cu tipul a ceea ce pointam, deci tipul variabilei a
carei adresa o va contine.
O data declarata (de ex:int), scriem "p=&a". Vom pune in p adresa lui a. Apoi vom folosi
"p=1", care va pune 1 in adresa pointata de "p". E ca si cum as scrie "a=1". Apoi vom
folosi "p=1;", care va pune 1 in adresa pointata de "p". E ca si cum as scrie "a=1;"
Pentru ca "p" contine adresa lui "a". Daca "p" contine adresa lui "a", atunci "p" e acelasi
lucru ca si "a". E aceeasi memorie, aceeasi adresa, si e acelasi tip.
*nume e obiectul de tip "tip", al carei adresa e continuta in "nume".
Cand avem un obiect de tip pointer putem adresa acest pointer ca si tablou.
Structurile de control: If, etc.
Inainte de return0 vom folosi apelul de sistem "write(1, "@", 1)" ... 1 este pt iesirea
standard, care are identificatorul de fisier 1; folosim @ si ii spunem cate caractere are
sirul, deci unul singur.
Verificam manualul functiei "write" cu man prin Windows+X, man.
Man2 este tipul sistem (exista 2 tipuri de man)
Fereastra e impartita in 2, pt a trece de la o fereastra la alta folositi Control+X, O
"write" necesita folosirea header-ului <unistd.h> (#include<unistad.h>)
int ft_putchar(char c)
{
write(1, &c, 1);
return (0);
}
Punem "write" intr-o functie "ft_putchar(char c)".
Ctrl+K = cut
Dam adresa caracterului in loc de caracterul in sine (cu $), ceea ce ne va permite sa-l
transformam in sir de caractere (ceea ce numim "char")
...
testam (recompilam) in linia de comanda si scriem: gcc -o jour02 jour02.c
relansam prin ./jour02
Se creeaza o functie care afiseaza de "n" ori caracterul trimis ca parametru
int ft_nputchar(char c, int n)
{
int i;
i=0;
while(i<n)
{
ft_putchar(c);
i=i+1;
}
}
Rezultatul va fi 43 caractere (pt ca se considera de la 0)
#include<unistd.h>
int ft_putchar(char c)
{
write(1, &c, 1);
return (0);
}
int ft_nputchar(char c, int n)
{
int i;
i=0;
while(i<n)
{
ft_putchar(c);
i=i+1;
}
return (0);
}
int main()
{
ft_nputchar('@', 42);
ft_putchar('\n');
return (0);
}
Zi 3:
Memoria e impartita in 2 parti:
-Memoria de nivel inalt numita stiva (stack). Cu cat adaugam mai multe elemente,
cu atat coboram mai mult in stiva.
-Memoria de nivel jos heap unde putem aloca memorie
Pointer la pointer:
Int **ptr2 - Deci ptr2 pointeaza spre adresa unui pointer la int (adresa pointerului
ptr, nu adresa lui a)
Prima data mergem in adresa lui ptr, care la randul lui pointeaza spre ceva, si
anume: adresa lui a, adica 3.
Aritmetica pointerilor
-putem face calcule cu o adresa, si apoi folosim * pentru a vedea ce e la noua
adresa
Tablouri:
Ex de tablou: in loc sa definesc 10 variabile de tip int, voi declara o singura variabila
are contine 10 valori de tip.
Int tab[10] : pe stiva vor exista 10 valori int, inar tab va fi un pointer implicit spre
prima dintre aceste valori.
tab[0]=42 si *(tab+0)=42 este exact acelasi lucru
Daca vreau sa accesez al 4-lea element din tablou, voi scrie *(tab+3).
Indexul unui element din tablou este dat de lungimea tabloului minus 1 pentru ca
accesam primul element cu 0.
Pt *(ptr+3) : ptr+3 este o adresa, iar *(ptr+3) este un int.
Siruri de caractere
-sirurile de caractere sunt o multime de bytes situati unul langa altui, care fiecare
contin cate un caracter.
-ultima valoare dintr-un sir ar trebui sa fie caracterul ASCII \0 sau valoarea
numerica 0.
Siruri de caractre:
size_t is an unsigned type. So, it cannot represent any negative values(<0). You use
it when you are counting something, and are sure that it cannot be negative. For
example, strlen() returns a size_t because the length of a string has to be at least 0.
RECURSIVITATE
-programare iterativa: utilizeaza bucle de instuctiuni care se repeta, care nu se
evalueaza si care returneaza valori manipuland variabile.
-in exemplul functiei ft_strlen, avem o variabila care porneste cu valoarea 0, apoi facem
o bucla, iar la fiecare iteratiei i se va incrementa valoarea cu 1. Se va manipula o
variabila externa pentru a returna la sfarsit un rezultat. Rezultatul este stocat intr-o
variabila.
-programare recursiva: avem functii care se vor autoapela pana la un punct in care
vom utiliza un mecanism pentru a returna un rezultat.
-vom folosi stiva: este o zona de memorie a programului care se va umple pe masura ce
apelam functii si care e vida la inceputul programului.
-Cand functia main este apelata, aceasta este impinsa (push) pe stiva.
-Dupa ce se apeleaza functia ft_putstr (in main), aceasta va fi pusa pe stiva.
-functia ft_putchar va apela functia "write", "write" va fi pusa pe stiva, si asa mai departe.
-principiul programarii recursive este ca de fiecare data cand apelam o functie, aceasta
va fi impinsa pe stiva. Se va evalua si la un moment dat cand executai functiei se va
termina, se revine la functia anterioara.
-functia curenta aflata in partea superioara a stivei va fi eliminata din stiva ("pop").
Functia va fi eliminata din stiva, deci vom reveni la cea dinainte.
-observam ca se repeta oarecum principiul papusilor Matryoshka - sunt functii imbricate
unele in altele.
-functiile recursive se autoapeleaza si instantele lor sunt impinse pe stiva una deasupra
celelilalte. Acest mecanism se aplica pana cand se obtine unul din cele doua rezultate
posibile.
-Avem o functie recursiva care se autoapeleaza si vom tot pune instante de-ale ei in
stiva, si daca nu ne oprim, stiva de memorie se va tot mari, pana cand se umple si
explodeaza -> programul va crapa, pentru ca sistemul ii va spune ca si-a depasit stiva
alocata.
-Urmatorul pas este sa ajungem la un moment dat in care se indeplineste o conditie de
oprire. Daca un anumit criteriu este indeplinit, functia nu se mai autoapeleaza, doar
returneaza. Daca un anumit criteriu este indeplinit, functia nu se mai autoapeleaza, doar
returneaza. Este acelasi lucru ca si conditia de oprire dintr-o bucla cu diferenta ca daca
ajung la conditia de oprire, nu mai adaug functii in stiva, facem "pop" de functii si
coboram stiva, pentru a reveni la starea initiala.
Exemplu pt. factorial:
Pt oricare n>0, n!=n*(n-1)*(n-2)*...*3*2*1
n!=n*(n-1)!
Pseudocod pt factorial:
fact(N) = N * fact(N-1)
fact(1) = 1
Vom avea eroarea "segmentation fault" atunci cand stiva e plina -> programul crapa ->
Trebuie sa punem o conditie de oprire pentru ca functia sa nu se repete la infinit.
O functie recursiva este o functie care se autoapeleaza, si are o conditie de terminare.
Efect: Copie sirul sursa in sirul dest. Operatia se termina dupa ce caracterul '\0' a fost mutat. Valoarea returnata este
adresa de inceput a sirului dest.
FUNCTIA strncpy
Prototip: char strncpy ( char *dest, const char *sursa, unsigned maxlen) ;
Efect: Copie exact maxlen caractere de la sursa in destinatie. Daca sursa<maxlen
atunci sfirsitul lui dest se umple cu zero. Daca lungimea sursei este mai mare sau egala cu maxlen atunci dest nu va fi
terminat cu '\0'.
Strstr(sir1,sir2); are rolul de a identifica daca sirul sir2 este subsir al sirului
sir1. Daca este, functia returneaza adresa de inceput a subsirului sir2 in sirul sir1,
altfel returneaza adresa 0. In cazul in care sir2 apare de mai multe ori in sir1, se
returneaza adresa de inceput a primei aparitii. Cautarea se face de la stanga la
dreapta
char *ft_strstr(char *str, char *to_find)
{
int i;
int j;
i = 0;
while (str[i] != '\0')
{
j = 0;
while (to_find[j] == str[i + j])
{
if (to_find[j + 1] == '\0')
{
return (str + i);
}
j++;
}
i++;
}
return (0);
}
FUNCTIA stricmp
Prototip: int strcmp (const char*s1, const char*s2 );
Efect: Compara sirul s1 cu s2 fara sa faca deosebire intre majuscule si minuscule.
int
{
FUNCTIA strncmp
Prototip: int strncmp ( const char *s1, const char *s2, unsigned maxlen );
Efect: Acelasi lucru ca functia strcmp dar compara doar primele maxlen corectare.
FUNCTIA strcat
Prototip: char *strcat ( const char * s, int c )
Efect: Cauta caracterul cu codul ASCII c in sirul s de la stinga la dreapta ( in directia inainte). Returneaza pointer la prima
aparitie a caracterului c in sirul s sau in cazul cind c nu este gasit returneaza NULL.
Obs.: Caracterul '\0' care termina orice sir de caractere se considera ca face parte din sir, de aceea, apelul strchr (sirc, 0 )
este corect si returneaza pointer pe caracterul
'\0' al sirului sirc.