Salut,
astazi voi incerca sa lamuresc cateva aspecte legate de pointeri.
Ei bine, un pointer este practic o variabila care retine o adresa de memorie (adresa unei date, adresa unei functii, adresa unei adrese din memorie, void - adresa catre o zona necunoscuta).
Exista doi operatori esentiali pe care ii vom folosim: * (dereferentiere) si & (referentiere) si apar in fata variabilei de tip pointer.
Acum o sa ma intrebati ce inseamna derefentiere si referentiere...
Este destul de simplu, * este folosit atunci cand dorim sa aflam valoarea stocata la adresa respectiva. Atunci cand este folosit la declararea unei variabile, acesta indica prezenta unui pointer la tipul respectiv.
Cu ajutorul lui & putem afla adresa din memorie a variabilei respective (si l-am si folosit deja la functia scanf).
Trebuie sa retinem faptul ca un pointer nu este alocat la definire. Va trebui ca noi sa facem asta si vom vedea cum putin mai tarziu.
Exemple:
int *a; // pointer la int sau vector de intregi
int b = 10; // variabila de tip int
char *c; // pointer la char sau sir de caractere (vector de caractere)
void *s = NULL; // initializare la null (valoare 0)
*a = 5; // initializare gresita, a nu a fost alocat si nu indica nicio adresa
a = &b; // initializare corecta, a indica acum adresa lui b
*a = 5; // initializare corecta, echivalenta cu b = 5
Dupa cum am spus deja, declaratia int *a este echivalenta cu int a[] deci putem declara vectori cu ajutorul pointerilor, cu conditia de a face, ulterior, alocarea memoriei. Pentru ca tot veni vorba de asta, exista 2 functii de baza care ne ajuta malloc si calloc. Ele se utilizeaza in modul urmator:
int *a;
// vom aloca un vector de 100 de elemente intregi
a = (int*)malloc(100 * sizeof(int));
a = (int*)calloc(100, sizeof(int));
Diferenta dintre cele doua este ca calloc face si initializarea componentelor la zero.
Important! De fiecare data cand folosim functiile de alocare a memoriei este fundamental sa o eliberam la finalul programului. Pentru aceasta exista functie free.
Multi se sperie de pointeri si gasesc acest lucru gresit. Daca sunt folositi corect, acestia fac minuni. Este foarte adevarat ca pot aparea si efecte secundare daca doi pointeri arata catre acelasi continut de memorie (cum am vazut in exemplul de mai sus), insa intotdeauna trebuie sa folosim pointerii cu atentie.
Cineva mi-a povestit odata cum vede el un pointer si a facut o analogie cu un ogar care indica spre prada de vanatoare (asa ca in desenele animate :) ). Evident cainele este variabila de tip pointer, iar prada este continutul/adresa din memorie.
Consider ca este de ajuns pentru astazi. Data viitoare vom vedea cum se folosesc acesti pointeri in probleme cu vectori. Pana atunci eu va doresc numai bine.
Blog IT
Un blog despre IT&C, stiri si tutoriale legate de calculatoare si informatica.
27 Sept 2012
25 Sept 2012
Introducere C - vectori
Salut,
astăzi, după o perioadă de inactivitate pentru care vă cer scuze, voi continua cu câteva lucruri introductive despre vectori.
Aceștia pot fi priviți ca o colecție liniară (elementele pot fi accesate dupa index) și omogenă (adică au elemente de același tip) de date.
În C indexarea începe de la zero.
Declarația este de felul următor
float b[50];
char s[10] = {0}; // asa se initializeaza toate elementele la valoarea zero
astăzi, după o perioadă de inactivitate pentru care vă cer scuze, voi continua cu câteva lucruri introductive despre vectori.
Aceștia pot fi priviți ca o colecție liniară (elementele pot fi accesate dupa index) și omogenă (adică au elemente de același tip) de date.
În C indexarea începe de la zero.
Declarația este de felul următor
<tip>
<nume_vector>[<dimensiune>];
Pentru început, vom declara vectori statici, adică vom specifica dimensiunea lor ca în forma de mai sus.
Acum câteva exemple de inițializare
int a[100];Acum câteva exemple de inițializare
float b[50];
char s[10] = {0}; // asa se initializeaza toate elementele la valoarea zero
Exemplu de citire a unui vector de întregi de la tastatură
int main() {
int a[100],n,i; // vectorul are maxim 100 de intregi
scanf ("%d",&n); // citim nr de elemente
for (i = 0; i < n; ++i)
scanf("%d", &a[i]);
for (i = 0; i < n; ++i)
printf("%d ", a[i]);
return 0;
}
Alte aplicații clasice cu vectori sunt căutările și sortările. În continuare vă voi da o implementare a sortării prin inserție.
#include <stdio.h>
#include <stdlib.h>
//sortare prin insertie, ca parametrii dam vectorul si dimensiunea sa
void insertie(int *v, int n){
int t, j, i;
for (i = 1;i < n; ++i){
t = v[i];
j = i;
while(j > 0 && t <= v[j - 1]){
v[j] = v[j-1];
--j;
}
v[j] = t;
}
}
int main(){
int i;
// declaram un vector de 10 elemente de tip int
int v[10];
// citirea numerelor
for (i = 0;i < 10;++i)
scanf("%d", &v[i]);
#include <stdio.h>
#include <stdlib.h>
//sortare prin insertie, ca parametrii dam vectorul si dimensiunea sa
void insertie(int *v, int n){
int t, j, i;
for (i = 1;i < n; ++i){
t = v[i];
j = i;
while(j > 0 && t <= v[j - 1]){
v[j] = v[j-1];
--j;
}
v[j] = t;
}
}
int main(){
int i;
// declaram un vector de 10 elemente de tip int
int v[10];
// citirea numerelor
for (i = 0;i < 10;++i)
scanf("%d", &v[i]);
// sortarea
insertie(v, 10);
// afisarea vectorului soratat
for (i = 0;i < 10;++i)
printf("%d ", v[i]);
return 0;
}
insertie(v, 10);
// afisarea vectorului soratat
for (i = 0;i < 10;++i)
printf("%d ", v[i]);
return 0;
}
25 Aug 2012
Introducere C - despre funcții
Salutare tuturor!
Astăzi vom vedea cum putem modulariza codul astfel încât să fie mult mai ușor de citit și de înțeles. Acest lucru se realizează, în principal, cu ajutorul funcțiilor, C-ul fiind prin excelență un limbaj procedural.
Funcțiile ne permit, totodată, să le reutilizăm după necesități. De exemplu, să presupunem că am făcut o funcție care verifică dacă un număr este prim. Dacă avem de rezolvat, o problemă mai complicată care necesită, la un moment dat, testarea unor numere pentru a vedea dacă ele sunt prime, atunci putem folosi funcția realizată anterior. Important este ca funcțiile să fie cât mai generale și să preia numai parametrii absolut necesari. Și pentru că am pomenit de parametrii, iată cum arată semnătura generică a unei funcții:
tip_rezultat nume_funcție(tip parametru1, tip parametru2, ...) {
// declarații și instrucțiuni
}
Apelarea se face în modul următor:
nume_funcție(lista parametri) daca tip_rezultat este void (adică nu întoarce nimic)
sau
variabila = nume_funcție(lista parametri) daca funcția întoarce ceva
Iar acum să modificăm ultimele exemple prezentate astfel încât programele să fie cu funcții.
1. Fiind date de la tastatură două numere întregi, să se afișeze cel mai mare divizor comun al lor. (Indiciu: Algoritmul lui Euclid)
#include <stdio.h>
int cmmdc (int a, int b) {
int r;
// testam cazul limita cand b este zero
if (b == 0) {
return a;
}
// aici ar fi mers un 'else', dar nu e nevoie datorita return-ului anterior
// aici este algoritmul propriu-zis
do{
r = a % b;
a = b;
b = r;
}while(r);
// la final, cmmdc-ul este in 'a'
return a;
}
int main(){
// declaram variabilele; ele vor fi initializate automat la zero
int a, b, c;
printf("Introduceti primul numar: ");
scanf("%d",&a);
printf("Introduceti al doilea numar: ");
scanf("%d",&b);
c = cmmdc(a,b);
printf("Cmmdc este %d\n",c);
return 0;
}
2. Să se verifice dacă un număr introdus de la tastatură este prim.
#include <stdio.h>
// functia va intoarce 0 (fals) sau 1 (adevarat) in functie de rezultatul testului
int e_prim(int nr){
int i, prim = 1;
/* pentru fiecare numar mai mic decat numarul nostru, verificam daca exista vreunul la care
* acesta acesta din urma se imparte exact
* s-a aratat ca nu e cazul sa verificam toate numerele, ci doar pe acelea mai mici decat nr/2
*/
for (i = 2; i < nr/2; ++i) {
if (nr % i == 0) {
printf("Numarul nu este prim\n");
prim = 0;
break; // am gasit ca numarul nu este prim si iesim fortat din bucla; nu are sens sa continuam
}
}
return prim;
}
int main(){
// vom folosi o variabila auxiliara pentru a putea afisa mesajul afirmativ de la sfarsit
// pornim de la ideea ca numarul este prim
int nr, i, prim = 1;
printf("Introduceti numarul: ");
scanf("%d",&nr);
prim = e_prim(nr);
if (prim) {
printf ("Numarul este prim\n");
}
else {
printf("Numarul nu este prim\n");
}
return 0;
}
Astăzi vom vedea cum putem modulariza codul astfel încât să fie mult mai ușor de citit și de înțeles. Acest lucru se realizează, în principal, cu ajutorul funcțiilor, C-ul fiind prin excelență un limbaj procedural.
Funcțiile ne permit, totodată, să le reutilizăm după necesități. De exemplu, să presupunem că am făcut o funcție care verifică dacă un număr este prim. Dacă avem de rezolvat, o problemă mai complicată care necesită, la un moment dat, testarea unor numere pentru a vedea dacă ele sunt prime, atunci putem folosi funcția realizată anterior. Important este ca funcțiile să fie cât mai generale și să preia numai parametrii absolut necesari. Și pentru că am pomenit de parametrii, iată cum arată semnătura generică a unei funcții:
tip_rezultat nume_funcție(tip parametru1, tip parametru2, ...) {
// declarații și instrucțiuni
}
Apelarea se face în modul următor:
nume_funcție(lista parametri) daca tip_rezultat este void (adică nu întoarce nimic)
sau
variabila = nume_funcție(lista parametri) daca funcția întoarce ceva
Iar acum să modificăm ultimele exemple prezentate astfel încât programele să fie cu funcții.
1. Fiind date de la tastatură două numere întregi, să se afișeze cel mai mare divizor comun al lor. (Indiciu: Algoritmul lui Euclid)
#include <stdio.h>
int cmmdc (int a, int b) {
int r;
// testam cazul limita cand b este zero
if (b == 0) {
return a;
}
// aici ar fi mers un 'else', dar nu e nevoie datorita return-ului anterior
// aici este algoritmul propriu-zis
do{
r = a % b;
a = b;
b = r;
}while(r);
// la final, cmmdc-ul este in 'a'
return a;
}
int main(){
// declaram variabilele; ele vor fi initializate automat la zero
int a, b, c;
printf("Introduceti primul numar: ");
scanf("%d",&a);
printf("Introduceti al doilea numar: ");
scanf("%d",&b);
c = cmmdc(a,b);
printf("Cmmdc este %d\n",c);
return 0;
}
2. Să se verifice dacă un număr introdus de la tastatură este prim.
#include <stdio.h>
// functia va intoarce 0 (fals) sau 1 (adevarat) in functie de rezultatul testului
int e_prim(int nr){
int i, prim = 1;
/* pentru fiecare numar mai mic decat numarul nostru, verificam daca exista vreunul la care
* acesta acesta din urma se imparte exact
* s-a aratat ca nu e cazul sa verificam toate numerele, ci doar pe acelea mai mici decat nr/2
*/
for (i = 2; i < nr/2; ++i) {
if (nr % i == 0) {
printf("Numarul nu este prim\n");
prim = 0;
break; // am gasit ca numarul nu este prim si iesim fortat din bucla; nu are sens sa continuam
}
}
return prim;
}
int main(){
// vom folosi o variabila auxiliara pentru a putea afisa mesajul afirmativ de la sfarsit
// pornim de la ideea ca numarul este prim
int nr, i, prim = 1;
printf("Introduceti numarul: ");
scanf("%d",&nr);
prim = e_prim(nr);
if (prim) {
printf ("Numarul este prim\n");
}
else {
printf("Numarul nu este prim\n");
}
return 0;
}
23 Aug 2012
Introducere C - probleme rezolvate (3)
Salutare tuturor!
Astăzi o să vă prezint ultima parte a problemelor simple urmând ca, de data viitoare, să trecem la modularizare și alte lucruri interesante.
Pe ordinea de zi, avem tot două probleme, după cum urmează
1. Fiind date de la tastatură două numere întregi, să se afișeze cel mai mare divizor comun al lor. (Indiciu: Algoritmul lui Euclid)
#include <stdio.h>
int main(){
// declaram variabilele; ele vor fi initializate automat la zero
int a, b, r;
printf("Introduceti primul numar: ");
scanf("%d",&a);
printf("Introduceti al doilea numar: ");
scanf("%d",&b);
// testam cazul limita cand b este zero
if (b == 0) {
printf("Cmmdc este %d\n",a);
return 0;
}
// aici ar fi mers un 'else', dar nu e nevoie datorita return-ului anterior
// aici este algoritmul propriu-zis
do{
r = a % b;
a = b;
b = r;
}while(r);
// la final, cmmdc-ul este in 'a'
printf("Cmmdc este %d\n",a);
return 0;
}
2. Să se verifice dacă un număr introdus de la tastatură este prim.
#include <stdio.h>
int main(){
// vom folosi o variabila auxiliara pentru a putea afisa mesajul afirmativ de la sfarsit
// pornim de la ideea ca numarul este prim
int nr, i, prim = 1;
printf("Introduceti numarul: ");
scanf("%d",&nr);
/* pentru fiecare numar mai mic decat numarul nostru, verificam daca exista vreunul la care
* acesta acesta din urma se imparte exact
* s-a aratat ca nu e cazul sa verificam toate numerele, ci doar pe acelea mai mici decat nr/2
*/
for (i = 2; i < nr/2; ++i) {
if (nr % i == 0) {
printf("Numarul nu este prim\n");
prim = 0;
break; // am gasit ca numarul nu este prim si iesim fortat din bucla; nu are sens sa continuam
}
}
// aici era corect si if (prim == 1)
// in C, o structura de tipul if (ceva) este echivalenta cu if (ceva != 0)
if (prim) {
printf ("Numarul este prim\n");
}
return 0;
}
Astăzi o să vă prezint ultima parte a problemelor simple urmând ca, de data viitoare, să trecem la modularizare și alte lucruri interesante.
Pe ordinea de zi, avem tot două probleme, după cum urmează
1. Fiind date de la tastatură două numere întregi, să se afișeze cel mai mare divizor comun al lor. (Indiciu: Algoritmul lui Euclid)
#include <stdio.h>
int main(){
// declaram variabilele; ele vor fi initializate automat la zero
int a, b, r;
printf("Introduceti primul numar: ");
scanf("%d",&a);
printf("Introduceti al doilea numar: ");
scanf("%d",&b);
// testam cazul limita cand b este zero
if (b == 0) {
printf("Cmmdc este %d\n",a);
return 0;
}
// aici ar fi mers un 'else', dar nu e nevoie datorita return-ului anterior
// aici este algoritmul propriu-zis
do{
r = a % b;
a = b;
b = r;
}while(r);
// la final, cmmdc-ul este in 'a'
printf("Cmmdc este %d\n",a);
return 0;
}
2. Să se verifice dacă un număr introdus de la tastatură este prim.
#include <stdio.h>
int main(){
// vom folosi o variabila auxiliara pentru a putea afisa mesajul afirmativ de la sfarsit
// pornim de la ideea ca numarul este prim
int nr, i, prim = 1;
printf("Introduceti numarul: ");
scanf("%d",&nr);
/* pentru fiecare numar mai mic decat numarul nostru, verificam daca exista vreunul la care
* acesta acesta din urma se imparte exact
* s-a aratat ca nu e cazul sa verificam toate numerele, ci doar pe acelea mai mici decat nr/2
*/
for (i = 2; i < nr/2; ++i) {
if (nr % i == 0) {
printf("Numarul nu este prim\n");
prim = 0;
break; // am gasit ca numarul nu este prim si iesim fortat din bucla; nu are sens sa continuam
}
}
// aici era corect si if (prim == 1)
// in C, o structura de tipul if (ceva) este echivalenta cu if (ceva != 0)
if (prim) {
printf ("Numarul este prim\n");
}
return 0;
}
20 Aug 2012
Codepad, un instrument util
După cum v-ați seama deja, aș vrea să vă spun două vorbe despre Codepad.
Acesta este un compilator / interpretor online pe care îl puteți folosi pentru a vă testa programele. Aveți însă grijă la citirile de la tastatură, care nu vor fi efectuate - va trebui să inițializați de mână variabilele respective. În rest, este un instrument ușor de utilizat și util, zic eu. Suportă mai multe limbaje de programare și oferă programului vostru rulat un link pe care îl puteți partaja cu prietenii.
Codepad poate fi găsit aici.
Acesta este un compilator / interpretor online pe care îl puteți folosi pentru a vă testa programele. Aveți însă grijă la citirile de la tastatură, care nu vor fi efectuate - va trebui să inițializați de mână variabilele respective. În rest, este un instrument ușor de utilizat și util, zic eu. Suportă mai multe limbaje de programare și oferă programului vostru rulat un link pe care îl puteți partaja cu prietenii.
Codepad poate fi găsit aici.
Introducere C - probleme rezolvate (2)
Salutare,
astazi continuam seria problemelor rezolvate.
1. De la tastatură se introduce un număr real ce reprezintă măsura unui unghi în radiani. Să se scrie un program pentru conversia acestuia în grade, minute şi secunde sexagesimale.
#include <stdio.h>
// asa ne definim noi o constanta
#define PI 3.14159265
int main(){
// definire variabile
float radiani, gf, mf;
int grade, minute, secunde;
printf(“Introduceti numarul de radiani: “);
scanf("%f", &radiani);
/** aici avem valoare introdusa de la tastatura
* mai trebuie sa facem calculele necesare conversiei
* primele doua initializari sunt interesante intrucat, mai intai, calculam
* valoarea reala (cu virgula) a expresiei, iar apoi obtinem si partea intreaga a rezultatului
* in variabila de tip int
*/
grade = gf = radiani * 180 / PI;
minute = mf = (gf - g) * 60;
secunde = (mf - m) * 60;
printf("%f radiani inseamna %d grade %d minute %d secunde.\n", radiani, grade, minute, secunde);
return 0;
}
2. Să se calculeze abaterea media patratică a unor valori rezultate în urma unui experiment. Formula de calcul poate fi găsită aici, la finalul primei secțiuni. Pentru usurință, aceasta poate fi puțin prelucrată făcând reducerile necesare și dând factor comun.
#include <stdio.h>
#include <math.h>
int main(){
int n,i;
double a, suma1 = 0, suma2 = 0, amp;
printf("Introduceti numarul valorilor: ");
scanf("%d",&n);
for (i=0;i<n;i++) {
printf("Introduceti valoarea %d: ",i+1);
scanf("%lf",&a);
suma1+=a*a;
suma2+=a;
}
amp=sqrt((n * suma1 - suma2 * suma2) / (n * (n - 1)));
printf("Abaterea medie patratica este %lf.\n",amp);
return 0;
}
Pana data viitoare, eu va doresc numai bine.
astazi continuam seria problemelor rezolvate.
1. De la tastatură se introduce un număr real ce reprezintă măsura unui unghi în radiani. Să se scrie un program pentru conversia acestuia în grade, minute şi secunde sexagesimale.
#include <stdio.h>
// asa ne definim noi o constanta
#define PI 3.14159265
int main(){
// definire variabile
float radiani, gf, mf;
int grade, minute, secunde;
printf(“Introduceti numarul de radiani: “);
scanf("%f", &radiani);
/** aici avem valoare introdusa de la tastatura
* mai trebuie sa facem calculele necesare conversiei
* primele doua initializari sunt interesante intrucat, mai intai, calculam
* valoarea reala (cu virgula) a expresiei, iar apoi obtinem si partea intreaga a rezultatului
* in variabila de tip int
*/
grade = gf = radiani * 180 / PI;
minute = mf = (gf - g) * 60;
secunde = (mf - m) * 60;
printf("%f radiani inseamna %d grade %d minute %d secunde.\n", radiani, grade, minute, secunde);
return 0;
}
2. Să se calculeze abaterea media patratică a unor valori rezultate în urma unui experiment. Formula de calcul poate fi găsită aici, la finalul primei secțiuni. Pentru usurință, aceasta poate fi puțin prelucrată făcând reducerile necesare și dând factor comun.
#include <stdio.h>
#include <math.h>
int main(){
int n,i;
double a, suma1 = 0, suma2 = 0, amp;
printf("Introduceti numarul valorilor: ");
scanf("%d",&n);
for (i=0;i<n;i++) {
printf("Introduceti valoarea %d: ",i+1);
scanf("%lf",&a);
suma1+=a*a;
suma2+=a;
}
amp=sqrt((n * suma1 - suma2 * suma2) / (n * (n - 1)));
printf("Abaterea medie patratica este %lf.\n",amp);
return 0;
}
Pana data viitoare, eu va doresc numai bine.
19 Aug 2012
Adaptor USB bluetooth nu a fost detectat de Nokia PC Suite
Adaptorul USB bluetooth cu seria ES-388 care foloseste driverul IVT BlueSoleil, prezinta o problema, nu este detectat de nokia pc suite si nici de ovi nokia. Aceata problema a fost prezentata de foarte multi utilizatori.
Motivul acestei probleme este dat de faptul ca de la versiunea 7.0 a programului nokia pc suite, stiva de drivere suportate de program nu suporta versiuni mai joase de 6.0 ale IVT BlueSoleil.
Modul cel mai simplu de rezolvare a acestei probleme este prin utilizarea unei versiuni mai vechi a programului nokia pc suite. Versiunea ce functioneaza destul de bine fiind 6.x.x.x. Sau achizionarea unei versiuni mai recente a softului dongle.
Modul in care se poate verifica daca problema este de la driver este urmatoarea:
1.Deschidere nokia pc suite / ovi nokia
2. Click HELP->About nokia pc suite...
3. Click pe Show system information dialog ( i ).
4. Daca driverul este recunoscut de program acesta ar trebui sa apara in lista din fereastra nou aparuta, exact ca in imaginea de mai jos. Daca nu apare atunci driverul nu a fost detectat de program si fie se updateatza driverul, fie se downgradeaza versiunea softului de transfer de date(acest acest nokia pc suite).
Subscribe to:
Posts (Atom)