Sari la conținut
ELFORUM - Forumul electronistilor

Invatat programare de la zero


riciu

Postări Recomandate

A venit vremea sa vorbim despre matrici, string-uri si pointeri. Toate aceste 3 concepte sunt strans legate unul de celalalt.

 

Trebuie sa recunosc ca pentru mine pointerii au fost o provocare.

Mi-a fost foarte greu sa inteleg la ce folosesc si ce sunt mai exact. La momentul cand am incercat prima oara sa inteleg ce este cu variabilele acestea pointer, un coleg tot incerca sa imi explice dar simteam ca mintea mea trece pe langa concept cam cum uleiul se prelinge pe o pelicula de apa.

 

Dar acum imi dau seama ca de fapt subiectul pointerilor nu este un subiect atat de dificil de inteles pe cat este de explicat. Asa ca problema mea nu venea din faptul ca nu ma ducea capul ci din faptul ca cei care imi explicau (sau cartile/articolele www) nu reuseau sa o faca pe intelesul meu, nefiind nici programator de profesie.

Am sa incerc sa ii explic asa cum mi-as fi dorit ca cineva sa mi-i explice atunci cand aveam nevoie sa inteleg acest subiect.

 

Dar mai intai matricile.

 

Numite "arrays" in engleza uneori au ajuns ca sa fie traduse ca arii. Asa ca o sa le puteti intalni si sub acest nume.

Cel mai adesea o sa intalniti matrici unidimensionale adica asa numitii vectori. Mai rar se pot intalni matrici bidimensionale si cam atat (matricile bidimensionale care le intalnim la nivel de hobby sunt matricile de string-uri de caractere). 

 

 

Ce este o matrice?

Este o colectie de variabile care toate au acelasi tip. Adica toate elementele matricii sunt ori INT ori LONG or CHAR or FLOAT etc. Nu se poate ca un element sa fie un tip si un altul sa fie de alt tip.

Aceste variabile dintr-o matrice, numite elemente ale matricii, sunt declarate una dupa alta in memorie cu alte cuvinte, adresele acestor elemente ale matricii sunt succesive, una dupa alta, incepand de la adresa cea mai mica pentru primul element si terminand cu adresa cea mai mare pentru ultimul element.

Acest lucru este important si va fi clarificat cand vom vorbi despre pointeri.

 

La ce este utila o matrice?

Cand avem mai multe variabile care trebuie folosite intr-un program si toate au sens impreuna atunci declaram o matrice. Cand avem nevoie sa stocam temporar mai multe informatii pana vor fi deservite, adica un asa numit buffer, folosim o matrice.

Spre exemplu putem declara o matrice de tip UNSIGNED INT si primul element sa fie luna, al 2-lea ziua, al 3-lea anul, al 4-lea ora, al 5-lea minutul, al 6-lea secunda.

Are sens sa punem totul impreuna pentru a le putea accesa direct fara sa ne batem capul.

 

Cum declaram o matrice?

int a[5];

Mai sus declaram o matrice unidimensionala (un vector) cu 5 elemente.

 

IMPORTANT: Elementele matricii incep cu numerotarea de la 0. Asa ca primul element din matrice este a[0] si ultimul element din matrice este a[4].

 

 

Cum initializam o matrice? In doua feluri.

 

Ori facem in genul:

a[5] = {14523, 123, 22, 34, 1201};

ori in genul:

a[0] = 14523;a[1] = 123;a[2] = 22;a[3] = 34;a[4] = 1201;

adica element cu element.

 

Cum accesam elementele unei matrici (adica variabilele componente)?

Cred ca v-ati prins deja: ne folosim de numele matricii urmat de un index incadrat intre paranteze patrate, adica:

a[3]

selectam elementul al ... 4-lea ... De ce al-4-lea? Pentru ca numaratoarea incepe de la 0.

 

NOTA: 

Daca facem initializarea tuturor elementelor unei matrici dintr-odata atunci putem face ori cum am descris mai sus, adica:

a[5] = {14523, 123, 22, 34, 1201};

