Aula 6 Instruções de selecção e instruções condicionais Instrução de selecção Ramificação Início da actividade if(G) Guarda instrução1; [G] [¬G] else instrução2; instrução1 instrução2 Actividade Transição Entroncamento 2 Introdução à Programação Fim da actividade 2003/2004 Instrução de selecção: Exemplo int x; cin >> x; x: int if(x < 0) x = 0; else x = 1; 13 1 ? cout << x << endl; 3 Introdução à Programação 13 1 2003/2004 Instrução condicional if(G) [G] instrução1; [¬G] instrução1 4 Introdução à Programação 2003/2004 Instrução condicional: Exemplo int x; cin >> x; x: int if(x < 0) x = 0; 13 ? cout << x << endl; 13 13 5 Introdução à Programação 2003/2004 Instrução condicional if(G) instrução1; [G] é o mesmo que [¬G] instrução1 if(G) instrução1; else ; // Instrução nula 6 Introdução à Programação 2003/2004 Porquê ser disciplinado? Para não errar? Problema simples na Aula prática Aposto: 7 Vão esquecer a disciplina Vão errar 1ª versão Vão errar 2ª versão Talvez acertem à terceira… Introdução à Programação 2003/2004 absolutoDe() /** Devolve o valor absoluto do argumento. @pre ?. @post ?. */ int absolutoDe(int const valor) { ... } O que faz Como funciona Como se usa 8 Introdução à Programação 2003/2004 absolutoDe(): pré-condição /** Devolve o valor absoluto do argumento. @pre V. @post ?. */ int absolutoDe(int const valor) { ... } 9 Introdução à Programação 2003/2004 absolutoDe(): condição-objectivo /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe. */ int absolutoDe(int const valor) { ... } 10 É suficiente? Não há relação entre o valor devolvido e valor! Introdução à Programação 2003/2004 absolutoDe(): condição-objectivo /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe. */ int absolutoDe(int const valor) { return 5; } 11 Errado! Mas, ... A condição objectivo verifica-se! Introdução à Programação 2003/2004 absolutoDe(): condição-objectivo /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe e (absolutoDe = valor ou absolutoDe = -valor). */ int absolutoDe(int const valor) { ... } 12 Introdução à Programação 2003/2004 absolutoDe() /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe e (absolutoDe = valor ou absolutoDe = -valor). */ int absolutoDe(int const valor) { int absoluto; ... return absoluto; } 13 Introdução à Programação 2003/2004 absolutoDe() /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe e (absolutoDe = valor ou absolutoDe = -valor). */ int absolutoDe(int const valor) { // V int absoluto; Asserções: afirmações acerca do estado do programa ... // 0 ≤ absoluto e // (absoluto = valor ou absoluto = -valor) return absoluto; } 14 Introdução à Programação 2003/2004 absolutoDe() /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe e (absolutoDe = valor ou absolutoDe = -valor). */ int absolutoDe(int const valor) { assert(true); Asserções: de Instruções afirmações asserção: // V acerca do estado Verificação explícita do de int absoluto; programa asserções. ... // 0 ≤ absoluto e // (absoluto = valor ou absoluto = -valor) assert(0 <= absoluto); assert(absoluto == valor or absoluto == -valor); return absoluto; } 15 Introdução à Programação 2003/2004 absolutoDe() Instruções que resolvem o problema: absoluto = valor; absoluto = -valor; 16 Introdução à Programação 2003/2004 Dedução de asserções (I) double x, y; ... y = x * x; Em que circunstâncias se garante que, depois desta instrução, se tem 2 < y? 17 Introdução à Programação 2003/2004 Dedução de asserções (II) double x, y; ... y = x * x; // 2 < y 18 Introdução à Programação 2003/2004 Dedução de asserções (III) double x, y; ... // ? y = x * x; // 2 < y 19 Introdução à Programação 2003/2004 Dedução de asserções (IV) double x, y; ... // PC: ? y = x * x; // CO: 2 < y 20 Introdução à Programação 2003/2004 Dedução de asserções (IV) double x, y; Conjunto de valores possíveis podia ser maior! ... // PC: 100 < x y = x * x; // CO: 2 < y 21 Muito restritiva. Demasiado forte! Introdução à Programação 2003/2004 Asserções Asserção A mais forte que asserção B: Asserção A mais fraca que asserção B: 22 A mais restritiva que B Conjunto de valores verificando A contido em conjunto de valores verificando B Asserções fortes correspondem a conjuntos pequenos A menos restritiva que B Conjunto de valores verificando A contém conjunto de valores verificando B Asserções fracas correspondem a conjuntos grandes Introdução à Programação 2003/2004 Partindo da condição objectivo... 1. Solução do problema é mais simples 2. Programação é actividade dirigida pelos objectivos 23 Introdução à Programação 2003/2004 Dedução da PC mais fraca Dada a instrução de atribuição variável = expressão; // CO Qual PC mais fraca possível? 24 Na CO, substituir todas as ocorrências de variável por expressão Introdução à Programação 2003/2004 Dedução da PC mais fraca: exemplo 1 double x, y; ... // PC: ? y = x * x; // CO: 2 < y 25 Introdução à Programação 2003/2004 Dedução da PC mais fraca: exemplo 1 double x, y; ... // PC: 2 < x2, ou seja, x < -2½ ou 2½ < x y = x * x; // CO: 2 < y 26 Introdução à Programação 2003/2004 Dedução da PC mais fraca: exemplo 2 // PC: ? ++x; // CO: x ≤ 0 é equivalente a // PC: ? x = x + 1; // CO: x ≤ 0 27 Introdução à Programação 2003/2004 Dedução da PC mais fraca: exemplo 2 // PC: x + 1 ≤ 0, ou seja, x ≤ -1 x = x + 1; // CO: x ≤ 0 28 Introdução à Programação 2003/2004 Dedução da PC mais fraca: exemplo 3 // PC: ? x = x * x - 2; // CO: 0 ≤ x 29 Introdução à Programação 2003/2004 Dedução da PC mais fraca: exemplo 3 // PC: 0 ≤ x2 - 2, ou seja, 2 ≤ x2, ou seja, // PC: x ≤ -2½ ou 2½ ≤ x x = x * x - 2; // CO: 0 ≤ x 30 Introdução à Programação 2003/2004 absolutoDe() // PC1: ? absoluto = -valor; // 0 ≤ absoluto e // (absoluto = valor ou absoluto = -valor) e // PC2: ? absoluto = valor; // 0 ≤ absoluto e // (absoluto = valor ou absoluto = -valor) 31 Introdução à Programação 2003/2004 absolutoDe(): PC1 // PC1: 0 ≤ -valor e // (-valor = valor ou -valor = -valor), ou seja, // PC1: valor ≤ 0 e (-valor = valor ou V), ou seja, // PC1: valor ≤ 0 e V, ou seja, // PC1: valor ≤ 0 absoluto = -valor; // 0 ≤ absoluto e // (absoluto = valor ou absoluto = -valor) 32 Introdução à Programação 2003/2004 absolutoDe(): PC2 // PC2: 0 ≤ valor e // (valor = valor ou valor = -valor), ou seja, // PC2: 0 ≤ valor e (V ou valor = -valor), ou seja, // PC2: 0 ≤ valor e V, ou seja, // PC2: 0 ≤ valor absoluto = valor; // 0 ≤ absoluto e // (absoluto = valor ou absoluto = -valor) 33 Introdução à Programação 2003/2004 absolutoDe(): instrução de selecção if(valor <= 0) absoluto = -valor; else // 0 < valor absoluto = valor; Diferente de 0 ≤ valor 0 < valor implica 0 ≤ valor // 0 < valor // 0 ≤ valor 34 Introdução à Programação 2003/2004 Implicação A implica B Conjunto de valores verificando A (A) está contido no conjunto de valores que satisfaz B (B) A é mais forte que B B A // A // B 35 Introdução à Programação 2003/2004 absolutoDe() /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe e (absolutoDe = valor ou absolutoDe = -valor). */ int absolutoDe(int const valor) { int absoluto; if(valor <= 0) absoluto = -valor; else absoluto = valor; assert(0 <= absoluto); assert(absoluto == valor or absoluto == -valor); return absoluto; } 36 Introdução à Programação 2003/2004 absolutoDe() /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe e (absolutoDe = valor ou absolutoDe = -valor). */ int absolutoDe(int const valor) { int absoluto = valor <= 0 ? –valor : valor; assert(0 <= absoluto); assert(absoluto == valor || absoluto == -valor); return absoluto; } 37 Introdução à Programação 2003/2004 absolutoDe() /** Devolve o valor absoluto do argumento. @pre V. @post 0 ≤ absolutoDe e (absolutoDe = valor ou absolutoDe = -valor). */ int absolutoDe(int const valor) { return valor <= 0 ? –valor : valor; } 38 Introdução à Programação 2003/2004 valorMaisProximoDentroDe() double valorMaisPróximoDentroDe(double const v, double const mín, double const máx) { double r; ... return r; } 39 Introdução à Programação 2003/2004 valorMaisProximoDentroDe() /** Devolve o valor de v limitado ao intervalo dado. @pre mín ≤ máx. @post (v < mín e valorMaisPróximoDentroDe = mín) ou (máx < v e valorMaisPróximoDentroDe = máx) ou (mín ≤ v e v ≤ máx e valorMaisPróximoDentroDe = v). */ double valorMaisPróximoDentroDe(double const v, double const mín, double const máx) { assert(mín <= máx); // PC: mín ≤ máx double r; ... // CO: v < mín e r = mín ou máx < v e r = máx ou mín ≤ v e v ≤ máx e r = v assert(v < mín and r = mín or máx < v and r = máx or mín <= v and v <= máx and r = v); return r; } 40 Introdução à Programação 2003/2004 valorMaisProximoDentroDe() Instruções que resolvem o problema: r = mín; r = máx; r = v; 41 Introdução à Programação 2003/2004 r = mín; // PC1: (v < mín e mín = mín) ou (máx < v e mín = máx) ou // (mín ≤ v e v ≤ máx e mín = v) r = mín; // (v < mín e r = mín) ou (máx < v e r = máx) ou // (mín ≤ v e v ≤ máx e r = v) Pode-se simplificar esta pré-condição: mín ≤ v e min = v // PC1: (v < mín e V) ou (máx < v e mín = máx) ou // (v ≤ máx e mín = v) // PC1: v < mín ou (máx < v e mín = máx) ou // (v ≤ máx e mín = v) 42 Introdução à Programação 2003/2004 r = máx; // PC2: (v < mín e máx = mín) ou (máx < v e máx = máx) ou // (mín ≤ v e v ≤ máx e máx = v) r = máx; // (v < mín e r = mín) ou (máx < v e r = máx) ou // (mín ≤ v e v ≤ máx e r = v) Pode-se simplificar a pré-condição para: v ≤ máx e máx = v // PC2: (v < mín e máx = mín) ou (máx < v e V) ou // (mín ≤ v e máx = v) // PC2: (v < mín e máx = mín) ou máx < v ou // (mín ≤ v e máx = v) 43 Introdução à Programação 2003/2004 r = v; // PC3: (v < mín e v = mín) ou (máx < v e v = máx) ou // (mín ≤ v e v ≤ máx e v = v) r = v; // (v < mín e r = mín) ou (máx < v e r = máx) ou // (mín ≤ v e v ≤ máx e r = v). Pode-se simplificar esta pré-condição para: // PC3: F ou F ou (mín ≤ v e v ≤ máx) ou seja // PC3: mín ≤ v e v ≤ máx 44 Introdução à Programação 2003/2004 Instrução de selecção (I) // PC: mín ≤ máx if(C1) // PC1: v < mín ou (máx < v e mín = máx) ou (v ≤ máx e mín = v) r = mín; else if(C2) // PC2: (v < mín e máx = mín) ou máx < v ou (mín ≤ v e máx = v) r = máx; else // PC3: mín ≤ v e v ≤ máx r = v; 45 Introdução à Programação 2003/2004 Instrução de selecção (II) Sabendo que min ≤ máx // PC: mín ≤ máx if(C1) // PC1: v < mín ou (máx < v e mín = máx) ou (v ≤ máx e mín = v) // v < mín ou (máx < v e mín = máx) ou mín = v // v ≤ mín ou (máx < v e mín = máx) r = mín; else if(C2) // PC2: (v < mín e máx = mín) ou máx < v ou (mín ≤ v e máx = v) // (v < mín e máx = mín) ou máx < v ou máx = v // (v < mín e máx = mín) ou máx ≤ v r = máx; else // PC3: mín ≤ v e v ≤ máx r = v; 46 Introdução à Programação 2003/2004 Instrução de selecção (III) Diferente de Sobreposições! 0 ≤ valor // PC: mín ≤ máx if(C1) // PC1: v ≤ mín ou (máx < v e mín = máx) r = mín; else if(C2) // PC2: (v < mín e máx = mín) ou máx ≤ v r = máx; else // PC3: mín ≤ v e v ≤ máx r = v; 47 Introdução à Programação 2003/2004 Instrução de selecção (IV) Eliminando as sobreposições // PC: mín ≤ máx if(C1) // PC1: v ≤ mín r = mín; else if(C2) // PC2: máx ≤ v r = máx; else // PC3: mín ≤ v e v ≤ máx r = v; 48 Introdução à Programação 2003/2004 Instrução de selecção (V) Eliminando ainda mais algumas sobreposições // PC: mín ≤ máx if(C1) // PC1: v < mín r = mín; else if(C2) // PC2: máx < v r = máx; else // PC3: mín ≤ v e v ≤ máx r = v; 49 Introdução à Programação 2003/2004 Instrução de selecção (VI) Escolhendo as condições // PC: mín ≤ máx if(v < mín) // PC1: v < mín r = mín; else if(máx < v) // PC2: máx < v r = máx; else // PC3: mín ≤ v e v ≤ máx r = v; 50 Introdução à Programação 2003/2004 valorMaisProximoDentroDe() /** ... */ double valorMaisPróximoDentroDe(double const v, double const mín, double const máx) { assert(mín <= máx); double r; if(v < min) r = mín; else if(máx < v) r = máx; else r = v; assert(v < mín and r = mín or máx < v and r = máx or mín <= v and v <= máx and r = v); return r; } 51 Introdução à Programação 2003/2004 valorMaisProximoDentroDe() /** ... */ double valorMaisPróximoDentroDe(double const v, double const mín, double const máx) { assert(mín <= máx); if(v < min) return mín; else if(máx < v) return máx; else return v; } 52 Introdução à Programação 2003/2004 valorMaisProximoDentroDe() /** ... */ double valorMaisPróximoDentroDe(double const v, double const mín, double const máx) { assert(mín <= máx); if(v < min) return mín; if(máx < v) return máx; return v; } 53 Introdução à Programação 2003/2004 Metodologia de desenvolvimento de instruções de selecção Especificar bem problema: escrever PC e CO Ver bem CO: será necessária instrução de selecção? Bom indício é existência de "ous" na CO Se for: 54 Ver CO e identificar n instruções (ou sequências de instruções) que permitam atingir CO Determinar pré-condição mais fraca de cada instrução Guarda de cada instrução é condição mais fraca que, dada a pré-condição global, garante verificação da sua pré-condição Fundamental que guardas cubram todos os casos! Se não acontecer, voltar atrás e tentar encontrar mais instruções para casos em falta Introdução à Programação 2003/2004 Aula 6: Sumário Instrução de selecção if else e instrução condicional if: Sintaxe Transformação entre tipos de instrução de selecção Exemplos Asserções Conceitos Dedução de asserções: directa e inversa Caso da instrução de atribuição Guardas de instruções de selecção Metodologia de desenvolvimento de instruções de selecção: importância de partir dos objectivos Simplificação de instruções de selecção Operação ? : Importância do cálculo curto-circuitado dos operadores lógicos 55 Introdução à Programação 2003/2004