No i się dowiedziałem paru ciekawych rzeczy. W takim razie miałbym jeszcze parę pytań w związku z odpowiedzią Endrju.
Zdziwiłem się, że wyświetlanie adresu w formacie dziesiętnym jest UB. Doczytałem więc trochę o tym i proszę powiedzcie mi, czy dobre wnioski wyciągnąłem:
- Aby wyświetlić adres zmiennej należy to zrobić z rzutowaniem adresu na typ "void *" i wyświetlić go w formie heksadecymalnej, np.
int x;
printf("%p", (void*)&x);
Pytanie - czy można wyświetlić adres w formie oktadecymalnej, tj. z użyciem specyfikatora "%o"?
Z kolei jak chcemy robić arytmetykę wskaźników, to należy użyć typu "ptrdiff_t".
Ok, to załóżmy, że chcę zobaczyć jaka jest różnica w bajtach pomiędzy 2 elementami tabeli w pamięci (tu swoją drogą kolejne pytanie - czy standard wymusza alokowanie elementów obok siebie w pamięci, jeśli jest to możliwe? Czy jest tak samo w C++? bo właściwie zawsze jak patrzę na adresy elementów z tablicy, to wychodzi na to, że tak). Należałoby wtedy zrobić to w ten sposób?
#include <stdio.h>
#include <stddef.h>
int main(void)
{
const size_t N = 100;
int numbers[N];
int *p2, *p1;
p1 = &numbers[0];
p2 = &numbers[10]; // 10 el. roznicy, czyli 40 bajtow
ptrdiff_t diff = p2-p1;
printf("Roznica pomiedzy p1 a p2 w bajtach: %td\n", sizeof(int) * diff);
return 0;
}
Jeśli dobrze kojarzę, to arytmetyka na typie niepełnym jest illegal, tj. nie można tego zrobić w ten sposób:
printf("Roznica pomiedzy p1 a p2 w bajtach: %ld\n", (void*)p2-(void*)p1);
Prawda?
Aczkolwiek kompiluje się bez problemu i daje dobry wynik (xcode 7.3).
I kończąc temat z "size_t" i "ptrdiff_t" - podejrzałem sobie po wykonaniu preprocesora, że to jest po prostu "typedef unsigned long int" i "signed long int" odpowiednia dla tych typów - czyli jak rozumiem te typy są stworzone po prostu dla wygody programisty i niejako informowania o tym, że zmienna tego typu będzie mówiła o ilość elementów np. w tablicy / będzie wykonywana operacja na wskaźnikach?
Kolejna sprawa, nie mogłem znaleźć odniesień w dokumentacji do punktów wymienionych przez Endrju (jedyna darmowa dokumentacja C99 jaką znalazłem to http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) i nie wiem co tu jest źle (pomijając przypisywanie niewiadomej wartości spod niezaalokowanego adresu)
int x = *fun(v1, v2, v1size, v2size);