Próbuję zrozumieć sposób, w jaki C obsługuje tablice, w tym przypadku, czytając tablicę dwuwymiarową, tak jakby to była tablica jednowymiarowa.
Biorąc pod uwagę ten prosty program w języku C.
#include <stdio.h>
int main(int argc, char *argv[]){
int array[4][4];
int i, j;
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
array[i][j] = (i+1)*(j+1);
printf("%d ", array[i][j]);
}
printf("n");
}
for(i = 0; i < 16; i++){
printf("%d ", array[i]);
}
printf("n");
}
Otrzymuję ten dziwny wynik.
1 2 3 4
2 4 6 8
3 6 9 12
4 8 12 16
56319776 56319792 56319808 56319824 56319840 56319856 56319872 56319888 56319904 56319920 56319936 56319952 56319968 56319984 56320000 56320016
Co jest drukowane w drugim for
pętla?
Odpowiedzi:
4 dla odpowiedzi № 1Co jest drukowane w drugiej pętli for?
Krótka odpowiedź brzmi: „to śmieci”. Oficjalna nazwa to „niezdefiniowane zachowanie”, ale zasadniczo jest to ciąg dowolnych cyfr dziesiętnych.
Długa odpowiedź jest nieco trudniejsza: przechodzisz printf
adresy tablic jednowymiarowych, które otrzymują ponownie zinterpretowany jako liczby całkowite. Zwróć uwagę, jak liczby są rozdzielane w tym samym kroku 16. Jest to rozmiar czterech int
w twoim systemie.
Jeśli chcesz uzyskać oryginalne liczby przez tablicę jednego wymiaru, możesz wymusić inną interpretację tablicy - jako wskaźnik do int
:
int *ptr = (int*)&array;
for(i = 0; i < 16; i++){
printf("%d ", ptr[i]);
}
W ten sposób tworzona jest sekwencja liczb z tablicy 2D, sposób, w jaki tablica jest przechowywana w pamięci (rząd po rzędzie).
4 dla odpowiedzi nr 2
Tablice 2D są uważane za tablicę 1D z tablic 1D. Drukuje adres tablic 1D, ale powinieneś użyć %p
specyfikator, aby wydrukować adres, w przeciwnym razie zostanie wywołany niezdefiniowane zachowanie.
for(i = 0; i < 4; i++){
printf("%p", (void *)array[i]);
}
int array[4][4]
jest typu tablica 2D z 16 liczb całkowitych lub można to powiedzieć array
jest tablicą 1D z 4 tablic 1D z int
"s.
Należy pamiętać, że tylko twój program wywołuje niezdefiniowane zachowanie z dwóch powodów:
1. zły specyfikator %d
służy do drukowania adresu.
2. uzyskujesz dostęp poza granicami ostatniej pętli. for(i = 0; i < 16; i++)
powinno być for(i = 0; i < 4; i++)