ori fiindca facem initializarea pentru fiecare element al matricii, compilatorul este in stare sa isi dea seama cate elemente are matricea si deci putem folosi si forma:

a[] = {14523, 123, 22, 34, 1201};

Stie compilatorul ca sunt 5 elemente pentru ca are 5 valori de initializare.

 

Cum putem face intializarea cu zero a unei matrici de sa zicem, 8 elemente (deci de la elementul 0 la elementul 7) usor?

Asa:

unsigned int i;int a[8];for (i = 0; i < 8; i++) {  a[i] = 0;}

Rezultatul este ca:

a[0] = 0;a[1] = 0;a[2] = 0;a[3] = 0;a[4] = 0;a[5] = 0;a[6] = 0;a[7] = 0;Deci toate 8 elementele sunt initializare cu zero.

O sa vedeti ca pe masura ce programati o sa gasiti utilitate matricilor.

 

Fiecare element al matricii va putea avea o valoare corespunzatoare tipului matricii.

 

Cu alte cuvinte daca matricea este tip UNSIGNED CHAR, adica:

unsigned char a[3];

fiecare element al matricii (a[0] sau a[1] sau a[2]) poate lua valori pe care o variabila tip UNSIGNED CHAR le poate lua, adica valori de la 0 la 255.

Si in acelasi fel pentru matrici cu alte tipuri.

 

Daca o matrice este tip SIGNED (SIGNED CHAR, SIGNED INT etc) atunci si elementele pot fi pozitive sau negative. Logic. :)

Editat de mars01
Link spre comentariu
Vizitator vezi_muti

 

Cel mai adesea o sa intalniti matrici unidimensionale adica asa numitii vectori. Mai rar se pot intalni matrici bidimensionale si cam atat (matricile bidimensionale care le intalnim la nivel de hobby sunt matricile de string-uri de caractere).

Nu cred ca este ceva deplasat sa se stie ca se pot definii si matrici 3D ...

Dar asta este alta poveste.

Spor la explicat. Faci bine ce faci.

Sunt curios cati cititori ai.

Editat de vezi_muti
Link spre comentariu

Vreau sa scap acum de toate chestiile astea de baza si sa ajung la intreruperi si apoi gata. Poate o sa fac ca exemplu o librarie, doua si apoi cred ca o sa trec la sectiunea proiecte.

De fapt asa se invata cu adevarat, cand ai un proiect de facut. Chiar si un voltampermetru ajuta, dar sa il faci tu tot. Adica de la schema la firmware, nu copiat de pe net ...

Link spre comentariu

Cum declaram o matrice?

int a[5];

Mai sus declaram o matrice unidimensionala (un vector) cu 5 elemente.

 

IMPORTANT: Elementele matricii incep cu numerotarea de la 0. Asa ca primul element din matrice este a[0] si ultimul element din matrice este a[4].

 

 

Cum initializam o matrice? In doua feluri.

 

Ori facem in genul:

a[5] = {14523, 123, 22, 34, 1201};

ori in genul:

a[0] = 14523;a[1] = 123;a[2] = 22;a[3] = 34;a[4] = 1201;

adica element cu element.

 

Primul fel de initializare e diferit de cel de al doilea, si are si sintaxa incompleta, deoarece nu compileaza in forma data fara tipul elementelor inainte de denumire variabilei.

Initializarea multipla se face doar o singura data si doar la locul unde este declarat vectorul, fiind initializare de tip "initalization list".

Cea de-a doua initializare se poate face in mai multe locuri, se poate reinitializa, si foloseste operatorul de atribuire sau constructorul de copiere (mai putin important pentru embedded informatiile legate de operatori, constructor e un termen de c++). Important e ca prima forma arata ceva de genu asta in forma completa:

int a[5] = {14523, 123, 22, 34, 1201};

sau

int a[] = {14523, 123, 22, 34, 1201};
Link spre comentariu

String-urile (de caractere).

 

Ce sunt string-urile?

 

Sunt matrici de caractere, sau mai degraba vectori (matrici unidimensionale).

 

Dar ati putea spune: ce sunt caracterele?

 

Limbajul C de programare intelege conceptele de numere si de caractere.

