(Parte 1 de 9)

Curso de Programaçªo em C

Vamos, neste curso, aprender os conceitos bÆsicos da linguagem de programaçªo C a qual tem se tornado cada dia mais popular, devido à sua versatilidade e ao seu poder. Uma das grandes vantagens do C Ø que ele possui tanto características de "alto nível" quanto de "baixo nível".

Apesar de ser bom, nªo Ø prØ-requisito do curso um conhecimento anterior de linguagens de programaçªo. É importante uma familiaridade com computadores. O que Ø importante Ø que vocŒ tenha vontade de aprender, dedicaçªo ao curso e, caso esteja em uma das turmas do curso, acompanhe atentamente as discussıes que ocorrem na lista de discussıes do curso.

O C nasceu na dØcada de 70. Seu inventor, Dennis Ritchie, implementou-o pela primeira vez usando um DEC PDP-1 rodando o sistema operacional UNIX. O C Ø derivado de uma outra linguagem: o B, criado por Ken Thompson. O B, por sua vez, veio da linguagem BCPL, inventada por Martin Richards.

problemas da Engenharia, Física, Química e outras CiŒncias, etcÉ bem provÆvel que o

O C Ø uma linguagem de programaçªo genØrica que Ø utilizada para a criaçªo de programas diversos como processadores de texto, planilhas eletrônicas, sistemas operacionais, programas de comunicaçªo, programas para a automaçªo industrial, gerenciadores de bancos de dados, programas de projeto assistido por computador, programas para a soluçªo de Navegador que vocŒ estÆ usando para ler este texto tenha sido escrito em C ou C++.

Estudaremos a estrutura do ANSI C, o C padronizado pela ANSI. Veremos ainda algumas funçıes comuns em compiladores para alguns sistemas operacionais. Quando nªo houver equivalentes para as funçıes em outros sistemas, apresentaremos formas alternativas de uso dos comandos.

Sugerimos que o aluno realmente use o mÆximo possível dos exemplos, problemas e exercícios aqui apresentados, gerando os programas executÆveis com o seu compilador. Quando utilizamos o compilador aprendemos a lidar com mensagens de aviso, mensagens de erro, bugs, etc. Apenas ler os exemplos nªo basta. O conhecimento de uma linguagem de programaçªo transcende o conhecimento de estruturas e funçıes. O C exige, alØm do domínio da linguagem em si, uma familiaridade com o compilador e experiŒncia em achar "bugs" nos programas. É importante entªo que o leitor digite, compile e execute os exemplos apresentados.

Capítulo 1 (Primeiros Passos)

O C Ø "Case Sensitive"

Vamos começar o nosso curso ressaltando um ponto de suma importância: o C Ø "Case Sensitive", isto Ø, 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 if e for, por exemplo, só podem ser escritos em minœsculas pois senªo o compilador nªo irÆ interpretÆ-los como sendo comandos, mas sim como variÆveis.

Dois Primeiros Programas Vejamos um primeiro programa em C:

#include <stdio.h> /* Um Primeiro Programa */ int main ()

{ printf ("Ola! Eu estou vivo!\n"); return(0); } Compilando e executando este programa vocŒ verÆ que ele coloca a mensagem Ola! Eu estou vivo! na tela.

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 œteis 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 vocŒ quiser usar uma destas funçıes deve-se incluir este comando. O C possui diversos arquivos-cabeçalhos.

Quando fazemos um programa, uma boa idØia Ø usar 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, inclusive, ter mais de uma linha.

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, quando estudarmos um pouco mais detalhadamente as funçıes do C. 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 próxima linha. É importante observar tambØm que os comandos do C terminam com ;

A œnica coisa que o programa realmente faz Ø chamar a funçªo printf(), passando a string (uma string Ø uma seqüŒncia de caracteres, como veremos brevemente) "Ola! Eu estou vivo!\n" como argumento. É por causa do uso da funçªo printf() pelo programa que devemos incluir o arquivo- cabeçalho stdio.h . A funçªo printf() neste caso irÆ apenas colocar a string na tela do computador. O \n Ø uma constante chamada de constante barra invertida. 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 Ola! Eu estou vivo! o cursor passarÆ para Podemos agora tentar um programa mais complicado:

#include <stdio.h>
int main ()
{
int Dias;/* Declaracao de Variaveis */
Anos=Dias/365.25;/* Conversao Dias->Anos */
}

float Anos; printf ("Entre com o nœmero de dias: "); /* Entrada de Dados */ scanf ("%d",&Dias); printf ("\n\n%d dias equivalem a %f anos.\n",Dias,Anos); return(0); 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(). O motivo disto só ficarÆ claro mais tarde. Observe que, no 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 (veremos isto com detalhes mais tarde).

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 float, respectivamente.

