Język ANSI C tablice wielowymiarowe Gdy tablica wielowymiarowa jest parametrem funkcji, to w standardzie ANSI C konieczne jest podanie wszystkich wymiarów poza pierwszym. Przykład. Napisać program wczytujący i drukujący dwie tablice o wymiarze 3x3. #include <stdio.h> void wczyt2d( int x[ ][3], int n) int i,j,k; for (i=0; i<n;i++) for (j=0;j<3;j++) do return; printf ("\n Podaj element [%d][%d]=",i, j); k=scanf("%d", &x[i][j]); fflush(stdin); while (k==0);
Przykład c.d. Język ANSI C tablice wielowymiarowe void druk2d( int x[ ][3], int n) int i,j; for (i=0; i<n;i++) for (j=0;j<3;j++) printf ("element [%d][%d]=%d",i, j, x[i][j]); printf("\n"); return; int main() int a[3][3], b[3][3]; wczyt2d(a,3); wczyt2d(b,3); druk2d(a,3); druk2d(b,3); system("pause"); return 0;
Język ANSI C tablice wielowymiarowe void kopiuj2d(int x[ ][3],int y[][3],int n); void druk2d( int x[ ][3], int n); int main() int b[3][3]= 2,1,1, 3,4,2, 2,3,4; int a[3][3]; kopiuj2d( a,b,3); druk2d(a,3); system("pause"); void kopiuj2d( int x[ ][3],int y[ ][3], int n) int i,j,k; for (i=0; i<n;i++) for (j=0;j<3;j++) x[i][j]=y[i][j]; return;
Język ANSI C tablice wielowymiarowe void druk2d( int x[ ][3], int n) int i,j; for (i=0; i<n;i++) for (j=0;j<3;j++) printf ("element [%d][%d]=%d ",i, j, x[i][j]); printf("\n"); return;
Język ANSI C tablice wielowymiarowe Przykład. Przepisywanie tablicy dwuwymiarowej do tablicy jednowymiarowej. void kopiuj1d_2d( int b[ ][2],int n1, int d[ ]); #include <stdio.h> int main () int tab2d[2][2]= 1,2,2,3; int tab1d[4]; int i; kopiuj1d_2d(tab2d, 2, tab1d); for (i=0;i<4; i++) printf(" %d ", tab1d[i]); system("pause"); void kopiuj1d_2d( int b[ ][2],int n1, int d[ ]) int i,j,k=0; for (i=0;i<n1;i++) for (j=0;j<2;j++) d[k++]=b[i][j];
Język ANSI C tablice wielowymiarowe Przykład. Mnożenie macierzy. #include <stdio.h> #define M 3 void mnoz_mac( int a[ ][M],int b[][m], int c[ ][M], int n) int i,j,k,s; for (i=0;i<n;i++) for (k=0;k<n;k++) s=0; for (j=0;j<n;j++) s=s+a[i][j]* b[j][k]; c[i][k]=s; int main () int u[m][m]= 1,2,1,1,1,1, 2,1,1; int v[m][m]= 2,1,0,1,2,0, 3,2,1; int z[3][3],i,j; mnoz_mac( u,v,z,m); for (i=0; i<m;i++) for (j=0;j<m;j++) printf ("z[%d][%d]=%d ",i, j, z[i][j]); printf("\n"); system("pause");
Język ANSI C tablice wielowymiarowe Wyniki działania programu mnożenia macierzy z[0][0]=7 z[0][1]=7 z[0][2]=1 z[1][0]=6 z[1][1]=5 z[1][2]=1 z[2][0]=8 z[2][1]=6 z[2][2]=1
Język ANSI C tablice wielowymiarowe Przekazywanie tablic w standardzie C99 Standard języka C wprowadzony w roku 1999 (C99) wprowadził istotne zmiany w stosunku do ANSI C. Nie jest on w pełni realizowany przez dostępne kompilatory, istotna część zmian wprowadzonych przez ten standard jest jednak uwzględniona w kompilatorze GNU C, który stanowi podstawę DevC++. Jedna z najbardziej istotnych zmian pojawia się przy przekazywaniu tablic wielowymiarowych do funkcji, gdzie wszystkie rozmiary przekazywanej tablicy mogą być zmiennymi, a nie stałymi ( poza pierwszym rozmiarem), jak to ma miejsce w ANSI C. W C99 rozmiar tablicy w funkcji może być zwykłą zmienną lokalną lub parametrem funkcji ( są to tzw. variable-length arrays).
Język ANSI C tablice wielowymiarowe Przekazywanie tablic w standardzie C99 Przykład. Wczytywanie i drukowanie tablic w standardzie C99(cz.1). #include <stdio.h> void wczyt2dc99( int n, int m, int x[n][m]) // ilosc kolumn nie musi być stałą, może być podana jako parametr int i,j; for (i=0;i<n;i++) for (j=0;j<m;j++) printf("\n Element [%d][%d]=",i,j); scanf("%d",&x[i][j]);
Język ANSI C tablice wielowymiarowe Przekazywanie tablic w standardzie C99 Przykład. Wczytywanie i drukowanie tablic w standardzie C99.(cz.2) void druk2dc99( int n, int m, int x[n][m]) int i,j; for (i=0;i<n;i++) for (j=0;j<m;j++) printf(" %d", x[i][j]); printf("\n");
Język ANSI C tablice wielowymiarowe Przekazywanie tablic w standardzie C99 Przykład. Wczytywanie i drukowanie tablic w standardzie C99.(cz.3) int main() int a[2][2], b[3][3]; wczyt2dc99(2,2,a); wczyt2dc99(3,3,b); druk2dc99( 2,2,a); druk2dc99( 3,3,b); system("pause"); return 0; // Tablice przekazywane do funkcji mają różne rozmiary // ilość kolumn nie musi być taka sama
Wyniki działania programu Element [0][0]=1 Element [0][1]=2 Element [1][0]=3 Element [1][1]=4 1 2 3 4 Element [0][0]=1 Element [0][1]=2 Element [0][2]=3 Element [1][0]=4 Element [1][1]=5 Element [1][2]=6 Element [2][0]=7 Element [2][1]=8 Element [2][2]=9 c.d. 1 2 3 4 5 6 7 8 9
Język ANSI C i C++ dynamiczna alokacja pamięci cz. I W językach C i C++ istnieją zasadniczo dwa rodzaje zmiennych: - zmienne zwykłe definiowane w funkcji main() lub na zewnątrz wszystkich funkcji lub w pewnym bloku. Każda zmienna tego rodzaju posiada swoją nazwę oraz określony typ. - zmienne dynamiczne tworzone i usuwane w trakcie działania programu; taki sposób przydzielania pamięci zwany jest alokacją w trakcie działania programu (ang. run-time allocation). Zmienne te nie posiadają nazw, znane są wyłącznie adresy przydzielonej im pamięci ( wskaźniki do tej pamięci). Do przydzielania pamięci zmiennym dynamicznym służą w ANSI C funkcje malloc i calloc. Do usuwania zmiennych dynamicznych stosuje się funkcję free.
Język ANSI C dynamiczna alokacja pamięci Funkcje malloc i calloc (stdlib.h) Każda z tych funkcji alokuje przydziela pamięć i zwraca adres tej pamięci (wskaźnik do tej pamięci). Rozmiar przydzielanej pamięci nie musi być znany podczas kompilacji. Funkcja malloc Nagłówek funkcji tej ma postać następującą: void * malloc (int); Funkcja malloc oczekuje, jako swojego argumentu, liczby bajtów, które mają być przydzielone w danym wywołaniu funkcji. Jeżeli przydzielenie pamięci jest możliwe, funkcja zwraca wskaźnik do tej pamięci, jeśli nie, funkcja zwraca NULL (zerowy wskaźnik). Zwracany wskaźnik jest typu void*, czyli jest to wskaźnik do void.
Język ANSI C dynamiczna alokacja pamięci Wskaźnik ten musi być przekształcony (przez rzutowanie) na wskaźnik do żądanego typu. Język C gwarantuje, że wskaźnik do void może być przekształcony na wskaźnik do każdego innego typu.
Język ANSI C dynamiczna alokacja pamięci Przykład. Zastosowanie funkcji malloc do alokacji pamięci dla zmiennej dynamicznej typu int. #include <stdio.h> #include<stdlib.h> int main() int *ptr; ptr=(int*) malloc( sizeof(int)); if (ptr= = NULL) printf( \n Przydzielenie pamięci nie było możliwe ); system("pause");return 1; printf(" Podaj wartosc :"); scanf("%d", ptr); printf("\n Wartosc to :", *ptr); free(ptr); system("pause"); return 0;
Język ANSI C dynamiczna alokacja pamięci Funkcja calloc Nagłówek funkcji tej ma postać następującą: void * calloc (int,int); Funkcja calloc oczekuje dwóch argumentów typu int. Pierwszy argument oznacza liczbę bloków pamięci, które mają zostać przydzielone, a drugi rozmiar pojedynczego bloku. Funkcja zwraca wskaźnik do pierwszego bloku. Wskaźnik ten jest typu void* i musi być rzutowany na wskaźnik do wymaganego typu.
#include <stdio.h> int main() int *ptr,i; Język ANSI C dynamiczna alokacja pamięci Przykład. Zastosowanie funkcji calloc do alokacji pamięci dla tablicy liczb typu int. ptr=(int *)calloc(5, sizeof(int)); for (i=0;i<5;i++) printf("\n Podaj element %d", i); scanf("%d", ptr++); ptr=ptr-5;//cofnięcie wskaźnika na początek tablicy for (i=0;i<5;i++) printf("\n Element [%d]=%d", *ptr++); ptr=ptr-5; free(ptr); system("pause"); return 0;
Język ANSI C dynamiczna alokacja pamięci Przykład. Dynamiczna alokacja tablicy z użyciem funkcji zwracającej wskaźnik. #include <stdio.h> #include <stdlib.h> int* wczyttab(int n); int main(int argc, char **argv) int *pa,i,n=5; pa=wczyttab(5); for (i=0;i<n;i++) printf("\n Element[%d]=%d",i, *pa++); pa=pa-5; free(pa); system("pause");
Język ANSI C dynamiczna alokacja pamięci Przykład cz. II ( ciąg dalszy programu) ( definicja funkcji zwracającej wskaźnik do wczytanej tablicy) int* wczyttab(int n) int i,*px; px=(int*) malloc(n*sizeof(int)); for (i=0;i<n;i++) printf("\n Podaj element[%d]=",i); scanf("%d",px++); px=px-n;// wskaźnik jest cofany o n elementów do tyłu, // tak aby wskazywał na początek obszaru pamięci // alokowanego dla tablicy return px; // wskaźnik jest zwracany (wysyłany do funkcji // która wywołała funkcję wczyttab, w tym przypadku // do funkcji main()
Język ANSI C dynamiczna alokacja pamięci Przykład. Program wczytujący tablicę dwuwymiarową przy użyciu wskaźnika, do funkcji przekazywany jest wskaźnik do pierwszego elementu tablicy dwuwymiarowej. #include <stdio.h> #include <stdlib.h> //Do funkcji przekazywany jest wskaźnik do pierwszego elementu //tablicy dwuwymiarowej oraz liczba wierszy i liczba kolumn. void wczyt(int *px, int w, int k) int i,j; for (i=0;i<w;i++) for (j=0;j<k;j++) printf("\n Podaj element [%d][%d]=",i,j); scanf("%d",px++);
Język ANSI C dynamiczna alokacja pamięci Przykład c.d. zastosowanie funkcji wczyt do wczytania tablicy dwuwymiarowej 3x3. int main() int x[3][3]; int *px; int i,j; system("cls"); px=&x[0][0]; wczyt(px,3,3); for (i=0;i<3;i++) for (j=0;j<3;j++) printf("\n element [%d][%d]=%d",i,j, x[i][j]); system("pause"); return 0;
Język ANSI C dynamiczna alokacja pamięci Przykład. Funkcja wczytd alokuje pamięć dla tablicy dwuwymiarowej o zadanej liczbie kolumn i zadanej liczbie wierszy, wczytuje tablicę i zwraca wskaźnik do jej pierwszego elementu. int *wczytd(int w, int k) int *px; int i,j; px=(int*)calloc(w*k,sizeof(int)); for (i=0;i<w;i++) for (j=0;j<k;j++) printf("\n Podaj element [%d][%d]=",i,j); scanf("%d",px++); px=px-w*k; return px;
Język ANSI C dynamiczna alokacja pamięci Przykład c.d. zastosowanie funkcji wczytd do wczytania tablicy dwuwymiarowej 3x3. int main() int *py,i,j; py=wczytd(3,3); for (i=0;i<3;i++) for (j=0;j<3;j++) printf("\n element [%d][%d]=%d",i,j,*py++); py=py-9; free(py); system("pause"); return 0;