Conceitos básicos da linguagem C 2 Em 1969 Ken Thompson cria o Unix. O C nasceu logo depois, na década de 70. Dennis Ritchie, implementou-o pela primeira vez usando o sistema operacional UNIX criado por Ken Thompson. O C é derivado de uma outra linguagem: a B, criada por Ken Thompson. A B, por sua vez, veio da linguagem BCPL, inventada por Martin Richards. Ken Thompson e Dennis Ritchie (da esquerda para direita), os criadores das linguagens B e C
3
Primeiros passos 4 O C é "Case Sensitive": maiúsculas e minúsculas fazem diferença. Se declararmos uma variável com o nome soma ela será diferente de Soma, SOMA, SoMa ou soma. Da mesma maneira os comandos do C (por exemplo, if e for), só podem ser escritos com letras minúsculas pois senão o compilador não irá interpretá-los como sendo comandos, mas sim como variáveis.
Primeiro Programa em C: 1 main () 2 { 3 } 5 O nº de cada linha serve apenas para facilitar a localização do código. A linha main() é uma parte comum a todos os programas em C. Os parênteses após a palavra main indicam que main é um bloco de construção do programa chamado função.
Os parênteses sem mais nada após o nome da função indicam que a função não recebe qualquer informação. 6 Os programas em C contêm uma ou mais funções, e uma delas deve ser main - Todos os programas em C começam a ser executados pela função main. O código executado pela função main ( ) é escrito entre as chaves { }. Este par de chaves e a parte do programa entre elas também é chamado um bloco (ou função). Mas afinal de contas, o que esse programa faz ao ser compilado?
Primeiro Programa em C (de verdade): 7 algoritmo inicio escreva("bem-vindo ao C!"); fim_algortimo ************************************************************************************************ 1 #include <stdio.h> 2 /* Um Primeiro Programa */ 3 int main () 4 { 5 printf ("Bem-vindo ao C!\n"); 6 return(0); 7 }
Compilando e executando este programa será coloca a mensagem Bem-vindo ao C! na tela do pc. 8 Vamos analisar o 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 para entrada e saída de dados: std = Standard (padrão em inglês); io = Input/Output (entrada e saída) stdio = Entrada e saída padronizadas
Toda vez que quisermos usar uma destas funções devese incluir este comando. 9 O C possui diversos arquivos-cabeçalhos (header files). Esses arquivos têm sempre a extensão.h Quando fazemos um programa usamos comentários que ajudem a elucidar o funcionamento do mesmo. No caso acima temos um comentário: /* Um Primeiro Programa */. O compilador C desconsidera qualquer coisa que esteja começando com /* e terminando com */. Um comentário pode ter mais de uma linha.
Um erro comum é esquecer de encerrar um comentário com */ ou começar um comentário com os caracteres */ ou terminar com /*. Exemplos de comentários: /* Prog 0199.c Companhia Autor: Eu Data: 23/10/2013 */ /**************************** * Prog 0199.c Companhia * * Autor: Eu * * Data: 23/10/2013 * *****************************/ 10
Os asteriscos horizontais ou verticais não têm significado especial. Servem para reforçar os comentários. 11 Os comentários podem ser colocados dentro de comandos, o que pode aumentar a complexidade de leitura do programa. printf ("Bem-vindo ao C!" /* Falta o /n */) */ Notar onde foi para o ponto e virg/*; A única situação em que os caracteres /* e */ não são ignorados pelo compilador acontece quando se encontram dentro de uma string.
printf ("Um comentário em C começa com /* e termina com */ \n"); 12 Como no exemplo anterior, 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, 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 chave esquerda, {, deve começar o corpo (ou o texto propriamente dito) de todas as funções.
Uma chave direita, }, equivalente deve terminar cada função. 13 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. (O que significa este retorno será visto posteriormente) O que esse programa realmente faz?
Chama a função printf(), passando a string (seqüência de caracteres) "Ola! Eu estou vivo!\n" como argumento. 14 É por causa do uso da função printf() pelo programa que devemos incluir o arquivo- cabeçalho stdio.h. A função printf() irá apenas colocar a string na tela do computador. O \n é uma constante chamada de constante barra invertida de "new line". Ele é interpretado como um comando de mudança de linha. Isto é, após imprimir Ola! Eu estou vivo! o cursor passará para a próxima linha.
O último caractere impresso por uma função que realiza qualquer impressão deve ser o de nova linha (\n). 15 Isto assegura que a função deixará o cursor da tela posicionado no início de uma nova linha. Outras constantes de barra invertida: \a Faz soar a campainha (Bell), do sistema. \\ Barra invertida. Imprime um caractere de barra invertida em uma instrução printf. \ Aspas duplas. Imprime um caractere de aspas duplas em uma instrução printf. Todos os comandos do C terminam com ;
A função printf pode imprimir Bem-vindo ao C! de várias maneiras. O programa a seguir produz a mesma saída do programa anterior: 1 /* Imprimindo em uma linha com duas instruções printf */ 2 #include <stdio.h> 3 int main () 4 { 5 printf ("Bem-vindo "); 6 printf ("ao C!\n"); 7 return(0); 8 } Ele coloca a mensagem Bem-vindo ao C! na tela do pc. 16
17 Isto acontece porque cada printf reinicia a impressão onde o printf anterior termina de imprimir. O primeiro printf imprime Bem-vindo seguido de um espaço, e o segundo printf começa a imprimir imediatamente após o espaço. Um printf pode imprimir várias linhas usando caracteres de nova linha, como mostra a figura a seguir. Cada vez que a seqüência de escape \n (nova linha) é encontrada, printf vai para o início da linha seguinte.
18 1 /* Imprimindo varias linhas com um único printf */ 2 #include <stdio.h> 3 int main () 4 { 5 printf "Bem-vindo\nao\nC!\n"); 6 return(0); 7 } Ele imprime a seguinte mensagem na tela do pc: Bem-vindo ao C! Vamos ver se aprendemos alguma coisa?
19 Suponhamos que queríamos escrever um programa que apresenta a seguinte saída: Hoje está um "lindo" dia!!! 1 #include <stdio.h> 2 int main () 3 { 4 printf ("Hoje está um "lindo" dia!!!"); 5 return(0); 6 } E ai??? Funciona ou não funciona??? Ou melhor, compila ou não compila?
O programa vai gerar um erro de compilação. Nesse caso, a string a ser escrita acaba junto a segunda aspas. O compilador detecta que após "Hoje está um" existe algo mais e emite um erro. Algoritmos As etapas para o desenvolvimento de um programa são: Análise: nesta etapa estuda-se o enunciado do problema para definidos dados de entrada, o processamento e os dados de saída. Algoritmo: Descrição do problema com suas soluções. Codificação: O algoritmo é transformado em código da linguagem de programação escolhida. 20
Estrutura sequencial em algoritmos Algoritmo declare bloco de comandos fim_algortimo 21 Declaração de variáveis em algoritmos: as variáveis são declaradas após apalavra declare. Exemplos: Declare inteiro inteiro1, inteiro2; real real1, real2; literal literal1, literal2; teste_lógico logico1, logico2;
Comandos de atribuição em algoritmos: é utilizado para conceder valores ou operações a variáveis, sendo representado pelo símbolo. Exemplos: inteiro1 4; inteiro2 inteiro1 + 2; literal1 "aula"; logico1 falso; 22 Comando de entrada em algoritmos: é utilizado para receber dados digitados pelo usuário, que serão armazenados em variáveis. Esse comando é representado pela palavra leia.
Exemplos: leia (inteiro1); //Um valor numérico digitado pelo usuário será armazenado na variável inteiro1. leia (literal1); //Um ou vários caracteres digitados pelo usuário serão armazenados na variável literal1. Comando de saída em algoritmos: mostra dados na tela ou na impressora. É representado pela palavra escreva, e os dados podem ser conteúdos de variáveis ou mensagens. Exemplo: Escreva x; //Mostra o valor armazenado na variável x. Escreva "Conteúdo de Y = ", Y; //Mostra a mensagem //"Conteúdo de Y = "e em seguida o valor armazenado na //variável Y. 23
Outro Programa Simples em C: Somar Dois Números Inteiros algoritmo Declare inteiro inteiro1, inteiro2, soma; inicio //Entrada de dados escreva("entre com o primeiro inteiro:"); leia(inteiro1); escreva ("Entre com o segundo inteiro: "); leia(inteiro2); //processamento soma <- inteiro1 + inteiro2; //saida de dados escreva("a soma e", soma); fim_algortimo 24
1 /* Programa de soma */ 2 #include <stdio.h> 3 int main( ) 4 { 5 int inteiro1, inteiro2, soma; /* declaração de variáveis*/ 6 7 printf("entre com o primeiro inteiro: \n"); /* prompt */ 8 scanf("%d", &inteiro1); /* le um inteiro */ 9 printf("entre com o segundo inteiro: \n"); /* prompt */ 10 scanf("%d", &inteiro2); /* le um inteiro */ 11 soma = inteiro1 + inteiro2; /* atribui soma */ 12 printf("a soma e %d/n", soma); /* imprime soma */ 13 return 0; /* indica que o programa foi bem-sucedido */ 14 } 25
Esse programa usa a função scanf da biblioteca padrão para obter dois números inteiros digitados pelo usuário, calcular a soma desses valores e imprimir o resultado. Ele imprime a seguinte mensagem na tela do pc: Entre com o primeiro inteiro 45 Entre com o segundo inteiro 72 A soma e 117 A linha int inteiro1, inteiro2, soma; é uma declaração de variáveis (as expressões inteiro1, inteiro2 e soma são os nomes das variáveis). Uma variável é uma posição na memória onde um valor pode ser armazenado para ser utilizado por um programa. 26
Esta declaração especifica que inteiro1, inteiro2 e soma são do tipo int o que significa que essas variáveis conterão valores inteiros: números inteiros como 7, 11, 0, 31914. As declarações devem ser colocadas depois da chave esquerda que inicia o corpo de main e antes de qualquer instrução executável. No programa anterior a declaração após o primeiro printf causaria um erro de sintaxe. É causado um erro de sintaxe quando o compilador não reconhece uma instrução (comando). Nesse caso o compilador emite uma mensagem de erro. 27
Os erros de sintaxe são transgressões às regras da linguagem (também são chamados de erros de compilação ou erros em tempo de compilação). No exemplo anterior, poderíamos ter escrito três declarações, uma para cada variável. Um nome de variável em C é qualquer identificador válido (letras, dígitos e sublinhados (_) que não começem com um dígito). Um identificador pode ter qualquer comprimento, mas somente os 31 primeiros caracteres serão reconhecidos. 28
29 A primeira letra de um identificador usado como nome de variável simples deve ser uma letra minúscula. Escolher nomes significativos tornar um programa autoexplicativo reduzindo a quantidade de comentários necessários. Separe as declarações das instruções executáveis em uma função por uma linha em branco, para ressaltar onde terminam as declarações e começam as instruções. A instrução: printf("entre com o primeiro inteiro: \n"); imprime a expressão Entre com o primeiro inteiro: na tela e se posiciona no início da próxima linha.
30 Esta mensagem é chamada de prompt porque diz ao usuário para realizar uma ação específica. A instrução: scanf("%d", &inteiro1); usa scanf para obter um valor fornecido pelo usuário pela entrada padrão. Esta função tem dois argumentos "%d" e &inteiro1. Quando temos mais de um parâmetro para uma função, eles serão separados por vírgula. O primeiro argumento, a string de controle de formato, indica o tipo de dado que deve ser fornecido pelo usuário.
31 O especificador de conversão %d indica que o dado deve ser um inteiro (a letra d significa "decimal integer" (inteiro do sistema decimal, ou seja, base 10). O % é considerado por scanf (e por printf) um caractere de escape (como o \) e a combinação %d é uma seqüência de escape como \n. O segundo argumento de scanf começa com um e-comercial (&), chamado em C de operador de endereço, seguido do nome da variável. O & quando combinado com o nome da variável, diz a scanf o local na memória onde a variável inteiro1 está armazenada.
O computador então armazena o valor de inteiro1 naquele local. 32 É muito importante preceder cada variável em todas as instruções scanf com um &. Ao executar scanf, o computador espera o usuário fornecer um valor para a variável inteiro1. O usuário responde digitando um inteiro e então aperta a tecla enter para enviar o número ao computador. A seguir, o computador atribui este número, ou valor, à variável inteiro1. Quaisquer referências posteriores a inteiro1 no programa usarão esse mesmo valor.
33 A instrução: printf("entre com o segundo inteiro: \n"); imprime a mensagem Entre com o segundo inteiro: na tela e então posiciona o cursor no início da próxima linha. Este printf também faz com que o usuário realize uma ação. A instrução: scanf("%d", &inteiro2); obtém o valor fornecido pelo usuário para a variável inteiro2. A instrução de atribuição: soma = inteiro1 + inteiro2; calcula o valor da soma das variáveis inteiro1 e inteiro2, e atribui o resultado à variável soma usando o operador de atribuição = (sinal de igualdade).
34 A instrução é lida como "soma recebe o valor de inteiro1 + inteiro2". A maioria dos cálculos é executada em instruções de atribuição. Os operadores = e + são chamados de operadores binários porque cada um deles tem dois operandos. No caso do operador +, os dois operandos são inteiro1 e inteiro2. No caso do operador =, os dois operandos são soma e o valor da expressão inteiro1 + inteiro2.
Colocar espaços em ambos os lados de um operador binário ressalta o operador e torna o programa mais legível. 35 O cálculo de uma instrução de atribuição deve estar sempre no lado direito do operador =. É um erro de sintaxe colocar o cálculo no lado esquerdo de um operador de atribuição (soma = inteiro1 + inteiro2;). A instrução: printf("a soma e %d\n", soma); usa a função printf para imprimir na tela a expressão A soma e seguida do valor numérico de soma. Este printf tem dois argumentos, "A soma e %d\n" e soma.
O primeiro argumento é a string de controle de formato que indica que um inteiro será impresso. 36 O especificador de conversão para um inteiro é o mesmo tanto em printf como em scanf. O segundo argumento especifica o valor a ser impresso. Poderíamos ter combinado as duas instruções anteriores na instrução dentro de instruções printf: printf("a soma e %d\n", inteiro1 + inteiro2); Erros comuns: Esquecer-se de uma (ou dois) aspas duplas em torno de uma string de controle de formato de printf ou scanf "%d".
Em uma especificação de conversão, esquecer-se do % na string de controle de formato de printf ou scanf. 37 Colocar uma seqüência de escape como \n fora da string de controle de formato de printf ou scanf. "A soma e %d\n" "A soma e %d " \n Colocar dentro de uma string de controle, a vírgula que deve separa-lá das expressões a serem impressas. printf("a soma e %d\n", inteirol + inteiro2); Esquecer-se de preceder uma variável, em uma instrução scanf, de um & quando essa variável deve obrigatoriamente ser precedida por ele.
Conceitos sobre Memória 38 Nomes de variáveis como inteiro1, inteiro2 e soma correspondem a locais na memória do computador. Todas as variáveis possuem um nome, um tipo e um valor. Quando scanf("%d", &inteiro1); é executada, o valor digitado pelo usuário é colocado no local da memória ao qual o nome inteiro1 foi atribuído. Suponha que o usuário digitou o número 45 como valor para inteiro1. O computador colocará 45 no local inteiro1.
39 Sempre que um valor é colocado em um local da memória, o novo valor invalida o anterior naquele local. Como as informações anteriores são destruídas, o processo de levar (ler) as informações para um local da memória é chamado leitura destrutiva (destructive read-in). Quando a instrução: scanf("%d", &inteiro2); é executada, o valor digitado é levado ao local inteiro.
Estas posições não são obrigatoriamente adjacentes na memória. 40 O programa soma os valores de inteiro1 e inteiro2 e coloca o valor da soma na variável soma. A instrução soma = inteiro1 + inteiro2; que realiza a soma também emprega leitura destrutiva. Quando a soma é calculada é colocada no local soma é destruído o valor que já poderia estar ali.
41 Atividade para a próxima semana (30/10/2013): Utilizando números reais (real) construa 4 algoritmos diferentes: a) Um para converter C para F (e um para converter F para C): b) Um para calcular o volume de uma lata: c) Um para mostrar o volume de um paralelepípedo: