Mogu se definisati pokazivači na strukture, na isti način kao pokazivači na bilo koji drugi tip promenljive.
Na primer, ako imamo strukturu POINT definisanu na sledeći način:
typedef struct point {
int x, y;
} POINT;
Možemo da definišemo promenljivu point_pok koja predstavlja pokazivač na podatak koji je tipa strukture POINT:
POINT *point_pok;
Pokazivaču na strukturu, kao i svim pokazivačima, se može dodeliti vrednost adrese neke promenljive koja je tipa POINT:
POINT s1;
POINT *point_pok = &s1;
Elementima strukture se može prisupiti preko pokazivača korišćenjem operatora ->
na sledeći način:
point_pok->x = 10;
Drugi način za pristup elementu strukture preko pokazivača je (*point_pok).x
, ali ovaj način se mnogo ređe koristi.
Potrebno je da definišemo funkciju koja će omogućiti korisniku promenu polja strukture tipa POINT, koju ćemo proslediti kao argument funkcije.
Pogrešno:
#include <stdio.h>
typedef struct point {
int x, y;
} POINT;
void get_point_wrong(POINT p) { // nova lokalna promenljiva vidljiva samo u ovoj funkciji (kopija strukture a)
printf("x = ");
scanf("%d", &p.x); // pristupamo poljima kopije
printf("y = ");
scanf("%d", &p.y);
printf("get_point_wrong:\n");
printf("x = %d, y = %d\n", p.x, p.y);
}
int main() {
POINT a = {0, 0};
printf("get_point_wrong\n");
get_point_wrong(a); // šaljemo vrednost stukture a
printf("main:\n");
printf("x = %d, y = %d\n", a.x, a.y);
}
Ispravno:
#include <stdio.h>
typedef struct point {
int x, y;
} POINT;
void get_point(POINT *p) { // argument je pokazivač, prosleđujemo adresu
printf("x = ");
scanf("%d", &p->x); // direktno pristupamo poljima strukture a
printf("y = ");
scanf("%d", &p->y);
printf("get_point:\n");
printf("x = %d, y = %d\n", p->x, p->y);
}
int main() {
POINT a = {0, 0};
printf("get_point\n");
get_point(&a); // šaljemo adresu strukture a
printf("main:\n");
printf("x = %d, y = %d\n", a.x, a.y);
}
#include <stdio.h>
int main() {
char str1[100], str2[100], str3[100];
printf("Unesite string koristeci fgets: ");
fgets(str1, sizeof(str1), stdin); // Učitavanje stringa sa standardnog ulaza koristeći fgets
printf("Uneti string koristeci fgets: %s", str1);
printf("Unesite string koristeci scanf: ");
scanf("%s", str2); // Učitavanje stringa sa standardnog ulaza koristeći scanf
printf("Uneti string koristeci scanf: %s", str2);
printf("Unesite string koristeci gets: ");
gets(str3); // Učitavanje stringa sa standardnog ulaza koristeći gets
printf("Uneti string koristeci gets: %s", str3);
return 0;
}
Potpisi funkcija su:
fgets(char *str, int num, FILE *stream)
: Učitava niz karaktera sa navedenog stream
-a (u ovom slučaju standardni ulaz) i smešta ga u string str
sve dok ne naiđe na num
karaktera, novi red ili kraj datoteke, što god prvo nastupi. Karakter novog reda se takođe čuva u stringu.scanf(const char *format, ...)
: Čita formatirane podatke sa standardnog ulaza prema datom formatu i smešta ih na odgovarajuće lokacije argumenta. Prilikom učitavanja stringova se string učitava do prvog razmaka ili novog reda.gets(char *str)
: gets()
je zastarela funkcija i nije preporučljivo je koristiti zbog sigurnosnih problema vezanih za prekoračenje bafera. Umesto toga, preporučuje se korišćenje fgets()
.String.h je biblioteka za rad sa stringovima u C programskom jeziku. Kako bismo mogli da je koristimo, potrebno je da je uključimo u kod pomoću #include <string.h>
.
Neke od važnijih funkcija ove biblioteke su:
strlen(const char *str)
- vraća dužinu stringa strstrcpy(char * destination, const char * source)
- kopira vrednost source stringa u destination stringstrcmp(const char * str1, const char * str2)
- poredi 2 stringa i, ako su jednaki vraća 0, ako je prvi veći od drugog vraća vrednost > 0, u suprotnom < 0strcat(char * destination, const char * source)
- dodaje kopiju source stringa na destination string*Napomena: Odnosi se na leksikografsko poređenje dva stringa. To je način poređenja nizova gde se redom upoređuju karakteri na istom položaju u nizovima. Ako se naiđe na karaktere koji se razlikuju, a na istoj su poziciji, karakter sa većom ASCII vrednošću smatra se većim stringom.
Ostale funkcije biblioteke možete pogledati ovde.
Unije su složeni tipovi podataka koji omogućavaju da se u isti memorijski prostor, u različitim trenucima, smeštaju podaci različitih tipova.
Unije se difinišu naredbom union
.
Za razliku od struktura, kod kojih sva polja imaju definisanu vrednost, kod unije samo jedno polje u datom trenutku ima definisanu vrednost, polje kome je posljednje dodeljena vrednost.
Svi članovi unije dele istu memorijsku lokaciju. Unija zauzima dovoljno memorije za najveći član unije.
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data;
printf("Union size: %ld bytes\n", sizeof(data));
data.i = 10;
printf("Integer value: %d\n", data.i);
data.f = 220.5;
printf("Float value: %f\n", data.f);
//printf("Integer value: %d\n", data.i); // ako pokušamo da pristupimo polju i, dobićemo neočekivanu vrednost jer unija u jednom trenutku može čuvati vrednost samo jednog polja
strcpy(data.str, "Hello");
printf("String value: %s\n", data.str);
return 0;
}
Veličina strukture predstavlja zbir bajtova svih članova strukture.
Veličina unije predstavlja veličinu najvećeg člana unije.
#include <stdio.h>
typedef struct {
int a,b;
char *c;
double d[2];
} STRUKTURA; // velicina ove strukture ce biti 32 bajta
// sizeof(int) = 4
// sizeof(double) = 8
// sizeof(char*) = 8
// 2 * sizeof(int) + sizeof(char*) + 2 * sizeof(double) = 32
typedef union {
int a,b;
char *c;
double d[2];
} UNIJA; // velicina ove strukture ce biti 16 bajta
// max(sizeof(int), sizeof(int), sizeof(char*), 2 * sizeof(double)) = 16
// staticki alociran niz se posmatra kao jedna promenljiva
// velicina unija je maksimalna velicina svih promenljivih
int main() {
printf("sizeof(STRUKTURA) = %ld\n", sizeof(STRUKTURA));
printf("sizeof(UNIJA) = %ld\n", sizeof(UNIJA));
return 0;
}