Cartea este concepută pentru o gamă largă de cititori interesați de programarea în C # Introduceți aici o scurtă adnotare
Carte: C # 4.0: Ghidul complet
Codul nesigur
Secțiunile de pe această pagină sunt:
În C #, este permis să scrie un cod așa-numit "nesigur". În această afirmație ciudată la prima vedere nu există nimic neobișnuit. Considerat nesigur nu prost cod scris, și un cod care nu se poate face sub controlul complet al unui limbaj comun de execuție (CLR). După cum este explicat în Capitolul 1, rezultatul programării în C # este, de obicei, codul gestionat. Cu toate acestea, acest limbaj de programare permite scrierea unui cod care nu rulează sub control complet în CLR. Acest cod negestionat nu este supusă acelorași controale și restricții ca cod gestionat, și se numește nesigur, deoarece nu se poate vedea în nici un fel în cazul în care efectuează orice acțiune periculoasă. Prin urmare, termenul nesigur nu înseamnă că codul are unele defecte. Aceasta înseamnă că codul poate efectua acțiuni care nu pot fi controlate într-un mediu gestionat.
În C #, indicatorii sunt declarați și utilizați în același mod ca în C / C ++. Dacă știți cum să le utilizați în C / C ++, atunci nu este dificil să faceți acest lucru în C #. Dar nu uitați că scopul principal al C # este de a crea un cod gestionat. Capacitatea acestui limbaj de programare de a susține codul neadministrat ar trebui să fie folosită pentru a rezolva doar un anumit tip de sarcini. Aceasta este mai degrabă o excepție decât regula pentru programarea în C #. În esență, pentru a compila codul neangajat, utilizați opțiunea de compilator / nesigur.
Indicatorii formează baza unui cod nesigur, așa că vom începe să luăm în considerare acest lucru cu ei.
Noțiuni de bază privind utilizarea indicatoarelor
Să ne îndreptăm spre un exemplu concret. Pentru a face variabila ip un pointer la o valoare de tip int. trebuie să o declarați după cum urmează.
Un pointer float este declarat așa cum se arată mai jos.
Tipul de date indicat de pointer în sine depinde de tipul corelat. Prin urmare, în exemplele de mai sus, variabila ip poate servi pentru a indica o valoare de tip int. și variabila fp - pentru a indica valoarea tipului de flotant. Ar trebui totuși să se țină cont de faptul că indicatorul nu interferează cu a indica nimic. De aceea pointerii sunt potențial nesigure.
Această diferență principală trebuie luată în considerare atunci când pornim codul C / C ++ la C #.
Operatori * și în indici
Operatorul * poate fi de asemenea utilizat în partea stângă a instrucțiunii de atribuire. În acest caz, se stabilește valoarea indicată de indicatorul corespunzător, ca în exemplul de mai jos.
Aplicarea cuvântului cheie nesigur
Orice cod care utilizează pointeri trebuie să fie marcat ca nesigur cu cuvântul cheie nesigur. În mod similar, puteți marca anumite tipuri de date (de exemplu, clase și structuri), membrii clasei (inclusiv metodele și operatorii) sau blocurile de coduri individuale ca fiind nesigure. De exemplu, aici este programul în care se utilizează pointerii în metoda Main (). marcate ca nesigure.
Acest program dă următorul rezultat.
Valoarea inițială a numărului: 99
Noua valoare a numărului: 10
Aplicarea modificatorului fix
În lucrul cu indicatori, modificatorul fix este adesea folosit. care împiedică eliminarea variabilei gestionate prin "colecția de gunoi". Necesitatea acestui lucru apare, de exemplu, dacă indicatorul se referă la un câmp dintr-un obiect dintr-o anumită clasă. Deoarece indicatorul nu cunoaște nimic despre acțiunile sistemului de colectare a gunoiului, acesta va indica obiectul greșit dacă ștergeți obiectul dorit. Următoarea este forma generală a modificatorului fix:
Următorul este un exemplu de utilizare a modificatorului fix.
Acesta este rezultatul executării acestui program.
Valoarea inițială a variabilei o.num: 19
Valoarea nouă a variabilei o.num: 10
În acest exemplu, modificatorul fix împiedică ștergerea obiectului. Și deoarece variabila p indică variabila instanță o.num. atunci se va indica o zonă nevalidă de memorie dacă ștergeți obiectul o.
Accesul la membrii structurii folosind un pointer
Un pointer poate indica un obiect de tip structură, cu condiția ca structura să nu conțină tipuri de date de referință. Pentru a accesa un membru al unei structuri utilizând un pointer, utilizați operatorul săgeată (->), mai degrabă decât operatorul punct (.). De exemplu, accesul la membrii structurii
se efectuează după cum urmează.
Operații aritmetice pe pointeri
Cele de mai sus pot fi rezumate astfel: după fiecare pointer increment va indica locația de memorie unde este stocat următorul element de tip corespunzător, iar după fiecare pointer decrement va indica locația de memorie în care elementul său stocat anterior de un tip adecvat.
Operațiile aritmetice pe indicatori nu se limitează la creșterea și decrementarea. Puteți adăuga și scădea valorile întregi de la indicatori la indicatori. Deci, după ce am calculat următoarea expresie:
variabila p1 va indica elementul 9 al tipului său corelat față de elementul pe care îl indică în acest moment.
Dacă nu puteți adăuga indicii, puteți scădea un indicator de la celălalt, cu condiția ca ambii indicatori să aibă același tip de referință. Rezultatul unei astfel de operațiuni va fi numărul de elemente de tip corelat care separă ambii indicatori.
Pe lângă adăugarea și scăderea unui întreg de la un pointer, precum și scăderea a două indicii, nu sunt permise alte operații aritmetice pe indicatori. În particular, nu puteți adăuga sau scădea valori flotante sau duble de la indicii la indicatori. Operațiile aritmetice pe indicatorii de tip void * nu sunt permise.
Mai jos este un rezultat aproximativ al acestui program. S-ar putea să fie diferit, deși decalajele dintre valorile afișate ar trebui să fie identice.
Comparând indicatorii
Pointerii pot fi comparați cu ajutorul unor astfel de operatori relaționali, ca ==. <и>. Dar pentru ca rezultatul comparării indicilor să fie semnificativ, ambii pointeri ar trebui să fie într-un fel legați între ei. Deci, dacă variabilele p1 și p2 sunt indicii pentru două variabile diferite și independente, atunci orice comparație, ca regulă, nu are sens. Dar dacă variabilele p1 și p2 indică variabilele conexe, de exemplu, elementelor din aceeași matrice, atunci compararea lor poate avea un anumit sens.
Pointeri și matrice
În C #, indicii și matricele sunt legate între ele. De exemplu, dacă specificați un nume de matrice fără un index, se formează un pointer la începutul matricei în operatorul cu modificatorul fix. De exemplu, luați în considerare următorul program.
Mai jos este rezultatul acestui program.
După cum rezultă din rezultatul de mai sus, expresii
sunt la fel. Dar, deoarece cea de-a doua formă este mai concisă, ea este mai des folosită în programare, când este necesar un pointer la începutul unei matrice.
Indexarea indicatorilor
Când un pointer accesează o matrice, poate fi indexat ca matrice în sine. Această sintaxă este mai convenabilă în unele cazuri, o alternativă la operațiile aritmetice pe pointeri. Luați în considerare următorul exemplu de program.
Mai jos este rezultatul acestui program.
După cum rezultă din rezultatul programului de mai sus, forma generală a expresiei cu pointerul
poate fi înlocuită cu următoarea sintaxă de indexare a matricei.
În ceea ce privește indexarea indicatorilor, este necesar să rețineți următoarele. În primul rând, cu o astfel de indexare, controlul limitelor matricei nu este efectuat. Prin urmare, pointerul poate accesa un element în afara limitelor matricei. În al doilea rând, proprietatea Lungime nu este prevăzută pentru pointer. care determină lungimea matricei. Prin urmare, dacă se utilizează un pointer, lungimea matricei nu este cunoscută în prealabil.
Pointeri și șiruri de caractere
După executarea modificatorului declarația fixă p variabilă va indica începutul unui șir de caractere care alcătuiesc linia. Această matrice se termină cu un caracter de sfârșit de linie, adică zero caracter. Prin urmare, această circumstanță poate fi utilizată pentru a verifica sfârșitul matricei. In C / C ++ linii sunt implementate ca matrice, care se încheie newline și, în consecință, a primit tip char * pointer la un șir de caractere, acesta poate fi manipulat în același mod ca și în C / C ++.
Mai jos este un program care demonstrează accesul la un șir de caractere printr-un pointer de tip char *.
Acest program dă următorul rezultat.
Totuși, trebuie avut în vedere faptul că variabila q este un pointer nu la o valoare întregă, ci la un pointer de tip int.