AUTO AVALIAO 1 - Veja como vocŒ estÆ. O que faz o seguinte programa? #include <stdio.h> int main() { int x; scanf("%d",&x); printf("%d",x); return(0); } 2 - Compile e execute os programas desta seçªo.

Introduçªo às 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.

#include <stdio.h>
int mensagem () /* Funcao simples: so imprime Ola! */
{
}
int main ()
{
}

Abaixo o tipo mais simples de funçªo: printf ("Ola! "); return(0); mensagem(); printf ("Eu estou vivo!\n"); return(0); Este programa terÆ o mesmo resultado que o primeiro exemplo da seçªo anterior. 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.

Argumentos

#include <stdio.h>
int square (int x) /* Calcula o quadrado de x */
{
}
int main ()
{
}

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. Vamos ver um outro exemplo simples de funçªo com argumentos: printf ("O quadrado e %d",(x*x)); return(0); int num; printf ("Entre com um numero: "); scanf ("%d",&num); printf ("\n\n"); square(num); return(0); 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 observar. Em primeiro lugar temos de satisfazer aos requesitos 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 ficar 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.

#include <stdio.h>

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.

{
}
int main ()
{

int mult (float a, float b,float c) /* Multiplica 3 numeros */ printf ("%f",a*b*c); return(0); float x,y; x=23.5; y=12.9; mult (x,y,3.87); return(0);

}

Retornando valores

#include <stdio.h>
int prod (int x,int y)
{
}

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 da multiplicaçªo. Veja: return (x*y);

{
}

int main () int saida; saida=prod (12,7); printf ("A saida e: %d\n",saida); return(0); Veja 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 o printf. Uma observaçªo adicional: se nªo especificarmos o tipo de retorno de uma funçªo, o compilador C automaticamente suporÆ que este tipo Ø inteiro. PorØm, nªo Ø uma boa prÆtica nªo se especificar o valor de retorno e, neste curso, este valor serÆ sempre especificado.

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.

#include <stdio.h>
float prod (float x,float y)
{
}
int main ()
{

Mais um exemplo de funçªo, que agora recebe dois floats e tambØm retorna um float:: return (x*y); float saida; saida=prod (45.2,0.0067); printf ("A saida e: %f\n",saida); return(0); }

Forma geral

Apresentamos aqui a forma geral de uma funçªo: tipo_de_retorno nome_da_funçªo (lista_de_argumentos) { código_da_funçªo }

AUTO AVALIAO Veja como vocŒ estÆ. Escreva uma funçªo que some dois inteiros e retorne o valor da soma.

Introduçªo BÆsica às Entradas e Saídas

Os caracteres sªo um tipo de dado: o char. O C trata os caracteres (’a’, ’b’, ’x’, etc)

Caracteres como sendo variÆveis de um byte (8 bits). Um bit Ø a menor unidade de armazenamento de informaçıes em um computador. Os inteiros (ints) tŒm um nœmero maior de bytes. Dependendo da implementaçªo do compilador, eles podem ter 2 bytes (16 bits) ou 4 bytes (32 bits). Na linguagem C, tambØm podemos usar um char para armazenar valores numØricos inteiros, alØm de usÆ-lo para armazenar caracteres de texto. Para indicar um caractere de texto usamos apóstrofes. Veja um exemplo de programa que usa caracteres: #include <stdio.h> int main () { char Ch; Ch=’D’; printf ("%c",Ch); return(0); } No programa acima, %c indica que printf() deve colocar um caractere na tela. Como vimos anteriormente, um char tambØm Ø usado para armazenar um nœmero inteiro. Este nœmero Ø conhecido como o código ASCII correspondente ao caractere. Veja o programa abaixo: #include <stdio.h> int main () { char Ch; Ch=’D’; printf ("%d",Ch); /* Imprime o caracter como inteiro */ return(0);} Este programa vai imprimir o nœmero 68 na tela, que Ø o código ASCII correspondente ao caractere ’D’ (d maiœsculo).

Muitas vezes queremos ler um caractere fornecido pelo usuÆrio. Para isto as funçıes mais usadas, quando se estÆ trabalhando em ambiente DOS ou Windows, sªo getch() e getche(). Ambas retornam o caractere pressionado. getche() imprime o caractere na tela antes de retornÆ-lo e getch() apenas retorna o caractere pressionado sem imprimí-lo na tela. Ambas as funçıes podem ser encontradas no arquivo de cabeçalho conio.h. Geralmente estas funçıes nªo estªo disponíveis em ambiente Unix (compiladores c e gc) e podem ser substituídas pela funçªo scanf(), porØm sem as mesmas funcionalidades. Eis um exemplo que usa a funçªo getch(), e seu correspondente em ambiente Unix: #include <stdio.h>