Numerele sunt folosite ca atare, dar caracterele pot fi atat numere cat si litere. Caracterele sunt folosite pentru reprezentari alfanumerice, adica mai clar, le folosesti cand vrei sa scrii un text undeva (poate intr-un fisier text, poate pe un LCD, poate pe un monitor etc).

 

Un caracter il scrii in C incadrand acel caracter intre apostrofuri. Adica asa:

'A'

Pentru a declara o variabila care are tipul caracter (cand spun tip aici ma refer la TYPE adica la chestii ca INT, FLOAT, LONG etc care au legatura cu spatiul alocat in memorie pentru o variabila cu tipul respectiv) facem in felul urmator:

char x = 'A';

NOTA: Trebuie sa subliniez ca atunci cand folosesc urmatoarea expresie:

char x = 1;

nu este totuna cu situatia cand scriu:

char x = '1';

De ce?

 

In limbajele de programare (nu numai C dar si restul) stim ca la baza este limbajul binar. Ok, putem scrie un numar zecimal in reprezentare binara dar cum scrii un caracter cum este de ex litera 'z'?

 

Niste tipi destepti au conceput reprezentarea numita ASCII. Gasiti tabelul aici.

In reprezentarea ASCII, au asociat numere pentru caractere.

 

De ex:

- numarul 1 este reprezentat fix de 1 dar ...

- caracterul '1' este reprezentat numeric cu numarul 49.

si tot asa ...

 

Bun dar de ce sa scrii numarul 1 folosindu-te de 1 si de ce sa scrii caracterul '1' folosindu-te de numarul 49?

Pai daca vrei sa tiparesti un caracter '1' pe ecranul unui LCD si cum LCD-urile accepta numai reprezentari ASCII atunci nu ai incotro si trebuie sa transformi cifra 1 in caracterul '1'.

O modalitate este asa (nu am sa explic de ce pentru ca acum nu imi vine in minte nici-o modalitate usoara de explicare a acestui lucru, de ce au ales aceia acest numar 48 ca reprezentare pentru caracterul '0'):

char x;x = 1 + '0';

unde 1 este cifra care vrem sa o transformam in caracter.

Caracterul '0' este reprezentat numeric cu numarul 48 asa ca putem sa scriem si asa:

char x;x = 1 + 48;

String-ul de caractere este o matrice de caractere. Singura particularitate este ca un string de caractere se termina intotdeuna cu un caracter invizibil numit caracterul NULL : '0'

 

Ideea este ca putem scrie un string ca o matrice, adica asa:

 

1. Prima forma:

char x[5] = {'G','i','g','e','l','0'};

si am pus in mod explicit caracterul NULL la final sau putem scrie mai usor:

 

2. Forma alternativa, folosita cel mai frecvent:

char x[] = "Gigel";

In acest ultim caz, compilatorul C o sa puna el caracterul NULL la final, chiar daca noi nu il vedem explicit, el este acolo. Asadar, atentie, forma 2 se scrie complet asa:

char x[5] = "Gigel";

Pentru ca sunt 6 caractere in stringul "Gigel" (cu indexi de la 0 la 5). Asta face sa fie mai usor pentru noi ca sa calculam cat punem in paranteze (cand punem ceva acolo) pentru ca numaram cate caractere are textul (string-ul) nostru si punem numarul intre parantezele patrate.

 

Asa ca indiferent cum scriem matricea x[], aceasta o sa aiba 6 elemente (5 elemente vin din caracterele gasite in "Gigel" si al 6-lea este caracterul NULL, adica '0').

 

Asa ca ce trebuie sa stim:

- un string se poate scrie ca o matrice sau in forma sa standard, cu ghilimele;

- nu este nevoie sa ii spunem intre parantezele patrate numarul de elemente pentru ca o sa isi calculeze singur compilatorul numarul de caractere din ce gaseste intre ghilimele; dar este o practica buna sa specificati numerele de caractere din string intre acele paranteze patrate ca sa sa fie mai vizibil cata memorie RAM consumati cu acel string.

