paradigmas de linguagens de programacao - aula #4
DESCRIPTION
Paradigmas de Linguagens de Programacao - Aula #4 Prof. ismar FrangoTRANSCRIPT
Paradigmas de Linguagens de Programação
Paradigma Imperativo [Passagem de parâmetros]Aula #4
(CopyLeft)2009 - Ismar Frango [email protected]
Passagem de parâmetros
Valor – C, Java...Referência – FORTRAN, C++, Pascal...Resultado (out) – Ada, C# Valor-resultado /*Copy-restore*/ (inout) – Ada, C#. Read-only – C/C++ (const)Macro - CNome – ALGOL...
“I write the music, produce it and the band plays within the parameters that I set.” Sting
Passagem por valor vs. referência
Valor• Caller passa o r-value do argumento para o sub-
programa– Reduz “aliasing” (dois nomes referenciando a mesma
localização de memória)• O sub-programa não pode mudar o r-value da variável
no escopo do caller– E quando usamos ponteiros?
– void swap(int *a, int *b) { … }
Referência• Caller passa o l-value do argumento para o sub-
programa.
Valor ou referência?
int h, i;void B(int* w) { int j, k; i = 2*(*w); *w = *w+1;} void A(int* x, int* y) { float i, j; B(&h);}int main() { int a, b; h = 5; a = 3; b = 2; A(&a, &b);}
int*
&a
Passagem por valor (C++)
21
void f(int *p) { *p = 5; p = NULL;}
int main() { int x=2; int *q = &x; f(q);} x = 5
q != NULL
Passagem por referência (C++)
22
void f(int A[]) { A[0] = 5;}
int main() { int B[10]; B[0] = 2; f(B); cout << B[0] << endl;}
5
Testando...
void Mystery( int & a, int & b, int c ){ a = b + c; b = 0; c = 0;}
void Print(){ int x = 0, y = 1, z = 2;
Mystery(x, y, z); cout << x << " " << y << " " << z; Mystery(x, y, z); cout << x << " " << y << " " << z << endl;}
A. 0 1 2 0 1 2 B. 3 0 0 3 0 0 C. 0 1 2 3 0 0D. 3 0 2 2 0 2E. 3 0 0 0 0 0
Testando...
#include <iostream>
void Sum(int a, int b, int & c){ a = b + c; b = a + c; c = a + b;}
int main(){ int x=2, y=3;
Sum(x, y, y); cout << x << " " << y << endl; return 0;}
A. Erro de compilação: y é passado por valor e ref. B. Erro de run-time : y é passado por valor e ref. C. 2 3D. 6 9E. 2 15
Associação posicional vs. Nomeada (Ada)
procedure POS_PARAM is procedure ADD_UP(X_VAL,Y_VAL,Z_VAL:INTEGER) is begin PUT(X_VAL+Y_VAL+Z_VAL); NEW_LINE; end ADD_UP;
begin
end POS_PARAM
ADD_UP(2,4,6); ADD_UP(X_VAL=>2, Y_VAL=>4, Z_VAL=>6); ADD_UP(Z_VAL=>6, X_VAL=>2, Y_VAL=>4); ADD_UP(2, Z_VAL=>6, Y_VAL=>4);
PPAPOSITIONAL PARAMETER
ASSOCIATION
NPANAMED
PARAMETER ASSOCIATION
Passagem por valor x referência (Pascal)
program P;var X, Y: Integer;
procedure Swap(A, B: Integer);var Temp:begin Temp := A; A := B; B := Temp;end;
begin readln(X, Y); Swap(X, Y); writeln(X, Y)end.
valor
Novas variáveis no ARI de
Swap
PFs VL
http://stwww.weizmann.ac.il/g-cs/benari/articles/varparm.pdf
Passagem por valor x referência (Pascal)
program P;var X, Y: Integer;
procedure Swap(var A, B: Integer);var Temp:begin Temp := A; A := B; B := Temp;end;
begin readln(X, Y); Swap(X, Y); writeln(X, Y)end.
ref
aliases VL
Passagem por valor (Java)
public class Teste{
private static void aloca(String x){ x="Hello";}
public static void main(String args[]){String b="World";aloca(b);System.out.println(b);}}
World
Passagem por valor (Java)
public class Teste{
private static String aloca(String x,String y){ x=x+y; return x;}
public static void main(String args[]){String a="Hello, ";String b="World";String c = aloca(a,b);
System.out.println(c==a);
String d="World";String e=new String("World");
System.out.println(b==d);System.out.println(b==e);
String f=e.intern();System.out.println(b==f);
}
}
falsetruefalsetrue
void Foo (StringBuilder x) { x = null; } ... StringBuilder y = new StringBuilder(); y.Append ("hello"); Foo (y); Console.WriteLine (y==null);
Passagem por valor (C#)
false
void Foo (StringBuilder x) { x.Append (" World"); } ... StringBuilder y = new StringBuilder(); y.Append (“Hello"); Foo (y); Console.WriteLine (y);
Hello World
String first = new String(“Hello”);String second = first;first += “World”;System.out.println(second);
Passagem por valor (Java)
Hello
void giveMeAString (Object y) { y = "This is a string"; } ...Object x = null; giveMeAString (x); System.out.println (x);
null
O que ocorre aqui?public class Teste2{public static void foo (String x) { x+=" World"; }
public static void main(String []a){String y = new String("Hello"); foo (y); System.out.println(y); }}
Hello
public class Teste3{public static void foo (StringBuilder x) { x.append(" World"); }
public static void main(String []a){StringBuilder y = new StringBuilder();y.append("Hello"); foo (y); System.out.println(y); }}
Hello World
Passagem e AlocaçãoJava vs. C vs. C#
class Elefante{ public int peso=1000; //:-( Thou shalt not do this!}
public class Teste{
public static void main(String args[]){Elefante dumbo = new Elefante();dumbo.peso=2000;Elefante dumbinho = dumbo;dumbinho.peso=500;System.out.println(dumbo.peso);}}
500
Java
Passagem e Alocação Java vs. C vs. C#
#include <stdio.h>typedef struct { int peso; }Elefante;
int main(){Elefante *dumbo = malloc (sizeof(Elefante));dumbo->peso=2000;Elefante *dumbinho = dumbo;dumbinho->peso=500;printf("%d",dumbo->peso);return 0;}
500
C
Passagem e Alocação Java vs. C vs. C#
C#include <stdio.h>typedef struct {int peso; }Elefante;
int main(){Elefante dumbo;dumbo.peso=2000;Elefante dumbinho = dumbo;dumbinho.peso=500;printf("%d",dumbo.peso);return 0;} 2000
Java vs. C vs. C#
using System;
public struct Elefante{ public int peso; }
public class testecs{public static void Main(string []a){Elefante dumbo = new Elefante(); dumbo.peso=2000; Elefante dumbinho = dumbo; dumbinho.peso=500; Console.WriteLine (dumbo.peso); }} 2000
C#
Java vs. C vs. C#
using System;
public class Elefante{ public int peso; }
public class testecs{public static void Main(string []a){Elefante dumbo = new Elefante(); dumbo.peso=2000; Elefante dumbinho = dumbo; dumbinho.peso=500; Console.WriteLine (dumbo.peso); }} 500
C#
void Foo (ref StringBuilder x) { x = null; } ...StringBuilder y = new StringBuilder(); y.Append ("hello"); Foo (ref y); Console.WriteLine (y==null);
Passagem por referência (C#)
using System;using System.Text;
public class testecsref{public static void Foo1 (ref Elefante x) { x.peso=1000 ;}
public static void Foo2 (Elefante x) { x.peso=0 ;}
public static void Main(string []a){Elefante dumbo=new Elefante(); Foo1 (ref dumbo); Console.WriteLine (dumbo.peso); Foo2 (dumbo); Console.WriteLine (dumbo.peso); }}
public class Elefante{ public int peso; }
public struct Elefante{ public int peso; }
10000
10001000
Qual a diferença entre passar um value object
por referência e um reference object por
valor?
true
Value objects x reference objects (C#)
void Foo (ref IntHolder x) { x.i=10; } ... IntHolder y = new IntHolder();y.i=5; Foo (ref y); Console.WriteLine (y.i);
10
public struct IntHolder { public int i; }
Value object + passagem por
referência
void Foo (IntHolder x) { x.i=10; } ... IntHolder y = new IntHolder();y.i=5; Foo (y); Console.WriteLine (y.i);
5
public class IntHolder { public int i; }
Reference object + passagem por
valor
Parâmetros out (C#)
void Foo (out int x) { int a = x; // Can't read x here - it's considered unassigned
// Assignment - this must happen before the method can complete normally x = 10; // The value of x can now be read: int a = x; } ... // Declare a variable but don't assign a value to it int y; // Pass it in as an output parameter, even though its value is unassigned Foo (out y); // It's now assigned a value, so we can write it out: Console.WriteLine (y);
Parâmetros in, out, in out (Ada)
procedure Quadratic(A, B, C: in Float; Root1, Root2: out Float);procedure Sort(V: in out Vector);
with CS_IO; use CS_IO;
procedure OUT_MODE_EXAMPLE is VALUE_1, VALUE_2: float; MEAN: float;
procedure MEAN_VALUE (NUM_1, NUM_2: in float; NUM_3: out float) is begin NUM_3:= (NUM_1+NUM_2)/2.0; end MEAN_VALUE;
begin MEAN_VALUE(VALUE_1, VALUE_2, MEAN); put("The mean is "); put(MEAN);new_line; new_line;end OUT_MODE_EXAMPLE;
Parâmetros in, out, in out (Ada)
with CS_IO; use CS_IO;
procedure IN_OUT_MODE_EXAMPLE is VALUE_1, VALUE_2: float;
procedure MEAN_VALUE (NUM_1: in out float; NUM_2: in float) is begin NUM_1:= (NUM_1+NUM_2)/2.0; end MEAN_VALUE;
begin get(VALUE_1);get(VALUE_2); put("BEFORE MEAN VALUE: VALUE_1 = "); put(VALUE_1);put(", VALUE_2 = ");put(VALUE_2);new_line; MEAN_VALUE(VALUE_1, VALUE_2); put("The mean is "); put(VALUE_1);new_line; put("AFTER MEAN VALUE: VALUE_1 = "); put(VALUE_1);put(", VALUE_2 = ");put(VALUE_2);new_line;end IN_OUT_MODE_EXAMPLE;
Parameter arrays –”params” (C#), ... (Java)
void ShowNumbers (params int[] numbers) { foreach (int x in numbers) { Console.Write (x+" "); } Console.WriteLine(); }
... int[] x = {1, 2, 3}; ShowNumbers (x); ShowNumbers (4, 5);
static int sum (int ... numbers) { int total = 0; for (int i = 0; i < numbers.length; i++) total += numbers [i]; return total; }
C#
Java
Parâmetros variáveis (C++)
void myprintf( char *format, ... ){va_list vl;int i;va_start( vl, args );for( i = 0; args[i] != '\0'; ++i ){ union any_t { int i; float f; char c;} any;if( args[i]=='i' ){ any.i = va_arg( vl, int ); printf( "%i\n", any.i );}else if( args[i]=='f' ){ any.f = va_arg( vl, float ); printf( "%f\n", any.f );}else if( args[i]=='c' ){any.c = va_arg( vl, char );printf( "%c\n", any.c );}else{ throw SomeException; }va_end( vl );}
Parâmetros default (Ada, C++)with CS_IO; use CS_IO; procedure EXAMPLE is N1: float:= 4.2; N2: float:= 9.6; procedure MEAN_VALUE (X1: in out float; X2: in float := 6.4) is begin X1:= (X1+X2)/2.0; end MEAN_VALUE
begin MEAN_VALUE(N1); put(N1); new_line; MEAN_VALUE(N1, N2); put(N1); new_line; end EXAMPLE;
#include <iostream>using namespace std; int a = 1;int f(int a) { return a; }int g(int x = f(a)) { return x; } int h() { a = 2; { int a = 3; return g(); }} int main() { cout << h() << endl;}
2
O que é impresso aqui?
Parâmetros read-only (C++)
class IntList{public: const Print (ostream &o);};
void f(const IntList &L) { L.Print(cout); }
bool Compare(const vector <int> & A)// precondition: A is sorted{ int k;
for (k=1; k<A.size(); k++) { if (A[k-1] == A[k]) return true; } return false;}
E se aqui não fosse
const?
Macros
#define MAXLINE 100
char line[MAXLINE]; ... getline(line, MAXLINE);
#define A 2 #define B 3 #define C A + B
int x = C * 2;
O que acontece
aqui?
Por que não tem ponto-e-
vírgula?
Pass-by-name (ALGOL)
procedure double(x); real x; begin x := x * 2 end;
double(C[j])
C[j] := C[j] * 2.
n
i
iix1
*][
real procedure Sum(j, lo, hi, Ej); value lo, hi; integer j, lo, hi; real Ej;begin real S; S := 0; for j := lo step 1 until hi do S := S + Ej; Sum := Send;
Sum(i, 1, n, x[i]*i)
Como simular isso em C++
ou Java?
Pass-by-name (ALGOL)
procedure swap (a, b);integer a, b, temp;begin temp := a; a := b; b:= tempend;
swap(x, y)
temp := x; x := y; y := temp
swap(i, x[i])
temp := i;i := x[i]; x[i] := temp Antes
i = 2
x[2] = 5
Depoisi =
5
x[2] = 5
x[5] = 2
+Exercícios...
/* If *y is zero and x > 0 : set *k to biggest integer.* If *y is zero and x <=0 : leave *k unchanged.* If *y is not zero :* set *k to be x divided by *y and increment *y by 1.*/#define INT_MAX 1000void check_divide (int *k, int x, int *y) {if (*y = 0)if (x > 0)*k = INT_MAX;else*k = x / *y /* *y cannot be 0 */;*y++;}
int main( ){ int a=2; check_divide(&a, a, &a); cout<<a;}
0
C++
/* If *y is zero and x > 0 : set *k to biggest integer.* If *y is zero and x <=0 : leave *k unchanged.* If *y is not zero :* set *k to be x divided by *y and increment *y by 1.*/#define INT_MAX 1000void check_divide (int *k, int x, int *y) {if (*y == 0) {if (x > 0)*k = INT_MAX;}else{*k = x / *y /* *y cannot be 0 */;(*y)++;}}
int main( ){ int a=2; check_divide(&a, a, &a); cout<<a;}
3
C++
#define TAM 10void change (int v[ ], int &ntx){ for (;ntx>0;ntx--) v[ntx]=ntx---1;}
int main(){ int k[TAM],i=0,; for(;;) { if (i==TAM) break; k[i++]= i*2;} change(k,i); for(;;) { if (i>TAM) break; cout<<k[i++]<<endl;}}
02163
105
147
189
C++
using namespace System; double average( ... array<Int32>^ arr ) { int i = arr->GetLength(0); double answer = 0.0; for (int j = 0 ; j < i ; j++) answer += arr[j]; return answer / i; }
int main() { Console::WriteLine("{0}", average( 1, 2, 3, 6 )); }
Visual C++ (.NET)
3
void g (int &a) { a++; }void h (int &a) { a*=2; }void k (int &a) { a*=10; }void f( int &number, void (*function)(int&) ){ (*function )( number );}
int main(){ int select, count=0; for (select = 1; select<=3 ;select++) { switch( select ) { case 1: f( count, g ); break; case 2: f( count, h ); break; case 3: f( count, k ); default: break; } } cout << count;}
20
C++
Pascalprocedure swap(arg1, arg2: integer); var temp : integer; begin temp := arg1; arg1 := arg2; arg2 := temp; end;
...{ in some other procedure/function/program }var var1, var2 : integer;begin var1 := 1; var2 := 2; swap(var1, var2);end;
Var1=1Var2=2
public class TestY{public static void differentArray(float[] x) { x = new float[100]; x[0] = 26.9f; }
public static void main(String a[]){ float[ ] xx = new float[100]; xx[0] = 55.8f; differentArray(xx); System.out.println("xx[0] = " + xx[0]);}}
Java
55.8
procedure sub1(x: int; y: int); begin x := 1; y := 2; x := 2; y := 3; end;
sub1(i, a[i]);
Algol
a={2,3}