#include <conio.h> /* Este programa usa conio.h . Se vocŒ nªo tiver a conio, ele nªo funcionarÆ no Unix */ int main () { char Ch; Ch=getch(); printf ("Voce pressionou a tecla %c",Ch); return(0); } Equivalente para o ambiente Unix do programa acima, sem usar getch(): #include <stdio.h> int main () { char Ch; scanf("%c", &Ch); printf ("Voce pressionou a tecla %c",Ch); return(0); } A principal diferença da versªo que utiliza getch() para a versªo que nªo utiliza getch() Ø que no primeiro caso o usuÆrio simplesmente aperta a tecla e o sistema lŒ diretamente a tecla pressionada. No segundo caso, Ø necessÆrio apertar tambØm a tecla <ENTER>.

Strings

No C uma string Ø um vetor de caracteres terminado com um caractere nulo. O caracter nulo Ø um caractere com valor inteiro igual a zero (código ASCII igual a 0). O terminador nulo tambØm pode ser escrito usando a convençªo de barra invertida do C como sendo ’\0’. Embora o assunto vetores seja discutido posteriormente, veremos aqui os fundamentos necessÆrios para que possamos utilizar as strings. Para declarar uma string, podemos usar o seguinte formato geral: char nome_da_string[tamanho]; Isto declara um vetor de caracteres (uma string) com nœmero de posiçıes igual a tamanho. Note que, como temos que reservar um caractere para ser o terminador nulo, temos que declarar o comprimento da string como sendo, no mínimo, um caractere maior que a maior string que pretendemos armazenar. Vamos supor que declaremos uma string de 7 posiçıes e coloquemos a palavra Joªo nela. Teremos:

J o a o \0

No caso acima, as duas cØlulas nªo usadas tŒm valores indeterminados. Isto acontece porque o C nªo inicializa variÆveis, cabendo ao programador esta tarefa. Portanto as œnicas cØlulas que sªo inicializadas sªo as que contŒm os caracteres ’J’, ’o’, ’a’, ’o’ e ’\0’ .

Se quisermos ler uma string fornecida pelo usuÆrio podemos usar a funçªo gets(). Um exemplo do uso desta funçªo Ø apresentado abaixo. A funçªo gets() coloca o terminador nulo na string, quando vocŒ aperta a tecla "Enter". #include <stdio.h> int main () { char string[100]; printf ("Digite uma string: "); gets (string); printf ("\n\nVoce digitou %s",string); return(0); } Neste programa, o tamanho mÆximo da string que vocŒ pode entrar Ø uma string de 9 caracteres. Se vocŒ entrar com uma string de comprimento maior, o programa irÆ aceitar, mas os resultados podem ser desastrosos. Veremos porque posteriormente.

Como as strings sªo vetores de caracteres, para se acessar um determinado caracter de uma string, basta "indexarmos", ou seja, usarmos um índice para acessarmos o caracter desejado dentro da string. Suponha uma string chamada str. Podemos acessar a segunda letra de str da seguinte forma: str[1] = ’a’;

Por quŒ se estÆ acessando a segunda letra e nªo a primeira? Na linguagem C, o índice começa em zero. Assim, a primeira letra da string sempre estarÆ na posiçªo 0. A segunda letra sempre estarÆ na posiçªo 1 e assim sucessivamente. Segue um exemplo que imprimirÆ a segunda letra da string "Joao", apresentada acima. Em seguida, ele mudarÆ esta letra e apresentarÆ a string no final. #include <stdio.h> int main() { char str[10] = "Joao"; printf("\n\nString: %s", str); printf("\nSegunda letra: %c", str[1]); str[1] = ’U’; printf("\nAgora a segunda letra eh: %c", str[1]); printf("\n\nString resultante: %s", str); return(0); } Nesta string, o terminador nulo estÆ na posiçªo 4. Das posiçıes 0 a 4, sabemos que temos caracteres vÆlidos, e portanto podemos escrevŒ-los. Note a forma como inicializamos a string str com os caracteres ’J’ ’o’ ’a’ ’o’ e ’\0’ simplesmente declarando char str[10] = "Joao". Veremos, posteriormente que "Joao" (uma cadeia de caracteres entre aspas) Ø o que chamamos de string constante, isto Ø, uma cadeia de caracteres que estÆ prØ-carregada com valores que nªo podem ser modificados. JÆ a string str Ø uma string variÆvel, pois podemos modificar o que nela estÆ armazenado, como de fato fizemos.

No programa acima, %s indica que printf() deve colocar uma string na tela. Vamos agora fazer uma abordagem inicial às duas funçıes que jÆ temos usado para fazer a entrada e saída.

printf

(Parte 1 de 9)

Comentários