Aulas de C

Aprendizado continuo. Linguagem antiga e moderna

O primeiro programa: HelloWorld.c

Olá todos!
Bem, agora vamos para algo de programação.

OK… Na realidade não é nada muito fantástico, mas a ideia é permitir que você tenha uma noção da estrutura de um programa C típico e de como ele é composto. Depois iremos explicar tudo de maneira mais detalhada.
Existe uma tradição em programação que o primeiro programa de computador para qualquer linguagem deve apresentar apenas uma mensagem na tela, normalmente “Hello World!“. Na realidade, se você usar o Google para pesquisar o termo “Hello World” em programação, você verá sites com coletâneas enormes de HelloWorlds nas mais diversas linguagens de programação, antigas ou modernas.
De qualquer modo, vamos ver nosso Hello World em C. Abra um editor de texto (como o Notepad do Windows ou quaisquer um dos editores de texto do Linux) e digite o que está abaixo as-is. (iremos explicar melhor logo) Se estiver usando uma IDE, abra-a e crie um arquivo com o conteúdo abaixo:
#include <stdio.h>

/* Nosso Hello World! (c) 2010 GPL */

int main (int argc, char** argv)
{

    printf(“Hello World!\n”); // Trouxemos ele do stdio.h
    return (0);
}

Não se preocupe em copiar a formatação do código: apenas digite-o como ele está. As cores são apenas para algumas explicações que serão dadas sobre o programa em questão.
Vamos começar então a destrinchar os que digitamos.
Repare na primeira linhas:

#include <stdio.h>

