Out-of-series #5 – Implementação de Filas em C/C++

Um dia desses em um projeto que estou desenvolvendo profissionalmente, me deparei com a necessidade do uso de filas (queues). Explicarei apenas brevemente o que são filas, pois pretendo explicá-las mais à frente na sequência de posts didáticos sobre programação. Segundo a nossa amiga Wikipedia, “as filas são estruturas de dados baseadas no princípio FIFO (first in, first out), em que os elementos que foram inseridos no início são os primeiros a serem removidos. Uma fila possui duas funções básicas: ENQUEUE, que adiciona um elemento ao final da fila, e DEQUEUE, que remove o elemento no início da fila”. É como se fosse uma fila normal (dessas que você sempre enfrenta no banco ou no caixa do supermercado…). O primeiro que chega, é o primeiro a ser atendido. Sempre que uma nova pessoa entra, ela é “inserida” no final da fila.

A seguir, mostrarei a implementação em C e em C++ (apesar da STL do C++ já implementar queues…) utilizando listas encadeadas. Espero que possa ser útil a vocês! 🙂

Para utilizar essas funções, basta criar um ponteiro para uma struct dado (struct dado *), inicializá-la com NULL e sempre colocá-la para pegar o retorno das funções.

Até a próxima 😀

Introdução à Linguagem C – Parte III

Olha eu aqui de novo. Como havia prometido, nessas férias vou movimentar um pouco as coisas por aqui, já que ao longo do ano a coisa vai ser feia. Último ano da faculdade, projeto de conclusão de curso, a minha tentativa de conseguir um mestrado vai ser colocada em prática, enfim, uma correria que só vendo.

Mas vamos parar com a conversa fiada e começar com a ação. Como prometido, nesta terceira e última parte da Introdução à Linguagem C, veremos os dois assuntos pendentes em relação a linguagem Pascal, tomando por base o ponto no qual nos encontramos: registros e as funções e procedimentos.

Bom, não vou me aprofundar muito no conceito do que seria um registro (há um post inteiro dedicado a eles), apenas vou citar as “novidades” na linguagem C. Bom, primeiramente, em C os registros são conhecidos como estruturas ou melhor, pela palavra chave struct. As structs são simplesmente agrupamentos variáveis. Vamos visualizar as diferenças de sintaxe, e em seguida explicaremos suas particularidades (utilizando o mesmo exemplo do post sobre registros):

Bom, no exemplo acima vocês tem a comparação entre o Algoritmo, a sintaxe em Pascal e a sintaxe em C. Neste caso citado acima, estamos utilizando registro para criar um novo tipo, chamado de Aluno (só relembrando, a linguagem C é case sensitive, ou seja, ao contrário da linguagem Pascal, Aluno e aluno são coisas diferentes!), criando em seguida uma variável desse novo tipo, com o nome umAluno. Posteriormente explicarei com mais detalhes o uso do typedef.

Utilizar um registro para definirmos um tipo é vantajoso apenas se utilizaremos esse tipo em vários locais do programa. Se fossemos utilizar apenas em um ponto do aplicativo, por exemplo, poderíamos fazer assim:

Isso também resultaria em uma variável de nome umAluno, com os campos nome e idade. “Certo… mas e se eu precisasse passar um registro desse por parâmetro para uma função? Como eu declararia isso?”. Bom, caso você precise passar um registro por parâmetro em uma função, precisaremos nomear essa nossa estrutura. De que forma? Adicionando um identificador entre a palavra reservada struct e o abre chaves. Por exemplo:

Lembrando apenas que, para que seja possível passar essa estrutura como parâmetro em funções, sua declaração deve ser feita de forma global (fora de qualquer função ou procedimento) e antes do seu primeiro uso. Ao final do post, quando exemplificarmos a declaração de funções, teremos um exemplo disso. 😉

