Język C: dynamiczne tablice dwuwymiarowe i funkcje
Wstęp
Język C pozwala deklarować tablice w „klasyczny sposób” to znaczy określając ich typ i liczbę elementów. Deklaracja tablicy jednowymiarowej wygląda tak:
1 |
int tab1d[10]; |
(w nawiasach podajemy liczbę elementów).
W przypadku tablic dwuwymiarowych deklaracja wygląda tak:
1 |
double tab2d[10][12]; |
w pierwszym nawiasie kwadratowym podana jest liczba wierszy, w drugim liczba kolumn.
Do elementów tablic dobieramy się w standardowy (cokolwiek to znaczy) sposób, na przykład:
1 2 |
tab2d[3][5] = tab1d[7]; tab1d[3] = round(tab2d[4][4]); |
Natomiast zapis z dwoma nawiasami kwadratowymi sugeruje, że mamy do czynienia z bardziej skomplikowanym tworem: jednowymiarową tablicą (adresów) jednowymiarowych tablic.
W istocie, nawet przy powyższych deklaracjach poprawny jest zapis
1 |
tab2d[3] |
na przykład
1 |
print("Adres wiersza 3 wynosi: %p\n", tab2d[3]); |
Zwracam uwagę na format wydruku %p
przeznaczony do drukowania wartości wskaźników.
Przykład
Poniższy przykład pokazuje jak można zadeklarować dynamiczną tablicę dwuwymiarową (i przekazać jej adres do funkcji).
Najpierw deklarujemy wskaźnik, w którym będą zapamiętane wszystkie adresy:
1 |
double **t; |
Jeżeli zapisać to w nawiasach double *(*t)
to widać że deklarujemy standardowo adres tablicy jednowymiarowej *()
. Druga gwiazdka mówi o tym, że elementami tej tablicy również będą adresy *t
.
Cały przykład wygląda tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* * main.c * Copyright (C) 2012 Wojciech Myszka <myszka@asusux> * * tablice is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * tablice is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include <stdlib.h> void dane(int, int, double **); double srednia(int N, int M, double **tablica); int main() { int i, j; /* Liczba wierszy N */ int N = 10; /* Liczba kolumn M */ int M = 12; /* Deklarujemy tablice zawierajaca adresy kolejnych wierszy... te dwie gwiazdki sa bardzo wazne: pierwsza (od lewej) mowi, ze bedzie to tablica jednowymiarowa... druga --- ...adresow (wskaznikow) */ double **t; /* ...i przydzielamy pamiec: */ t = malloc( N * sizeof( double * ) ); if ( t == NULL ) { /* Oraz sprawdzamy, czy zostala przydzielona */ printf("Nie moge przydzielic pamieci!\n"); goto koniec; } /* Teraz przydzielamy pamiec dla kazdego wiersza */ for ( i = 0; i < N; i++ ) { t[i] = malloc( M * sizeof( double ) ); if ( t[i] == NULL ) { /* i sprawdzamy czy zostala przydzielona */ printf("Nie moge przydzielic pamieci!\n"); goto koniec; } } /* Do elementow tablicy dobieramy sie normalnie: */ t[1][10] = 100.; dane(N, M, t); for ( i = 0; i < N; i++ ) { for ( j = 0; j < M; j++ ) printf("%.3f ", t[i][j]); printf("\n"); } return ( 0 ); koniec: return 1; } void dane(int N, int M, double **tablica) { /* * Tablica dwuwymiarowa w funkcji */ int i, j; for ( i = 0; i < N; i++ ) for ( j = 0; j < M; j++ ) tablica[i][j] = -1; } |