Baixe o app para aproveitar ainda mais
Prévia do material em texto
MINISTÉRIO DA EDUCAÇÃO SECRETARIA DE EDUCAÇÃO PROFISSIONAL E TECNOLÓGICA INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DO TRIÂNGULO MINEIRO CAMPUS PARACATU Linguagem C Tecnologia em Análise e Desenvolvimento de Sistemas Prof. Gustavo Alexandre de Oliveira Silva Janeiro de 2016 SUMÁRIO Capítulo 1 Introdução à Linguagem C ................................................................................................................. 11 1. Histórico...................................................................................................................................... 11 2. A Linguagem de Programação C ................................................................................................. 13 2.1. Características da Linguagem de Programação C ................................................................ 14 2.2. Compiladores ....................................................................................................................... 14 2.3. Como Criar um Programa Executável .................................................................................. 15 Capítulo 2 Conceitos Básicos ............................................................................................................................... 17 1. A Estrutura Básica de um Programa em C.................................................................................. 17 1.1. Elementos Básicos do Programa ......................................................................................... 17 1.2. Instruções de Programa ....................................................................................................... 19 2. Diretivas do Pré-Processador ..................................................................................................... 21 2.1. A diretiva #include ............................................................................................................... 21 2.2. A diretiva #define................................................................................................................. 23 3. Detalhando a Estrutura Básica de um Programa em C .............................................................. 25 4. Introdução à Funções ................................................................................................................. 25 4.1. Argumentos e Parâmetros ................................................................................................... 26 4.2. Retornando Valores ............................................................................................................. 28 4.3. Sintaxe Básica ...................................................................................................................... 29 5. Introdução Básica às Entradas e Saídas ..................................................................................... 29 5.1. A Função PRINTF() ............................................................................................................... 29 5.2. A Função SCANF() ................................................................................................................ 31 6. Palavras Reservadas em Linguagem C........................................................................................ 32 Capítulo 3 Tipologia de Dados ............................................................................................................................. 33 1. Sintaxe ........................................................................................................................................ 33 2. Identificadores ............................................................................................................................ 34 3. Tipos de Dados ........................................................................................................................... 35 3.1. O Tipo CHAR ......................................................................................................................... 35 3.2. O Tipo INT ............................................................................................................................ 36 3.3. Os Tipos FLOAT e DOUBLE ................................................................................................... 36 3.4. O Tipo VOID ......................................................................................................................... 37 3.5. Modificadores de Tipos de Dados ....................................................................................... 37 3.6. Caracteres e Cadeias de Caracteres .................................................................................... 39 3.6.1. Caracteres ..................................................................................................................... 39 3.6.2. Cadeias de Caracteres (Strings) .................................................................................... 40 4. Variáveis ..................................................................................................................................... 41 4.1. Declaração de Variáveis em C .............................................................................................. 42 4.2. Escopo de Variáveis ............................................................................................................. 43 4.3. Classe de Armazenamento de Variáveis .............................................................................. 46 4.4. Inicialização de Variáveis ..................................................................................................... 49 5. Constantes .................................................................................................................................. 50 5.1. Comando #DEFINE ............................................................................................................... 51 5.2. Comando CONST .................................................................................................................. 52 5.3. Caracteres de Escape ........................................................................................................... 52 Capítulo 4 Operadores e Expressões ................................................................................................................... 54 1. Operadores ................................................................................................................................. 54 1.1. Operador de Atribuição ....................................................................................................... 54 1.2. Operadores Aritméticos ...................................................................................................... 56 1.3. Operadores Relacionais ....................................................................................................... 58 1.4. Operadores Lógicos ............................................................................................................. 59 1.5. Operadores Bit-a-Bit ............................................................................................................ 60 1.6. Operadores de Atribuição Simplificada ............................................................................... 62 1.7. Operadores de Pré e Pós-Incremento ................................................................................. 63 1.8. Modeladores de Tipos (CASTS) ............................................................................................ 65 2. Expressões ..................................................................................................................................66 2.1. Conversão de Tipos em Expressões ..................................................................................... 66 2.2. O Operador Vírgula (,).......................................................................................................... 66 3. Precedência de Operadores ....................................................................................................... 67 Capítulo 5 Instruções Primitivas .......................................................................................................................... 70 1. Comando de Atribuição .............................................................................................................. 70 2. Comandos de Saída de Dados .................................................................................................... 71 2.1. Printf() .................................................................................................................................. 71 2.2. Putchar() .............................................................................................................................. 75 2.3. Puts() .................................................................................................................................... 75 2.4. Recursos Avançados da Função Printf() .............................................................................. 76 2.4.1. Expressão de Controle .................................................................................................. 77 2.4.2. Flags............................................................................................................................... 81 2.4.3. Largura .......................................................................................................................... 83 2.4.4. Precisão ......................................................................................................................... 84 2.4.5. Comprimento ................................................................................................................ 86 2.4.6. Resumo dos especificadores de formato ...................................................................... 87 2.4.7. Mais de uma linha na função printf() ........................................................................... 89 3. Comandos de Entrada de Dados ................................................................................................ 89 3.1. Scanf() .................................................................................................................................. 89 3.2. Getchar() .............................................................................................................................. 92 3.3. Getch() e Getche() ............................................................................................................... 92 3.4. Gets().................................................................................................................................... 93 3.5. Recursos Avançados da Função Scanf() ............................................................................... 94 3.5.1. Expressão de Controle .................................................................................................. 95 3.5.2. O Campo Asterisco (*)................................................................................................... 98 3.5.3. O Campo Largura ........................................................................................................ 100 3.5.4. O Campo Modificadores ............................................................................................. 101 3.5.5. Lendo apenas caracteres pré-determinados .............................................................. 101 4. Interface com o Usuário ........................................................................................................... 103 5. Funções Pré-Definidas .............................................................................................................. 106 5.1. Funções de Entrada e Saída ............................................................................................... 107 5.2. Funções de Utilidade Padrão ............................................................................................. 109 5.3. Funções Matemáticas ........................................................................................................ 110 5.4. Funções de Testes de Tipos de Caracteres ........................................................................ 111 5.5. Funções de Operações com Strings ................................................................................... 112 5.6. Funções de Manipulação de Interface .............................................................................. 113 5.7. Funções de Data e Hora ..................................................................................................... 113 Capítulo 6 Estruturas de Controle do Fluxo de Execução ................................................................................. 115 1. Estrutura Sequencial ................................................................................................................ 115 2. Estrutura Condicional ............................................................................................................... 116 2.1. Estrutura Condicional Simples ( If ).................................................................................... 118 2.2. Estrutura Condicional Composta ( If-Else ) ........................................................................ 120 2.3. Estrutura Condicional Ternária .......................................................................................... 124 2.4. Estrutura Condicional Múltipla ( Switch ) .......................................................................... 125 2.5. Estruturas Condicionais Aninhadas ................................................................................... 132 3. Estrutura Iterativa .................................................................................................................... 135 3.1. Estrutura Iterativa Condicional .......................................................................................... 136 3.1.1. Estrutura Iterativa Condicional com Teste no Início (While) ...................................... 136 3.1.2. Estrutura Iterativa Condicional com Teste no Final (Do-While) ................................. 139 3.2. Estrutura Iterativa Contada ............................................................................................... 141 3.2.1. Estrutura Iterativa Contada (For) ................................................................................ 141 3.3. Laço Infinito ....................................................................................................................... 146 3.4. Casos de Uso ...................................................................................................................... 147 3.4.1. Exemplos Típicos de Uso ............................................................................................. 149 3.5. Estruturas Iterativas Aninhadas ......................................................................................... 154 3.6. Comandos de Desvio ......................................................................................................... 155 3.6.1. Comando break ........................................................................................................... 155 3.6.2. Comando continue ...................................................................................................... 158 3.6.3. Comando goto .............................................................................................................160 Capítulo 7 Variáveis Compostas Homogêneas .................................................................................................. 162 1. Array de Uma Dimensão – Vetor .............................................................................................. 165 1.1. Declaração de Vetor .......................................................................................................... 165 1.2. Acesso à Elementos do Vetor ............................................................................................ 165 1.3. Operações Básicas com Vetores ........................................................................................ 167 2. Array de Duas Dimensões – Matriz .......................................................................................... 169 2.1. Declaração de Matriz ......................................................................................................... 169 2.2. Acesso à Elementos da Matriz ........................................................................................... 169 1.3. Operações Básicas com Matrizes ...................................................................................... 170 3. Array de Múltiplas Dimensões ................................................................................................. 172 4. Inicialização de Arrays .............................................................................................................. 174 4.1. Inicialização sem Tamanho ................................................................................................ 176 4.2. Array de Tamanho Variável ............................................................................................... 177 5. Arrays de Caracteres – Strings .................................................................................................. 179 5.1. Inicialização de Strings ....................................................................................................... 180 5.2. Acesso à Elementos de Strings .......................................................................................... 181 5.3. Manipulação de Strings ..................................................................................................... 181 5.3.1. Leitura de Strings ........................................................................................................ 182 5.3.1. Escrita de Strings ......................................................................................................... 185 5.4. Funções para Manipulação de Strings ............................................................................... 187 5.4.1. Tamanho de string ...................................................................................................... 187 5.4.2. Cópa de string ............................................................................................................. 187 5.4.3. Concatenação de strings ............................................................................................. 188 5.4.4. Comparação de strings................................................................................................ 189 5.4.5. Conversão de string para numérico ............................................................................ 189 5.5. Vetores de Strings .............................................................................................................. 190 Capítulo 8 Variáveis Compostas Heterogêneas ................................................................................................ 192 1. Estruturas – Struct .................................................................................................................... 193 1.1. Declaração de Variável do Tipo Estrutura ......................................................................... 195 1.2. Acesso à Campos de Variável do Tipo Estrutura ............................................................... 196 1.3. Inicialização de Variável do Tipo Estrutura ........................................................................ 197 1.4. Array de Variável do Tipo Estrutura .................................................................................. 198 1.5. Atribuição entre Variáveis do Tipo Estrutura .................................................................... 199 1.6. Estruturas Aninhadas ......................................................................................................... 201 2. Uniões – Union ......................................................................................................................... 203 2.1. Declaração de Variável do Tipo União ............................................................................... 203 3. Enumerações – Enum ............................................................................................................... 206 3.1. Declaração de Variável do Tipo Enumeração .................................................................... 207 3.2. Enumerações e Constantes ............................................................................................... 208 4. Typedef ..................................................................................................................................... 209 Capítulo 9 Funções ............................................................................................................................................ 213 1. Declaração de Função .............................................................................................................. 213 2. Protótipo de Funções ............................................................................................................... 215 2.1. Arquivos-Cabeçalhos ......................................................................................................... 217 3. Funcionamento de uma Função ............................................................................................... 218 3.1. Parâmetros da Função ....................................................................................................... 219 3.1.1. Declarando os parâmetros de uma função ................................................................ 220 3.1.2. Funções sem lista de parâmetros ............................................................................... 220 3.2. Corpo da Função ................................................................................................................ 221 3.3. Retorno da Função............................................................................................................. 224 3.3.1. Funções sem retorno de valor .................................................................................... 225 3.3.2. Funções com retorno de valor .................................................................................... 226 4. Passagem de Parâmetros ......................................................................................................... 230 4.1. Passagem de Parâmetros por Valor .................................................................................. 231 4.2. Passagem de Parâmetros por Referência .......................................................................... 233 4.3. Comparativo entre Passagem de Parâmetros ................................................................... 237 4.4. Passagem de Arrays como Parâmetros ............................................................................. 239 4.5. Passagem de Estruturas como Parâmetros ....................................................................... 242 4.5.1. Passagem de Estruturas por Valor ..............................................................................242 4.5.2. Passagem de Estruturas por Referência ..................................................................... 243 4.6. Operador Seta .................................................................................................................... 245 5. Recursividade ........................................................................................................................... 246 6. Argumentos para a Função Principal Main() ............................................................................ 254 Capítulo 10 Ponteiros .......................................................................................................................................... 257 1. Declaração de Ponteiros........................................................................................................... 257 2. Manipulação de Ponteiros ....................................................................................................... 259 2.1. Inicialização e Atribuição ................................................................................................... 259 2.1.1. Apontando um ponteiro para nenhum lugar ............................................................. 260 2.1.2. Apontando um ponteiro para algum lugar na memória ............................................ 260 2.1.3. Os operadores * e & ................................................................................................... 262 2.1.4. Atribuição entre ponteiros .......................................................................................... 262 2.2. Aritmética com Ponteiros .................................................................................................. 264 2.3. Operações Relacionais com Ponteiros .............................................................................. 266 3. Ponteiros Genéricos ................................................................................................................. 267 4. Ponteiros e Arrays .................................................................................................................... 269 4.1. Ponteiros e Arrays Multidimensionais ............................................................................... 272 4.2. Array de Ponteiros ............................................................................................................. 273 5. Ponteiro para Ponteiro ............................................................................................................. 275 Capítulo 11 Alocação Dinâmica ........................................................................................................................... 278 1. Funções para Alocação de Memória ........................................................................................ 279 1.1. Sizeof .................................................................................................................................. 280 1.2. Malloc ................................................................................................................................ 281 1.3. Calloc .................................................................................................................................. 283 1.4. Realloc ................................................................................................................................ 285 1.5. Free .................................................................................................................................... 287 2. Alocação de Arrays Multidimensionais .................................................................................... 289 2.1. Usando Array Unidimensional ........................................................................................... 289 2.2. Usando Ponteiro para Ponteiro ......................................................................................... 291 2.3. Usando Ponteiro para Ponteiro para Array ....................................................................... 295 Capítulo 12 Arquivos ........................................................................................................................................... 298 1. Conceitos Básicos ..................................................................................................................... 299 1.1. Tipos de Arquivos............................................................................................................... 299 1.2. Sobre Escrita e Leitura em Arquivos .................................................................................. 300 1.3. Ponteiro de Arquivo ........................................................................................................... 300 2. Abertura e Fechamento de Arquivos ....................................................................................... 301 2.1. Abrindo um Arquivo .......................................................................................................... 301 2.1.1. Caminho absoluto e caminho relativo para o arquivo ............................................... 302 2.1.2. Modo de abertura do arquivo .................................................................................... 302 2.1.3. Finalizando o programa em caso de erro ................................................................... 304 2.2. Fechando um Arquivo ........................................................................................................ 305 3. Escrita e Leitura em Arquivos ................................................................................................... 306 3.1. Escrita e Leitura de Caractere ............................................................................................ 306 3.1.1. Escrevendo um caractere............................................................................................ 306 3.1.2. Lendo um caractere .................................................................................................... 307 3.2. Fim de Arquivos ................................................................................................................. 310 3.3. Arquivos Pré-Definidos ...................................................................................................... 311 3.4. Buffer ................................................................................................................................. 311 3.5. Posição Atual dentro do Arquivo ....................................................................................... 312 3.6. Escrita e Leitura de Strings ................................................................................................ 313 3.6.1. Escrevendo uma string ................................................................................................ 314 3.6.1. Lendo uma string ........................................................................................................ 315 3.7. Escrita e Leitura de Bloco de Bytes .................................................................................... 317 3.7.1. Escrevendo blocos de bytes ........................................................................................ 317 3.7.2. Lendo blocos de bytes................................................................................................. 320 3.8. Escrita e Leitura de Dados Formatados ............................................................................. 323 3.8.1. Escrevendo dados formatados ................................................................................... 323 3.8.2. Lendo dados formatados ............................................................................................ 325 4.Movimentação dentro de Arquivos ......................................................................................... 327 5. Exclusão de Arquivos ................................................................................................................ 329 6. Erro de Acesso a Arquivos ........................................................................................................ 330 Capítulo 13 Diretivas de Compilação .................................................................................................................. 334 1. Diretiva #INCLUDE .................................................................................................................... 334 2. Definindo Macros: Diretivas #DEFINE e #UNDEF ..................................................................... 334 2.1. Definindo Símbolos com #DEFINE ..................................................................................... 335 2.2. Definindo Constantes com #DEFINE .................................................................................. 335 2.3. Definindo Funções e Macros com #DEFINE ....................................................................... 336 2.3.1. Funções macro com mais de uma linha ...................................................................... 338 2.3.2. Operadores especiais # e ## ....................................................................................... 338 2.4. Apagando uma Definição: #UNDEF ................................................................................... 339 3. Diretivas de Inclusão Condicional............................................................................................. 340 3.1. Diretivas #IFDEF e #IFNDEF ................................................................................................ 340 3.2. Diretivas #IF, #ELSE e #ELIF ................................................................................................ 341 4. Controle de Linha: Diretiva #LINE............................................................................................. 343 5. Erro: Diretiva #ERROR .............................................................................................................. 344 6. Diretiva #PRAGMA .................................................................................................................... 344 7. Diretivas Pré-Definidas ............................................................................................................. 345 Referências Bibliográficas ................................................................................................................ 346 11 CAPÍTULO 1 INTRODUÇÃO À LINGUAGEM C 1. HISTÓRICO C é uma linguagem de programação compilada de propósito geral, estruturada, imperativa, procedural, padronizada pela ISO. A primeira versão de C foi criada por Dennis Ritchie em 1972 nos laboratórios Bell para ser incluído como um dos softwares a serem distribuídos juntamente com o sistema operacional Unix do computador PDP-11, na equipe certificada por Ken Thompson. Ao ponto de vista técnico, o surgimento do C iniciou com a linguagem ALGOL 60, definida em 1960. ALGOL era uma linguagem de alto nível, que permitia ao programador trabalhar "longe da máquina", sem se preocupar com os aspectos de como cada comando ou dado era armazenado ou processado. Foi criado para substituir o FORTRAN. ALGOL não teve sucesso, talvez por tentar ser de muito alto nível em uma época em que a maioria dos sistemas operacionais exigiam do usuário um grande conhecimento de hardware. Em 1967 surgiu CPL (Combined Programming Language) nas universidades de Londres e Cambridge com o objetivo, segundo a equipe do projeto, de "trazer ALGOL à terra", ou "manter contato com a realidade de um computador real". Da mesma forma de ALGOL, CPL não foi bem aceita, em especial pelos projetistas de sistemas operacionais que a consideravam difícil de implementar. Ainda em 1967, em Cambridge, Martin Richards criou o BCPL (Basic CPL), uma simplificação do CPL, tentando manter apenas as "boas coisas do CPL". Em 1970, Ken Thompson, chefe da equipe que projetou o UNIX para o PDP11 do Bell Labs, implementou um compilador para uma versão mais reduzida do CPL. Batizou a linguagem de B. Tanto BCPL quanto B mostravam-se muito limitadas, prestando-se apenas para certas classes de problemas. Isto se fez sentir especialmente na primeira versão do PDP11, lançado no mercado em 1971. Um dos fatores que levou à isto foi a intenção do grupo responsável pelo UNIX de reescrevê-lo todo em uma linguagem de alto nível, e para isto B era considerado lenta. Estes problemas levaram a que o projetista Dennis Ritchie, do Bell Labs, fosse encarregado de projetar uma nova linguagem, sucessora do B, que viria então, a ser chamada de C. A linguagem C buscou manter o "contato com o computador real" e ainda sim dar ao programador novas condições para o desenvolvimento de programas em áreas diversas, como comercial, científica e de engenharia. Por muitos anos (aproximadamente 10) a sintaxe (formato) tida como padrão da linguagem C foi aquela fornecida com o UNIX versão 5.0 do Bell Labs. A principal documentação deste padrão encontra-se na publicação "The C Programming Language", de Brian Kernighan e Dennis Ritchie (K&R), tida como a "bíblia da linguagem C". 12 O mais interessante desta versão de C era que os programas-fonte criados para rodar em um tipo de computador podiam ser transportados e recompilados em outros sem grandes problemas. A esta característica dá-se o nome de portabilidade. Com ela, uma empresa que desenvolve um programa pode fazê-lo rodar em diferentes computadores sem ter um elevado custo a cada vez que isto for feito. No início dos anos 80, C passou a ser reconhecida como uma linguagem de propósito geral e contava com diversos compiladores desenvolvidos por vários fabricantes. Nessa época havia uma série de compiladores C semelhantes, porém estes compiladores frequentemente apresentavam várias discrepâncias e eram incompatíveis entre si. Isto tornava a padronização da linguagem uma necessidade real. A padronização foi iniciada pela ANSI – American National Standard Institute – em 1983 e finalizada em 1989. Um grande esforço de padronização foi feito a fim de padronizar a linguagem. Atualmente ainda há versões de compiladores próprias de cada fabricante, porém a maioria dos fabricantes oferece uma opção de compatibilidade com o padrão ANSI C. A linguagem C é uma linguagem de propósito geral, o que quer dizer que se adapta a praticamente qualquer tipo de projeto, altamente portável e extremamente rápida em tempo de execução. A linguagem C++ é uma evolução da linguagem C que incorpora orientação a objetos. Linguagens como Java e C# foram influenciadas pela linguagem C. A linguagem C tem influenciado, direta ou indiretamente, muitas linguagem desenvolvidas posteriormente, tais como C++, Java, C# e PHP. Na figura ao lado é possível ver uma breve história da evolução da linguagem C e de sua influência no desenvolvimentos de outras linguagens de programação. Provavelmente, a influência mais marcante da linguagem foi a sua sintaxe: todas as linguagem mencionadas combinam a sintaxe de declaração e a sintaxe da expressão da linguagem C com sistemas de tipo, modelos de dados, etc. Observe abaixo como um comando de impressão de números variando de 1 até 10 pode ser implementado em diferentes linguagens: 13 Em C: for (i=1; i<=10; i++) { printf(“%d\n”,i); } Em Java: for (int i=1; i<=10; i++) { System.out.println(i); } Em PHP: for ($i=1; $i<=10; $i++) { echo $i; }Em Perl: for ($i=1; $i<=10; $i++) { print $i; } 2. A LINGUAGEM DE PROGRAMAÇÃO C A filosofia básica da linguagem C é que os programadores devem estar cientes do que estão fazendo, ou seja, supõe-se que eles saibam o que estão mandando o computador fazer, e explicitem completamente as suas instruções. Assim, ela alia a elegância e a flexibilidade das linguagens de alto nível (suporte ao conceito de tipo de dados, por exemplo) com o poderio das linguagens de baixo nível (manipulação de bits, bytes e endereços). O C é uma linguagem de programação de finalidade geral, utilizada no desenvolvimento de diversos tipos de aplicação, como processadores de texto, sistemas operacionais, sistemas de comunicação, programas para solução de problemas de engenharia, física, química e outras ciências, etc. O código-fonte de um programa C pode ser escrito em qualquer editor de texto que seja capaz de gerar arquivos em código ASCII (sem formatação). Após a implementação, o programa-fonte (um ou mais arquivos-fonte) é submetido aos processos de compilação e linkedição para gerar o programa executável (com extensão “exe”). Durante o processo de compilação, cada arquivo-fonte é compilado separadamente, produzindo um arquivo de código-objeto com a extensão “obj”. Estes arquivos-objeto contêm instruções em linguagem de máquina (códigos binários) entendidas somente pelos microprocessadores. Na linkedição, todos os arquivos-objetos pertencentes ao projeto, bem como as bibliotecas declaradas nos códigos-fonte são processadas em conjunto, visando a produção do arquivo executável correspondente. Normalmente, tanto o arquivo-objeto quanto o arquivo executável possuem o mesmo nome do arquivo-fonte. Entretanto, quando desejado, o usuário poderá definir diferentes nomes para cada tipo de arquivo. A Linguagem de Programação C pode ser descrita como: 14 Imperativa: o programa descreve uma sequencia lógica de passos que devem ser executados para resolver o problema. Em oposição ao paradigma declarativo que se expressa o que se espera obter e não os passos para se chegar nesse objetivo. Procedural: o programa é estruturado usado procedimentos, no caso do C, o nome é funções. Alto nível (com acesso a baixo nível): uma linguagem com um nível de abstração relativamente elevado, longe do código de máquina e mais próximo à linguagem humana. Compilada: o código fonte em texto puro é traduzido, ou seja compilado para uma linguagem de máquina gerando um arquivo executável. Multiplataforma: praticamente para todas as plataformas foi implementado pelo menos um compilador C. Podemos também usar o compilador de uma plataforma e gerar executáveis de outras plataformas ( “cross compiler”). Tipo de dado estático: Todos os objetos em C tem um tipo definido seja uma variável, literal, função, etc. Esse tipo não é alterado durante a existencial do objeto. 2.1. CARACTERÍSTICAS DA LINGUAGEM DE PROGRAMAÇÃO C A linguagem C possui algumas características básicas: Alta portabilidade inerente da padronização ANSI, ou seja, é possível tomar um código- fonte escrito para uma máquina, compilá-lo e rodá-lo em outra com pouca ou nenhuma alteração; Gera programas formados basicamente por funções, o que facilita a modularização e a passagem de parâmetros entre os módulos; Inicia a execução a partir da função main(), necessária em todos os programas; Uso de chaves ({ }) para agrupar comandos pertencentes a uma estrutura lógica (estruturas de decisão e repetição, por exemplo) ou a uma função; Uso do ponto e vírgula (;) ao final de cada comando; É “case sensitive”, ou seja, o compilador difere maiúsculas de minúsculas. Assim, se declarar uma variável de nome idade, esta será diferente de Idade, IDADE, etc. Além disso, todos os comandos da linguagem devem ser escritos em minúsculo. 2.2. COMPILADORES A maneira de se comunicar com um computador chama-se programa e a única linguagem que o computador compreende é a linguagem de máquina. Portanto, todos os programas que se comunicam com a máquina deve, estar em linguagem de máquina. O problema é que não conseguimos programar em linguagem de máquina. O que fazemos é escrever programas em linguagens de alto nível e depois traduzir tais programas para a linguagem de máquina. Os programas que fazem essa tradução são chamados de tradutores. 15 O computador deve converter os comandos dados em linguagem de alto nível para linguagem de máquina (códigos binários). Esta tarefa de conversão é feita por um programa especial de computador, isto é, um programa que recebe as instruções em linguagem de alto nível e dá como saída outro programa constituído de instruções binárias. Ao programa original, em linguagem de alto nível, dá-se o nome de Programa Fonte e ao resultado, em linguagem de máquina, de Programa Objeto. Existem dois métodos básicos de abordagem na tradução de linguagem de alto nível para linguagem de máquina: interpretadores e compiladores. No primeiro método, o programa tradutor recebe a primeira instrução do programa fonte, confere para ver se está escrita corretamente, converte-a em linguagem de máquina e então ordena ao computador que execute esta instrução. Depois repete o processo para a segunda instrução, e assim sucessivamente, até a última instrução do programa fonte. Quando a segunda instrução é trabalhada, a primeira é perdida, isto é, apenas uma instrução fica na memória em cada instante. Se este programa fonte for executado uma segunda vez, novamente haverá uma nova tradução, comando por comando, pois os comandos em linguagem de máquina não ficam armazenados para futuras execuções. Neste método, o programa tradutor recebe o nome de INTERPRETADOR. No segundo método, o programa tradutor lê a primeira instrução do programa fonte, faz uma consistência de sua sintaxe e, se não houver erros, converte-a para linguagem de máquina; segue para a próxima instrução, repetindo o processo até que a última instrução seja atingida ou a consistência aponte algum erro. Neste método, o programa tradutor recebe o nome de COMPILADOR. Se não houver erros, o compilador cria um programa em disco com a extensão .obj, contendo as instruções já traduzidas. Este programa não pode ser executado até que sejam agregadas a ele as funções em linguagem de máquina que foram utilizadas no programa e estão em arquivos de bibliotecas. Este trabalho é feito por um programa chamado linkeditor que. Além de juntar as funções necessária ao programa .obj, cria um produto final em disco com a extensão .exe, o qual pode ser executado diretamente do sistema operacional. Um compilador não criará um programa em linguagem de máquina antes que esteja absolutamente livre de erros. Neste segundo processo, a execução fica mais rápida em relação ao primeiro, pois se economiza o tempo de retradução de cada instrução a cada nova execução. Entretanto, a cada modificação introduzida no programa fonte é necessária uma nova tradução completa para obter um novo programa objeto, o que torna o processo mais dificultoso na fase de desenvolvimento, quando muitas modificações são feitas. Além disso, geralmente, o compilador exige mais memória que o interpretador. 2.3. COMO CRIAR UM PROGRAMA EXECUTÁVEL Para se criar um programa executável, deve-se seguir os passos abaixo: 16 Digitar seu programa com o auxílio de um processador de textos no modo não documento e gravá-lo em disco, dando a ele um nome com a extensão .c – o programa criado é chamado de fonte. Compilar o código fonte seguindo as instruções do seu compilador, o que criará um programa com a extensão .obj em disco – o programa gerado é chamado de objeto. Linkeditar o objeto seguindo as instruçõesdo seu linkeditor, o que resultará em um programa com a extensão .exe em disco – o programa resultante é chamado de executável. Há muito a se falar quando o assunto é IDE (Integrated Development Enviroment) principalmente em dias de hoje que há uma infinidade de ambiente de desenvolvimento integrado para programação. Assim, para editar, compilar e linkeditar os programas em C, você poderá utilizar compiladores disponíveis gratuitamente online. Dentre os compiladores gratuitos existentes, dá- se destaque a: Dev C++ pode ser baixado gratuitamente pelo site http://www.bloodshed.net/ Code::Blocks pode ser baixado gratuitamente pelo site http://www.codeblocks.org/ Os dois IDEs acima cumprem suas funções básicas de compilar e executar códigos. Entretanto, existem diferenças entre uma e outra ferramenta. Observe: Code::Blocks (wx)Dev-C++ Multiplatforma (roda em Windows e Linux) Só roda em Windows Em constante desenvolvimento Dev-C++ não está, mas wxDev-C++ está Escrito em C++ Escrito em Delphi Bastante estável Muito instável Muitos plug-ins Não é extensível Não é tão simples mas, customizável Simples Adequado para projetos maiores Não adequado para projetos maiores Muitos comandos Não tem muitos comandos Suporta muitas bibliotecas Não suporta muitas bibliotecas Muitos modelos de projeto Pouco a oferecer com modelos Importa arquivos Dev-C+ Não importa projetos do Code::Blocks Melhor para editar opções Apenas um bloco de nota colorido Não há traduções inclusive nos pacotes Muitas traduções 17 CAPÍTULO 2 CONCEITOS BÁSICOS 1. A ESTRUTURA BÁSICA DE UM PROGRAMA EM C Um programa em linguagem C apresenta a seguinte estrutura básica: <diretivas> declarações de variáveis/constantes globais prototipação de funções tipo_de_dado main(lista_de_parâmetros) /* função principal e obrigatória */ { declarações_variáveis/constantes_locais bloco_de_comandos; estruturas_de_controle [comentários] chamada_outras_funções } tipo_de_dado nome_da_func1(lista_de_parâmetros) { bloco_de_comandos; } tipo_de_dado nome_da_func2(lista_de_parâmetros) { bloco_de_comandos; } • • • tipo_de_dado nome_da_funcN(lista_de_parâmetros) { bloco_de_comandos; } 1.1. ELEMENTOS BÁSICOS DO PROGRAMA Observe abaixo o menor programa possível em C: 1. int main() 2. { 3. 4. return 0; 5. } 18 A função main() Esse programa compõe-se de uma única função chamada main(). O nome de uma função pode ser qualquer um, com exceção de main(), reservado para a função que inicia a execução do programa. Em todo programa C deve existir uma função chamada main(), Ela marca o ponto de início do programa, que termina quando for encerrada a execução da função main(). Se um programa for constituído de uma única função, esta será main(). A função main()particular desse primeiro programa é do tipo int. Isso significa que a função deverá retornar um número inteiro. A instrução de retorno é a seguinte: return 0; A linguagem C aceita a escrita da função main() resumida. Assim, o exemplo anterior poderia ser escrito da seguinte forma: 1. main() 2. { 3. 4. } A forma resumida é convertida automaticamente pelo compilador para a forma normal anterior. Os parênteses Os parênteses após o nome main() são a característica que permite que o compilador saiba que se trata de uma função. Sem eles, o compilador poderia pensar que o nome se refere a uma variável. No nosso programa, os parênteses estão vazios, mas nem sempre isso ocorre. As chaves Toda função em C deve começar com uma chave de abertura de bloco ({) e terminar com uma chave de fechamento de bloco (}). As chaves delimitam o corpo da função. Os espaços em branco Você pode inserir espaços em branco, tabulações e pelar linhas à vontade em seus programas. O compilador ignora esses caracteres. Você pode escrever várias instruções em uma única linha, separadas por qualquer número de espaços ou tabulações, ou pode escrever uma instrução em várias linhas. Não há um estilo obrigatório para a escrita de programas em C. 19 Contudo, não se pode inserir espaços em branco no meio de uma palavra ou de um símbolo da linguagem. Não podemos inserir linhas em branco ou espaços em textos escritos entre aspas, em nomes de funções, operadores, comandos de linguagem e diretivas do pré-processador. Além disso, é interessante se observar as máximas de programação que ditam as normas padrões na escrita de programas limpos e inteligíveis. 1.2. INSTRUÇÕES DE PROGRAMA Observe agora, outro exemplo: 1. /* 2. * nome: exemplo1.c 3. * descrição: primeiro exemplo em C 4. * data: 19/11/2015 5. */ 6. #include<stdio.h> 7. #include<stdlib.h> 8. int main() 9. { 10. // imprime Bom Dia 11. printf(“Bom dia.\n”); 12. system(“PAUSE”); 13. return 0; 14. } Como pode ser visto acima, um programa em C é um texto com palavras em inglês e símbolos que tem regras léxicas e semânticas distintas. Essas regras formam a estrutura e as normas para se escrever um programa na linguagem C. Podemos começar a definir dois tipos básicos de texto que podemos encontrar: textos da linguagem e textos de comentários. Textos da linguagem formam a estrutura do programa e comentários servem para documentar o programa e são ignorados pelo compilador. Os comentários podem ser de uma linha ou comentários de múltiplas linhas. Comentários de múltiplas linhas começam com /* e terminam com */. Tudo o que estiver entre esses símbolos é considerado comentário. Um comentário de uma linha só inicia-se com // e termina no final da linha. No exemplo acima, podemos identificar comentário de várias linhas da linha 1 até a 5. Comentário de uma linha temos na linha 9. Se removermos os comentários, ficaríamos com: 1. #include<stdio.h> 2. #include<stdlib.h> 3. int main() 4. { 5. printf(“Bom dia.\n”); 6. system(“PAUSE”); 7. return 0; 8. } 20 Compilando e executando este programa, você verá que aparece na tela a seguinte mensagem: Bom dia. Vamos analisar esse programa por partes. A linha #include <stdio.h> diz ao compilador que ele deve incluir o arquivo cabeçalho stdio.h. Neste arquivo existem declarações de funções úteis para entrada e saída de dados. Já a linha #include <stdlib.h> diz ao compilador que ele deve incluir o arquivo cabeçalho stdlib.h. Neste arquivo existem funções para conversão de números, alocação de memória e tarefas similares. Toda vez que você quiser usar uma destas funções deve-se incluir este comando. O C possui diversos arquivos-cabeçalho. A linha int main() indica que estamos definindo uma função de nome main. Todos os programas em C têm que ter uma função main, pois é esta função que será chamada quando o programa for executado. O conteúdo da função é delimitado por chaves { }. O código que estiver dentro das chaves será executado sequencialmente quando a função for chamada. A palavra int indica que esta função retorna um inteiro. O que significa este retorno será visto posteriormente. A última linha do programa, return(0); , indica o número inteiro que está sendo retornado pela função, no caso o número 0. A única coisa que o programa realmente faz é chamar a função printf(), passando a string "Bom dia.\n" como argumento. É por causa do uso da função printf() pelo programa que devemos incluir o arquivo cabeçalho stdio.h. O programa acima apresenta três instruções. A primeira instrução printf(“Bom dia.”); imprime a frase entre aspas duplas na telado computador. A função printf() neste caso irá apenas colocar a string na tela do computador. O \n é uma constante chamada de caractere de escape. No caso, o \n é a constante barra invertida de "new line" e ele é interpretado como um comando de mudança de linha, isto é, após imprimir “Bom dia.”, o cursor passará para a próxima linha. A segunda instrução system(“PAUSE”); solicita ao computador uma pausa até que uma tecla seja pressionada no teclado. É por causa do uso da instrução system() pelo programa que devemos incluir o arquivo cabeçalho stdlib.h. Já a terceira instrução return 0; solicita à função main() que retorne o valor 0 a quem a chamou. Nesse caso, o sistema operacional. Toda instrução em C deve terminar com um ponto-e-vírgula (;), parte crucial da sintaxe da linguagem que pode ser facilmente esquecido por programadores distraídos, acarretando a apresentação de erro de compilação. Uma função pode ter qualquer número de instruções. Elas devem ser escritas entre as chaves que delimitam o corpo da função e são executadas na ordem em que escrevemos. 21 2. DIRETIVAS DO PRÉ-PROCESSADOR O pré-processador é um programa que examina o programa fonte em C e executa certas modificações com base em instruções chamadas diretivas. Durante a confecção do código-fonte, além dos comandos normais, o programador poderá utilizar-se de diretivas de compilação. As diretivas são prontamente reconhecidas, vista que aparecem quase sempre no início dos arquivos- fonte, com o prefixo # seguido pelo nome da diretiva e seus argumentos. Ao contrário dos comandos normais, não se usa ponto e vírgula ao final da declaração da diretiva. Elas direcionam o compilador entre vários caminhos durante a fase de pré-processamento. As diretivas do pré-processador não fazem parte da linguagem C – elas servem para auxiliar no desenvolvimento do programa fonte. Etapas do processo de compilação/linkedição 2.1. A DIRETIVA #INCLUDE A diretiva #include permite incorporar, no programa-fonte, o conteúdo de outro arquivo passado como argumento. Ela propicia a utilização de arquivos de inclusão criados pelo usuário ou fornecidos junto com o compilador (normalmente arquivos de cabeçalho com extensão “h”). Os arquivos criados pelos usuários visam a reutilização de funções de uso geral já desenvolvidas, de modo a evitar digitações repetitivas. Já os arquivos fornecidos pelo fabricante do compilador visam suprir as definições e declarações mais frequentemente necessárias, de acordo com a norma ANSI-C, possibilitando, assim, a portabilidade do código-fonte. A diretiva #include apresenta a seguinte sintaxe básica: #include <arquivo.h> , onde arquivo.h é o nome do arquivo cabeçalho. Na verdade, o compilador substitui a linha contendo essa diretiva pelo conteúdo do arquivo indicado. Essa substituição é executada antes do programa ser compilado. Assim, o efeito 22 obtido é a apresentação de um texto, como se tivéssemos digitado todo o conteúdo do arquivo indicado. A diretiva #include aceita uma segunda sintaxe: #include “meuarquivo.h” Quando usamos os sinas < e >, o arquivo é procurado somente na pasta include criada na instalação do seu compilador. Quando usamos aspas duplas, o arquivo é procurado primeiramente na pasta atual e depois, se não for encontrado, na pasta include. Independentemente da forma utilizada, este comando ordena ao pré-processador que carregue o conteúdo do arquivo indicado como parte integrante do programa-fonte, exatamente naquele ponto. Tal ação não afeta fisicamente o programa-fonte. Os arquivos de inclusão podem ser agrupados, isto é, um arquivo de inclusão pode conter outros arquivos de inclusão adicionais, e assim por diante, até o limite de pelo menos 8 níveis, conforme determinação do padrão ANSI. A tabela abaixo apresenta alguns arquivos de inclusão presentes na maioria dos compiladores, que podem ser utilizados na confecção dos programas. Arquivos de Cabeçalho – Padrão ANSI C Arquivo Finalidade assert.h Contém a macro “assert” que é usada para incluir diagnóstico em programas ctype.h Declara funções para testar caracteres errno.h Define o número de erro do sistema float.h Define os valores em ponto flutuante específicos do compilador limits.h Define tipos de valores-limites específicos do compilador locale.h Utilizada para adaptar as diferentes convenções culturais math.h Define as funções matemáticas e macros usadas para operações matemáticas em linguagem C setjmp.h Provê uma forma de evitar a sequência normal de chamada e retorno de função profundamente aninhada signal.h Provê facilidades para manipular condições excepcionais que surgem durante a execução, como um sinal de interrupção de uma fonte externa ou um uso na execução stdarg.h Define macros para acessar argumentos quando uma função usa um número variável de argumentos stddef.h Define funções, constantes, macros e estruturas usadas para operações padrões de entrada e saída stdio.h Contém funções, tipos e macros de entrada e saída 23 stdlib.h Contém funções para conversão de números, alocação de memória e tarefas similares string.h Define funções para manipulação de “strings” time.h Define funções e estruturas usadas na manipulação de data e hora. 2.2. A DIRETIVA #DEFINE Outra diretiva também muito utilizada é a diretiva #define. Ela é o mecanismo básico do C para criar macros e identificadores. A diretiva #define é precedida do símbolo # e seguida de dois argumentos, de acordo com a finalidade desejada. Na criação de um identificador, o primeiro argumento indica o nome do identificador e o segundo define o conteúdo que será associado a este identificador. Observe o exemplo abaixo: #define NOME “Gustavo Silva” Neste caso, o pré-processador da compilação substituirá toda a aparição subsequente do identificador NOME, em qualquer lugar do programa-fonte, pela string “Gustavo Silva”. Vale ressaltar que, se o pré-processador encontrar a palavra NOME dentro de uma string, isto é, entre aspas (por exemplo, “Digite o seu NOME”), não será realizada nenhuma substituição. Quando a string é muito longa para ocupar uma única linha, pode-se empregar o caractere especial de escape (barra invertida - \) antes de pressionar <ENTER> e continuar digitando o texto restante na próxima linha. Observe o exemplo a seguir: #define AVISO “Este texto é muito grande, assim estou \ utilizando a barra invertida para mantê-lo dentro da minha tela” Não existe nenhuma regra de substituição de strings. Assim, qualquer sequência de caracteres será literalmente e exatamente inserida no programa-fonte, onde quer que o identificador correspondente seja encontrado. A única exceção é o artifício de continuação de linha, já que a barra invertida não é parte integrante da string. A verificação sintática (sentido contextual) da substituição será realizada posteriormente durante a fase de compilação propriamente dita. Na criação de macros, a diretiva #define funciona de modo similar a uma função, exceto pelo fato de que, como macro, ela permite que argumentos sejam suprimidos, ao contrário das funções. O primeiro argumento da diretiva indica o nome da macro e os argumentos que serão utilizados por ela. Já o segundo argumento define como os argumentos da macro serão aplicados quando o pré-processador encontrar o nome da macro no programa-fonte restante. Observe o exemplo abaixo de macro: 24 #define CUBO(X) ((X)*(X)*(X)) Neste exemplo, o pré-processador substituirá o texto CUBO(X) pelo valor correspondente a X3, como nos exemplos abaixo: CUBO(2) ((2)*(2)*(2)) = 8 CUBO(A+B) ((A+B)*(A+B)*(A+B)) Nesteúltimo caso, é possível notar a importância dos parênteses em torno X na definição da ação na declaração da diretiva #define. Sem eles, a substituição de CUBO(A+B) seria equivocada, visto que o resultado seria (A+B*A+B*A+B) e a multiplicação tem precedência sobre a soma. O ANSI-C fornece dois operadores do pré-processador para serem utilizados em macros definidas pela diretiva #define. São eles: # transforma o argumento que ele precede em uma string entre aspas Exemplo: #define mkstr(s) # s printf(mkstr(Processamento de Dados)); ## concatena duas palavras Exemplo: #define concat(a,b) a ## b printf(concat(“Processamento”,” de Dados”); Em ambos os casos, o resultado gerado é equivalente ao comando: printf(“Processamento de Dados”); Apesar de existirem outras diretivas de compilação, inclusive algumas que permitem compilação condicional, essas fogem ao escopo do curso e, portanto, não serão discutidas neste material. 25 3. DETALHANDO A ESTRUTURA BÁSICA DE UM PROGRAMA EM C Observe agora um programa um pouco mais complicado: 1. #include <stdio.h> 2. int main () 3. { 4. int dias; /* declaração de variáveis */ 5. float anos; 6. printf ("Entre com o número de dias: "); /* entrada de dados */ 7. scanf ("%d",&dias); 8. anos=dias/365.25; /* conversão dias->anos */ 9. printf ("\n\n%d dias equivalem a %f anos.\n",dias,anos); 10. return 0; 11. } Vamos entender como o programa acima funciona. São declaradas duas variáveis chamadas dias e anos. A primeira é um int (inteiro) e a segunda um float (ponto flutuante). As variáveis declaradas como ponto flutuante existem para armazenar números que possuem casas decimais, como 5,1497. É feita então uma chamada à função printf(), que coloca uma mensagem na tela. Queremos agora ler um dado que será fornecido pelo usuário e colocá-lo na variável inteira dias. Para tanto usamos a função scanf(). A string "%d" diz à função que iremos ler um inteiro. O segundo parâmetro passado à função diz que o dado lido deverá ser armazenado na variável dias. É importante ressaltar a necessidade de se colocar um & antes do nome da variável a ser lida quando se usa a função scanf(). Observe que, em C, quando temos mais de um parâmetro para uma função, eles serão separados por vírgula. Temos então uma expressão matemática simples que atribui a anos o valor de dias dividido por 365.25 (365.25 é uma constante ponto flutuante 365,25). Como anos é uma variável float o compilador fará uma conversão automática entre os tipos das variáveis. A segunda chamada à função printf() tem três argumentos. A string "\n\n%d dias equivalem a %f anos.\n" diz à função para pular duas linhas, colocar um inteiro na tela, colocar a mensagem " dias equivalem a ", colocar um valor float na tela, colocar a mensagem " anos." e pular outra linha. Os outros parâmetros são as variáveis, dias e anos, das quais devem ser lidos os valores do inteiro e do ponto flutuante, respectivamente. 4. INTRODUÇÃO À FUNÇÕES Uma função é um bloco de código de programa que pode ser usado diversas vezes em sua execução. O uso de funções permite que o programa fique mais legível, mais bem estruturado. Um programa em C consiste, no fundo, de várias funções colocadas juntas. 26 Veja abaixo o tipo mais simples de função: 1. #include <stdio.h> 2. int mensagem() /* função mais simples: só imprime Olá! */ 3. { 4. printf ("Olá!\n"); 5. return 0; 6. } 7. int main () 8. { 9. mensagem(); 10. printf ("Eu estou vivo!\n"); 11. return 0; 12. } Este programa irá apresentar na tela a mensagem Olá! em uma linha e Eu estou vivo! em outra. O que ele faz é definir uma função mensagem() que coloca uma string na tela e retorna 0. Esta função é chamada a partir de main(), que, como já vimos, também é uma função. A diferença fundamental entre main e as demais funções do problema é que main é uma função especial, cujo diferencial é o fato de ser a primeira função a ser executada em um programa. 4.1. ARGUMENTOS E PARÂMETROS Vimos acima um exemplo de função que exibe uma mensagem na tela. As funções não são estáticas assim, e não fazem somente isso. Através de parâmetros e argumentos, pode-se enviar dados para as funções trabalharem e fazerem algo mais útil para nossos programas. Parâmetros são canais pelos quais se estabelece uma comunicação bidirecional entre uma função e o algoritmo chamador. Dados são passados pelo algoritmo, ou retornados por este ao primeiro por meio de parâmetros. Assim, parâmetros são variáveis que a função recebe. O número e tipo de parâmetros são pré-estabelecidos na declaração da função. E essa declaração, dos tipos e nomes das variáveis, acontece dentro dos parênteses. Por exemplo, se formos criar uma função que recebe e soma dois números, declaramos a função com os tipos de variáveis (inteiro ou float, por exemplo) e o nome dessas variáveis. void soma(int a, int b) { } Pronto, declaramos uma função com dois parâmetros. Agora, dentro dessa função, podemos usar a e b. É como se elas tivessem sido declaradas entre parênteses. E quais os valores desses parâmetros? São os que serão passados à função pelo algoritmo principal. Esses valores são os argumentos. 27 Por exemplo, se a função soma(1,2) é invocada, os argumentos passados são 1 e 2. Dessa forma, os parâmetros a e b vão receber os valores 1 e 2, respectivamente. Ou seja, o valor que aparece primeiro é armazenado no primeiro parâmetro, o segundo valor é armazenado no segundo parâmetro e assim sucessivamente. Note agora que essas funções não são estáticas. Elas mudam de acordo com os valores que são passados à elas. Assim, argumentos são as entradas que a função recebe. É através dos argumentos que passamos parâmetros para a função. Já vimos funções com argumentos. As funções printf() e scanf() são funções que recebem argumentos. Observe abaixo um outro exemplo simples de função com argumentos: 1. #include <stdio.h> 2. int square (int x) /* calcula o quadrado de x */ 3. { 4. printf ("O quadrado é %d",(x*x)); 5. return 0; 6. } 7. int main () 8. { 9. int num; 10. printf ("Entre com um número: "); 11. scanf ("%d",&num); 12. printf ("\n\n"); 13. square(num); 14. return 0; 15. } Na definição de square(), dizemos que a função receberá um argumento inteiro x. Quando fazemos a chamada à função, o inteiro num é passado como argumento. Há alguns pontos a serem observados. Em primeiro lugar, temos de satisfazer aos requisitos da função quanto ao tipo e à quantidade de argumentos quando a chamamos. Apesar de existirem algumas conversões de tipo, que o C faz automaticamente, é importante ficarmos atento. Em segundo lugar, não é importante o nome da variável que se passa como argumento, ou seja, a variável num, ao ser passada como argumento para square() é copiada para a variável x. Dentro de square() trabalha-se apenas com x. Se mudarmos o valor de x dentro de square(), o valor de num na função main() permanece inalterado. Vamos dar um exemplo de função de mais de uma variável. Repare que, neste caso, os argumentos são separados por vírgula e que deve-se explicitar o tipo de cada um dos argumentos, um a um. Note, também, que os argumentos passados para a função não necessitam ser todos variáveis porque mesmo sendo constantes serão copiados para a variável de entrada da função. 28 1. #include <stdio.h> 2. int mult (float a, float b, float c) /* multiplica 3 números */ 3. { 4. printf ("%f",a*b*c); 5. return 0; 6. } 7. int main () 8. { 9. float x,y;10. x=23.5; 11. y=12.9; 12. mult (x,y,3.87); 13. return 0; 14. } 4.2. RETORNANDO VALORES Muitas vezes é necessário fazer com que uma função retorne um valor. As funções que vimos até aqui estavam retornando o número 0. Podemos especificar um tipo de retorno indicando-o antes do nome da função. Mas para dizer ao C o que vamos retornar precisamos da palavra reservada return. Sabendo disto fica fácil fazer uma função para multiplicar dois inteiros e que retorna o resultado desta multiplicação. Observe: 1. #include <stdio.h> 2. int prod (int x, int y) 3. { 4. return (x*y); 5. } 6. int main () 7. { 8. int saida; 9. saída = prod(12,7); 10. printf ("A saida é: %d\n",saida); 11. return(0); 12. } Observe que, como prod retorna o valor de 12 multiplicado por 7, este valor pode ser usado em uma expressão qualquer. No programa, fizemos a atribuição deste resultado à variável saida, que posteriormente foi impressa usando printf(). Uma observação adicional: se não especificarmos o tipo de retorno de uma função, o compilador C automaticamente irá supor que este tipo é inteiro. Porém, não é uma boa prática não se especificar o valor de retorno. Com relação à função main(), o retorno sempre será inteiro. Normalmente faremos a função main retornar um zero quando ela é executada sem qualquer tipo de erro. 29 Observe um outro exemplo de função que recebe dois valores floats e também retorna um float. 1. #include <stdio.h> 2. float prod (float x, float y) 3. { 4. return (x*y); 5. } 6. int main () 7. { 8. float saida; 9. saída = prod(45.2,0.0067); 10. printf ("A saida é: %f\n",saida); 11. return(0); 12. } 4.3. SINTAXE BÁSICA Apresentamos aqui a sintaxe básica de uma função: tipo_de_retorno nome_da_função (lista_de_parâmetros) { bloco_de_comandos; } 5. INTRODUÇÃO BÁSICA ÀS ENTRADAS E SAÍDAS 5.1. A FUNÇÃO PRINTF() A função printf() é uma função de I/O (entrada e saída) presente na biblioteca padrão, fornecida com os compiladores C. A função printf() está associada à saída padrão do sistema operacional (geralmente o vídeo). Ela permite exibir dados na saída padrão. As definições necessárias ao uso de printf() estão no arquivo stdio.h. Os parênteses indicam que estamos, realmente, procedendo com uma função. No interior dos parênteses estão as informações passadas pela função main() à função printf(). Como vimos, esta informação é chamada de argumento de printf(). Quando o programa encontra essa linha, desvia o fluxo de controle para a função printf() que executa a tarefa de imprimir na tela do computador o que foi passado como 30 argumento e, quando encerra a sua execução, o fluxo de controle é devolvido para a próxima instrução do algoritmo principal. A função printf() tem a seguinte sintaxe básica: printf (“expressão_de_controle”, lista_de_argumentos); Teremos, na expressão de controle, uma descrição de tudo que a função vai colocar na tela. A expressão de controle mostra não apenas os caracteres que devem ser colocados na tela, mas também quais as variáveis e suas respectivas posições. Isto é feito usando-se os códigos de controle, que usam a notação %. Na expressão de controle indicamos quais, de qual tipo e em que posição estão as variáveis a serem apresentadas. É muito importante que, para cada código de controle, tenhamos um argumento na lista de argumentos. Observe na tabela abaixo, alguns dos códigos de controle %: Código Significado %d inteiro %f float %c caractere %s string %% coloca na tela um % Observe alguns exemplos de printf() e o que eles exibem: Sintaxe Exibição na tela printf ("Teste %% %%"); Teste % % printf ("%f",40.345); 40.345 printf ("Um caractere %c e um inteiro %d", 'D', 120); Um caractere D e um inteiro 120 printf ("%s e um exemplo","Este"); Este e um exemplo printf ("%s%d%%","Juros de ",10); Juros de 10% Maiores detalhes sobre a função printf(), incluindo outros códigos de controle, serão vistos em capítulos posteriores. 31 5.2. A FUNÇÃO SCANF() A função scanf() é uma função de I/O (entrada e saída) presente na biblioteca padrão, fornecida com os compiladores C. A função scanf() está associada à entrada padrão do sistema operacional (geralmente o teclado). Ela permite ler dados formatados da entrada padrão. Assim, como printf(), as definições necessárias ao uso de scanf() estão no arquivo stdio.h. Quando o programa encontra essa linha, desvia o fluxo de controle para a função scanf() que executa a tarefa de ler os dados inseridos e armazená-los nas respectivas variáveis, e quando encerra a sua execução, o fluxo de controle é devolvido para a próxima instrução do algoritmo principal. A sintaxe da função scanf() é similar à de printf(), isto é, uma expressão de controle seguida por uma lista de argumentos separados por virgulas. A principal diferença está na lista de argumentos. Os argumentos de scanf() devem obrigatoriamente ser endereços de variáveis. A função scanf() tem a seguinte sintaxe: scanf (“expressão_de_controle”, lista_de_argumentos); A expressão de controle contém códigos de controle precedidos por um sinal de %.A lista de argumentos deve obrigatoriamente consistir dos endereços das variáveis. Outra coisa importante que deve-se lembrar é de sempre colocar o operador & antes das variáveis da lista de argumentos. Este operador é chamado de operador de endereços e será discutido no próximo capítulo. Observe na tabela abaixo, alguns dos códigos de controle %: Código Significado %d inteiro %f float %c caractere simples %s string de caracteres Observe alguns exemplos de scanf() sendo utilizado em algoritmos: /* Programa que calcula a sua idade em dias */ 1. #include <stdio.h> 2. #include <stdlib.h> 3. int main() 4. { 5. float anos, dias; 32 6. printf(“Digite a sua idade em anos: “); 7. scanf(“%f”,&anos); 8. dias = anos * 365; 9. printf(“A sua idade em dias é %f.\n”,dias); 10. system(“PAUSE”); 11. return 0; 12. } /* Programa que calcula a média de 4 notas de um aluno */ 1. #include <stdio.h> 2. #include <stdlib.h> 3. int main() 4. { 5. float n1, n2, n3, n4, media; 6. printf(“Digite as quatro notas do aluno:\n“); 7. scanf(“%f%f%f%f”,&n1,&n2,&n3,&n4); 8. media = (n1+n2+n3+n4)/4; 9. printf(“\nA média das notas do aluno é %f.\n”, media); 10. system(“PAUSE”); 11. return 0; 12. } Maiores detalhes sobre a função scanf(), incluindo outros códigos de controle, serão vistos em capítulos posteriores. 6. PALAVRAS RESERVADAS EM LINGUAGEM C Todas as linguagens de programação possuem palavras reservadas. As palavras reservadas não podem ser usadas a não ser nos seus propósitos originais, isto é, não podemos declarar funções ou variáveis com os mesmos nomes. Como o C é "case sensitive", podemos declarar uma variável For, apesar de haver uma palavra reservada for, mas isto não é uma coisa recomendável de se fazer pois pode gerar confusão. Observe abaixo algumas palavras reservadas do ANSI C. Veremos o significado destas palavras chave nos capítulos posteriores. auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile
Compartilhar