Com relação a sintaxe dos registros em C, não há muito mistério. Iniciamos com a palavra reservada struct, seguida ou não do identificador daquela estrutura. Em seguida, temos a definição dos campos que comporão aquela estrutura. Isso é feito da mesma forma que declaramos variáveis (observe os exemplos citados acima). Após o fecha chaves, podemos ter um nome de variável, que terá como forma essa estrutura. No final, encerra-se a declaração com ponto e vírgula. Cabe frisar que, caso não haja um nome de variável após a definição dos campos, você terá declarado apenas a estrutura, e não uma variável com o formato da estrutura. Ficou um pouco confuso? Vou tentar explicar melhor. Ao declarar uma estrutura, o struct { … } apenas indica o formato dela, mesmo que você coloque o identificador entre o struct e o {. Digamos assim. Se escrevermos int a; teremos uma variável do tipo inteiro. Se escrevermos struct { … } a; teremos uma variável do tipo da estrutura que definimos. Um dos motivos de frequentemente utilizarmos o typedef é para evitarmos de ter que sempre colocar struct <algumacoisa> sempre que precisarmos utilizar essa estrutura em nosso programa. Para finalizar as dúvidas: o identificador entre o struct e o { é o nome da estrutura e o que vem depois do } e antes do ; é então a declaração de uma variável do tipo da estrutura. Quaisquer dúvidas sobre o assunto, deixem nos comentários que eu tento explicar melhor.

Para acessar os campos da estrutura, assim como na linguagem Pascal, utilizamos o . seguido do nome do campo. Por exemplo:

Como pode ser visto, não tem nenhum mistério ao acessar os campos do registro. Esse tipo de acesso só não vai se alterar quando a struct for um ponteiro, mas isso discutiremos no post sobre ponteiros, mais adiante. Só atentem que o segundo argumento da chamada à função scanf, quando o valor é um vetor de caracteres (string), não usa-se o operador & (na 1ª parte desta introdução falei sobre isso).

Concluída então a nossa discussão a respeito de registros, falaremos então a respeito de funções e procedimentos. A primeira coisa que tenho a falar é que, em C, não há distinção entre função e procedimento. Como assim??? É. Ao contrário da linguagem Pascal que define uma palavra chave para função (function) e uma para procedimento (procedure), na linguagem C não há essa distinção. A único detalhe que definirá um procedimento de uma função, e o tipo void como retorno da função, pois em C os procedimentos também podem conter a palavra return ao final de seu escopo. Estranho, né? Vamos então a alguns exemplos de função, em Algoritmo, Pascal e C:

A declaração de uma função inicia com o tipo de retorno, no caso deste exemplo, um valor inteiro (int). Logo em seguida, temos o nome de nossa função, seguida com a lista de argumentos, devidamente acompanhados de seus tipos, separados por vírgula (e não ponto e vírgula, como em Pascal) e circundados por parênteses. Logo em seguida, definimos o escopo de nossa função em um bloco entre chaves. O processamento ocorre da mesma maneira com que nas outras partes do programa. O bloco é encerrado pelo retorno, ou seja, a palavra chave return seguido do valor constante ou variável, entre parênteses ou não.

Como já adiantei anteriormente no post, a declaração de um procedimento apenas se diferencia pelo fato do tipo de retorno ser void (o tipo vazio, lembram-se?). Além disso, pode-se simplesmente omitir a linha de retorno ou colocar apenas return; como verificaremos no exemplo a seguir.

Viu? Praticamente nenhuma diferença em relação às nossa funções.

Bom, então aqui finalmente encerramos a nossa Introdução à Linguagem C, depois de três longos posts. Quaisquer dúvidas que por acaso permanecerem, por favor postem nos comentários, pois a sua dúvida pode ser também a dúvida de outras pessoas. Mais uma vez peço encarecidamente que não me enviem programas para eu fazer. Esses exercícios que o curso técnico / faculdade pedem são de suma importância para fixar o conteúdo e desenvolver o seu raciocínio lógico. Devido ao grande número de e-mails que recebo desse tipo, tenho simplesmente que ignorá-los…

Espero ter ajudado com essa série de posts, e vamos que vamos. Em breve (ou não, vai depender do tempo), continuaremos com essa série de posts didádicos, falando sobre os temidos ponteiros!!! Até lá! 🙂

Procurando a parte 1 ou parte 2 dessa introdução?

Introdução à Linguagem C – Parte II

Olá pessoas! Aqui estou eu novamente pra mais um post da nossa série de aprendizado. Como prometido, neste post vamos completar alguns conceitos básicos da programação estruturada que já havíamos estudado na linguagem Pascal, mas dessa vez na linguagem C. No post passado, falamos da estrutura de seleção se (ou if). Outra estrutura de seleção também muito utilizada é o switch (em Pascal, utilizávamos o case). Com o switch, comparamos o conteúdo de uma variável com algumas constantes, e dessa forma selecionamos que trecho de código nossa aplicação irá executar. Abaixo, um trecho de código mostrando essa estrutura em Algoritmo, Pascal e em C. Logo após falaremos sobre os detalhes da sintaxe:

Temos algumas características interessantes a serem discutidas nesse trecho de código. Na estrutura switch, temos a palavra chave switch seguida do nome da variável que será comparada com as constantes. Neste exemplo, supomos que temos uma variável inteira (int) de nome ‘voto’. Em seguida, temos as comparações definidas. Elas são compostas da palavra chave case (que define um caso de teste), seguida da constante com a qual queremos comparar. Esta constante não precisa necessariamente ser um valor inteiro. Pode ser um caractere, um ponto flutuante, etc.

Após a constante, colocamos : indicando que ali se inicia o trecho de código correspondente àquela decisão. Após os dois pontos, podemos ou não abrir chaves. É raro ver quem faz isso, mas fica do gosto de cada um. Alguns preferem por questão de organização, mas nada que um identamento bem feito não resolva. Enfim, usem ou não as chaves para definir este trecho de código (nos exemplos aqui do blog, não utilizarei). No caso deste exemplo nosso, incrementamos as variáveis correspondentes, simulando que cada uma representaria um candidato específico em uma eleição (logo à frente explicarei esta maneira ‘diferente’ de incrementar variáveis em C).

Ao fim do código de cada bloco case, temos a palavra chave break. O programa, ao encontrar o comando break, sai da estrutura case, “pulando” para a próxima linha depois do fecha chaves. “Nossa, mas por que essa complicação??”. A estrutura switch funciona com “labels”. Quando você define uma comparação case, você está na verdade definindo uma “marcação” à estrutura. Ao executar, o programa vai procurar dentro desses “labels” definidos até encontrar uma comparação que satisfaça o conteúdo atual da variável. Os labels são apenas “marcadores”, ou seja, precisamos do break para avisar que ali se encerra o “bloco”. Caso não coloquemos a palavra chave break, o aplicativo continuará sua execução linearmente, passando pelos blocos de código dos outros casos de teste. Em geral, na linguagem C, a palavra break indica que o programa deve sair da execução de uma estrutura (de seleção ou de repetição). Por exemplo, se estivermos dentro de um while e o programa encontrar a palavra break, ele irá pular para a primeira linha após o fecha chaves (ou o encerramento) da estrutura while. Paralelamente ao break, temos a palavra chave continue que faz o contrário: faz o programa voltar à primeira linha da estrutura em que ele se encontra (no exemplo do while, voltaria para a primeira linha do bloco de código definido por ele). Em situações mais propícias, faremos uso dele e exemplificaremos melhor.

Continuando, caso a variável do switch não satisfaça a nenhum dos casos de teste definidos, ele procurará pela palavra chave default que indica o que fazer quando todos os casos de teste falharem. Caso não haja nenhuma ação a ser realizada caso a variável não corresponda a nenhum dos casos de teste, podemos omitir o trecho default ou deixá-lo vazio. Perceba que ele não possui a palavra chave break, pois já é o último “caso” definido, e seguindo sua execução, sairá automaticamente da estrutura switch.

Nesse trecho demonstrado acima, temos uma forma bastante interessante de incrementar variáveis. Ao colocarmos o nome de uma variável seguido de ++, simplesmente pegamos o valor que ela possui e acrescentamos 1. Simples e rápido. Podemos fazer a mesma coisa para decrementarmos, utilizando (bastante lógico, não?). Vocês podem já ter visto estes incrementos e decrementos antes e depois do nome da variável. Assim:

Qual seria, então a diferença entre as duas formas? Na verdade, só fará diferença caso você esteja utilizando o operador de incremento dentro de uma expressão. Se o incremento estiver antes do nome da variável, o incremento será realizado antes do valor da variável ser utilizado na expressão. Se estiver depois, será utilizado depois. Veja o exemplo abaixo:

Simples, porém necessita de atenção ao utilizar uma forma ou outra. Fica a dica!

Bom, já somos capazes de fazer decisões com o nosso programa, utilizando as estruturas if e switch da linguagem C. Para encerrarmos esta segunda parte da introdução à linguagem C, iremos ver como fica a sintaxe das estruturas de repetição. A primeira que iremos ver é a estrutura while. Como pode ser visto nos exemplos a seguir, sua estrutura é bastante semelhante à sua correspondente em Pascal. No exemplo, temos versões em Algoritmo, Pascal e C:

Como pode ser percebido, a estrutura while na linguagem C é bem mais “resumida” em comparação com a linguagem Pascal. Nela, inserimos a palavra chave while, seguida da condição para a realização da repetição entre parênteses (neste exemplo, a variável ‘contador’ ser menor que 18). Logo após, temos o abre chaves que define o bloco de repetição. Caso o bloco de repetição tiver apenas um comando, pode-se omitir as chaves. Neste nosso exemplo, temos um estrutura condicional que será repetida. Nenhuma novidade, a não ser o ‘operador’ += que eu inseri ali. Este operador nada faz do que somar ao valor atual da variável o que temos após ele. No exemplo, estamos somando 2 ao valor da variável ‘contador’. Bastante objetivo, não? O mesmo pode ser feito com os outro operadores (-=, *=, /= …). Mais uma dica para agilizar a escrita de seus códigos em linguagem C! 🙂

Outra estrutura de repetição utilizada é o do-while. Ele difere-se um pouco do nosso repeat-until do Pascal, pois no do-while ele repete o bloco enquanto a condição é satisfeita, enquanto que no repeat-until repetia-se enquanto a condição não era satisfeita. “Mas como eu vou portar meus códigos de Pascal pra C, se não existem estruturas iguais?”. Basta adaptar a condição. Nos exemplos a seguir, veremos códigos equivalentes em Algoritmo, Pascal e C:

Bom, a sintaxe é bastante simples, e semelhante ao while já demonstrado anteriormente. Iniciamos com a palavra chave do e o bloco de código definido entre chaves. Após o bloco, temos a palavra chave while e a condição para a execução do bloco entre parênteses. O único detalhe é que, após a condição, é necessário o uso de ponto e vírgula. Quando a adaptação do código em Pascal, se vocês perceberem, basta “inverter” a condição. Em Pascal, a condição era “menor que 200”. Em C, ficou “maior ou igual a 200”, ou seja, a faixa de valores contrárias à versão em Pascal.

Veremos agora, para encerrar essa segunda parte da Introdução à Linguagem C. O laço de repetição for tem uma estrutura relativamente diferente do que era visto na linguagem Pascal. Vejamos um exemplo prático em Algoritmo, Pascal e C, e em seguida discutiremos as particularidades da sintaxe e estrutura desse laço em C:

Podemos logo de cara dizer que sua estrutura é diferente da linguagem Pascal. Vamos explicar trecho a trecho como ela funciona. Primeiramente, é bom lembrar que em Pascal, a estrutura for incrementava automaticamente a variável definida em seu escopo automaticamente (nesse exemplo acima, a variável ‘indice’). Em C, isso não é regra. Já já veremos por que.

Primeiramente, temos a palavra chave for, seguida das regras de suas regras de execução entre parênteses. Se vocês perceberem, temos três subdivisões dentro dos parênteses. A primeira parte (no exemplo acima, indice = 0) indica o que deve ser feito antes de começarmos a inicialização do for. Neste caso, atribuiremos o valor 0 para a variável chamada indice. Podemos realizar mais de uma instrução de inicialização, separadas por vírgula. “Como assim?”. Vamos supor que queremos inicializar duas variáveis, i e j. colocaríamos for (i = 0, j =3; i < 40; i++, j–). Alguma coisa assim.

O segundo “parâmetro” do for é a condição que deve ser satisfeita para que o for continue sendo executada. Antes de executar o bloco de código, ele verifica essa condição. Foi satisfeita? Não? Então executo de novo. Foi satisfeita? Sim? Então eu pulo para a próxima instrução depois do bloco do for. Devemos sempre tomar um certo cuidado com essas condições, não só no for, mas também no while e no do-while, para evitarmos que o nosso programa fique em um looping infinito e nunca termine sua execução. Por isso, atenção ao programar!

A última parte indica o que deverá ser feito após cada execução do for. No exemplo que definimos ali em cima, iremos incrementar em 1 a variável chamada indice (olhem lá o nosso operador “especial”). Como mostrei acima, pode ser definida mais de uma ação neste “parâmetro”, como um incremento e um decremento. Fica ao seu gosto e necessidade.

Após a definição destes “parâmetros”, temos então o bloco de código que será executado. No caso acima, temos uma instrução de leitura para um vetor. Aproveitando esse exemplo falarei sobre uma peculiaridade dos vetores e matrizes na linguagem C.

Atentem, que, ao contrário do Algoritmo e da linguagem Pascal, o nosso vetor em C começa lendo a sua posição 0. Isso mesmo! Na linguagem C, os vetores e matrizes começam em sua posição 0. Ou seja, se caso declararmos um vetor

teremos um vetor com o nome vetor com dez posições: 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9. Por isso, em nosso for, colocamos como condicional indice < 10. Quando igualar a 10, ele encerra a execução, não lendo essa posição. Caso tentarmos acessar a posição 10 desse vetor declarado com 10 posições, obteremos um erro de memória. Fica então, mais uma dica pra vocês 😉

Então, pessoas, chegamos ao fim dessa segunda parte da nossa Introdução à Linguagem C. No próximo post da série, a terceira e última parte dessa nossa introdução, veremos os registros e as funções e procedimentos na linguagem C, para então continuarmos com esses nossos estudos. Não se espantem caso encontrarem algumas coisas diferentes aqui pelo blog, pois pretendo explorar algumas coisas de Java nos próximos posts também.

Como não sei se terminarei outro post até o fim do ano, desejo a vocês, caros leitores deste blog, um ótimo Natal e um ano de 2011 repleto de realizações. Agradeço imensamente as mais de 10.000 visitas que já recebi, os e-mails e comentários de agradecimento, enfim, o crescimento no número de visitas (que foi de mais de 220% de 2009 pra 2010) e o apoio de vocês.

Abraço e até logo!

Perdeu a parte 1? Ou quer ver a parte 3?

Introdução à Linguagem C – Parte I

Pare por um instante! Após ler este post, a sua vida como programador nunca mais será a mesma… você será apresentado à linguagem considerada por alguns como A linguagem de programação… ou melhor, ela não é “A” linguagem, ela é a Linguagem C!!!!!

É, até que eu tentei fazer um início de post meio diferente do “E aí pessoal”… soou meio fantástico demais, sem ser tão fantástico assim, mas tudo bem. Valeu a intenção…

Bom, no post de hoje vamos tratar, então, de uma nova linguagem, a linguagem C. Bom, antes de começarmos a vê-la, vale nos informarmos um pouco sobre a história, origens, características e etc.

A Linguagem C é uma linguagem compilada (assim como Pascal), ou simplificadamente, o seu código, após passar pelo processo de compilação/linker, é convertido em arquivo executável. Além disso, ela é uma linguagem estruturada, ou seja, o seu código é organizado e definidos em blocos.

Ela foi criada por Dennis Ritchie em 1972, para desenvolver o Unix, que originalmente havia sido escrito em Assembly (ou Linguagem de Montagem – linguagem de programação de baixo nível, muito próxima à linguagem de máquina). Por permitir uma integração com Assembly (os códigos poderiam se misturar ao código em C), tornou-se uma das linguagens de programação mais utilizadas. Influenciou muitas linguagens, inclusive C++, que foi desenvolvida originalmente como uma extensão da linguagem C, englobando características da Programação Orientada a Objetos. Devido à sua ampla utilização, e a imensa gama de variações que foram sendo criadas ao longo de seu desenvolvimento, foi padronizada em 1999, padrão conhecido como C99. Em 2000, foi adotado como padrão ANSI. Em 2007, começou a surgir uma nova idéia de padronização, englobando novas funcionalidades à linguagem. Essa idéia é conhecida como C1X.

Bom, acho que de história isso é suficiente para o post. Quem se interessar por mais detalhes, pode acessar os links da Wikipedia que se encontram ao longo do texto.

Para programarmos, precisamos de um compilador, que irá transformar nosso código-fonte em programa. Para desenvolvermos, podemos optar por uma IDE ou Ambiente de Desenvolvimento Integrado, que reúnem ferramentas como editor de texto, compilador, depurador (debugger – permite encontrarmos erros de lógica). As opções gratuitas mais populares, sem sombra de dúvida, são Dev-C++ e Code::Blocks. Ambos os sistemas estão disponíveis para Windows e Linux. A última versão do Dev-C++ é a versão 4.9.9.2 (5.0 beta), de 2005, disponível para download aqui. Já o Code::Blocks encontra-se na versão 10.05, de maio desse ano (eles utilizam a nomenclatura de versão “Ubuntu”), que pode ser obtida aqui. Eu, particularmente, prefiro o Code::Blocks apesar dele ser um pouco mais “pesado”. Já tive problema com bugs no Dev-C++ (o que me causou algumas dores de cabeça quando desenvolvia meu projeto de 1º ano na faculdade. . .). A seguir, temos uma imagem da janela dos dois ambientes:

Tela principal do DevC++

Tela principal do Code::Blocks

A instalação dos dois ambientes é bastante tranquila e intuitiva (apesar do Code::Blocks estar disponível apenas em inglês). Qualquer dúvida, basta deixar um comentário.

Para aqueles que preferem utilizar o Linux para programar, também existem boas opções de IDE, como KDevelop e Anjuta, além dos próprios Code::Blocks e Dev-C++. Basta usar o gerenciador de pacotes de sua preferência ou baixar diretamente dos sites correspondentes e instalar. 🙂

Bom, já ficamos sabendo da história, já preparamos o nosso ambiente de programação. Mas e daí? Eu quero é programar! Como é a sintaxe dessa tal linguagem C? É totalmente diferente de Pascal? Tudo que eu já aprendi é inútil?

Calma, calma. Todos os conceitos já vistos até aqui serão utilizados e as diferenças serão explicadas. Pra começarmos, vamos ver o famoso Alô Mundo em Algoritmo, em Pascal e em C. As diferenças serão explicadas logo a seguir:

Bom, logo de cara é meio chocante, meio nada a ver com Pascal. Mas calma, é bem simples. Primeiramente, podemos ver que o nome do programa não aparece mais no código. Em C, programas podem conter vários arquivos de código, o que torna totalmente dispensável adicionar o nome do programa aos arquivos. Então, observação 1: em C, não temos o nome do programa no código. Logo em seguida, temos #include <stdio.h> que “equivale” ao uses crt. Os includes indicam arquivos de cabeçalho (daí a extensão .h – header) que contêm funções. No caso, stdio (standard in out) possui referências às funções padrão de entrada e saída. Podemos generalizar uma observação 2 dizendo que todos os programas em C terão o #include <stdio.h>. Em seguida, temos o “assustador” int main(void)! Calma, calma pessoal. Vamos explicar. Por padrão definido na linguagem, todo programa em C é composto de funções e deve conter a função main, que é a primeira função do programa, a que é chamada pelo sistema operacional quando o sistema é chamado. Tá, mas e esse tal de int main(void), o que significa. Significa o seguinte: a função de nome main devolverá um valor do tipo inteiro – int – e não receberá nada como argumento – void. O abre e fecha chaves equivale ao nosso begin / end do Pascal, ou seja, o que definimos entre eles é o que a função irá fazer. Podemos, então, definir as funções em C com o seguinte formato:

<valor de retorno> <nome da função>(<lista de argumentos>)

Aproveitando a cartada, vou falar sobre os tipos primitivos em C.

  • int – o nosso querido amigo, inteiro
  • long – o inteiro, com uma maior capacidade (para números beeeeem grandes)
  • float – o conhecido real. Chamado de float ou “ponto flutuante” porque a vírgula (ou ponto, nos EUA) “caminha” ou “flutua” (haja criatividade!)
  • double – float com maior precisão de casas após a vírgula
  • char – tipo caractere
  • void – o “nada”, “vazio”, “coisa nenhuma”… Não é usado para declarar variáveis, apenas para valores de retorno e parâmetros de funções.

Putz, acabou??? E a string??? E o booleano??? Calma, gente… C, ao contrário de Pascal (que foi desenvolvida para ser uma linguagem voltada para o ensino da programação), foi desenvolvida para fornecer flexibilidade aos programadores. String em C, são na verdades vetores de caracteres terminados com ”. Este caractere serve pra diferenciar strings de vetores de caracteres comuns. Por exemplo, uma string com o meu nome ficaria com ‘R’ ‘a’ ‘f’ ‘a’ ‘e’ ‘l’ ”, ou seja, seria um vetor de 7 posições. Já o tipo booleano só passou a existir a partir do padrão C99 (desde que seja incluído o arquivo stdbool.h), sendo então chamado de bool. Mas no geral, a linguagem C considera todo inteiro igual a 0 (zero) como falso e qualquer valor não-zero como verdadeiro.

Bom, continuando a nossa análise do nosso pequeno Alo Mundo. Logo após à declaração da função main, temos uma abre-chaves. Em C, as chaves delimitam o corpo das funções e dos laços, da mesma forma como temos o begin e o end em Pascal. Bastante simples, não? E poupa digitação, agilizando a codificação! 🙂

Prosseguindo, temos uma chamada ã função printf. Esta é a função padrão da linguagem para a escrita de texto na tela do console. Na chamada a ela, passamos uma constante de texto. Em C, as constantes de texto vem entre aspas duplas, em vez das aspas simples do Pascal. Mas o que seria esse n no final?? Em C, temos algumas constantes para a formatação de texto. n é pra pular de linha. Outra constante bastante utilizada é o t que indica uma tabulação horizontal.

Para concluirmos, temos o return 0; que indica o retorno da função (como foi declarado que a função main retorna um inteiro, precisamos retorná-lo, certo?). Mas por que 0? E pra quem estamos retornando isso? Estamos retornando 0 para o sistema operacional. O valor 0 indica que o programa executou corretamente, sem erros.

Vamos agora ver um exemplo com a função de leitura e o uso de condicionais.

Vamos começar, então, explicando o uso das condicionais. Como pode ser percebido, pouquíssima coisa muda em relação ao Pascal. não temos a palavra then após a sentença condicional e o uso dos parênteses é obrigatório. A seguir, a lista dos operadores lógicos em C, que por sua vez diferem um pouco dos já conhecidos em Pascal:

  • Igualdade: ==
  • Menor, Maior, Menor ou Igual, Maior ou Igual: <, >, <=, >=
  • Diferente: !=
  • E: &&
  • Ou: || (dois pipes, aquele símbolo geralmente Shift+Contrabarra)

Como pode ser visto, nenhuma novidade. A lógica funciona da mesma maneira: executa-se o bloco if caso a sentença seja verdadeira e o bloco else (caso exista), caso seja falsa.

Agora, vamos verificar a nossa função de leitura, a função scanf. Nesta função, passamos dois parâmetros para a mesma. Primeiramente, devemos passar o formato do conteúdo que vamos ler. Como assim??? Calma, no começo pode parecer um tanto quanto confuso, mas é mais simples do que parece. Neste primeiro parâmetro, especificamos o tipo da variável que vamos ler. Os argumentos mais comuns são:

  • “%d” ou “%i” – para o tipo int
  • “%f” para o tipo float
  • “%c” para o tipo char
  • “%s” para strings (ou melhor, vetores de caracteres char[])

Já no segundo parâmetro, passamos a variável em que queremos guardar o conteúdo lido. Mas por que esse & antes do nome da variável??? Porque na verdade estamos passando o endereço na memória desta variável. Mas não se preocupe com isso por enquanto. Essa história de endereços será vista com mais calma quando chegarmos nos famosos (e temidos) ponteiros. Logo logo a gente chega lá. Voltando ao scanf, o único tipo que não necessita do & é quando vamos ler strings (pelo fato de vetores já serem ponteiros… mais uma vez, não se preocupe com isso por enquanto!).

Bom, aqui encerro a primeira parte da Introdução à Linguagem C. Pratiquem a programação, busquem materiais diferentes (tolo é o homem de um só livro, dizia um professor do Ensino Fundamental…) e divirtam-se! Desculpem-me por esse hiato entre os posts, mas a vida de faculdade no 3º ano não está fácil. Assim que possível, posto a segunda e última parte dessa nossa introdução. No próximo post, explicarei a estrutura de seleção switch e as estruturas de repetição while, do-while e for. E quem sabe uma explicação sobre funções!

Uma última coisa antes de encerrar. Gente, por favor não fiquem pedindo programas prontos, sejam nos comentários, sejam via e-mail. Tenho recebido inúmeros e-mails com pedidos do tipo. Sinceramente, os exercícios que os professores passam no curso técnico / faculdade servem pra que vocês desenvolvam o seu raciocínio lógico. Treinar, errar, quebrar a cabeça é essencial para um bom aprendizado. Digo isso para o bem de vocês mesmos como futuros profissionais. Fica a dica!

Abraço a todos e boa programação!

Confira a parte 2 aqui e a parte 3 aqui!