1. wskaźnik wskaźnika:
int **tab;
Do czego w takim wypadku odnosi się:
tab;
*tab;
**tab;
Ten zapis jest trochę błędny, bo przy rozróżnianiu wskaźników powinieneś użyć też typu, bo ma on znaczenie.
więc w tym przykładzie:
int tab1;
To jest zwykła zmienna typu int. Jest ona tworzona na stosie i jest niszczona gdy program wyjdzie poza zakres {} klamerek czyli np. poza zakres jakiejś funkcji. Może przechowywać wartości takie jak: -5, 10, 999. Dokładny zakres wartości którą może przechowywać jest zależny od architektury procesora.
int *tab2;
To jest wskaźnik na zmienną typu int. Jest on tworzony na stosie i jest niszczony gdy program wyjdzie poza zakres {} klamerek czyli np. poza zakres jakiejś funkcji. Może przechowywać wartości takie jak: 0xEE1279CA. Dokładny zakres wartości którą może przechowywać jest zależny od architektury procesora.
Taki wskaźnik może wskazywać na zmienną typu int, ale może też wskazywać na początek tablicy typów int.
// tworzenie tablicy dynamicznej składającej się z 10 intów.
int *tab2 = malloc(sizeof(int) * 10);
free(tab2); //gdzieś dalej w programie.
Podobny wskaźnik, ale o typie char* może wskazywać na tablicę charów, czyli na tekst.
char *tab2 = "jakis tekst";
int **tab3;
To jest wskaźnik na wskaźnik który wskazuje na zmienną typu int. Jest on tworzony na stosie i jest niszczony gdy program wyjdzie poza zakres {} klamerek czyli np. poza zakres jakiejś funkcji. Może przechowywać wartości takie jak: 0xEE1279CA. Dokładny zakres wartości którą może przechowywać jest zależny od architektury procesora.
Taki typ potrafi przechowywać inny wskaźnik lub tablicę wskaźników
Mam nadzieję, że o takie wyjaśnienie Ci chodziło. Po więcej informacji odsyłam do książek o języku C.
2. strncpy
char napis[20];
strncpy(napis, "tekst", sizeof napis-1);
napis[sizeof napis -1] = 0;
Dlaczego sizeof napis-1, a nie sizeof napis?
linia 1: tworzona jest tablica dwudziestu zmiennych typu char. (oczywiście indeksowane od 0 do 19).
linia 2: wykorzystano tu bezpieczne kopiowanie (funkcja strncpy - http://www.cplusplus.com/reference/cstring/strncpy/). Cała ta linia to poprostu wydanie takiego polecenia: skopiuj sizeof(napis)-1 znaków z tekstu "tekst" do tablicy napis. Dzięki dodatkowemu parametrowi (sizeof(napis)-1) mamy pewność, że zakres tablicy napis nie zostanie przekroczony - nie wystąpi buffer overflow.
linia 3: zerujemy ostatni bajt tablicy. sizeof(napis) - 1 bo sizeof(napis) zwróci 20, a tablice są indeksowane od zera więc nie ma komórki napis[20]. Najdalszą jest napis[19]. Ten -1 zapewnia, że odwołujemy sie do ostatniej komórki tablicy.
Zerujemy, bo tablice tekstowe muszą się kończyć zerem.
To samo w linii 14 w następnym listingu.
strncpy(haslo, argv[1], sizeof(haslo) - strlen(haslo) - 1);
To jest bezpieczne kopiowanie z argv[1] (argumentu który przekazujemy przy uruchomieniu programu z konsoli).
Niestety nie rozumiem dlaczego jest tam strlen(haslo). Ta tablica jest niezainicjalizowana więc nie wiem dlaczego użyte jest liczenie długości stringa.
3. UCS-2
#include <stdio.h>
#include <stddef.h>
#include <stddef.h>
int main(){
wchar_t* wcs1 = L"Ala ma kota.";
wchar_t* wcs2 = L"Kot ma Ale.";
wchar_t calosc[25];
wcscpy(calosc, wcs1);
*(calosc + wcslen(wcs1)) = L' ';
wcscpy(calosc + wcslen(wcs1) + 1, wcs2);
printf("lancuch wyjsciowy: %ls\n", calosc);
return 0;
}
Co oznaczają linijki 11 i 12?
*(calosc + wcslen(wcs1)) = L' ';
Linia 11 wpisuje spację (rzutowaną na wchar_t) do tablicy calosc pod indeksem wsclen(wsc1). Gdzie wsclen(wsc1) będzie wartość określająca długość stringu wskazywanego przez wskaźnik wsc1.
W tym przypadku, to po prostu znaczy calosc[12] = ' ';
wcscpy(calosc + wcslen(wcs1) + 1, wcs2);
Ten kod odpowiada za skopiowanie całego napisu z pod wskaźnika wsc2 do tablicy calosc pod indeksem wsclen(wsc1) + 1. Ponieważ wsclen(wsc1) zwróci 12, to ta linia po prostu dopisze tekst z pod wskaźnika wsc2 do tablicy calosc zaczynając od indeksu 13.