ProgramareProcedurala2013-M7
-
Upload
ana-maria-bucur -
Category
Documents
-
view
219 -
download
0
Transcript of ProgramareProcedurala2013-M7
-
7/25/2019 ProgramareProcedurala2013-M7
1/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 1
Programare procedurala M7
Tehnici de programare C (P2)
Grigore ALBEANU
http://www.researcherid.com/rid/H-4522-2011
-
7/25/2019 ProgramareProcedurala2013-M7
2/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 2
Agenda
Pointeri. Elemente de baza(Recapitulare)
Pointeri la functii. Aplicatii
Macrodefinitii (Recapitulare)
Programare generica
-
7/25/2019 ProgramareProcedurala2013-M7
3/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 3
Pointeri - > elemente de baza
#include
int EqualStruct (void *, void *, long); int EqualStruct (void *rec1, void *rec2, long lung){
unsigned char *ptr1; unsigned char *ptr2; register long ctr;
for (
ptr1 = (unsigned char *)rec1, ptr2 = (unsigned char *)rec2, ctr = lung / sizeof(unsignedchar);
ctr; --ctr)
if (*ptr1++ != *ptr2++) return 0;
return1;
}
typedef struct { char a; int b;} MyStruct;
int main(void){
MyStruct s1, s2; *(int*)(&s1) = 0x55555561; s1.b = 42;
*(int*)(&s2) = 0x55555561; s2.b = 42;
printf("%d", EqualStruct((MyStruct *)(&s1), (MyStruct *)(&s2), sizeof(MyStruct)));
}
Modificati continutul
locatiilor. Afisati
adresele. Schimbati
ordinea variabilelor
-
7/25/2019 ProgramareProcedurala2013-M7
4/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 4
Pointeri la functii
Functii ca argumenteale altor functii
Functii callback (inprogramarea orientatape evenimente /comenzi)
Prea multe stele(stars)?
int *(*f)(int *); /*
comentariu */ int *g(int *x){static int
a=1; a+=*x; return &a;}
f=g
#include
int *g(int *x){static int a=1; a+=*x;printf("%d\n", a); return &a;}
int main(void){
int zz = 5, i, n=5;
int *(*f)(int *)=NULL;f=g;
int *aa;
printf("%x\n", aa=f(&zz));
for (i=1; i
-
7/25/2019 ProgramareProcedurala2013-M7
5/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 5
Functii ca argumente ale altor functii(call back)
#include int int_sort( const void *a, const void *b ){
int xa = *(int*)a; int xb = *(int*)b;
if (xa < xb) return -1; else if (xa == xb) return 0; else return 1;
}
int main(void){int X[10]; int i;
for ( i = 0; i < 10; ++i ) X[ i ] = 10 - i;
qsort(X, 10 , sizeof(int), int_sort);
for (i = 0; i < 10; ++i) printf ( "%d\n" ,X[ i ] );return 0;
}Functiile se transmit prin pointeri, nu prin
valoare
http://www.cprogramming.com/tutorial/function-pointers.html
Lui qsort nu-I pasa de codul
functiei (aici int_sort).
Se spune ca este un apel call
back.
-
7/25/2019 ProgramareProcedurala2013-M7
6/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 6
Functii ca argumente ale altor functii(moduri de abordare)
float ADD(float a, float b) { return a+b; }float SUB(float a, float b) { return a-b; }
float MUL(float a, float b) { return a*b; }
float DIV (float a, float b) { return a/b; }void OP(float a, float b, float (*ptF)(float,
float)){float rez = ptF(a, b); printf(%f, rez);}
Utilizare: OP(3.14, 2.71, &ADD); OP(3.14,2.71, SUB); /* cu &, fara & : comentariu*/
-
7/25/2019 ProgramareProcedurala2013-M7
7/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 7
Alte aspecte Compararea pointerilor
la functiiif(ptF>0){
if(ptF == &DIV)printf(Apel adresat lui DIV\n"); }
else
printf("Pointer ne initializat!!\n");
Intoarcerea unui pointer lao functie
Metoda 1: Direct
float (*GetOP(const char opCode))
(float, float){
switch(opCode){
case +: return &ADD;
case -: return &SUB;case *: return &MUL;
case /: return %DIV;
default: return NULL;
}
Metoda 2: Utilizare typedef
typedef float(*ptF)(float, float);
ptF GetOP(const char opCode){
switch(opCode){
case +: return &ADD;
case -: return &SUB;
case *: return &MUL;
case /: return %DIV;
default: return NULL;
}
Decodificati: http://unixwiz.net/techtips/reading-cdecl.html
-
7/25/2019 ProgramareProcedurala2013-M7
8/20
-
7/25/2019 ProgramareProcedurala2013-M7
9/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 9
Dispatch tables acces la
componentele unui tablou director
struct entry{ char *command; int (*func)(int, int);};
struct entry table[] = { {"add", &add}, {"subtract", &subtract} };
int (*getDispatchPtr(char *comm))(int, int) {
int i;
for(i = 0; i < 2; i++) {
if (strcmp(table[i].command, comm) == 0) return table[i].func;}return 0;
}
/* Utilizare:*/
ptF pt = NULL;
.pt = getDispatchPtr("subtract");
.
int rez = (*pt)(100, 20);
http://www.cise.ufl.edu/class/cop4600su10/discussion/disc4/2.html
In computer science, a dispatch table is a table of pointers to
functions or methods. Use of such a table is
a common technique when implementing late binding
in object-oriented programming.
-
7/25/2019 ProgramareProcedurala2013-M7
10/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 10
Bibliografie suplimentara (1)
http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557/Callback-Functions-Tutorial.htm
http://stackoverflow.com/questions/142789/what-is-a-callback-in-c-and-how-are-they-
implemented/147241#147241 http://ocw.mit.edu/courses/electrical-engineering-
and-computer-science/6-087-practical-programming-in-c-january-iap-2010/lecture-
notes/MIT6_087IAP10_lec08.pdf http://www.compileonline.com/compile_c_online.php
-
7/25/2019 ProgramareProcedurala2013-M7
11/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 11
Macrodefinitii operatorul #
#define
#define nume subst
#define BUFFER_SIZE 1024
#define nume(parametri) subst
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
Parametrii nu sunt substituiti in siruri de caractere cu exceptia situatieiin care este prezent # (op = stringification)
Fie codul
#define Avertizare_daca(EXP) \
do { if (EXP) fprintf (stderr, Atentie: " #EXP "\n"); } while (0)
Utilizare:
Avertizare_daca(x == 0);/* adica: do { if (x == 0) fprintf (stderr, Atentie: " "x == 0" "\n"); } while (0); */
-
7/25/2019 ProgramareProcedurala2013-M7
12/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 12
Macrodefinitii operatorul ##
#include
#define Avertizare_daca(EXP) \
do { if (EXP) fprintf (stderr, "Atentie: " #EXP "\n"); } while (0)
#define COMMAND(NAME) { #NAME, NAME ## _command }
void quit_command(void){};
void help_command(void){};
struct command{
char *name;
void (*function) (void);
};
struct command commands[] ={
COMMAND (quit),
COMMAND (help),
};
int main(void){int x=0;
Avertizare_daca(x==0);
/* puts(commands[0].name); puts(commands[1].name); */
return 0;
}
#include
#define Avertizare_daca(EXP) \
do { if (EXP) fprintf (stdout, "Atentie: " #EXP
"\n"); } while (0)
#define COMMAND(NAME) { #NAME, NAME ##
_command }
struct command{
char *name;
void (*function) (void);
};void quit_command(void){};
void help_command(void){};
int main(void){
int x=0;
struct command commands[] ={
COMMAND (quit),
COMMAND (help),};
puts(commands[1].name);
Avertizare_daca(x==0);
puts(commands[0].name);
return 0;
}Stderr, stdout ! Atentie !
-
7/25/2019 ProgramareProcedurala2013-M7
13/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 13
Programare generica
Utilizarea pointerilor (void *) Utilizarea macrodefinitiilor
Proiectul SGLIB (Templates in C++: STL)
(Generics/Colections in Java/C++)
-
7/25/2019 ProgramareProcedurala2013-M7
14/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 14
Utilizarea pointerilor void *#include
#include
int main(){
int a[]={3,6,4,1,8},t=4,k;(k=cauta(a, sizeof(a)/sizeof(int), sizeof(int),&t)) ==-1?
printf("\nElement inexistent!!!") :
printf("\nElementul pe pozitia %d",k);
double b[]={3.5,6.2,4.9,28.15},el_r=6.2;
(k=cauta(b, sizeof(b)/sizeof(double), sizeof(double),
&el_r)) ==-1?printf("\nElement inexistent!!!") :
printf("\nElementul pe pozitia %d",k);
char *sir="Sir de caractere!!!", el_c='i';
(k=cauta(sir, strlen(sir), sizeof(char), &el_c)) ==-1?
printf("\nElement inexistent!!!") :printf("\nElementul pe pozitia %d",k);
}
#include
int cauta(void *v, int n, int dim_el,void *el){
char *ec=(char*)v;
for(int i=0; i
-
7/25/2019 ProgramareProcedurala2013-M7
15/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 15
Utilizarea Macrodefinitiilor (1)
/* Definitie Generica operator de concatenare */
#define GENERIC_MAX( TYPE ) \TYPE TYPE##_MAX( TYPE a, TYPE b ) \
{ \
return (a > b) ? a : b; \
}
pentru a genera:
int int_MAX( int a, int b )
{
return (a > b) ? a : b;
}
float float_MAX( float a, float b )
{
return (a > b) ? a : b;}
double double_MAX( double a, double b )
{
return (a > b) ? a : b;
}
GENERIC_MAX(int)
GENERIC_MAXfloat)GENERIC_MAX(double)
#include
/* Definitie generica operator de
concatenare */
#define GENERIC_MAX( TYPE ) \
TYPE TYPE##_MAX( TYPE a, TYPE b ) \
{ \
return (a > b) ? a : b; \
}
GENERIC_MAX( int )
GENERIC_MAX( float )GENERIC_MAX( double )
int main(void){
int x=10, y=20;
float a=2.3f, b=6.7f;
double u=3.14, v=6.28;
printf("%d\n", int_MAX(x, y));printf("%f\n", float_MAX(a, b));
printf("%f\n", double_MAX(u,v));
return 0;
}
-
7/25/2019 ProgramareProcedurala2013-M7
16/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 16
Demonstratie
http://www.compileonline.com/compile_c_online.php
-
7/25/2019 ProgramareProcedurala2013-M7
17/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 17
Utilizarea Macrodefinitiilor (2)/*
DECL_NOD
Scop: Declarare nod de tip specificat.
*/#define DECL_NOD( TIP ) \
typedef struct _NOD_##TIP \
{ \
TYPE data; \
struct _NOD_##TIP *next; \
} NOD_##TIP;
/*
DEF_FUN( TIP )
Scop: Definirea unei functii pentru crearea unui nod de tip specificat.
*/
#define DEF_FUN( TIP ) \
NOD_##TYPE *NOD_NOU_##TIP( TIP data ) \
{ \
NOD_##TIP *NODnou = \
(NOD_##TYP *)malloc( sizeof( NOD_##TIP ) ); \NODnou->data = data; \
NODnou->next = NULL; \
return NODnou; \
}
http://cecilsunkure.blogspot.ro/2012/08/generic-programming-in-c.html
-
7/25/2019 ProgramareProcedurala2013-M7
18/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 18
Tema -
Implementarea listelor inlantuite inLinux Kernel
http://www.cs.fsu.edu/~baker/devices/lxr/
http/source/linux/include/linux/list.h
http://isis.poly.edu/kulesh/stuff/src/klist/
-
7/25/2019 ProgramareProcedurala2013-M7
19/20
Versiunea 2013 G. Albeanu, Programare Procedura, M7 19
Proiectul SGLIB
SGLIB API(?) generic pentru C -> ofera
macrodefinitii pentru:- Sortarea tablourilor
- Manipularea listelor inlantuite simplu
- Manipularea listelor dublu inlantuite
- Manipularea arborilor R-B
- Manipularea structurilor cu acces prin hash
#include "sglib.h"
Manual:http://sglib.sourceforge.net/doc/index.html
http://sourceforge.net/projects/sglib/files/sglib/
-
7/25/2019 ProgramareProcedurala2013-M7
20/20