Ela, por incrível que pareça, ainda não é código C… Na verdade não exatamente. Todo “comando” que comece com o # (sharp, tralha, cerquilha, lasanha, entre outras formas de dizer que já ouvi por aí) é um comando para o pré-processador, que indica que o compilador deve tomar alguma atitude especial. Nesse caso, o #include adiciona ao arquivo em questão o conteúdo de um outro arquivo, no caso o arquivo stdio.h. O fato de ele estar entre os sinais de maior-menor tem uma função especial: ele faz o compilador buscar esse arquivo entre os arquivos da biblioteca-padrão do C. A biblioteca-padrão do C representa comandos que normalmente espera-se que façam parte do compilador independentemente da plataforma, versão ou tipo do compilador específico e, embora não sejam necessariamente obrigatórios, eles são quase sempre encontrados em qualquer bom compilador. É possível programar-se em C sem as bibliotecas-padrão (na realidade, em alguns casos é desejável, como no caso de programar-se C para microprocessadores), mas em geral um bom compilador irá incluir as bibliotecas padrão do C. Em alguns casos, o maior-menor irá representar a inclusão de arquivos de outras bibliotecas que fazem parte dos includes do compilador. Falaremos mais sobre isso quando entrarmos na questão de programação com múltiplos objetos e afins.
O stdio.h vêm de STandarD I/O Headers (Cabeçalhos de Entrada e Saída Padrão). Ele faz referências a funções de entrada e saída padronizadas pelo C. No caso, os cabeçalhos indicam ao compilador que tipo de funções o programa irá usar e como ele irá se comportar nesse caso. Veremos mais no futuro, mas o que é importante saber é que, sem essa linha, esse programa (e qualquer outro que exija funções de entrada e saída padrão) irá dar erro no momento da sua geração (ou compilação).
Chega de falar dessa linha. Vamos falar sobre uma coisa muito importante em C: comentários.
Comentários são basicamente isso: comentários. Em geral, comentários são apenas texto informativo que é inserido em um programa para documentá-lo, sendo sumariamente ignorado pelo compilador (veremos mais sobre o compilador ainda nesse post). Em alguns casos, com o uso de ferramentas certas, comentários podem ser muito úteis, ajudando a documentar um programa de maneiras muito inteligentes. Uma utilidade também dos comentários é que eles podem ser usados como método de depuração (correção de problemas): basta comentar-se o trecho de código onde existam problemas e verificar se os mesmos persistem uma vez que o programa seja re-executado.
No C, existem dois tipos de comentários:

  • O padrão mais antigo, onde começa-se o comentário com /* e termina com */: nesse caso, é considerado comentário tudo que estiver entre esses dois símbolos. A vantagem desse tipo de comentário é que ele é multi-line, ou seja, você pode adicionar linhas e linhas de comentário, desde que todos os comentários estejam entre esses dois símbolos;
  • Um padrão mais recente (parte do padrão chamado C99), que é usar-se duas barras (//): na verdade, esse padrão já usado a um bom tempo, em especial em compiladores que compilem código de C++ além de C (veremos C++ em tópicos mais avançados). Ele permite comentários in-line, ou seja, comentários a partir de um determinado ponto de uma linha de código. Para o compilador, tudo entre as duas barras e o final da linha onde elas estão será considerado comentário;

Bem, não precisamos falar mais dos comentários, então vamos voltar à nossa  Repare nas linhas comentadas em azul:

int main (int argc, char** argv)
{
<…>
}

Aqui estamos utilizando uma função main para colocar o código principal do nosso programa. O C trabalha com o conceito de função para separar os trechos de códigos, sendo que uma função é basicamente um bloco de código (um trecho de código separado pelos colchetes { }) com um nome. Veremos mais sobre isso quando entramos em funções. O importante agora é saber que main é o nome que damos a essa função onde colocamos nosso código (o texto em preto no programa acima).
A função main, porém, é especial e exige um pouquinho de atenção: ela é considerada o ponto de entrada de um programa. Para ser exato, caso não exista uma função main dentro de um programa, o compilador irá dar erro ao compilar (existem situações em que você não usará main em um arquivo C. Veremos isso ao falarmos sobre a programação com múlltiplos fontes e bibliotecas). Ela também tem uma construção razoavelmente padronizada, que é int main (int argc, char** argv). Você pode criar seu main com outras definições (ou cabeçalhos… lembram lá de cima?), mas alguns compiladores poderão acusar um alerta (uma mensagem que não é de erro, mas indica detalhes que podem dar problema) de que o main em questão sai do padrão do C. Em geral, o mainmain será escrito dessa maneira como indicamos e, caso você use uma IDE, o arquivo principal do seu projeto quase sempre terá um como o acima (falaremos mais sobre esse conceito de projeto no futuro).
Toda função em C é composta de três fatores, que explicaremos por alto (voltaremos mais nesse assunto quando falarmos de variáveis e funções), e a main não escapa desse padrão:

  • Retorno: diz qual o valor final que a função irá devolver ao sistema uma vez que termine de executar;
  • Nome: como ela é identificada pelo programador (quando o programa for compilado, esse nome é substituído por informações que indicarão onde ela ficará na memória do computador no momento da execução);
  • Parâmetros: O que ela espera de informação de quem quer que a chame. Normalmente são representados por um tipo, que indica qual o tipo de valor que é esperado, e por um nome de parâmetro, que indica como esse parâmetro será usado pelo programador;

Na realidade, é possível especificar-se funções que não retornem nada e não tenham parâmetros. Veremos isso em funções e quando falarmos dos tipos de dados em C.
No caso específico do main, ela é do tipo int (que representa valores inteiros – sem casas decimais – tanto positivos quanto negativos), chama-se main e possui como parâmetros um int chamado argc e um char** chamado argv. Esses parâmetros, no caso de main representam:

  • argc: o número de argumentos passados pelo programa e;
  • argv: uma lista dos mesmos (na verdade, o argv é mais complexo que isso, mas não iremos aprofundar mais nele. Por enquanto, o importante é saber como ele trabalha);

OK… Até agora vimos que precisamos dizer ao C que funções de biblioteca iremos usar e qual é nossa função main, além de dizer a ele o que ele deve retornar ao sistema operacional e como ele deve receber parâmetros do sistema operacional. Agora vamos aos comandos reais.

    printf(“Hello World!\n”); // Trouxemos ele do stdio.h
    return (0);

Bem, esses dois comandos basicamente imprimem na tela o texto “Hello World!” na tela e encerram o programa. Mas esses comandos possuem detalhes que os diferenciam e que são importantes para entender o C:
O primeiro comando se chama printf (de PRINT Formatted, “imprimir com formatação”). Esse comando é parte das bibliotecas padrão do C, na verdade da stdio que já mencionamos anteriormente. Embora seja parte da biblioteca padrão, ele não é, vamos dizer assim, obrigatório para um compilador C. Na verdade, ele não é uma palavra reservada, ou seja, um comando que é obrigatório da existência em C e que não pode possuir outro igual. De certa forma, um desenvolvedor pode criar seu próprio comando printf e colocá-lo em uma biblioteca à parte, o que pode ser útil para, por exemplo, quando vai programar-se microprocessadores (que não possuem saídas visuais, portanto havendo necessidade de um printf). No caso, ele recebe um texto para imprimir na tela. Na verdade, esse texto pode possuir determinados conjuntos de caracteres especiais que indicam como deverá ser formatado o código em questão, aos quais chamamos de formatos e caracteres de controles (veremos mais adiante sobre isso). No caso, temos um caracter de controle (símbolos que representam caracteres que não são visualizáveis normalmente), o \n, que indica que deve-se pular uma linha ao terminar-se de imprimir esse texto. Portanto, o que printf vai fazer aqui é (1) escrever na tela “Hello World!” e (2) pular uma linha.
Quem leu até aqui com calma vai perceber que a “mágica” já está feita. Então o programa não acabaria aqui? Para que o segundo comando, o tal return (0)?
O comando return é parte das palavras reservadas do C. Uma palavra reservada normalmente representa um comando ou informação interna da linguagem de programação C cujo nome não pode ser usado para MAIS NADA a não ser pelo que é indicado. O padrão C determina um conjunto de palavras reservadas, como return, int ou float. Importante ver a diferença entre os dois: um programador poderia criar sua própria versão de printf, mas não poderia criar uma versão de return.
O return é um comando que normalmente encerra qualquer função, devolvendo o controle do programa para quem quer que tenha chamado a função. No caso de main, pode-se dizer que quem chama a função main (o programa principal) é o ssitema operacional, portanto é ele que vai receber de volta o controle quando o comando return for executado nesse caso, o que indica o final do programa. O 0 entre parênteses é um valor inteiro que o sistema pode usar para fazer testes (no caso de programas automatizados e afins). No nosso caso, como não existe, digamos assim, um “dar errado”, o valor 0 foi adotado mais por convenção, mas esse valor pode ser mudado se for necessário, embora não aprofundaremos esse tópico aqui. Importante a saber aqui é que (1) return é uma palavra reservada e não pode ter outro no C, (2) ele devolve o controle ao sistema operacional nessa situação e (3) ele pode devolver um valor que pode ser usado pelo sistema operacional. No momento, basta saber essa informação: nos aprofundaremos no funcionamento de return quando estudarmos funções.
OK… O programa está pronto. O que fazer com ele?
Diferentemente de algumas linguagens de programação mais atuais, como Python, PERL, PHP ou Ruby, o C é uma linguagem compilada. Isso quer dizer que precisamos usar um programa, chamado compilador, para traduzir as instruções do nosso programa (chamado de código fonte) para instruções que o computador compreenda e seja capaz de executar (chamado de código objeto ou binário). No caso, vamos utilizar o GCC para compilar o nosso programa: salve o código digitado como HelloWorld.c (na realidade, você pode escolher qualquer nome, mas é bom usar nomes claros, que identifiquem facilmente seu código) e abra um terminal (no Linux) ou um Prompt de Comando (no DOS/Windows). Entre no mesmo diretório onde você gravou o seu HelloWorld.c e digite o seguinte comando:

gcc -o HelloWorld HelloWorld.c

O comando em questão irá compilar seu código e irá gravar o binário em um arquivo. No caso do Linux especificamente, o padrão do GCC é gravar o binário em um arquivo de saída a.out. Utilizamos então a opção -o (output) pada gravar o código em um arquivo de saída chamado HelloWorld. Imaginando que tudo esteja correto, usamos o comando ./HelloWorld para executarmos nosso Hello World!
OK, você deve ter visto o Hello World! e se perguntado em algum momento “Não entendi!”. Algumas “brincadeiras” que você pode fazer para entender alguns conceitos que colocamos aqui:

  1. Comente ou remova a linha #include e veja o resultado ao compilar o programa;
  2. Modifique o nome main para alguma outra coisa e tente compilar o programa. Substitua o retorno int ou os parâmetros entre parênteses dele por void (sem retorno/parâmetro);
  3. Adicione mais linhas printf com o texto que você quiser e coloque ou não o caracter de controle \n e veja como o programa irá se comportar;

Essas “brincadeiras” irão permitir que você pegue alguns dos conceitos sobre os quais falamos até agora e irá divertir você. Caso tenha alguma dúvida sobre esse post, por favor, adicione nos comentários sua dúvida. Em especial, se a dúvida envolver erros no programa, copie a saída que deu na compilação e informe seu sistema operacional e compilador.
Semana que vem estarei postando mais coisas. A jornada de programação C apenas começou.

8 Respostas para “O primeiro programa: HelloWorld.c

  1. Francisco 16/11/2010 às 10:13

    Achei exelente a forma como estão preparadas suas aulas. Estarei sempre acompanhando elas.

  2. Marcelo Gondim 17/11/2010 às 1:40

    heheh já achei o primeiro erro no código acima:

    /* Nosso Hello World! (c) 2010 GPL *

    e deveria ser:

    /* Nosso Hello World! (c) 2010 GPL */
    🙂

  3. Pingback: Controle de Fluxo e Operandos Lógicos « Aulas de C

  4. Pingback: Funções – Parte 1 « Aulas de C

  5. Wagner Macedo 12/01/2011 às 10:37

    Estou começando a acompanhar suas aulas. São muito didáticas, sei que vou aprender muito com elas, parabéns!

  6. Pingback: Sobre arquivos de código-fonte, arquivos de cabeçalhos e projetos « Aulas de C

  7. jessemenegat 20/09/2014 às 0:03

    Muito bom. Muito bem explicado. Tens uma didática muito boa.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: