






































































Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Encontra documentos específicos para os exames da tua universidade
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Conceitos básicos de programação em c, abordando funções, laços de repetição (for, while, do-while), estruturas de controle (if, else if, switch), manipulação de strings (strcpy, strcmp) e matrizes. Além disso, é abordado o conceito de ponteiros e sua aplicação em funções e manipulação de matrizes.
Tipologia: Notas de estudo
1 / 78
Esta página não é visível na pré-visualização
Não perca as partes importantes!







































































Centro Nacional de Alto Desempenho em São Paulo CENAPAD-SP.
Setembro de 2009.
I ntr o du çã o
Este curso visa ensinar ao aluno os conceitos básicos da linguagem de programação C, cujas virtudes mais importantes são a sua versatilidade, confiabilidade, regularidade e fácil uso (é uma linguagem amigável). Uma das grandes vantagens do C é que ele possui tanto características das linguagens de programação de "alto nível" quanto de "baixo nível", isto é, a linguagem C é um software voltado para o desenvolvimento de programas robustos e eficientes. Para aprendê-lo não é necessário o conhecimento de nenhuma outra linguagem de programação prévia, embora facilite a aprendizagem uma boa familiaridade com computadores.
A genealogia do C é simples. O primeiro ancestral do C é a linguagem Algol60, desenvolvida por um Comitê Internacional em 1960. O Algol60 apareceu poucos anos após o Fortran, embora seja muito mais sofisticado do que o Fortran. Apesar de suas virtudes, como regularidade da sintaxe e a sua estrutura modular, foi considerado abstrato e geral demais. Em 1963, entre Cambridge e a Universidade de Londres, foi criado o CPL, ou Linguagem de Programação Combinada, o que foi a primeira tentativa de trazer o Algol à terra. Continuou grande e complexo. O BCPL, Linguagem básico de programação combinada, tentou resolver o problema levando ao CPL as suas características básicas. Seu inventor foi Martin Richards, em Cambridge, no ano de 1967. Em 1970, nos Laboratórios Bell, Ken Thompson derivou a linguagem B, mais uma simplificação do CPL.
Nos mesmos Laboratórios da Companhia Telefônica Bell, Dennis Ritchie, em 1972, implementou o C pela primeira vez rodando o sistema operacional UNIX. O sucesso de Ritchie com o C foi baseado na recuperação da generalidade perdida, principalmente utilizando habilmente os tipos de dados e sem sacrificar a simplicidade grandemente procurada pelo BCPL e o B.
O C tem a coerência das linguagens de programação pensadas por uma única pessoa, como o BCPL, o B, o Lisp, o Pascal etc. Foi formada uma organização para elaborar e manter um padrão do C, é o ANSI C. Neste curso, estuda-se principalmente os comandos desta padronização chamada ANSI C ou C padronizado pela ANSI.
A primeira experiência e a primeira co mpi la ção
Apresenta-se nesta seção o primeiro programa exemplo, que é muito simples, e permitirá conhecer a biblioteca padrão para entrada e saída de dados, a idéia inicial do formato de um programa em C e permitirá efetuar a nossa primeira compilação. Leia bem, eu disse primeira compilação e não primeira complicação.
Inicia-se esta seção, indicando que o C é caso sensitivo, isto é, as maiúsculas e minúsculas são diferenciadas. Por exemplo, uma variável chamada contador é diferente de uma outra chamada Contador , e também de contadoR , CONTAdor , etc.
O exemplo está no arquivo ex01.c. Abra-o com o editor de texto da sua preferência, leia, pergunte e compile. Antes de responder as perguntas sobre a compilação, deve-se entender o texto do arquivo exemplo. O objetivo do programa exemplo é mostrar na tela uma mensagem de boas vindas. O arquivo foi gerado por um editor de texto comum, e nele está- se tentando dizer ao computador que mostre a mensagem. A linguagem utilizada para transmitir as instruções é a linguagem C, que é acessível aos humanos, mas não é acessível diretamente para o computador. O computador apenas executa as instruções que tem no seu repertório a nível de máquina, isto é, as instruções que utilizam os programadores a nível da linguagem assembler. Para utilizar C é necessário um programa tradutor de instruções em C nas suas equivalentes a nível máquina. Estes programas tradutores são chamados de compiladores.
O escrito nos arquivos exemplos utilizando a linguagem C são chamados de códigos fonte. Então a tarefa do compilador é traduzir o código fonte em instruções que o computador possa entender e executar. O produto gerado pelo compilador é um arquivo com o chamado código executável, isto é o mesmo programa original na forma que o computador possa ler e executar.
Um programador em C não apenas utiliza a sintaxe da linguagem para gerar um código fonte, ele também utiliza abreviaturas para simplificar o código. Estas abreviaturas não são conhecidas pelo compilador, então devem ser expandidas antes de passar o código para o compilador. Existe em C, um pré-processador C, que toma o código fonte de um programa e gera um outro código fonte expandido, deixando-o pronto para ser traduzido pelo compilador.
Por outro lado, quando se implementa um programa visando algum objetivo especifico, geralmente utilizam-se vários arquivos de código, e então é necessário ligar todos eles. Esta tarefa é do link-editor, ele ligará todo o código necessário gerando apenas um arquivo executável. Este arquivo executável é chamado a.out quando nada é especificado.
Felizmente, tudo isto é escondido para os simples mortais, e todos os passos mencionados, após ter editado o código fonte, são executados no Unix simplesmente digitando uma das seguintes linhas de comandos:
A primeira linha de comando compila o código fonte ex01.c e gera um executável chamado a.out. Na Segunda e na terceira linha a opção –o permite atribuir um nome ao arquivo executável, e na terceira linha –lm força ao link-editor a considerar a biblioteca pronta do C com funções matemáticas especiais.
O programa executável pode ou não realizar o que o programador projetou. Quando não tenha sucesso, procure o erro no código fonte com um editor de texto, pois é provável que exista um erro lógico no programa. Após, salve as mudanças, compile e execute novamente.
E o código exemplo ex01.c? Abra-o e analise-o. Observe o formato utilizado e as partes que podem ser identificadas nesse formato. Como mencionado acima, existem várias bibliotecas prontas para facilitar a entrada e saída de dados ou informação de e para o computador. Na linguagem C, existe a biblioteca padrão de entrada/saída, que é incluída simplesmente digitando a expressão #include <stdio.h>. Esta biblioteca é um conjunto de funções que permitem a interface com o usuário, isto é, neste arquivo existem definições de funções úteis para entrada e saída padronizada de dados. Toda vez que se queira usar uma destas funções deve-se incluir este comando. O C possui diversos arquivos-cabeçalhos.
Por exemplo, em stdio.h foi definida a função printf(...) para dizer ao computador o que é e como ele deve mostrar na tela alguma informação. A função printf( ) mostra na tela a
Fundamentos da linguagem C
Estuda-se aqui a sintaxe da linguagem C, a sintaxe é o conjunto de regras detalhadas para cada construção válida na linguagem C.
Os dados ou valores a manipular em um programa podem ser variáveis ou constantes. Em C uma constante é um espaço de memória cujo valor não deve ser alterado durante a execução de um programa. E uma variável é um espaço de memória que recebeu um nome e armazena um valor que pode ser modificado.
Os nomes utilizados para referenciar variáveis, funções ou vários outros objetos definidos pelo usuário são chamados de identificadores. Os primeiros 32 caracteres são significativos, diferenciando-se as maiúsculas das minúsculas. Os identificadores devem satisfazer duas condições: começar com uma letra ou sublinhado (), e os caracteres subsequentes devem ser letras, números ou sublinhado (). O identificador de uma variável tem mais duas restrições, não pode ser igual a uma palavra reservada da linguagem C (palavra-chave), nem igual ao nome de uma função declarada pelo programador ou pelas bibliotecas do C. As palavras-chave são identificadores predefinidos que possuem significados especiais para o compilador.
Pal avr as -c h ave
asm const else for Near sizeof union auto continue enum goto Register static unsigned break default extern if Return struct void case do far int Short switch volatile char double float long Signed typedef while
Os tipos de dados definem as propriedades dos dados manipulados em um programa. Quando você declara um identificador dá a ele um tipo de dado. Um tipo de dado determina como o valor desse dado será representado, que valores podem expressar e as operações que podem ser executadas com estes valores.
Todas as variáveis e as constantes possuem uma característica comum, um tipo de dado associado. Não é necessário especificar o tipo de dado de uma constante, pois ele é determinado pelo seu valor. Entretanto, ao declarar uma variável, além de escolher um nome apropriado para ela, deve dizer ao compilador que tipo de informação se deseja armazenar nela.
Tipos de dados
Tipo de dado Armazenamento Intervalo de valores Observações
char
int
1 byte -128 a 127 Pelo menos 8 bits 2 bytes -32 768 a 32 767 Pelo menos 16 bits long int 4 bytes -2 147 483 648 a 2 147 483 647
O dobro de um inteiro
unsigned ... float double pointer
idem 0 a 2 * medida Sem sinal 4 bytes 3.4e-38 a 3.4e+38 Simples precisão 8 bytes 1.7e-308 a 1.7e+308 Doble precisão 2 (4) bytes ponteiro – perto (longe)
Às vezes em um compilador pode-se encontrar uma faixa maior do que a mostrada na tabela, mas não uma faixa menor.
O C tem cinco tipos básicos: char, int, float, double, void. O char é um tipo de dado numérico, mas é associado com o conjunto de caracteres ASCII(como as letras do alfabeto). O int é para armazenar valores numéricos inteiros. O float e o double são para armazenamento de valores numéricos em dígitos de precisão. O float em precisão simples e o double em dupla precisão. O void (vazio em inglês) é um tipo especial, e o seu estudo será feito posteriormente.
Exceto o void, os tipos de dados básicos podem ter vários modificadores. Um modificador é utilizado para alterar o significado de um tipo básico para adaptá-lo às necessidades da situação. Os modificadores de tipo do C são quatro: signed, unsigned, long e short. Os quatro podem ser aplicados a inteiros e caracteres. Ao float não se pode aplicar nenhum e ao double pode-se aplicar apenas o long. A intenção é que short e long devam prover tamanhos diferentes de inteiros onde isto for prático.
Uma constante literal é a variedade mais comum. Elas compõem-se de valores como 3.14, 2, ou ainda de informações de string digitados diretamente no texto do programa, “Alo pessoal.”. O C também permite inserir constantes numéricas hexadecimais(base dezesseis) ou octais(base oito). As constantes hexadecimais começam com 0x, exemplo: 0x12A4, e as constantes de base oito começam com zero (0), exemplo: 01342. Cuidado, nunca digite 021 para referenciar o número 21, o compilador C considera isto como 17 (21 em base 8). Uma constante caracter deve ser inserida como ‘c’.
A forma “c”, com aspa dupla, é utilizada para inserir uma string constante, neste caso, é um vetor de dois caracteres, o ‘c’ e o ‘\0’ (caracter nulo finalizando a cadeia). Como o último caracter constante, existem várias outras constantes de barra invertida que tem significado especial. Alguns deles são: \b – retrocesso, \n – nova linha, \t – tabulação horizontal, \v – tabulação vertical, \r – retorno de carro, \a – alerta(sinal sonoro), \” – aspas, \’ – apóstrofo, \ - barra invertida.
Uma constante declarada é formada ao anteceder a palavra-chave const à definição normal de uma variável. Observar que deste jeito pode-se especificar tipo de dado, terminar com ponto e vírgula e inicializar a constante. Exemplo: const notamaxima = 10;
Uma constante definida é dada utilizando uma macro #define. Neste caso, a constante é dada pelo pré-processador no código substituindo o nome definido pelo valor de definição. Observe que #define não especifica tipos de dados, não utiliza o símbolo de atribuição (=) e nem termina com ponto e vírgula. Exemplo : #define MAXIMANOTA 10
Ao invés de definir constantes individuais que recebem valores subjacentes, pode-se utilizar constantes enumeradas para criar listas categorizadas que atingem o mesmo objetivo. Utilizando a palavra chave enum diz-se ao compilador que os itens dados devem ser enumerados, isto é, associados a números sequenciais iniciando com o zero, quando nada é especificado, mas pode atribuir-se um valor expresso e os seguintes assumem valores consecutivos. Um elemento de uma enumeração não tem endereço de armazenamento em memória. Exemplos,
enum CORES {vermelho, amarelo, azul, laranja, verde, violeta} cor;
enum STATUS{FALSE, TRUE, FAIL=0, OK, NOT_RUN=-1}; STATUS estado;
O escopo de uma variável refere-se aos limites de validade de uma variável. Apenas no escopo de uma variável as instruções podem-se referir à variável.
Como mencionado acima, antes de utilizar uma variável ela deve ser declarada. Nesta declaração é estabelecido um identificador e um tipo de dado para a variável. Além disso, pode-se especificar a forma de armazenamento da variável, isto tem a ver com seu escopo e se o armazenamento é na memória ou nos registros do CPU.
Uma variável automática é armazenada na memória e seu escopo é limitado ao bloco no qual aparece, isto é, enquanto esse bloco ou qualquer um outro bloco mais interior ao atual está sendo executado a variável existe. Quando o bloco onde a variável automática foi declarada acaba a variável deixa de existir. Exemplo : auto int segundos;
Uma variável registro é uma variável automática que pode ser armazenada nos registros do CPU, se existir algum registro livre e de tamanho suficiente para armazenar a variável. As variáveis armazenadas nos registros do CPU são bem mais rápidas, embora devam ser utilizadas apenas para as variáveis do seu programa que são muito utilizadas. O número de registros do CPU disponíveis é limitado. Exemplo : register int segundos;
Uma variável estática são locais como as variáveis automáticas. A diferença é que as variáveis estáticas não desaparecem quando acaba o bloco ou a função onde ela foi declarada, o valor da variável persiste mesmo que não seja disponível. Se retorna-se ao bloco ou a função onde foi declarada uma variável estática, ela fica novamente disponível e com o último valor armazenado nela. As variáveis estáticas inicializam-se apenas uma vez no tempo de compilação, portanto ocupam memória mesmo que não estejam ativas. Exemplo : static int segundos;
Uma variável externa tem escopo global, isto é, existem em qualquer bloco e estão disponíveis a qualquer função que necessite utilizá-la. Ela é acessível a todas as instruções não, importando onde estejam localizadas. Exemplo : extern int segundos;
Em resumo, as variáveis automáticas são locais aos seus próprios blocos ou funções e os seus valores desaparecem quando o bloco ou função termina. As variáveis estáticas são também locais mas os seus valores persistem, e as variáveis externas são globais e os seus valores também persistem.
A linguagem C é pragmática, daí que admite valores por default, valores que são assumidos na falta de especificação. A forma de armazenamento de uma variável tem valor por default: o compilador assumirá uma forma de armazenamento pelo contexto quando nada é especificado. Isto significa que o valor por default não é único. Se uma variável é definida em um bloco ou função e não é especificada a forma de armazenamento é assumida automática, mas se foi declarada fora de qualquer bloco ou função ela será assumida externa pelo compilador.
Os operadores aritméticos são usados para desenvolver operações matemáticas. A seguir apresenta-se a lista dos operadores aritméticos do C:
O pe r ad or Aç ão
O C possui operadores aritméticos unários e binários. Os unários agem sobre uma variável apenas, modificando ou não o seu valor, e retornam o valor final da variável. O operador – como troca de sinal é um operador unário que retorna o valor da variável multiplicado por -
Os binários usam duas variáveis e retornam um terceiro valor, sem alterar as variáveis originais. A soma, subtração, multiplicação, divisão e resto são operadores binários pois pegam duas variáveis, somam, subtraem, multiplicam, dividem ou acha o resto dos seus valores sem alterar as variáveis, e retornam este resultado.
O operador de atribuição do C é o sinal de igual, =. O que ele faz é pegar o valor à direita e atribuir à variável da esquerda. Além disto ele retorna o valor que atribuiu à esquerda, assim sendo são válidas as seguintes sentenças :
double x, valor, custo; x = valor = custo = 123.5;
&& o E lógico || o OU lógico ! Negação (unário não)
Ao contrário de outras linguagens, o operador de atribuição em C pode ser utilizado em expressões que envolvem outros operadores, formando os chamados operadores de atribuição compostos. Os operadores compostos condensam sentenças de atribuição da forma : Variável = Variável operador expressão ; na forma : Variável operador = expressão ;
Exemplo : valor = valor + custo; escreve-se na forma : valor += custo; Os operadores atribuição podem ser compostos com os operadores aritméticos (veja a primeira linha da tabela) e podem ser compostos com os operadores bit a bit (segunda linha da tabela).
Os operadores relacionais do C realizam comparações entre variáveis. Relação refere-se as relações que os valores podem ter um com o outro. Os operadores relacionais são :
Maior do que = Maior ou igual < Menor do que <= Menor ou igual == Igual a != Diferente de
Os operadores relacionais retornam o valor 1 para verdadeiro e retornam 0 para falso.
Os operadores lógicos fazem operações com valores lógicos, isto é, verdadeiro e falso. Verdadeiro é qualquer valor diferente de zero (0), enquanto zero é falso. As operações de avaliação produzem um resultado zero ou um. Os operadores lógicos são:
em forma sequencial. O valor de uma expressão com o operador vírgula é dado pela expressão mais a direita, isto é útil quando utilizado com um operador atribuição, veja o exemplo seguinte: itens = ( numero = 3, numero++, 2*numero); primeiro atribui o 3 para numero, depois numero é incrementado para 4 e no final atribui 8 a itens. Os parêntesis são necessários o operador atribuição tem precedência sobre o operador vírgula.
O operador sizeof é unário e retorna o tamanho em bytes da variável. Exemplo int itens; itens = sizeof(itens); em itens foi atribuído o valor 2. Este operador é usado para gerar códigos portáveis que dependem do tamanho dos tipos de dados.
Precedência refere-se à ordem em que o C avalia os operadores quando existem dois ou mais deles em uma sentença. O C tem um conjunto de regras incorporadas para determinar a ordem em que os operadores são avaliados, e é preciso decorá-las para redigir códigos que realizem corretamente as operações. Dizer que um operador tem precedência maior que um outro operador significa que será avaliado antes. Como exemplo, os operadores de relação e lógicos tem a precedência menor que os operadores aritméticos.
A associação refere-se à ordem de avaliação de operadores de igual precedência. Eles podem ser avaliados primeiro de direita à esquerda ou de esquerda à direita.
A seguir está uma tabela com os operadores, a sua precedência e a associação respectiva. A ordem de precedência é de cima para baixo, sendo avaliados primeiro aqueles que estão mais acima.
Precedência Associação ( ) [ ]. -> (^) Da esquerda para a direita ! ~ -(unário) ++ -- *(unário) &(unário) (cast) sizeof
Da direita para a esquerda
O problema da precedência e a associação é superado utilizando parênteses no código, e apenas decorando as precedências mais importantes.