Baixe o app para aproveitar ainda mais
Prévia do material em texto
Linguagem C Ricardo Terra rterrabh@gmail.com Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 1 / 341 Conteúdo 1 Introdução Tópicos Importantes 2 Sintaxe Básica 3 Ponteiros 4 Tópicos Relevantes 5 Extras Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 2 / 341 Introdução Tópicos Importantes Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 3 / 341 Introdução – Tópicos Importantes Origem do C Dennis Ritchie BCPL→ B→ C em 1970 Devido a popularidade de microcomputadores, um grande número de implementações surgiram compatíveis, porém com algumas discrepâncias Para evitar discrepâncias, o ANSI (American National Standards Institute), em 1983, criou o padrão C ANSI Modificado em 1989 (C89) Modificado em 1999 (C99) Modificado em 2009? Não Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 4 / 341 Introdução – Tópicos Importantes Linguagem Estruturada exceto por uma única característica Médio Nível nível mais alto: Pascal, COBOL, Java... médio nível: C, C++... nível mais baixo: Assembly... Para programadores foi criada, influenciada e testada por programadores não se admire que C seja a linguagem mais popular entre excelentes programadores Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 5 / 341 Introdução – Tópicos Importantes Compiladores X Interpretadores Interpretador lê o código-fonte linha a linha, executando a instrução específica daquela linha Compilador lê o programa inteiro, converte-o em um código-objeto (ou código de máquina) de modo que o computador consiga executá-lo diretamente Qual é mais rápido? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 6 / 341 Introdução – Tópicos Importantes Forma de um programa C Declarações globais Funções definidas pelo programador Função main 1 declarações globais 3 t ipo−de−retorno funcao( l i s t a −de−parâmetros ) { . . . 5 } 7 . . . 9 i n t main( i n t argc , char∗ argv [ ] ) { . . . 11 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 7 / 341 Introdução – Tópicos Importantes Exemplo de um programa C 1 #include<std io . h> #include<math . h> 3 const double P I = 3.141596; 5 double calcularArea (double ra io ) { 7 return P I ∗ pow( raio , 2 ) ; } 9 i n t main( i n t argc , char ∗argv [ ] ) { 11 double raio , area ; p r i n t f ( " D ig i te o raio : " ) ; 13 scanf ( "% l f " , &raio ) ; area = calcularArea ( ra io ) ; 15 p r i n t f ( " Area = % l f " , area ) ; return 0; 17 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 8 / 341 Introdução – Tópicos Importantes Um pouco sobre a função main A função main é o ponto de entrada de uma aplicação C. Usualmente, um aplicação C se inicia no método main e, a partir dele, invoca diversas outras funções. Por fim, essa função retorna um valor inteiro Esse valor retornado não é impresso, serve apenas para indicar ao sistema operacional ou para um aplicativo que invocou o seu aplicativo qual foi o código de retorno Por padrão, o retorno 0 indica que o aplicativo encerrou conforme esperado. Os outros valores podem ser definidos conforme a necessidade de cada aplicação Normalmente, valores negativos se referem a erros Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 9 / 341 Introdução – Tópicos Importantes Valores de retorno da função main Nesta apostila, adota-se os seguintes valores de retorno: 0→ encerramento conforme esperado -1→memória insuficiente -2→ argumentos de linha de comando incorretos -3→ problema ao abrir arquivo Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 10 / 341 Introdução – Tópicos Importantes Palavras reservadas • auto • double • int • struct • break • else • long • switch • case • enum • register • typedef • char • extern • return • union • const • float • short • unsigned • continue • for • signed • void • default • goto • sizeof • volatile • do • if • static • while Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 11 / 341 Introdução – Tópicos Importantes Processo de compilação Criar o programa Compilar o programa Linkeditar o programa com as funções necessárias da biblioteca Por utilizarmos uma IDE de desenvolvimento esse processo fica bem mais transparente Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 12 / 341 Introdução – Tópicos Importantes Mapa de memória em C Quatro regiões logicamente distintas: código do programa variáveis globais pilha (stack) heap região de memória livre a ser requisitada (alocação dinâmica) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 13 / 341 Introdução – Tópicos Importantes C versus C++ C++ é uma versão estendida e melhorada da linguagem C que é projetada para suportar programação orientada a objetos C++ contém e suporta toda a linguagem C e mais um conjunto de extensões orientadas a objetos Portanto: Você não pode programar em C++ se não souber C Tudo que aprender da linguagem C, poderá ser utilizado em C++ Compiladores compatíveis? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 14 / 341 Introdução – Tópicos Importantes IDEs Eclipse (ver material disponibilizado de como configurar) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 15 / 341 Introdução – Tópicos Importantes IDEs Dev-Cpp 5 (http://www.bloodshed.net/devcpp.html) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 16 / 341 Conteúdo 1 Introdução 2 Sintaxe Básica Expressões Comandos condicionais Comandos de repetição Arranjos Variáveis Funções Estruturas 3 Ponteiros 4 Tópicos Relevantes 5 Extras Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 17 / 341 Sintaxe Básica Expressões Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 18 / 341 Sintaxe Básica – Expressões Definições Expressão é o elemento mais fundamental da linguagem C São mais gerais e mais poderosas que na maioria das outras linguagens de programação As expressões são formadas por: dados (representados por variáveis ou constantes) operadores Exemplos: 2 + 4 * (7 - 3) (-b + delta) / (2 * a) calcularArea(raio=3.98) printf((a%2==0 || ++b<=pow(x,y)) ? "SÍ": "NO") Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 19 / 341 Sintaxe Básica – Expressões Tipos básicos: Caractere (char) Inteiro (int) Ponto flutuante (float) Ponto flutuante de precisão dupla (double) Sem valor (void) Modificadores: signed unsigned long short Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 20 / 341 Sintaxe Básica – Expressões Tipo char Representa um caractere ASCII 1 byte Na verdade, é um inteiro sem sinal (0 a 255) Exemplo 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { char ch ; 5 scanf ( "%c" , &ch ) ; p r i n t f ( "%c" , ch ) ; /∗ Imprime o caractere l ido∗/ 7 ch = ’A’ ; 9 p r i n t f ( "%d" , ch ) ; /∗ Imprime o codigo ASCII numerico∗/ 11 ch = 65; p r i n t f ( "%c" , ch ) ; /∗ Imprime o caractere∗/ 13 return 0; 15 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 21 / 341 Sintaxe Básica – Expressões Tipo int Representa um inteiro 4 bytes (normalmente) Exemplo 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t i ; 5 scanf ( "%d" , & i ) ; p r i n t f ( "%d" , i ) ; /∗ Imprime o numero l ido∗/ 7 i = ’0 ’ ; 9 p r i n t f ( "%d" , i ) ; /∗ Imprime o codigo ASCII numerico∗/ 11 i = 48; p r i n t f ( "%c" , i ) ; /∗ Imprime o caractere ASCII correspondente∗/ 13 return 0; 15 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 22 / 341 Sintaxe Básica – Expressões Tipo float Representa um número decimal 4 bytes (normalmente) Exemplo 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { f l o a t f ; 5 scanf ( "%f " , &f ) ; 7 p r i n t f ( "%f " , f ) ; /∗ Imprime o numero l ido∗/ 9 f = 1.234; p r i n t f ( "%f " , f ); 11 f = 1.3213e2 ; 13 p r i n t f ( " %.2 f " , f ) ; /∗ Imprime com apenas 2 casas decimais∗/ 15 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 23 / 341 Sintaxe Básica – Expressões Tipo double Representa um número decimal com maior precisão que float 8 bytes (normalmente) Exemplo #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 double d ; 6 scanf ( "% l f " , &d ) ; p r i n t f ( "% l f " , d ) ; /∗ Imprime o numero l ido∗/ 8 d = 1.234; 10 p r i n t f ( "% l f " , d ) ; 12 d = 1.3213e2 ; p r i n t f ( " %.2 l f " , d ) ; /∗ Imprime com apenas 2 casas decimais∗/ 14 return 0; 16 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 24 / 341 Sintaxe Básica – Expressões C não tem um tipo lógico Utiliza-se qualquer valor inteiro 0→ false diferente de 0→ true Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 25 / 341 Sintaxe Básica – Expressões Identificadores nomes de variáveis, funções, rótulos e vários outros objetos definidos pelo usuário São case-sensitive Na verdade, C é case-sensitive Identificador válido: A primeira letra deve ser uma letra ou um underline ( _ ) As letras subsequentes devem ser letras, números ou underline Exemplos: idade, nome, sexo, telefone1, a1, A1, _x, _y, ... Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 26 / 341 Sintaxe Básica – Expressões Uma variável é uma posição nomeada de memória, que é utilizada para guardar um valor que pode ser modificado pelo programa Todas as variáveis devem ser declaradas e inicializadas antes de serem utilizadas (Padrão C89, o qual iremos seguir) Declaradas: dentro de funções (variáveis locais) como parâmetros de funções (parâmetros formais) fora de todas as funções (variáveis globais) Podem já ser inicializadas Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 27 / 341 Sintaxe Básica – Expressões Exemplo de variáveis #include<std io . h> 2 double PI = 3.141596; 4 i n t soma( i n t x , i n t y ) { 6 return x + y ; } 8 i n t main( i n t argc , char ∗argv [ ] ) { 10 i n t c = soma(2 , 3 ) ; p r i n t f ( "c = %d" , c ) ; 12 return 0; } Pergunta-se Quais são as variáveis locais? E as globais? E os parâmetros formais? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 28 / 341 Sintaxe Básica – Expressões Modificadores de tipo de acesso (quantificadores): const O valor da variável não pode ser modificada por seu programa Exemplo: const double PI = 3.141596; volative O valor da variável pode ser alterada de uma maneira não explicitamente especificada pelo programa Exemplo: volative double taxa = 0.65; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 29 / 341 Sintaxe Básica – Expressões Especificadores de tipo de classe de armazenamento: extern Diz ao compilador que os tipos e nomes de variável que o seguem foram declarados em outro arquivo fonte Exemplo: Já existe um arquivo matematica.c que possui declarado – como variável global – o valor de PI. Imagine que esteja desenvolvendo um outro arquivo fonte e queira utilizar o valor do PI já declarado. Você utiliza normalmente, mas deve deixar claro que o valor de PI está declarado em um outro arquivo. Assim declara-se PI como a seguir: extern PI; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 30 / 341 Sintaxe Básica – Expressões Especificadores de tipo de classe de armazenamento: static Variáveis permanentes, i.e., mantém seus valores entre as chamadas Só é inicializado na primeira vez que a função é chamada Funciona como uma variável global (mantendo seu valor), contudo não possui visibilidade global, somente para a própria função (como em variáveis locais) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 31 / 341 Sintaxe Básica – Expressões Exemplo static 1 #include<std io . h> 3 i n t contador ( ) { s t a t i c i n t count = 0; 5 return ++count ; } 7 i n t main( i n t argc , char ∗argv [ ] ) { 9 p r i n t f ( " count = %d\n " , contador ( ) ) ; p r i n t f ( " count = %d\n " , contador ( ) ) ; 11 p r i n t f ( " count = %d\n " , contador ( ) ) ; return 0; 13 } Pergunta-se O que será impresso? E se a variável count não fosse static? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 32 / 341 Sintaxe Básica – Expressões register Antigamente: Variável armazenada em um registrador Atualmente: Variável armazenada de tal modo que seja o mais rápido possível Exemplo: register int count; auto Declaração de variáveis locais, porém não é utilizada Por padrão, todas as variáveis não globais são auto Exemplo: auto int idade; ↔ int idade; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 33 / 341 Sintaxe Básica – Expressões Em C, constantes referem-se a valores fixos que o programa não pode alterar Constantes caracteres: ’A’, ’B’, ’C’, ... São envolvidas por aspas simples (’) Constantes inteiras: 1, 2, 3, 4, ... Constantes em ponto flutuante: 3.14, 4.67, ... Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 34 / 341 Sintaxe Básica – Expressões Constantes Hexadecimais e Octais Hexadecimal: inicia com 0x Exemplo: 0x18 equivale a 24 Octal: inicia com 0 Exemplo: 017 equivale a 15 Constantes string: “uma string qualquer” Conjunto de caracteres envolvidos por aspas duplas ( ”) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 35 / 341 Sintaxe Básica – Expressões Constantes caractere de barra invertida Para a maioria dos caracteres, as aspas simples funcionam bem, porém para enter, tab, esc seria bem complicado representá-los, uma vez que são teclas de ação. Por isto, C criou as constantes especiais de barra invertida Constantes especiais mais utilizadas \n Nova Linha \r Retorno de Carro (CR) \t Tabulação horizontal \’ Aspas Simples \" Aspas Duplas \0 Nulo \\ Barra Invertida \a Alerta Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 36 / 341 Sintaxe Básica – Expressões Quatro classes de operadores: Aritméticos Relacionais Lógicos Bit a bit Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 37 / 341 Sintaxe Básica – Expressões Operadores Artiméticos + - ∗ / % (corresponde ao mod do Pascal) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 38 / 341 Sintaxe Básica – Expressões Prioridades e Associatividades normais Parênteses mudam as prioridades 2 + 2 * 4 != (2 + 2) * 4 Operador / Operando inteiros: Divisão Inteira: (7 / 2 = 3) Pelo menos um ponto flutuante: Divisão Fracionária: 7.0 / 2.0 = 3.5 7.0 / 2 = 3.5 7 / 2.0 = 3.5 Operador % Resto de divisão inteira Ex: 4 % 2 = 0 e 5 % 2 = 1 Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 39 / 341 Sintaxe Básica – Expressões Operadores Aritméticos em Atribuições Compostas Em geral, os operadores aritméticos possuem um operador de atribuição correspondente: Exemplo: A = A + 2 ↔ A += 2 Outros: -= *= /= %= Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 40 / 341 Sintaxe Básica – Expressões Exemplo de operadores de atribuição compostos 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t valor = 10; 5 valor += 10; 7 p r i n t f ( "%d" , valor ) ; /∗ valor : 20 ∗/ 9 valor −= 10; p r i n t f ( "%d" , valor ) ; /∗ valor : 10 ∗/ 11 valor ∗= 5; 13 p r i n t f ( "%d" , valor ) ; /∗ valor : 50 ∗/ 15 valor /= 10; p r i n t f ( "%d" , valor ) ; /∗ valor : 5 ∗/ 17 valor %= 3; 19 p r i n t f ( "%d" , valor ) ; /∗ valor : 2 ∗/ 21 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 41 / 341 Sintaxe Básica – Expressões Operadores Aritméticos de incremento e decremento ++ (incrementa 1) -- (decrementa 1) Exemplos: A = A + 1 ↔ A += 1 ↔ A++ ↔ ++A A = A - 1 ↔ A -= 1 ↔ A-- ↔ --A Posicionamento (vale para ++ e para --) ++ após a variável: pós-incremento (retorna e incrementa) ++ antes da variável: pré-incremento (incrementae retorna) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 42 / 341 Sintaxe Básica – Expressões Exemplos 1 i n t i = 0; System . out . p r i n t f ( "%d" , i ++); System . out . p r i n t f ( "%d" , i ) ; System . out . p r i n t f ( "%d" , −− i ) ; 2 i n t i = 0; System . out . p r i n t f ( "%d" , ++ i ) ; System . out . p r i n t f ( "%d" , i ) ; System . out . p r i n t f ( "%d" , i −−); System . out . p r i n t f ( "%d" , i ) ; Pergunta-se Qual a saída de cada printf? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 43 / 341 Sintaxe Básica – Expressões 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t i = 0 ; 5 p r i n t f ( "%d" , i ++) ; p r i n t f ( "%d" , i −−); 7 p r i n t f ( "%d" , −− i ) ; p r i n t f ( "%d" , i ) ; 9 i = 6 ; 11 p r i n t f ( "% l f " , ++ i / 2 . 0 ) ; 13 return 0; } Pergunta-se Qual a saída de cada printf? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 44 / 341 Sintaxe Básica – Expressões Operadores Relacionais: == (comparação) != (diferença) < > <= >= Operadores Lógicos: São eles: & (and), | (or) e ! (not) Normalmente, para and e or, utiliza-se operadores de curto circuito que fazem com que a expressão só seja analisada até que seja possível determinar o resultado São eles: && (and) e || (or) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 45 / 341 Sintaxe Básica – Expressões Operadores Lógicos de Curto Circuito Ao encontrarem um valor que determine seu resultado, não testam mais as outras condições, isto é, a expressão só será analisada até que seja possível determinar o resultado Exemplo: considere que os métodos a e b retornem booleano a() & b()→ executa os dois métodos para obter o resultado a() | b()→ executa os dois métodos para obter o resultado a() && b()→ se o método a retornar false, o resultado será false e o método b nem será executado a() || b()→ se o método a retornar true, o resultado será true e o método b nem será executado Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 46 / 341 Sintaxe Básica – Expressões Entendeu mesmo? #include<std io . h> 2 i n t a ( ) { re turn 0; } 4 i n t b ( ) { re turn 1; } i n t c ( ) { re turn 0; } 6 i n t d ( ) { re turn 1; } 8 i n t main( i n t argc , char ∗argv [ ] ) { p r i n t f ( "%d" , a ( ) & b ( ) & c ( ) & d ( ) ) ; 10 p r i n t f ( "%d" , a ( ) && b ( ) && c ( ) && d ( ) ) ; p r i n t f ( "%d" , a ( ) || b ( ) || c ( ) || d ( ) ) ; 12 return 0; 14 } Pergunta-se Quais métodos serão executados e qual o retorno dos printf’s das linhas 9, 10 e 11? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 47 / 341 Sintaxe Básica – Expressões Tiro no pé! #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t a = 0; i f (a != 0 & 2 / a > 5) { 6 p r i n t f ( "OK" ) ; } else { 8 p r i n t f ( "NOK" ) ; } 10 return 0; 12 } Pergunta-se O programa acima apresenta um erro fatal. Como evitá-lo? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 48 / 341 Sintaxe Básica – Expressões Operadores bit a bit: & (and) Ex: 3 & 1 ↔ 0011 & 0001 ↔ 0001 ↔ 1 | (or) Ex: 3 | 1 ↔ 0011 | 0001 ↔ 0011 ↔ 3 ˆ (xor) Ex: 3 ˆ 1 ↔ 0011 ˆ 0001 ↔ 0010 ↔ 2 Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 49 / 341 Sintaxe Básica – Expressões Operadores bit a bit: ~ (complemento de um) Ex: 3 ↔ ˜0011 ↔ 1100 ↔ 12 << (deslocamento à esquerda) Ex: 4 << 1 ↔ 0100 << 1 ↔ 1000 ↔ 8 >> (deslocamento à direita) Ex: 4 >> 1 ↔ 0100 >> 1 ↔ 0010 ↔ 2 >>> (deslocamento à direita com sinal) Ex: -127 >>> 1 ↔ 2147483584 Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 50 / 341 Sintaxe Básica – Expressões Exercícios 10 & 13 ? 10 | 13 ? 10 ˆ 13 ? 0 ? 8 » 1 ? 2 « 2 ? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 51 / 341 Sintaxe Básica – Expressões Comentários Algumas vezes se deseja explicar um código, explicitar uma informação em linguagem natural. Para isso existem os comentários. Eles não deixam o programa mais lento e seu uso é altamente recomendável. Existem dois tipos de comentários em C ANSI: Comentário até final de linha. Tudo escrito após ele na linha, é considerado comentário. Exemplo: i n t rg ; // só os números serão armazenados Comentário de bloco. Tudo escrito entre /* e */ é considerado comentário. Exemplo: /∗ pode i n c l u i r vár ias l inhas ∗/ Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 52 / 341 Sintaxe Básica Comandos condicionais Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 53 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais (if, switch e operador ternário) Comando condicionais são aqueles que dependendo de uma condição executam um bloco, caso a condição não seja atendida, o bloco não será executado C provê suporte a três comandos condicionais: if switch operador ternário (? :) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 54 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - if Sintaxe do comando if i f ( condicao ) { comando1; comando2; comando3; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 55 / 341 Sintaxe Básica – Comandos condicionais Observações: Os parênteses que envolvem a condição são OBRIGATÓRIOS Diferentemente de Pascal, Delphi (Object Pascal) etc A condição deverá retornar um tipo booleano Os comandos somente serão executados se a condição for verdadeira Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 56 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - if O uso dos braços NÃO é obrigatório caso seja apenas um único comando Porém, a boa prática recomenda a utilização de braços independente do número de comandos Melhor indentação do código i f ( 1 ) comando; equivale a: i f ( 1 ) { comando; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 57 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - if Como faço o conhecido: se verdade então . . . senão . . . i f ( condicao ) { comando1; comando2; comando3; } else { comando4; comando5; comando6; } Pergunta-se Quais comandos serão executados se a condição for verdadeira? E se for falsa? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 58 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - if 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t a, b; 5 scanf ( "%d %d" , &a, &b ) ; i f (a >= b) { 7 p r i n t f ( "%d e maior ou igual a %d! " , a, b ) ; } else { 9 p r i n t f ( "%d e menor que %d! " , a, b ) ; } 11 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 59 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - if Comando if podem ser aninhados #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t nota ; scanf ( "%d" , ¬a ) ; 6 i f (nota >= 90) { 8 p r i n t f ( " Nota A" ) ; } else i f (nota >= 80) { 10 p r i n t f ( " Nota B " ) ; } else i f (nota >= 70) { 12 p r i n t f ( " Nota C" ) ; } else { 14 p r i n t f ( "Reprovado " ) ; } 16 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 60 / 341 Sintaxe Básica – Comandos condicionais Exemplo if 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { char op; 5 p r i n t f ( " D ig i te um operador (+−/∗): " ) ; scanf ( "%c" , &op ) ; 7 i f (op == ’+ ’ || op == ’−’ ) { 9 p r i n t f ( " Operador de Baixa Prior idade .\n " ) ; } else i f (op == ’ / ’ || op == ’∗ ’ ) { 11 p r i n t f ( " Operador de Alta Pr ior idade .\n " ) ; } else { 13 p r i n t f ( " Caractere Inval ido !\n " ) ; } 15 return 0; 17 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 61 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - switch Na instrução switch, uma variável de tipoprimitivo char ou int é comparada com cada valor em questão. Se um valor coincidente é achado, a instrução (ou instruções) depois do teste é executada Sintaxe: switch ( var iavel ) { case 1: comandoA; break ; case 2: comandoB; break ; case 3: comandoC; break ; default : comandoPadrao; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 62 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - switch Se nenhum valor for encontrado, a instrução default é executada O comando break é necessário para quebrar o switch, pois assim que encontrada a opção correta, é executado tudo em seguida Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 63 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - switch #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 char l e t ra = ’B ’ ; switch ( le t ra ) { 6 case ’A’ : p r i n t f ( " Entrou em A" ) ; break ; case ’B ’ : p r i n t f ( " Entrou em B " ) ; 8 case ’C’ : p r i n t f ( " Entrou em C" ) ; break ; case ’D’ : p r i n t f ( " Entrou em D" ) ; break ; 10 default : p r i n t f ( " Entrou em Default " ) ; } 12 return 0; } Pergunta-se Qual a saída? E se o valor de letra fosse ’C’? E se fosse ’a’? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 64 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - switch 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { char l e t ra = ’B ’ ; 5 switch ( le t ra ) { default : p r i n t f ( " Entrou em Default " ) ; 7 case ’A’ : p r i n t f ( " Entrou em A" ) ; break ; case ’B ’ : p r i n t f ( " Entrou em B " ) ; break ; 9 case ’C’ : p r i n t f ( " Entrou em C" ) ; break ; case ’D’ : p r i n t f ( " Entrou em D" ) ; break ; 11 } return 0; 13 } Pergunta-se Qual a saída? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 65 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - switch 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { char l e t ra = ’b’ ; 5 switch ( le t ra ) { case ’A’ : p r i n t f ( " Entrou em A" ) ; break ; 7 case ’B ’ : p r i n t f ( " Entrou em B " ) ; break ; default : p r i n t f ( " Entrou em Default " ) ; 9 case ’C’ : p r i n t f ( " Entrou em C" ) ; break ; case ’D’ : p r i n t f ( " Entrou em D" ) ; break ; 11 } return 0; 13 } Pergunta-se Qual a saída? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 66 / 341 Sintaxe Básica – Comandos condicionais Exemplo switch 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { char op; 5 p r i n t f ( " D ig i te um operador (+−/∗): " ) ; scanf ( "%c" , &op ) ; 7 switch (op) { 9 case ’+ ’ : case ’−’ : p r i n t f ( " Operador de Baixa Prior idade .\n " ) ; break ; 11 case ’∗ ’ : case ’ / ’ : p r i n t f ( " Operador de Alta Pr ior idade .\n " ) ; break ; 13 default : p r i n t f ( " Caractere Inval ido !\n " ) ; } 15 return 0; 17 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 67 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - Operador Ternário Existem situações cujo uso do if não é “elegante” Por exemplo, suponha que a função max retorne o maior número dentre os dois passados via parâmetros formais 1 i n t max( i n t a, i n t b) { i f (a > b) { 3 return a; } else { 5 return b; } 7 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 68 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - Operador Ternário O operador ternário é uma expressão, significando que ele devolve um valor O operador ternário é muito útil para condicionais (curtas e simples) e tem o seguinte formato: variável = <condição> ? seTrue : seFalse; A condição pode estar envolvida entre parênteses para facilitar a leitura, contudo não é obrigatório Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 69 / 341 Sintaxe Básica – Comandos condicionais Exemplos: i n t a = 2; i n t b = 3; i n t c = ( a > b ) ? a : b; Indica que se a for maior que b, c recebe o valor de a, caso contrário recebe o valor de a, isto é, c recebe o maior valor entre a e b Pergunta-se Qual o valor das variáveis abaixo: i n t peso = ( 2 != 2 ) ? 80 : 63; char l e t ra = ( 1 == 1 ) ? ’R ’ : ’ T ’ ; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 70 / 341 Sintaxe Básica – Comandos condicionais Comandos condicionais - Operador Ternário Não necessariamente o retorno do operador ternário deve ser atribuído a uma variável Por exemplo, seu retorno pode ser o retorno de uma função como faz a função max com operador ternário: i n t max( i n t a, i n t b) { return (a > b) ? a : b; } Ou mesmo o retorno pode servir como parâmetro de chamada de uma função: p r i n t f ( (a > b) ? "a maior ! " : "b maior ! " ) ; p r i n t f ( "%d" , (a > b) ? a : b ) ; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 71 / 341 Sintaxe Básica Comandos de repetição Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 72 / 341 Sintaxe Básica – Comandos de repetição Comandos repetição (while, do...while e for) Comandos de repetição são utilizados para repetir um bloco de código C provê suporte a três comandos de repetição: while (enquanto) do...while (faça...enquanto) for (para) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 73 / 341 Sintaxe Básica – Comandos de repetição Comandos repetição - while O comando while é utilizado para repetir um bloco de acordo com uma condição É considerado um loop de pré-teste Isto é, testa a condição antes de executar o bloco Sintaxe: while ( condicao ) { comando1; comando2; comandoN; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 74 / 341 Sintaxe Básica – Comandos de repetição Comandos repetição - while 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t i = 0 ; 5 while ( i < 10) { 7 p r i n t f ( "%d" , ++ i ) ; } 9 return 0; 11 } Pergunta-se Qual a saída? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 75 / 341 Sintaxe Básica – Comandos de repetição Comandos repetição - do...while O comando do...while é semelhante ao while, contudo é um comando de repetição de pós-teste Isto é, somente ao final da execução do bloco que se verifica a condição Geralmente, é utilizado quando se deseja testar a condição somente a partir da segunda iteração Por exemplo, uma leitura da opção de um menu. Pede para digitar uma primeira vez. Somente se não digitar uma opção válida que pede para digitar novamente Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 76 / 341 Sintaxe Básica – Comandos de repetição Sintaxe: do { comando1; comando2; comandoN; } while ( condicao ) ; Observe o ponto-e-vírgula após os parênteses da condição. Não o esqueça! Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 77 / 341 Sintaxe Básica – Comandos de repetição Comandos repetição - do...while 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t i = 0 ; 5 do { 7 p r i n t f ( "%d" , ++ i ) ; } while (1 != 1 ) ; 9 return 0; 11 } Pergunta-se Qual a saída? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 78 / 341 Sintaxe Básica – Comandos de repetição Exemplo 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t i ; 5 do { 7 p r i n t f ( " D ig i te um numero entre 0 e 10: " ) ; scanf ( "%d" , & i ) ; 9 } while ( i < 0 || i > 10) ; 11 p r i n t f ( "Numero digitado : %d\n " , i ) ; 13 return 0; } Pergunta-se Qual a saída? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 79 / 341 Sintaxe Básica – Comandos de repetição Comandos de repetição - for Comando de repetição mais poderoso da linguagem C É composta por: Inicialização: executado uma única vez no início do loop Condição: executado sempre antes de cada iteração. Se verdadeira, o bloco é executado. Se falsa,é finalizado Operação : executado sempre ao término de cada iteração Sintaxe f o r ( i n ic ia l i zacao ; condicao ; operacao ) { comando1; comando2; . . . comandoN; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 80 / 341 Sintaxe Básica – Comandos de repetição Exemplo #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t i ; 6 f o r ( i = 0 ; i < 10; i ++) { p r i n t f ( "%d" , i ) ; 8 } 10 return 0; } Pergunta-se Qual a saída? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 81 / 341 Sintaxe Básica – Comandos de repetição Sintaxe No laço for, a inicialização, condição e operação são todas opcionais Exemplo 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t i = 0 ; 5 f o r ( ; ; ) { /∗ Sem condicao , admite−se sempre verdade ∗/ p r i n t f ( "%d" , ++ i ) ; 7 } return 0; 9 } Pergunta-se Qual a saída? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 82 / 341 Sintaxe Básica – Comandos de repetição Comandos de repetição - for Podemos ter um for dentro de outro, e outro dentro de outro, e outro dentro de outro... 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t i , j ; 5 f o r ( i = 0 ; i <= 2 ; i ++) { 7 f o r ( j = 0 ; j < 2 ; j ++) { p r i n t f ( "%d %d" , i , j ) ; 9 } } 11 return 0; } Pergunta-se Qual a saída? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 83 / 341 Sintaxe Básica – Comandos de repetição Comandos de repetição - for Um comando for pode ter várias inicializações, uma condição complexa e várias operações Exemplo #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t i , d ; 6 f o r ( i = 1 , d = 2 ∗ i ; i <= 10 || d == 22; i ++ , d = i ∗ 2) { p r i n t f ( "%d − %d\n " , i , d ) ; 8 } 10 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 84 / 341 Sintaxe Básica – Comandos de repetição Comando break Inserido dentro de um bloco de repetição (pode também ser while ou do...while) Caso seja executado, o bloco de repetição é finalizado Exemplo 1 i n t main( i n t argc , char ∗argv [ ] ) { i n t i = 0 ; 3 f o r ( ; i < 10; i ++) { i f ( i == 3) { 5 break ; } 7 p r i n t f ( "%d" , i ) ; } 9 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 85 / 341 Sintaxe Básica – Comandos de repetição Comando continue Inserido dentro de um bloco de repetição Caso seja executado, a iteração atual do bloco de repetição é interrompida e parte para a próxima iteração Exemplo i n t main( i n t argc , char ∗argv [ ] ) { 2 i n t i ; f o r ( i = 0 ; i < 10; i ++) { 4 i f ( i == 3 || i == 5) { continue ; 6 } p r i n t f ( "%d" , i ) ; 8 } return 0; 10 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 86 / 341 Sintaxe Básica – Comandos de repetição Comando de repetição - for Logicamente, pode-se utilizar break e continue conjuntamente Exemplo i n t main( i n t argc , char ∗argv [ ] ) { 2 i n t i , j ; f o r ( i = 0 ; i < 3 ; i ++) { 4 i f ( i == 1) { continue ; 6 } f o r ( j = 0 ; j < 2 ; j ++) { 8 p r i n t f ( "%d %d\n " , i , j ) ; break ; 10 } } 12 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 87 / 341 Sintaxe Básica – Comandos de repetição Comando de repetição rotulados Ao contrário de linguagens como Java, C ANSI não possui blocos de repetição rotulados Por exemplo, dependendo uma certa condição de um bloco mais interno, você quer quebrar ou continuar a partir do bloco mais externo Exemplo em Java 1 externo : f o r ( i =0; i < 3 ; i ++) { 3 f o r ( j =0; j < 3 ; j ++) { i f ( i == 1 && j == 1) { 5 break externo ; } 7 System . out . p r i n t f ( "%d %d\n " , i , j ) ; } 9 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 88 / 341 Sintaxe Básica – Comandos de repetição Exemplo Neste exemplo, se o valor de j e de k forem 1, o bloco de repetição de k é encerrado e volta a iteração do bloco de repetição de j E se fosse para encerrar o for mais externo? Exemplo 1 i n t main( i n t argc , char ∗argv [ ] ) { i n t i , j , k ; 3 f o r ( i = 0 ; i < 3 ; i ++) { f o r ( j = 0 ; j < 3 ; j ++) { 5 f o r ( k = 0 ; k < 3 ; k++) { i f ( j == 1 && k == 1) { 7 break ; } 9 p r i n t f ( "%d %d %d\n " , i , j , k ) ; } 11 } } 13 p r i n t f ( " Programa Encerrado . " ) ; return 0; 15 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 89 / 341 Sintaxe Básica – Comandos de repetição Solução A solução seria utilizar rótulos (labels) Contudo, seu uso é perigoso e pouco recomendado Exemplo 1 i n t main( i n t argc , char ∗argv [ ] ) { i n t i , j , k ; 3 f o r ( i =0; i <3; i ++) { f o r ( j =0; j <3; j ++) { 5 f o r ( k =0; k <3; k++) { i f ( j == 1 && k == 1) { 7 goto fora ; } 9 p r i n t f ( "%d %d %d\n " , i , j , k ) ; } 11 } } 13 fora : p r i n t f ( " Programa Encerrado . " ) ; 15 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 90 / 341 Sintaxe Básica Arranjos Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 91 / 341 Sintaxe Básica – Arranjos Arranjos - Conceito Arranjos – também conhecidos como vetor, array etc – são coleções de um mesmo tipo em sequência Arranjos podem ser de tipos primitivos (char, int, float, double), de um outro arranjo, de uma estrutura, de enumeração... Pode se ter um arranjo de inteiros ou um arranjo de caracteres ou um arranjo de arranjo de pontos flutuantes Contudo, não se pode ter um arranjo que contenha inteiros e pontos flutuantes Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 92 / 341 Sintaxe Básica – Arranjos Arranjos - Declaração Declaração: i n t notas [ 5 ] ; /∗ Arranjo de 5 i n t e i r o s ∗/ 2 char l e t r a s [ 5 ] ; /∗ Arranjo de 5 caracteres ∗/ Assim como variáveis comuns, os elementos do arranjo não são inicializados automaticamente. Contudo, você pode declarar já inicializando: i n t notas [5 ] = {4 ,6 ,6 ,9 ,8 } ; 2 char l e t r a s [5 ] = {65 , ’E ’ , ’ I ’ , ’O’ , ’U ’ } ; char nome[100] = "ANA" ; /∗ s t r i n g de 100 caracteres ∗/ Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 93 / 341 Sintaxe Básica – Arranjos Arranjos - Declaração Um arranjo de tamanho n, tem suas posições indexadas de 0 a n-1. Exemplo: 1 i n t notas [ 5 ] = {8 ,7 ,8 ,9 ,3 } ; notas [ 3 ] = 7 ; 3 p r i n t f ( "%d" , notas [ 4 ] ) ; Para obter o tamanho de um arranjo, basta dividir o seu tamanho pelo tamanho ocupado por cada elemento utilizando a função sizeof. Exemplo: 1 i n t tam = s i zeof ( notas ) / s i zeof ( i n t ) ; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 94 / 341 Sintaxe Básica – Arranjos Declarando, inicializando e iterando um arranjo de inteiros 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t notas [ 5 ] , i ; 5 i n t tam = s i zeof ( notas ) / s i zeof ( i n t ) ; 7 f o r ( i = 0 ; i < tam; i ++) { 9 notas [ i ] = 0 ; } 11 return 0; 13 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 95 / 341 Sintaxe Básica – Arranjos Declarando, inicializando e iterando um arranjo de caracteres #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t i ; char vogais [ 5 ] = { ’A’ , ’E ’ , ’ I ’ , ’O’ , ’U ’ } ; 6 f o r ( i = 0 ; i < s i zeof ( vogais ) / s i zeof ( char ) ; i ++) { 8 p r i n t f ( "%c" , vogais [ i ] ) ; } 10 return 0; 12 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 96 / 341 Sintaxe Básica – Arranjos Arranjos - Acesso aos elementos Arranjos permite recuperar ou alterar qualquer um de seus elementos Os arranjos em C sempre iniciam-se na posição 0 Isto indica que ele termina em uma posição inferior ao tamanho (n-1) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 97 / 341 Sintaxe Básica – Arranjos Exemplo #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 char l et r a s [ 1 0 ] ; 6 l e t r a s [ 0 ] = ’A’ ; /∗ A t r i b u i a 1a posicao do arranjo ∗/ p r i n t f ( "%c" , l e t r a s [ 0 ] ) ; /∗ Imprime a 1a posicao do arranjo ∗/ 8 l e t r a s [ 1 ] = ’B ’ ; 10 l e t r a s [ 2 ] = ’C’ ; /∗ . . . ∗/ 12 l e t r a s [ 9 ] = ’H’ ; l e t r a s [10] = ’ I ’ ; /∗ ERRO ∗/ 14 return 0; 16 } O erro acima acessa uma área de memória não reservada ao arranjo. Isso pode alterar o funcionamento normal do programa ou até mesmo "derrubá-lo" Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 98 / 341 Sintaxe Básica – Arranjos Entendendo arranjos de caracteres Um arranjo de caracteres é como qualquer outro arranjo. Se ele tem tamanho n, ele tem n posições disponíveis indexadas de 0 a n-1 Um arranjo de caracteres não é um string Em C, não existe o tipo string. Ele é simulado por um arranjo de caracteres em que o caractere ‘\0’ delimita o seu final Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 99 / 341 Sintaxe Básica – Arranjos Arranjo de caracteres como Arranjo de caracteres Suas posições válidas são – como de todos os arranjos – de 0 a n-1 Seu tamanho é calculado pelo uso da função sizeof A leitura/impressão de cada caractere usa-se %c Exemplo 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { char placa [ 7 ] = { ’B ’ , ’A’ , ’D’ , ’0 ’ , ’0 ’ , ’0 ’ , ’7 ’ } ; 5 i n t i ; 7 f o r ( i = 0 ; i < s i zeof (placa ) / s i zeof ( char ) ; i ++) { p r i n t f ( "%c" , placa [ i ] ) ; 9 } 11 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 100 / 341 Sintaxe Básica – Arranjos Arranjo de caracteres como string Suas posições válidas são de 0 a n-2. No pior caso, a posição n-1 deve conter o terminador nulo Seu tamanho é calculado pelo uso da função srtlen da biblioteca string.h A leitura utiliza a função gets e a impressão usa-se %s Exemplo #include<std io . h> 2 #include< s t r i n g . h> 4 i n t main( i n t argc , char ∗argv [ ] ) { char nome[ 100 ] ; 6 gets (nome) ; /∗ Le s t r i n g ∗/ 8 p r i n t f ( "O nome digitado f o i %s (%d caracteres ) " , nome, ( i n t ) s t r l e n (nome ) ) ; 10 return 0; 12 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 101 / 341 Sintaxe Básica – Arranjos Arranjos - Cópia Observe o seguinte trecho: int vA[4] = {1,2,3,4}, vB[4]; Cópia completamente errada: vB = vA; Cópia correta: f o r ( i =0; i <4; i ++){ 2 vB [ i ] = vA[ i ] ; } Isto é, uma posição de cada vez No for, utilizei a literal 4 para limitar a iteração somente para demonstração, contudo qual seria mais apropriado? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 102 / 341 Sintaxe Básica – Arranjos Arranjos Multidimensionais Pode-se criar um arranjo de arranjos O mais comum é o bidimensional que vemos como uma matriz A declaração é somente acrescentar o número de colunas Por exemplo: int matriz[4][3] declara-se uma matriz de 4 linhas e 3 colunas matriz[4][3] = {{1,0,0},{0,1,2},{2,3,4},{0,6,7}}; Representação : 1 0 0 0 1 2 2 3 4 0 6 7 Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 103 / 341 Sintaxe Básica – Arranjos Arranjo Bidimensional - Exemplo Criando uma matriz 3x2, zerando e setando valores 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t matr iz [ 3 ] [ 2 ] , i , j ; /∗ Declara uma matr iz 3x2 ∗/ 5 f o r ( i = 0 ; i < 3 ; i ++) { f o r ( j = 0 ; j < 2 ; j ++) { 7 matriz [ i ] [ j ] = 0 ; } 9 } 11 matriz [ 0 ] [ 0 ] = 1 ; /∗ A t r i b u i o valor 1 ao canto super ior esquerdo ∗/ matriz [ 2 ] [ 1 ] = 7 ; /∗ A t r i b u i o valor 7 ao canto i n f e r i o r d i r e i t o ∗/ 13 return 0; 15 } matriz 1 0 0 0 0 7 Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 104 / 341 Sintaxe Básica – Arranjos Arranjo Bidimensional - Exemplo com sizeof O exemplo anterior não utilizou sizeof porque o cálculo do tamanho depende do entendimento de ponteiros. Só para saberem, o certo seria: #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t matr iz [ 3 ] [ 2 ] , i , j ; /∗ Declara uma matr iz 3x2 ∗/ f o r ( i = 0 ; i < s i zeof ( matriz ) / s i zeof ( matriz [ i ] ) ; i ++) { 6 f o r ( j = 0 ; j < s i zeof ( matriz [ i ] ) / s i zeof ( i n t ) ; j ++) { matriz [ i ] [ j ] = 0 ; 8 } } 10 matriz [ 0 ] [ 0 ] = 1 ; /∗ A t r i b u i o valor 1 ao canto super ior esquerdo ∗/ 12 matriz [ 2 ] [ 1 ] = 7 ; /∗ A t r i b u i o valor 7 ao canto i n f e r i o r d i r e i t o ∗/ 14 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 105 / 341 Sintaxe Básica – Arranjos Exemplo Completo Leitura de cada elemento de uma matriz 2x3 e posterior impressão #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t matr iz [ 2 ] [ 3 ] , i , j ; 6 f o r ( i = 0 ; i < s i zeof ( matriz ) / s i zeof ( matriz [ i ] ) ; i ++) { f o r ( j = 0 ; j < s i zeof ( matriz [ i ] ) / s i zeof ( i n t ) ; j ++) { 8 p r i n t f ( " D ig i te matr iz [%d][%d ] : " , i , j ) ; scanf ( "%d" , &matriz [ i ] [ j ] ) ; 10 } } 12 f o r ( i = 0 ; i < s i zeof ( matriz ) / s i zeof ( matriz [ i ] ) ; i ++) { 14 f o r ( j = 0 ; j < s i zeof ( matriz [ i ] ) / s i zeof ( i n t ) ; j ++) { p r i n t f ( "%d\t " , matriz [ i ] [ j ] ) ; 16 } p r i n t f ( " \n " ) ; 18 } 20 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 106 / 341 Sintaxe Básica Variáveis Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 107 / 341 Sintaxe Básica – Variáveis Variáveis Uma variável é uma posição nomeada de memória São declaradas basicamente em três lugares: dentro de funções → variáveis locais nos parâmetros de funções→ parâmetros formais fora de todas as funções → variáveis globais Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 108 / 341 Sintaxe Básica – Variáveis Variáveis Variáveis locais são reconhecidas apenas dentro do bloco em que foi declarada e existem apenas enquanto o bloco de código em que foi declarada está sendo executado Parâmetros formais serão vistos quando abordarmos funções, mas, para adiantar, se comportam exatamente como variáveis locais que são reconhecidas apenas dentro da função Variáveis globais são variáveis declaradas fora de qualquer função que são reconhecidas por todo o programa e podem ser utilizadas por qualquer bloco de código Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 109 / 341 Sintaxe Básica – Variáveis Exemplo 1 #include<std io . h> #include<math . h> 3 const double PI = 3.141596; /∗ Variavel Global ∗/ 5 double area(double r ) { /∗ Parametro Formal ∗/ 7 return PI ∗ pow( r , 2 ) ; } 9 i n t main( i n t argc , char ∗argv [ ] ) { 11 double raio ; /∗ Variavel Local ∗/ p r i n t f ( " D ig i te o raio : " ) ; 13 scanf ( "% l f " , &raio ) ; p r i n t f ( "A area da circunferencia e : % l f " , area( raio ) ) ; 15 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 110 / 341 Sintaxe Básica – Variáveis Variáveis Globais Características: São declaradas no arquivo fonte fora do escopo de qualquer função Existem durante todo o ciclo de vida do programa Só são acessíveis às funções declaradas depois delas no mesmo arquivo fonte Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 111 / 341 Sintaxe Básica – Variáveis Variáveis Globais - Exemplo #include<std io . h> 2 void func1 ( ) { 4 p r i n t f ( " Var . Global g nao acess ivel " ) ; } 6 i n t g ; /∗ var iavel global ∗/ 8 void func2 ( ) { 10 g++; p r i n t f ( " Var . Global g acess ivel : %d" , g ) ; 12 } 14 i n t main( i n t argc , char ∗argv [ ] ) { g = 5; 16 func1 ( ) ; func2 ( ) ; 18 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 112 / 341 Sintaxe Básica – Variáveis Variáveis Uma variável dentro de um bloco interno esconde a variável de mesmo nome no bloco externo Observe os exemplos a seguir em que temos variáveis com o mesmo nome emníveis lexicográficos diferentes e tente aferir a saída gerada pelo programa Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 113 / 341 Sintaxe Básica – Variáveis Variáveis - Níveis Lexicográficos 1 #include<std io . h> 3 i n t i = 8; /∗ var iavel global∗/ 5 i n t main( i n t argc , char ∗argv [ ] ) { i n t i = 3; 7 p r i n t f ( "%d" , i ) ; return 0; 9 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 114 / 341 Sintaxe Básica – Variáveis Variáveis - Níveis Lexicográficos 1 #include<std io . h> 3 i n t a ; /∗ var iavel global ∗/ 5 void func ( i n t a) { /∗ parametro formal ∗/ p r i n t f ( "%d" , a ) ; 7 i f (a > 2) { i n t a = 7; /∗ var iavel local ∗/ 9 p r i n t f ( "%d" , a ) ; } 11 a += 7; p r i n t f ( "%d" , a ) ; 13 } 15 i n t main( i n t argc , char ∗argv [ ] ) { a = 3; /∗ atr ibuicao a var iavel global ∗/ 17 func (a ) ; p r i n t f ( "%d" , a ) ; 19 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 115 / 341 Sintaxe Básica Funções Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 116 / 341 Sintaxe Básica – Funções Função Um programa C é uma coleção de funções Uma das funções deve se chamar main ponto de entrada Uma função pode: receber parâmetros declarar variáveis locais conter instruções executáveis retornar um valor Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 117 / 341 Sintaxe Básica – Funções Função Uma função não pode declarar outra função Este é o motivo pelo qual a linguagem C não é classificada integralmente como estruturada em blocos Isso não pode! i n t f ( ) { 2 . . . . . . 4 i n t g ( ) { /∗ Nao pode! ∗/ 6 } . . . 8 . . . } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 118 / 341 Sintaxe Básica – Funções Função A função deve ser declarada antes do local onde é chamada O comando return efetua o retorno (término) da função Uma função pode ou não ter um retorno Uma função pode ou não ter parâmetros formais Exemplos 1 void m1( ) { . . . } /∗ sem retorno e sem parametros formais ∗/ 3 void m2(double x ) { . . . } /∗ sem retorno e com um par . formal ∗/ 5 i n t m3( ) { . . . } /∗ com retorno e sem parametros formais ∗/ 7 i n t m4( char c, i n t f ) { . . . } /∗ com retorno e com dois param. ∗/ Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 119 / 341 Sintaxe Básica – Funções Ordem de Declaração Função deve ser declarada antes de seu uso: no caso, soma está declarada antes de main 1 #include<std io . h> 3 i n t soma( i n t x , i n t y ) { /∗ parametros Formais ∗/ return x + y ; 5 } 7 i n t main( i n t argc , char ∗argv [ ] ) { i n t a = 2 , b = 3 , to ta l ; 9 /∗ chamada a funcao : valores de a e b copiados para x e y ∗/ 11 to ta l = soma(a, b ) ; 13 p r i n t f ( "Soma: %d" , to ta l ) ; return 0; 15 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 120 / 341 Sintaxe Básica – Funções Função Sintaxe: retorno nome ( < param { , param} > ) { corpo } Exemplos 1 void imprimir ( ) { . . . } 3 i n t dobro ( i n t x ) { . . . } 5 double somar (double a, double b) { . . . } 7 void l i s t a r ( i n t notas [ ] , i n t tam) { . . . } Convém salientar que a passagem de parâmetros em C é sempre por valor, i.e., os valores são copiados da origem para o destino Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 121 / 341 Sintaxe Básica – Funções Exemplo - Passagem por Valor 1 #include<std io . h> 3 void func ( i n t k ) { k = 3; 5 } 7 i n t main( i n t argc , char ∗argv [ ] ) { i n t i = 2; 9 func ( i ) ; p r i n t f ( "%d" , i ) ; 11 return 0; } Pergunta-se Qual o valor de i impresso? Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 122 / 341 Sintaxe Básica – Funções Função Retorno de funções Uma função pode retornar valores de qualquer tipo, exceto arranjos ou outras funções Uma função que retorna nada, deve ter seu retorno declarado como void A expressão que segue o return é o valor retornado não se deve colocar parênteses return x+y; e não return (x+y); O valor de retorno pode ser ignorado por exemplo, a função printf retorna um valor, mas geralmente se ignora Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 123 / 341 Sintaxe Básica – Funções Função Término de uma função Ao encontrar a chave de fechamento Ao ser retornada (return) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 124 / 341 Sintaxe Básica – Funções Exemplo #include<std io . h> 2 #include< s t r i n g . h> 4 i n t imprimeRetornandoTamanho ( char s t r [ ] ) { p r i n t f ( "%s " , s t r ) ; 6 return s t r l e n ( s t r ) ; /∗ Nao precisa de parenteses , mas pode ∗/ } 8 i n t main( i n t argc , char ∗argv [ ] ) { 10 char s t r [ 100 ] ; p r i n t f ( " D ig i te o nome: " ) ; 12 gets ( s t r ) ; imprimeRetornandoTamanho ( s t r ) ; 14 return 0; } Tamanho do string retornado pela função foi ignorado Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 125 / 341 Sintaxe Básica – Funções Função Como já se sabe, arranjos podem ser passados como parâmetros para funções Contudo, ao se passar arranjos, além da função receber o arranjo, ela deve receber o tamanho do arranjo Pois, dentro da função não funcionará corretamente a função sizeof Exceção para arranjos de caracteres que estão representando strings, pois o tamanho do string é definido pelo caractere ’\0’ e é utilizada a função strlen Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 126 / 341 Sintaxe Básica – Funções Exemplo 1 #include<std io . h> 3 void imprimeArranjo ( i n t v [ ] , i n t tam) { i n t i ; 5 f o r ( i = 0 ; i < tam ; i ++) { p r i n t f ( "%4d" , v [ i ] ) ; 7 } } 9 i n t main( i n t argc , char ∗argv [ ] ) { 11 i n t v [ 4 ] = { 4 , 9 , 2 , 3 } ; imprimeArranjo (v , s i zeof (v ) / s i zeof ( i n t ) ) ; 13 return 0; } O tamanho deve ser passado Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 127 / 341 Sintaxe Básica – Funções Exemplo #include<std io . h> 2 #include< s t r i n g . h> 4 void imprimeStr ing ( char s t r [ ] ) { i n t i , tam; 6 tam = s t r l e n ( s t r ) ; f o r ( i = 0 ; i < tam; i ++) { 8 p r i n t f ( "%c" , s t r [ i ] ) ; } 10 } 12 i n t main( i n t argc , char ∗argv [ ] ) { char v [10] = { ’A’ , ’N’ , ’A’ , ’\0 ’ , ’ I ’ , ’X ’ , ’K ’ , ’^ ’ , ’%’ , ’ ! ’ } ; 14 imprimeStr ing (v ) ; return 0; 16 } Não precisa passar o tamanho quando o arranjo de caracteres estiver representando um string Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 128 / 341 Sintaxe Básica – Funções Exercícios de Fixação Implementar as funções: fatorial escreveMaior retornaMenorElemento retornaMaiorElemento retornaMedia Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 129 / 341 Sintaxe Básica – Funções Exercício - Fatorial #include<std io . h> 2 long i n t fa t ( i n t n) { 4 i n t i ; long i n t res = 1 ; 6 i f (n == 0 || n == 1) { return 1; 8 } f o r ( i = 2 ; i <= n ; i ++) { 10 res ∗= i ; } 12 return res ; } 14 i n t main( i n t argc , char ∗argv [ ] ) { 16 i n t n ; scanf ( "%d" , &n ) ; 18 p r i n t f ( "%d! = %ld " , n , fa t (n ) ) ; return 0; 20 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 130 / 341 Sintaxe Básica – Funções Exercício - Escreve Maior #include<std io . h> 2 void escreveMaior ( i n t n) { 4 i n t i ; f o r ( i = n ; i >= 1 ; i−−) { 6 p r i n t f ( "%d" , i ) ; p r i n t f ( ( i > 1) ? " > " : " \n " ) ; 8 } } 10 i n t main( i n t argc , char ∗argv [ ] ) { 12 i n t n ; scanf ( "%d" , &n ) ; 14 escreveMaior (n ) ; return 0; 16 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 131 / 341 Sintaxe Básica – Funções Exercício - Escreve Maior (hardcore) #include<std io . h> 2 void escreveMaior ( i n t n) { 4 f o r ( ; n >= 1; p r i n t f ( "%d" ,n ) , p r i n t f (n−− > 1 ? " > " : " \n " ) ); } 6 i n t main( i n t argc , char ∗argv [ ] ) { 8 i n t n ; scanf ( "%d" , &n ) ; 10 escreveMaior (n ) ; return 0; 12 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 132 / 341 Sintaxe Básica – Funções Exercício - Retorna Menor Elemento #include<std io . h> 2 i n t retornaMenorElemento ( i n t v [ ] , i n t tam) { 4 i n t i ; i n t menor = v [ 0 ] ; 6 f o r ( i = 1 ; i < tam ; i ++) { i f (v [ i ] < menor) { 8 menor = v [ i ] ; } 10 } return menor ; 12 } 14 i n t main( i n t argc , char ∗argv [ ] ) { i n t v [ 5 ] = { 2 , 4 , 5 , 1 , 3 } ; 16 i n t tam = s i zeof (v ) / s i zeof ( i n t ) ; p r i n t f ( "Menor e l . : %d" , retornaMenorElemento (v , tam ) ) ; 18 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 133 / 341 Sintaxe Básica – Funções Ordem de Declaração Uma função pode ser implementada após seu ponto de chamada ou mesmo em um outro arquivo fonte Entretanto, para utilizá-la deve-se especificar, ao menos, o seu protótipo O protótipo de uma função consiste em especificar seu retorno, seu nome e o tipo dos seus parâmetros formais Uma espécie de assinatura da função Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 134 / 341 Sintaxe Básica – Funções Funciona? 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t a = 2 , b = 3 , to ta l ; 5 to ta l = soma(a, b ) ; p r i n t f ( "Soma: %d" , to ta l ) ; 7 return 0; } 9 i n t soma( i n t x , i n t y ) { 11 return x + y ; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 135 / 341 Sintaxe Básica – Funções E agora? 1 #include<std io . h> 3 /∗Protot ipo ∗/ i n t soma( i n t , i n t ) ; 5 i n t main( i n t argc , char ∗argv [ ] ) { 7 i n t a = 2 , b = 3 , to ta l ; to ta l = soma(a, b ) ; 9 p r i n t f ( "Soma: %d" , to ta l ) ; return 0; 11 } 13 i n t soma( i n t x , i n t y ) { return x + y ; 15 } Com o uso de protótipo, a função main sabe que existe a função soma Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 136 / 341 Sintaxe Básica – Funções Importante É importante mencionar que o uso de protótipo não se limita apenas à função main, mas sim, à qualquer função que deseje acessar métodos declarados abaixo dela 1 #include<std io . h> 3 /∗Protot ipo∗/ i n t ePar ( i n t ) ; 5 i n t resto ( i n t , i n t ) ; 7 i n t main( i n t argc , char ∗argv [ ] ) { i n t n ; 9 scanf ( "%d" , &n ) ; p r i n t f ( ( ( ePar (n ) ) ? "%d eh par " : "%d eh impar " ) , n ) ; 11 return 0; } 13 i n t ePar ( i n t n) { 15 return resto (n , 2) ? 0 : 1 ; /∗ Acessando funcao declarada abaixo ∗/ } 17 i n t resto ( i n t x , i n t y ) { 19 return x % y ; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 137 / 341 Sintaxe Básica – Funções Recursão Como se sabe, uma função pode chamar uma outra função Essa “outra função” pode ser ela mesma Uma função que chama a si mesma é dita ser uma função recursiva Funções recursivas podem chamar a si mesmas direta ou indiretamente a( ) que chama a( ) a( ) que chama b( ) que chama a( ) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 138 / 341 Sintaxe Básica – Funções Recursão Existem problemas que são naturalmente recursivos O mais clássico é o fatorial 0! = 1! = 1 n! = n * (n-1)! Ao se implementar uma função recursiva, o mais importante é definir o seu ponto de parada No exemplo do fatorial, a recursão para quando se chega no 0 ou 1 Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 139 / 341 Sintaxe Básica – Funções Exercícios de Fixação Implementar as funções: fatorial recursivo fibonacci recursivo escreveMaior recursivo Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 140 / 341 Sintaxe Básica – Funções Exercício - Fatorial Recursivo #include<std io . h> 2 /∗Protot ipo ∗/ 4 long i n t fa t ( i n t ) ; 6 i n t main( i n t argc , char ∗argv [ ] ) { i n t n ; 8 scanf ( "%d" , &n ) ; p r i n t f ( "%d! = %ld " , n , fa t (n ) ) ; 10 return 0; } 12 long i n t f a t ( i n t n) { 14 i f (n == 0 || n == 1) { return 1; /∗ Ponto de Parada ∗/ 16 } return n ∗ fa t (n − 1 ) ; /∗ Codigo da Recursao ∗/ 18 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 141 / 341 Sintaxe Básica – Funções Exercício - Fibonacci Recursivo #include<std io . h> 2 /∗Protot ipo ∗/ 4 long i n t f i b ( i n t ) ; 6 i n t main( i n t argc , char ∗argv [ ] ) { i n t n ; 8 scanf ( "%d" , &n ) ; p r i n t f ( " f i b (%d) = %ld " , n , f i b (n ) ) ; 10 return 0; } 12 long i n t f i b ( i n t n) { 14 i f (n == 0 || n == 1) { /∗ Ponto de Parada ∗/ return n ; 16 } return f i b (n − 1) + f i b (n − 2 ) ; /∗ Codigo da Recursao ∗/ 18 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 142 / 341 Sintaxe Básica – Funções Algumas funções da biblioteca padrão Funções de E/S (stdio.h) printf(), scanf(), fprintf(), fscanf(), gets() Funções Matemáticas (math.h) sin(), cos(), exp(), log(), pow(), sqrt() Teste e manipulação de caracteres (ctype.h) isDigit(), isAlpha(), toupper() Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 143 / 341 Sintaxe Básica – Funções Algumas funções da biblioteca padrão Funções de propóstio geral (stdlib.h) malloc(), free(), exit(), rand() Manipulação de strings e arranjos (string.h) strcpy(), strcmp(), strcat(), memcpy() Manipulação de datas e horas (time.h) localtime(), time(), clock() Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 144 / 341 Sintaxe Básica Estruturas Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 145 / 341 Sintaxe Básica – Estruturas Estruturas (Struct) O que conhecemos como record em Pascal, em C é conhecido como struct Uma estrutura é uma coleção de variáveis referenciadas por um nome, fornecendo uma maneira conveniente de atribuir informações (variáveis) relacionadas de forma agrupada A definição de uma estrutura é um modelo a ser seguido por todas as variáveis de seu tipo As variáveis que compreendem a estrutura são também conhecidas como campos ou atributos da estrutura Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 146 / 341 Sintaxe Básica – Estruturas O exemplo abaixo cria uma estrutura para representação de uma data: s t r u c t data { 2 i n t dia ; i n t mes; 4 i n t ano; } Para declarar uma variável do tipo data, faz-se como abaixo: struct data d; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 147 / 341 Sintaxe Básica – Estruturas Instrução typedef A instrução typedef permite denotar novos nomes à linguagem Assim, pode-se utilizar o comando typedef para que se simplificar a declaração de variáveis de estrutura Exemplo 1 typedef s t r u c t { i n t dia ; 3 i n t mes; i n t ano; 5 } data ; Assim, a estrutura é simplesmente conhecida como data e declaração se faz como um tipo primitivo (char, int etc) data d; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 148 / 341 Sintaxe Básica – Estruturas Exemplo struct – Atribuição e Acesso aos elementos 1 #include<std io . h> 3 typedef s t r u c t { i n t dia ; 5 i n t mes ; i n t ano ; 7 } data ; 9 i n t main( i n t argc , char ∗argv [ ] ) { data d ; 11 d . dia = 31; d .mes = 12; 13 d .ano = 1999; 15 p r i n t f ( "A data e %2.d/%2.d/%4.d\n " , d . dia , d .mes, d .ano ) ; 17 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 149 / 341 Sintaxe Básica – Estruturas Exemplo struct – Leitura e Acesso aos elementos #include<std io . h> 2 typedef s t r u c t { 4 i n t dia ; i n t mes ; 6 i n t ano ; } data ; 8 i n t main( i n t argc , char ∗argv [ ] ) { 10 data d ; 12 scanf ( "%d" , &d . dia ) ; scanf ( "%d" , &d .mes ) ; 14 scanf ( "%d" , &d .ano ) ; 16 p r i n t f ( "A data e %2.d/%2.d/%4.d\n " , d . dia , d .mes, d .ano ) ; 18 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 150 / 341 Sintaxe Básica – EstruturasExemplos (struct) Vamos a seguir, ver e entender mais exemplos utilizando estruturas Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 151 / 341 Sintaxe Básica – Estruturas Exemplo 1 Um exemplo que possui uma estrutura chamada cliente e que, dentro dessa estrutura, possui um campo do tipo endereco (outra estrutura), i.e., um cliente possui suas informações e ainda possui um endereço Nesse exemplo, serão lidos todos os dados de um cliente e depois serão impressos os dados lidos (observe a notação ponto para acessar os membros de uma estrutura) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 152 / 341 Sintaxe Básica – Estruturas 1 #include<std io . h> 3 typedef s t r u c t { char logradouro [ 6 0 ] ; 5 i n t numero ; } endereco ; 7 typedef s t r u c t { 9 i n t codigo ; char nome[ 6 0 ] ; 11 endereco e ; } cl iente ; 13 i n t main( i n t argc , char ∗argv [ ] ) { 15 cl iente c ; 17 p r i n t f ( "Codigo : " ) ; scanf ( "%d" , &c . codigo ) ; 19 p r i n t f ( "Nome: " ) ; gets (c .nome) ; 21 p r i n t f ( " Logradouro : " ) ; gets (c . e . logradouro ) ; 23 p r i n t f ( "Numero: " ) ; scanf ( "%d" , &c . e . numero ) ; 25 p r i n t f ( " Cl iente %d: %s res ide em %s , %d\n " , c . codigo , c .nome, 27 c . e . logradouro , c . e . numero ) ; 29 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 153 / 341 Sintaxe Básica – Estruturas Exemplo 2 Um exemplo que possui uma estrutura chamada carro e que, dentro dessa estrutura, possui um campo do tipo proprietario (outra estrutura), i.e., um carro possui suas informações e ainda possui um proprietário Nesse exemplo, serão atribuídos todos os dados de um carro e depois serão impressos os dados atribuídos (observe a notação ponto para acessar os membros de uma estrutura) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 154 / 341 Sintaxe Básica – Estruturas #include<std io . h> 2 #include< s t r i n g . h> 4 typedef s t r u c t { i n t rg ; 6 char nome[ 6 0 ] ; } propr ie tar io ; 8 typedef s t r u c t { 10 char modelo[ 3 0 ] ; i n t ano; 12 char placa [ 7 ] ; propr ie tar io p ; 14 } carro ; 16 i n t main( i n t argc , char ∗argv [ ] ) { carro c ; 18 st rcpy (c . modelo, "GOL" ) ; 20 c .ano = 2010; strncpy (c . placa , "BAD0007 " , 7 ) ; 22 c .p . rg = 10200300; st rcpy (c .p .nome, " Ricardo Terra " ) ; 24 p r i n t f ( "CARRO: %s , ano %d, placa %.7 s\n " , c . modelo, c .ano, c . placa ) ; 26 p r i n t f ( " PROPRIETARIO : %s (RG: %d) " , c .p .nome, c .p . rg ) ; 28 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 155 / 341 Sintaxe Básica – Estruturas Dica: A atribuição pode ser simplificada Observe declaração da variável carro 1 #include<std io . h> #include< s t r i n g . h> 3 typedef s t r u c t { 5 i n t rg ; char nome[ 6 0 ] ; 7 } propr ie tar io ; 9 typedef s t r u c t { char modelo[ 3 0 ] ; 11 i n t ano; char placa [ 7 ] ; 13 propr ie tar io p ; } carro ; 15 i n t main( i n t argc , char ∗argv [ ] ) { 17 carro c = { "GOL" , 2010 , "BAD0007 " , { 10200300 , " Ricardo Terra " } } ; 19 p r i n t f ( "CARRO: %s , ano %d, placa %.7 s\n " , c . modelo, c .ano, c . placa ) ; p r i n t f ( " PROPRIETARIO : %s (RG: %d) " , c .p .nome, c .p . rg ) ; 21 return 0; 23 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 156 / 341 Sintaxe Básica – Estruturas Exemplo 2 Um exemplo que possui uma estrutura chamada aluno e que, dentro dessa estrutura, possui um campo do tipo disciplina (outra estrutura) que possui um campo do tipo professor (outra estrutura), i.e., um aluno possui uma única disciplinas que está vinculada a um professor Nesse exemplo, serão atribuídos todos os dados de um aluno e depois serão impressos os dados lidos (observe a notação ponto para acessar os membros de uma estrutura) Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 157 / 341 Sintaxe Básica – Estruturas 1 #include<std io . h> 3 typedef s t r u c t { i n t ctps ; 5 char nome[ 6 0 ] ; } professor ; 7 typedef s t r u c t { 9 i n t codigo ; char nome[ 6 0 ] ; 11 professor prof ; } disc ip l ina ; 13 typedef s t r u c t { 15 i n t matricula ; char nome[ 6 0 ] ; 17 disc ip l ina disc ; } aluno ; 19 i n t main( i n t argc , char ∗argv [ ] ) { 21 aluno a = { 40 , "JORGE" , { 1 , "ED−I " , { 1001 , " Terra " } } } ; 23 p r i n t f ( "%d\n " , a . matricula ) ; p r i n t f ( "%s\n " , a .nome) ; 25 p r i n t f ( "%d\n " , a . disc . codigo ) ; p r i n t f ( "%s\n " , a . disc .nome) ; 27 p r i n t f ( "%d\n " , a . disc . prof . ctps ) ; p r i n t f ( "%s\n " , a . disc . prof .nome) ; 29 return 0; 31 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 158 / 341 Conteúdo 1 Introdução 2 Sintaxe Básica 3 Ponteiros Conceitualização Aritmética Alocação Dinâmica de Memória Alocação Dinâmica de Arranjos Multidimensionais 4 Tópicos Relevantes 5 Extras Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 159 / 341 Ponteiros Conceitualização Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 160 / 341 Ponteiros – Conceitualização O que são ponteiros? Um ponteiro é uma variável que contém um endereço de memória Esse endereço é normalmente a posição de uma outra variável na memória Se uma variável contém o endereço de uma outra, então a primeira variável é dita apontar para a segunda Eis a origem do nome ponteiro Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 161 / 341 Ponteiros – Conceitualização Variáveis ponteiros? Se uma variável irá conter um ponteiro, ela deve ser declarada como tal. A forma geral para declarar uma variável ponteiro é: tipo *nome; Um ponteiro aponta para uma outra variavél. Contudo, em sua inicialização – como em todos os tipos de variáveis – seu valor inicial é lixo de memória. Utilizando NULL, pode-se criar um ponteiro e apontá-lo para nulo int *p = NULL; Para imprimir o endereço de memória, utiliza-se %p printf("O ponteiro p aponta para %p", p); Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 162 / 341 Ponteiros – Conceitualização Os operadores de ponteiros Inicialmente, existem dois operadores especiais para ponteiros: * e & O operador & é um operador unário que devolve o endereço na memória do seu operando Exemplo 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t count = 100; 5 i n t ∗p ; 7 p = &count ; 9 p r i n t f ( "O endereco apontado por p e %p" , p ) ; 11 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 163 / 341 Ponteiros – Conceitualização Os operadores de ponteiros É colocado em p o endereço da memória que contém a variável count Esse endereço é a posição interna ao computador daquela variável O endereço não tem relação alguma com o valor de count O operador & pode ser imaginado como “o endereço de”, assim como o comando de atribuição do último exemplo significa “p recebe o endereço de count” Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 164 / 341 Ponteiros – Conceitualização Os operadores de ponteiros O operador * é o complemento de &. É um operador unário que devolve o valor da variável localizada no endereço que o segue int q = *p; Sabendo que p contém o endereço da variável count, i.e., p aponta para count podemos pensar no resultado de duas maneiras: o exemplo coloca o valor de count em q o exemplo coloca o valor da variável apontada por p em q O operador * pode ser imaginado como “no endereço apontado por”, assim como o exemplo acima significa “q recebe o valor que está no endereço apontado por p” Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 165 / 341 Ponteiros – Conceitualização Exemplo #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t count = 100; i n t ∗p ; 6 p = &count ; 8 p r i n t f ( "%d" , ∗p ) ; /∗ Imprimira 100 ∗/ 10 ∗p = 34; /∗ Altera valor de count para34 ∗/ p r i n t f ( "%d" , count ) ; /∗ Imprimira 34 ∗/ 12 p r i n t f ( "%d" , ∗p ) ; /∗ Imprimira 34 ∗/ 14 return 0; } Observe que pode-se imprimir ou alterar o valor a partir do ponteiro para a variável Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 166 / 341 Ponteiros – Conceitualização Exemplo 1 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t x = 2; 5 i n t ∗p ; 7 p = &x ; /∗ Ponteiro recebe o endereco de x ∗/ ∗p = 4; /∗ O endereco apontado por p, recebe 4 ∗/ 9 p r i n t f ( " valor de x : %d\n " , x ) ; /∗ Imprimira 4 ∗/ 11 return 0; 13 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 167 / 341 Ponteiros – Conceitualização Exemplo 2 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t x = 2; 5 i n t ∗p1 , ∗p2 ; 7 /∗ Um ponteiro so recebe um endereco ou um outro ponteiro ∗/ p1 = &x ; 9 p2 = p1 ; 11 p r i n t f ( "%p = %p? Apontam para o mesmo endereco?\n " , p1 , p2 ) ; 13 p r i n t f ( " Valor apontado por p1 : %d\n " , ∗p1 ) ; /∗ Imprimira 2 ∗/ p r i n t f ( " Valor apontado por p2 : %d\n " , ∗p2 ) ; /∗ Imprimira 2 ∗/ 15 return 0; 17 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 168 / 341 Ponteiros – Conceitualização Passagem por valor A convenção de C de passagem de parâmetros é por valor, isto é, quando se passa o valor de uma variável para uma função, tem-se a certeza que seu valor não será alterado Exemplo 1 #include<std io . h> 3 void incrementa ( i n t x ) { x++; /∗ Incrementa x ∗/ 5 } 7 i n t main( i n t argc , char ∗argv [ ] ) { i n t x = 10; 9 incrementa (x ) ; /∗ Passei o valor de x ∗/ p r i n t f ( " valor de x : %d\n " , x ) ; /∗ Imprimira 10 ∗/ 11 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 169 / 341 Ponteiros – Conceitualização Simulando uma chamada por referência Muito embora a convenção de C de passagem de parâmetros seja por valor, você pode simular uma chamada por referência Para isso, passa-se o endereço de uma variável para um ponteiro (parâmetro formal de uma função) Isso faz com que o endereço da variável seja passado à função e, desse modo, você pode alterar o valor da variável fora da função Contudo, isso não se qualifica como passagem por referência, uma vez que o endereço da variável é copiado para o ponteiro, i.e., ainda é passagem por valor Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 170 / 341 Ponteiros – Conceitualização Simulando uma chamada por referência Endereços de variáveis são passados para as funções de forma simples Obviamente é necessário declarar os parâmetros formais da função como do tipo ponteiro Exemplo #include<std io . h> 2 void incrementa ( i n t ∗x ) { 4 (∗x )++; /∗ Incrementa o valor da var iavel apontada por x ∗/ } 6 i n t main( i n t argc , char ∗argv [ ] ) { 8 i n t x = 10; incrementa(&x ) ; /∗ Passei o endereco de x ∗/ 10 p r i n t f ( " valor de x : %d\n " , x ) ; /∗ Imprimira 11 ∗/ return 0; 12 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 171 / 341 Ponteiros – Conceitualização Exemplo - Função de troca de valores #include<std io . h> 2 void troca ( i n t ∗ , i n t ∗ ) ; /∗ Protot ipo ∗/ 4 i n t main( i n t argc , char ∗argv [ ] ) { 6 i n t x = 2 , y = 4; 8 p r i n t f ( " x = %d e y = %d\n " , x , y ) ; troca(&x , &y ) ; 10 p r i n t f ( " x = %d e y = %d\n " , x , y ) ; 12 return 0; } 14 void troca ( i n t ∗x , i n t ∗y ) { /∗ Observe o uso do aster i sco (∗ ) ∗/ 16 i n t temp = ∗x ; ∗x = ∗y ; 18 ∗y = temp; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 172 / 341 Ponteiros – Conceitualização Exemplo - Função de troca de valores (hardcore) 1 #include<std io . h> 3 void troca ( i n t ∗ , i n t ∗ ) ; /∗ Protot ipo ∗/ 5 i n t main( i n t argc , char ∗argv [ ] ) { i n t x = 2 , y = 4; 7 p r i n t f ( " x = %d e y = %d\n " , x , y ) ; 9 troca(&x , &y ) ; p r i n t f ( " x = %d e y = %d\n " , x , y ) ; 11 return 0; 13 } 15 void troca ( i n t ∗x , i n t ∗y ) { /∗ sem uso de var iavel a u x i l i a r ∗/ ∗x += ∗y ; /∗ x = ( x + y ) ∗/ 17 ∗y = ∗x − ∗y ; /∗ y = ( x + y ) − y = x ∗/ ∗x −= ∗y ; /∗ x = ( x + y ) − x = y ∗/ 19 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 173 / 341 Ponteiros Aritmética Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 174 / 341 Ponteiros – Aritmética Arranjos e Ponteiros Arranjos e ponteiros são intimamente relacionados em C O nome de um arranjo é um ponteiro constante para o primeiro elemento do arranjo Exemplo: double v[5]; Logo, as seguintes sintaxes são equivalentes: *v ↔ v[0] v ↔ &v[0] Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 175 / 341 Ponteiros – Aritmética Logo, são assinaturas equivalentes de funções: void funcao (float v[], int tam) ou void funcao (float *v, int tam) Logo, são chamadas equivalentes às funções: funcao(v, tam); ou funcao(&v[0], tam); Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 176 / 341 Ponteiros – Aritmética Possíveis operações: Sejam p, pa e pb ponteiros e i um número inteiro p + i → ponteiro p é deslocado i elementos para direita p - i → ponteiro p é deslocado i elementos para esquerda pa - pb → retorna a distância, em elementos, entre os ponteiros pa e pb Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 177 / 341 Ponteiros – Aritmética Portanto, segue-se que: double v[5]; v[0] = 1.4; ↔ *v = 1.4; v[2] = 1.6; ↔ *(v+2) = 1.6; Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 178 / 341 Ponteiros – Aritmética Aritmética de Ponteiros: + e - Movimentam um ponteiro levando em consideração o tamanho do tipo do elemento Observe: 1 f l o a t v [ 5 ] ; f l o a t ∗p ; 3 p = v ; /∗Ponteiro p está apontando para v [0 ] ∗/ p = v + 2; /∗Ponteiro p está apontando para v [2 ] ∗/ 5 p−−; /∗Ponteiro p está apontando para v [1 ] ∗/ Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 179 / 341 Ponteiros – Aritmética Exemplo 1 Assim que se iterava um arranjo: 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t i , v [ ] = { 13 , 15 , 17 , 19 , 21 } ; 5 i n t tam = s i zeof (v ) / s i zeof ( i n t ) ; 7 f o r ( i = 0 ; i < tam ; i ++) { p r i n t f ( "%d\t " , v [ i ] ) ; 9 } 11 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 180 / 341 Ponteiros – Aritmética Exemplo 2 - Arranjo de inteiros Agora, assim que se itera um arranjo: #include<std io . h> 2 i n t main( i n t argc , char ∗argv [ ] ) { 4 i n t i , v [ ] = { 13 , 15 , 17 , 19 , 21 } ; i n t tam = s i zeof (v ) / s i zeof ( i n t ) ; 6 i n t ∗p ; 8 f o r ( i = 0 , p = v ; i < tam ; i ++ , p++) { p r i n t f ( "%d\t " , ∗p ) ; 10 } 12 return 0; } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 181 / 341 Ponteiros – Aritmética Exemplo 2 - Arranjo de caracteres Idêntico ao anterior, porém o arranjo é de caracteres 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { char vogais [ ] = { 65 , ’E ’ , ’ I ’ , 79 , ’U ’ } ; 5 i n t i , tam = s i zeof ( vogais ) / s i zeof ( char ) ; char ∗p ; 7 f o r ( i = 0 , p = vogais ; i < tam ; i ++ , p++) { 9 p r i n t f ( "%c\t " , ∗p ) ; } 11 return 0; 13 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 182 / 341 Ponteiros – Aritmética Exemplo 3 Se além de um ponteiro para o primeiro elemento tivermos um outro ponteiro para o último elemento, pode-se iterar sem as variáveis i e tam: 1 #include<std io . h> 3 i n t main( i n t argc , char ∗argv [ ] ) { i n t v [ ] = { 13 , 15 , 17 , 19 , 21 } ; 5 i n t ∗p , ∗q ; i n t tam = s i zeof (v ) / s i zeof ( i n t ) ; 7 f o r (p = v , q = v + tam − 1; p <= q ; p++) { 9 p r i n t f ( "%d\t " , ∗p ) ; } 11 return 0; 13 } Ricardo Terra (rterrabh@gmail.com) Linguagem C 8 de julho de 2011 183 / 341 Ponteiros – Aritmética Ponteiros para estrutura A linguagem C ANSI
Compartilhar