WYK ADY Z C, WYK AD4, /*funkcja przeszukująca tablicę*/


/*funkcja przeszukująca tablicę*/

#include<stdio.h>

#include<stdlib.h>

#define MAXKOL 8

/*makro wypelnia tablice o podanym rozmiarze liczbami losowymi z przedzialu okreslonymi parametrami wywolania oraz drukuje zawartosc tej tablicy*/

#define LOSUJ_TAB(t,n,a1,a2) \

{ \

int i; \

srand(a1+a2); \

for(i=0; i<=n-1; i++) \

{ \

do \

t[i]=rand(); \

while(t[i]<a1 || t[i]>a2); \

} \

printf(”\n Tablica ”); \

printf(#t); \

printf(”\n”); \

for (i=0; i<=n-1; i++) \

{ \

if (i % MAXKOL ==0 && i>1) \

printf(”\n”); \

printf(”%7d”,t[i]); \

} \

}

#define RA 28

#define RB 23

main()

{

int a[RA], b[RB], max;

int podaj_max( int t[],int n);

LOSUJ_TAB(a,RA,100,200);

max=podaj_max(a,RA);

printf(”\nWartosc maksymalna = %d\n”,max);

LOSUJ_TAB(b,RB,1000,2000);

max=podaj_max(b,RB);

printf(”\nWartosc maksymalna = %d\n”,max);

}

/* funkcja max*/

int podaj_max(int t[],int n)

{

int i, max;

max = t[0];

for (i=0; i<=n-1; i++)

if (t[i] > max)

max = t[i];

return (max);

}

Wynik:

Tablica a

134 140 176 125 107 187 156 137

149 165 111 128 195 100 147 159

174 131 181 188 197 104 194 182

123 110 158 180

Wartosc maksymalna = 197

Tablica b

1548 1127 1487 1449 1032 1753 1350 1725

1359 1984 1133 1499 1234 1716 1145 1192

1421 1751 1852 1736 1743 1840 1587

Wartosc maksymalna = 1984

/* modyfikacja tablicy przez funkcje*/

#include <stdio.h>

#include <math.h>

/* makro wypelnia tablice o podanym rozmiarze liczbami*/

#define WYP_TAB(t,n,fun,typ,xp,dx) \

{ \

int i; \

typ x; \

x = xp; \

for(i=0; i<=n-1; i++) \

{ \

t[i] =fun(x); \

x += dx; \

} \

}

#define MAXKOL 8

/*makro drukuje tablice t o rozmiarze n*/

#define DRUKUJ_TAB(t,n,fm) \

{ \

int i; \

printf(”\n Tablica ”); \

printf(#t); \

printf(”\n”); \

for (i=0; i<=n-1; i++) \

{ \

if (i % MAXKOL ==0 && i>1) \

printf(”\n”); \

printf(#fm,t[i]); \

} \

}

#define RA 28

#define RB 23

/* funkcja modyfikujaca tablice - elementy dodatnie zostaja zamienione na 1 pozostale na 0*/

void mod_tab (int t[], int n)

{

int i;

for (i=0; i<=n-1; i++)

if(t[i] > 0)

t[i] = 1;

else

t[i] = 0;

}

/* modul glowny*/

main()

{

int a[RA], b[RB];

WYP_TAB(a,RA,20*sin,double,0.,0.5);

DRUKUJ_TAB(a,RA,%7d);

printf(”\n------modyfikacja------\n”);

mod_tab(a,RA);

DRUKUJ_TAB(a,RA,%7d);

printf(”\n********************\n”);

WYP_TAB(b,RB,30*cos,double,1.,0.5);

DRUKUJ_TAB(b,RB,%7d);

printf(”\n------modyfikacja------\n”);

mod_tab(b,RB);

DRUKUJ_TAB(b,RB,%7d);

}

Wynik:

Tablica a

0 9 16 19 18 11 2 -7

-15 -19 -19 -14 -5 4 13 18

19 15 8 -1 -10 -17 -19 -17

-10 -1 8 16

------modyfikacja------

Tablica a

0 1 1 1 1 1 1 0

0 0 0 0 0 1 1 1

1 1 1 0 0 0 0 0

0 0 1 1

Tablica b

16 2 -12 -24 -29 -28 -19 -6

8 21 28 29 22 10 -4 -18

-27 -29 -25 -14 0 14 25

------modyfikacja------

Tablica b

1 1 0 0 0 0 0 0

1 1 1 1 1 1 0 0

0 0 0 0 0 1 1

/* Wskazniki*/

#include<stdio.h>

main()

{

int u =13, v, *pu, *pv;

pu=&u;

pv=&v;

v=*pu;

printf(”\n&u = %p &v = %p”, &u, &v);

printf(”\n&pu = %p &pv = %p”, &pu, &pv);

printf(”\npu = %p pv = %p”, pu, pv);

printf(”\n u = %-12d v = %d”, u, v);

}

Wynik:

&u = 1D74:0FD4 &v = 1D74:0FD6

&pu = 1D74:0FD8 &pv = 1D74:0FDC

pu = 1D74:0FD4 pv = 1D74:0FD6

u = 13 v = 13

#include<stdio.h>

main()

{

int u[] = {1,2,3,4,5,6,7,8,9,10,11,12,13};

printf(”\n u = %p &u[0] = %p”, u, &u[0]);

printf(”\n&u[1] = %p &u[2] = %p”, &u[1], &u[2]);

printf(”\n u[0] = %-12d u[8] = %d”, u[0], u[8]);

printf(”\n *u = %-12d *(u+8) = %d”, *u, *(u+8));

}

Wynik:

u = 1D78:0FC6 &u[0] = 1D78:0FC6

&u[1] = 1D78:0FC8 &u[2] = 1D78:0FCA

u[0] = 1 u[8] = 9

*u = 1 *(u+8) = 9

Deklarowanie wskaźników

typ danych * nazwa zmiennej wskaźnikowej

float u, v;

float *pv = &v;

z użyciem instrukcji przypisania : pv=&v;

Szczególnym przypadkiem wartości wskaźnika jest zero, czyli pusta wartość (wskazanie na nic). Zwyczajowo definiuje się dla takiej sytuacji stałą o nazwie NULL:

#define NULL 0

float u, v;

float *pv = NULL;

Przykładowe deklaracje wskaźników

Deklaracja

Komentarz

int *p

p jest wskaźnikiem do obiektu typu int

char *tab[8] tablica dla 8 wskaźników do obiektów typu char

char **tab deklaracja wskaźnika do wskaźnika

int (*p)[10] p jest wskaźnikiem do tablicy 10-elementowej

int *p(void) p jest bezparametrową funkcją zwracającą

wskaźnik do obiektu typu int

int (*p)(char *s) p jest wskaźnikiem do funkcji zwracającej

wartość typu int, której argumentem jest

wskaźnik do łańcucha znaków

int (*p[10])(int i); p jest 10-elementową tablicą wskaźników

do funkcji zwracających wartości całkowite,

których argumentami są również wartości

całkowite

int *(*p[10])(int *i); p jest 10-elementową tablicą wskaźników

do funkcji zwracających wskaźniki do obiektów

typu int, których argumentami są wskaźniki

również do obiektów typu int.

Wskaźnik i funkcje

# include<stdio.h>

main()

{

int x =13, y = 33;

void zeruj1(int u, int v);

void zeruj2(int *pu, int *pv);

printf(”\n Przed wywolaniem zeruj1: x =%d y = %d”, x, y);

zeruj1(x, y);

printf(”\n Po wywolaniu zeruj1: x =%d y = %d”, x, y);

zeruj2(&x, &y);

printf(”\n Po wywolaniu zeruj2: x =%d y = %d”, x, y);

}

void zeruj1(int u, int v)

{

u = 0;

v = 0;

}

void zeruj2(int *pu, int *pv)

{

*pu = 0;

*pv = 0;

}

Wynik:

Przed wywolaniem zeruj1: x = 13 y = 33

Po wywolaniu zeruj1: x = 13 y = 33

Po wywolaniu zeruj2: x = 0 y = 0

#include<stdio.h>

#include<ctype.h>

main()

{

char linia[80];

int litery =0; /*liczba liter w linii */

int cyfry = 0; /*liczba cyfr w linii */

int odstepy = 0; /*liczba znakow odstepu */

int inne = 0; /*inne znaki */

int suma; /*calkowita liczba znakow */

int analiza(char linia[], int *l, int *c, int *o, int *i);

printf(”\nPodaj linie tekstu:\n”);

scanf(”%[^\n]”,linia);

suma = analiza(linia, &litery, &cyfry, &odstepy, &inne);

printf(”\n----------Raport----------”);

printf(”\n Liczba znaków = %2d, w tym:”, suma);

printf(”\n Liczba liter = %2d”, litery);

printf(”\n Liczba cyfr = %2d”, cyfry);

printf(”\n Liczba odstepow = %2d”, odstepy);

printf(”\n Liczba innych = %2d”, inne);

}

int analiza(char linia[], int *l, int *c, int *o, int *i)

{

char znak;

int j = 0;

while((znak=toupper(linia[j]))!='\0')

{

if(znak >= 'A' && znak <='Z')

++*l;

else if(znak >='0' && znak <= '9')

++ *c;

else if(znak == ' ' || znak == '\t')

++ *o;

else

++ *i;

++j;

}

return(j);

}

Wynik:

Podaj linie tekstu:

”Moj program do zastosowania wskaznikow.”

----------Raport----------

Liczba znakow = 41, w tym:

Liczba liter = 34

Liczba cyfr = 0

Liczba odstepow = 4

Liczba innych = 3

Wybór funkcji przez wskaźnik:

#include<stdio.h>

main() /*wybor funkcji przez indeks*/

{

void proces1(void);

void proces2(void);

void proces3(void);

void (*wybor[3])(void) = {proces1, proces2, proces3};

int i=0, j=1, k=2;

wybor[i]();

wybor[k]();

wybor[j]();

wybor[0]();

}

void proces1(void)

{

printf(“\n111111111111111111111111”);

}

void proces2(void)

{

printf(“\n2 2 2 2 2 2 2 2 2 2 2 2 ”);

}

void proces3(void)

{

printf(“\n3 3 3 3 3 3 3 3”);

}

Wynik:

111111111111111111111111

3 3 3 3 3 3 3 3

2 2 2 2 2 2 2 2 2 2 2 2

111111111111111111111111

W powyższym programie zadeklarowano tablicę wskaźników do bliźniaczych funkcji oraz dokonano wywołań tych funkcji w oparciu o numer indeksu.

Argumentem funkcji - wskaźnik do innej funkcji

#include<stdio.h>

#include<math.h>

main()

{

double spc(double x);

double funkcja2(double x, double (*fun)(double x));

double y, x=1.12345;

y=funkcja2(x,sin);

printf(”\nx = %f, sin(x) = %f, 2 * sin(x) = %f”,x, sin(x), y);

y=funkcja2(x,cos);

printf(”\nx = %f, cos(x) = %f, 2 * cos(x) = %f”,x, cos(x), y);

y=funkcja2(x,tan);

printf(”\nx = %f, tan(x) = %f, 2 * tan(x) = %f”,x, tan(x), y);

y=funkcja2(x,spc);

printf(”\nx = %f, spc(x) = %f, 2 * spc(x) = %f”,x, spc(x), y);

}

double spc(double x)

{

return (sin(x) + cos(x));

}

double funkcja2(double x, double (*fun)(double(x))

{

return (2 * fun(x));

}

Wynik:

x = 1.123450, sin(x) = 0.901598, 2 * sin(x) = 1.803196

x = 1.123450, cos(x) = 0.432575, 2 * cos(x) = 0.865149

x = 1.123450, tan(x) = 2.084261, 2 * tan(x) = 4.168522

x = 1.123450, spc(x) = 1.334173, 2 * spc(x) = 2.668345

Funkcja funkcja2 podwaja wartość obliczoną przez inną funkcję dostępną przez wskaźnik.

/* rownowaznosc zapisow dostepu do elementow tablicy 1- wymiarowej przez indeks i przez wskaznik*/

#include<stdio.h>

main()

{

int i, x[10] = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109};

for (i=0; i<=9; i++)

printf(”\ni=%d x[i]=%d *(x+i)=%d &x[i]=%p x+i=%p”,

i, x[i], *(x+i), &x[i], x+i );

}

Wynik:

i=0 x[i]=100 *(x+i)=100 &x[i]=1D73:0FCC x+i= 1D73:0FCC

i=1 x[i]=101 *(x+i)=101 &x[i]=1D73:0FCE x+i= 1D73:0FCE

i=2 x[i]=102 *(x+i)=102 &x[i]=1D73:0FD0 x+i= 1D73:0FD0

i=3 x[i]=103 *(x+i)=103 &x[i]=1D73:0FD2 x+i= 1D73:0FD2

i=4 x[i]=104 *(x+i)=104 &x[i]=1D73:0FD4 x+i= 1D73:0FD4

i=5 x[i]=105 *(x+i)=105 &x[i]=1D73:0FD6 x+i= 1D73:0FD6

i=6 x[i]=106 *(x+i)=106 &x[i]=1D73:0FD8 x+i= 1D73:0FD8

i=7 x[i]=107 *(x+i)=107 &x[i]=1D73:0FDA x+i= 1D73:0FDA

i=8 x[i]=108 *(x+i)=108 &x[i]=1D73:0FDC x+i= 1D73:0FDC

i=9 x[i]=109 *(x+i)=109 &x[i]=1D73:0FDE x+i= 1D73:0FDE

/*dla tablicy 2-wymiarowej */

int i, x[10][20];

i = x[5][8];

i = *(x[5] + 8);

i = *(*(x +5) +8);

Równoważne deklaracje tablic:

  1. Tablica 1-wymiarowa 10-elementowa typu int:

int *x; int x[10]; #define MAX 10 int x[MAX];

x = (int*)malloc(10 * sizeof(int));

lub

x=(int*)calloc(10, sizeof(int));

Funkcje z modułu alloc.h

void *malloc(size_t n) - zwraca wskaźnik do n bajtów niezainicjowanej

pamięci lub NULL

void *calloc(size_t n, size_t size) - zwraca wskaźnik do obszar mogące-

go pomieścić tablicę n elementów

podanego rozmiaru size

void *realloc(void *ptr, size_t size) - zmienia rozmiar bloku wskazane-

go przez ptr na size

void free(void *ptr); - zwalnia obszar pamięci wskazywany przez ptr,

ptr powinien być wartością zwróconą wcześniej

przez funkcje: calloc, malloc lub realloc.

  1. Tablica 2-wymiarowa 10 razy 20 elementów typu int:

int (*x)[20]; int x[10][20];

  1. Tablica n-wymiarowa, ogólny zapis deklaracji:

typ danych (*wskaźnik_tab) [wyrażenie2]...[wyrażenie N];

zamiast

typ danych nazwa_tab[wyrażenie1]...[wyrażenieN];

#include<stdio.h>

#include<alloc.h>

#define WIER 10

#define KOL 20

#define WYP_TAB(t,maxw,maxk,op) \

{ \

int w, k; \

for (w=0; w<=maxw-1; w++) \

for (k=0; k<=maxk-1; k++) \

*(*(*t+w)+k) = w op k; \

}

main()

{

int (*a)[WIER][KOL], (*b)[2*WIER][3*KOL];

/*przydzielenie pamieci dla tablic */

a = (int*)malloc(WIER * KOL * sizeof(int));

b = (int*)malloc(2 * WIER * 3 * KOL * sizeof(int));

/*wypelnienie tablic liczbami */

WYP_TAB(a, WIER, KOL, +);

WYP_TAB(b, 2*WIER, 3*KOL, *);

/*wyrywkowa kontrola */

printf(”\n a[0][0] = %4d /ma być 0/”,*(*(*a ) ));

printf(”\n a[5][5] = %4d /ma być 10/”,*(*(*a+5)+5));

printf(”\n a[9][8] = %4d /ma być 17/”,*(*(*a+9)+8));

printf(”\n b[0][0] = %4d /ma być 0/”,***b );

printf(”\n b[5][5] = %4d /ma być 25/”,*(*(*b+5)+5));

printf(”\n b[9][8] = %4d /ma być 72/”,*(*(*b+9)+8));

/*zwolnienie pamieci */

free(a);

free(b);

}

Wynik:

a[0][0] = 0 /ma być 0/

a[5][5] = 10 /ma być 10/

a[9][8] = 17 /ma być 17/

b[0][0] = 0 /ma być 0/

b[5][5] = 25 /ma być 25/

b[9][8] = 72 /ma być 72/

/*Wygenerowanie tablicy trójkątnej*/

#include<stdio.h>

#include<alloc.h>

#define WIER 8

main()

{

int *x[WIER]; /*1-wymiarowa tablica wskaźników*/

int w,k; /*indeksy: wiersz, kolumna*/

/*przydzielenie pamieci dla tablicy trojkatnej */

/*liczba elementow w wierszu = numer wiersza +1*/

for(w=0;w<=WIER -1;w++)

x[w]=(int*)malloc((w + 1)*sizeof(int));

/*wypelnienie tablicy liczbami*/

for(w=0;w<=WIER -1 ;w++)

for(k=0;k<=w;k++)

*(x[w] + k) = 100 + w + k;

/*wydruk tablicy*/

for(w=0;w<=WIER -1 ;w++)

{

printf(”\n”);

for(k=0;k<=w;k++)

printf(”%7d”,*(x[w] + k));

}

}

Wynik:

100

101 102

102 103 104

103 104 105 106

104 105 106 107 108

105 106 107 108 109 110

106 107 108 109 110 111 112

107 108 109 110 111 112 113 114

Program operujący na tablicy wskaźników do łańcuchów znaków (tj. linii tekstu o różnych długościach). Program umożliwia wprowadzenie j linii tekstu, a następnie wyprowadza je w porządku alfabetycznym.

#include<stdio.h>

#include<alloc.h>

#include<string.h>

#define WIER 4000

#define MAXL 80

main()

{

void sortuj_tab(char *a[], int max);

char *x[WIER]; /*tablica wskaźników do linii tekstu */

char s[MAXL]; /*linia wprowadzana z klawiatury */

char koniec = `#'; /*znak konca wprowadzania */

int i = 0; /*indeks: numer linii tekstu */

int j = 0; /*liczba wprowadzonych linii */

/*Wprowadzenie linii tekstu*/

printf(”\nPodaj linie tekstu do posortowania alfabetycznego”);

printf(”\nMaksymalna liczba linii wynosi : %4d”, WIER);

printf(”\nMaksymalna liczba znakow w linii : %4d”, MAXL);

printf(”\nZnak konca wprowadzenia : %c”, koniec);

printf(”\n---------------------------------------------\n”);

while(i<=WIER-1)

{

printf(”> ”); /*znak zachety*/

gets(s);

if (*s == koniec)

{

x[i] = NULL;

break;

}

else

{

x[i] = (char*)malloc(strlen(s) +1); /*rezerwacja pamieci*/

strcpy(x[i], s); /*skopiowanie linii s w miejsce x[i]*/

j++;

}

++i;

}

printf(”\n---------------------------------------------\n”);

/*Sortowanie w porzadku alfabetycznym */

sortuj_tab(x, j);

/*Wyprowadzenie posortowanych linii */

printf(”\n---------------------------------------------\n”);

i=0;

while(i<=WIER - 1)

{

if(x[i] == NULL)

break;

else

printf(”\n %s”, x[i]);

++i;

}

printf(”\n---------------------------------------------\n”);

}

void sortuj_tab(char *a[], int max)

{

int i, j;

char *s;

for(i=0; i<=max-2; i++)

for(j=i+1; j<=max-1; j++)

if(strcmp(a[i], a[j]) > 0)

{

s = a[i];

a[i] = a[j];

a[j] = s;

}

}

Operacje na wskaźnikach:

  1. Jeżeli dana jest deklaracja np. int a[10]; to do i-tego elementu tablicy możemy się odwołać dwojako: y=a[i]; lub y=*(a+i);

  2. Jeśli jest dana deklaracja np. int b[9][9]; to do elementu (i,j) w tablicy możemy odwołać się trojako: y=b[i][j]; lub y=*(b[i]+j); lub y=*(*(b+i)+j);

  3. Jeżeli p jest wskaźnikiem zadeklarowanym jako int *p; to przypisanie p=&a[0]; ustawia p na początek tablicy a. Jeżeli zapiszemy x=*p; będzie to równoważne zapisowi x=a[0];

  4. Jeżeli p wskazuje na pewien element tablicy a, to z definicji p+1 wskazuje na element następny, a p-1 na element poprzedni;

  5. Zapis p+i oznacza adres, natomiast *(p+i) zawartość pod wskazanym adresem;

  6. Jeżeli mamy zapis p+1(dodaj 1 do wskaźnika), to z definicji znaczy to, że (bez względu na typ obiektu) wskazanie dotyczyć będzie obiektu następnego. /Przyrost skalowany jest przez rozmiar pamięci zajmowanej przez wskazany obiekt/. p++ wskazuje na następny obiekt, a p-- na poprzedni obiekt;

  7. Ponieważ nazwa tablicy reprezentuje położenie jej zerowego elementu, przypisanie p=&a[0]; może być zastąpione prostszym zapisem: p=a;

  8. W definicji parametrów formalnych funkcji równoważne są zapisy: char s[]; oraz char *s;

  9. Równoważna jest również deklaracja tablicy: char *t[10]; oraz char **t;

  10. Zapis **p jest równoważny *(*p) i oznacza wskazanie pośrednie (wskaźnik do wskaźnika). Zapis ***p jest równoważny *(*(*p)) i jest wskaźnikiem do wskaźnika do wskaźnika ...

  11. Równoważne są również następujące zapisy: *p+=1; oraz (*p)++; W postaci drugiej zapisu nawiasy są niezbędne, gdyż chodzi o zwiększenie o jeden zawartości wskazywanego obiektu, a nie wskaźnika;

  12. Na wskaźnikach mogą być wykonywane następujące operacje:



Wyszukiwarka

Podobne podstrony:
WYK ADY Z C, WYK AD3, /* funkcje*/
wyk ad4 Mikro
10 WYK X Regulacja funkcji genów u bakterii1id 10654 ppt
ZS wyk éad4
10 WYK X Regulacja funkcji genów u?kterii1
Wyk ad 2 Funkcje 19 luty bez obrazkow
wyk ad4 Mikro
MBRT wyk ad4 wydruk
Komunikologia wyk ad4 2010 Symbole kolektywne
IwZP30 00Y Funkcje i formuły tablicowe, WSE notatki
przeszukiwanie tablicy n elementow dziel i zwyciezaj
funkcje cd tablice znaków operacje lancuchowe
WYK ADY Z C, WYK AD5, /*Wygenerowanie tablicy trójkątnej*/
wyk ady z etyki 1 5 internet
ZPKB wyk ady AK
fizjo - wyk+éady, Leśnictwo UP POZNAŃ 2013, Fizjologia roślin drzewiastych
DI Wyk ady (prof K Marcinek) [2006 2007]
Techniki wytwarzania-drewno, Ukw, II Lic, Drewno, Wyk�?ady

więcej podobnych podstron