- tipul unui string este CHAR; intr-un char incape orice reprezentare ASCII, vedeti ca numarul maxim in tabelul ASCII este 127 (o variabila de tip CHAR adica mai corect scris signed char, ia valori de la -128 pana la 127).

- regulile de la matrici se aplica si aici, primul caracter intr-un string are indexul 0, al 2-lea caracter indexul 1 si tot asa. 

De ex, x[1] in exemplul de mai sus este caracterul 'i'.

Asadar fiecare element din string se poate accesa folosind index-ul sau.

 

 

La ce ne foloseste sa stim despre STRING-uri?

Pai daca veti vrea sa faceti programe care sa tipareasca ceva pe ecran LCD va veti lovi de nevoia de a lucra cu string-uri. Si tot hobbystul vrea sa afiseze ceva pe un LCD: fie ca este o temperatura, fie ca este o frecventa sau un meniu etc etc toate acestea trebuie sa fie stocate in program sub forma de string-uri de caractere ca sa poata fi intelese de LCD in primul rand si in al 2-lea rand pentru a usura manipularea acestor texte, adica string-uri. Plus altele :)

Editat de mars01
Link spre comentariu

Interesant ca ai grija sa atragi atentia ca sunt 6 caractere in textul "Gigel", cu terminatorul de sir de caractere, 0, insa ai definit variabila cu 5 caractere. :)

Pentru texte de afisat care nu se schimba se foloseste "const" mult, in unele cazuri, anumite compilatoare optimizeaza uitilizarea memoriei RAM.

Editat de core
Link spre comentariu
  • 6 luni mai târziu...
  • 1 lună mai târziu...

String-ul de caractere este o matrice de caractere. Singura particularitate este ca un string de caractere se termina intotdeuna cu un caracter invizibil numit caracterul NULL : '0'

 

Ideea este ca putem scrie un string ca o matrice, adica asa:

 

1. Prima forma:

char x[5] = {'G','i','g','e','l','0'};

Cred că în loc de '0' aici este vorba de '\0'.

Link spre comentariu
  • 3 săptămâni mai târziu...

Folosesc mikroPascal.

Daca am un string de 5 caractere si vreau sa folosec functia Lcd_Out pentru a afisa stringul dar nu de la inceput ci incepand cu al 2-lea caracter pana la sfarsit, se poate ?

Link spre comentariu

Poti formata stringul inainte de a il afisa.

 

In ceea ce priveste functia closed source a mikroe de afisare pe LCD, poti citi in help exact ce poate face. Adica ...

Nu stiu sintaxa Pascal prea bine (au trecut multi ani de cand incercau sa ne invete in liceu Pascal) dar in C, pentru ca functia accepta ca parametru un pointer, poti face ceva de genul (PIC16F887, uC-ul folosit de mikroe in exemplele lor):

sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

unsigned char string[] = "yPrimavara";

void main() {
  ANSEL  = 0;
  ANSELH = 0;
  C1ON_bit = 0;
  C2ON_bit = 0;
  Lcd_Init();

  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Out(1, 1, &string + 1);
}

 

Rezultatul va fi ca in loc ca pe LCD pe pozitia (linie = 1, coloana = 1) sa apara afisat "yPrimavara" va fi afisat "Primavara" adica incepand cu caracterul al 2-lea.

Editat de mars01
Link spre comentariu

In C, operatorul & inseamna operatorul adresa http://www.c4learn.com/c-programming/c-pointer-address-operator/

Se pare ca in Pascal acest operator este reprezentat cu @ https://www.tutorialspoint.com/pascal/pascal_pointers.htm

 

Ce pot sa iti spun este ca programul de mai sus este functional. Se compileaza si rezultatul simularii in Proteus este conform cu designul.

Posibil ca in Pascal sa trebuiasca sa folosesti paranteze suplimentare in jurul (@string + 1). Sau altceva. Poate type casting pentru valoarea 1 intr-un UNSIGNED CHAR ... adica (@string +(unsigned char)1).

Cum spuneam nu sunt familiar cu sintaxa, regulile, Pascal.

 

LE: ce erori primesti?

Editat de mars01
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări