Documente Academic
Documente Profesional
Documente Cultură
Introdução a C
APOSTILA DE LÓGICA DE PROGRAMAÇÃO (ALGORITMOS)
ALGORITMO
Definição: Sequência finita de passos que levam à execução uma tarefa.
Ou seja, para que o computador realize alguma atividade deve ser passado a ele um passo-
a-passo para que ele faça o que lhe foi solicitado corretamente. Por exemplo, para se fritar
batatas é necessário, inicialmente, descascar as batatas, em seguida cortá-las para só
então, finalmente, fritá-las. É essa sequência de passos que chamamos de algoritmos e é
dessa forma que os computadores operam.
PROGRAMAS
“Os programas de computadores nada mais são do que algoritmos escritos numa linguagem
de computador (Pascal, C, COBOL, Fortran, Visual Basic entre outras) e que são
interpretados e executados por uma máquina, no caso um computador.” (MORAES, 2000)
As linguagens de programação são como os idiomas que os seres humanos usam para se
comunicar, só que a linguagem de programação é a maneira em que os homens se fazem
ser entendidos pelas máquinas em seus interpretadores. Para cada linguagem existe um
interpretador específico.
“Os algoritmos são descritos em uma linguagem chamada pseudocódigo. Este nome é uma
alusão à posterior implementação em uma linguagem de programação, ou seja, quando
formos programar em uma linguagem, por exemplo Visual Basic, estaremos gerando código
em Visual Basic. Por isso os algoritmos são independentes das linguagens de
programação. Ao contrário de uma linguagem de programação não existe um formalismo
rígido de como deve ser escrito o algoritmo.” (MORAES, 2000)
EXERCÍCIOS RESOLVIDOS
1) Crie um algoritmo para resolver a expressão numérica:
Multiplique 7 x 10
Subtraia 9
Some 56
Multiplique 5 x 8
Subtraia de 3
Some 106
Divida 42 por 2
Subtraia 48
2)
Desligar chuveiro;
} Senão
Ir para o banheiro;
Desligar chuveiro;
Fim do Algoritmo.
3)
Pegar a bala
Chupar a bala
FLUXOGRAMA
Outra forma de se escrever um algoritmo é através de fluxograma. Fluxograma nada mais é
do que símbolos que representam os passos lógicos de um determinado algoritmo.
Exemplo:
Quando falamos em número e letra, por exemplo, estamos tipando símbolos, declarando
que alguns representam letras e possuem uma determinada maneira que devem ser
utilizados de acordo com o seu significado, o mesmo acontece com os números. O
computador, assim como nós seres humanos, também precisa que se defina o que cada
símbolo representa para poder executar algumas operações. Os tipos primitivos existentes
na linguagem computacional são inteiro, real, caractere e lógico.
LÓGICO: Toda e qualquer situação só pode assumir apenas dois estados: Verdadeiro
e Falso
Toda variável, ao ser utilizada num algoritmo, deve ser nomeada através de um identificador
e deve ser tipada.
ESTRUTURAS DE CONTROLE
Existem três tipos de estruturas de controle (sequenciação, repetição e seleção). Através da
combinação dessas estruturas podemos criar algoritmos que solucionem nossos problemas.
Repita
(bloco de código)
Enquanto (condição)
Exemplo 1.1
Inicio
Pegar bala;
Se bala = morango{
Vá para o Fim;
Senão {
Retirar o papel;
Chupar a bala;
}Fim
Exemplo 2
Exemplo 3:
PROGRAMA SOMA_SALARIOS;
VAR
//Começo do algoritmo
INICIO
REPITA
LER (SALARIO);
SOMA:=SOMA+SALARIO
ATE SALARIO<0;
ESCREVER (SOMA)
FIM.
LINGUAGEM C
LÓGICA NÃO É MÁGICA
A partir daqui será iniciado o estudo de C, uma linguagem de programação resistente ao tempo,
que permite perceber os processos de forma minuciosa, com vários recursos que fazem dela uma
das linguagens mais utilizadas ainda hoje.
Esperamos que você tenha percebido que a lógica não lhe dirá o que usar. Essa será uma
questão de muita leitura das bibliotecas e funções para saber qual se adequa à melhor situação.
O intuito de estudar lógica é o de saber pensar seqüencialmente, elencando as prioridades
corretas na hora de programar, assim, evitando erros, gerando otimizações, códigos com menos
esforço computacional, etc. Não se preocupe: todos cometem falhas em lógica, mas não a culpe
se não há domínio da sintaxe e desleixo quanto ao uso correto de todas as entidades envolvidas
em C.
Boa leitura!
x = 23;
printf ("Este e o valor do numero x: %d ", x);
system ("PAUSE");
return 0;
}
Explicando brevemente:
int main () { : esta é a declaração da função principal (main). Todo programa deve ter uma
para funcionar.
x = 23; : atribuição do valor 23, a x. Costuma-se ler: x recebe 23, ou x deve ser igual a 23.
printf ("Este e o valor do numero x: %d ", x); : essa é uma função (explicaremos
a seguir) que imprime na tela o valor atual da variável x (no console será exibido: Este e o valor
do numero x: 23).
system ("PAUSE"); : esta função força uma pausa no sistema esperando por uma tecla.
Alguns compiladores pausam o console (prompt) após a execução do programa, mas outros não
o fazem e sem essa instrução o programa não seria visto.
return 0; : é a instrução final da função main, ou seja, do programa. Ela diz que o retorno da
função ao sistema operacional é 0.
Todo o código precisa ser gerado a partir de um editor de texto padrão (Notepad, Notepad++,
gEdit, etc.). Outros editores (Microsoft Word, Wordpad, por exemplo) podem incluir dados e
formatos que o compilador desconheça. O programador gera um código-fonte (source code), que
é o programa em si, contendo os comandos da linguagem. Ao solicitar a compilação, ocorre a
validação de erros de sintaxe (declaração dos comandos, uso correto da linguagem), caso não
seja encontrado nenhum erro é gerado um código-objeto, que é a tradução do código fonte para
uma forma em que o computador pode executar diretamente. Esta tradução é feita pelo
Compilador, que após a tradução pode executar o código. A Linkedição trata da adição de dados
ao código-objeto referenciados no código fonte. Esses dados são fornecidos por bibliotecas (A
biblioteca C padrão com funções que realizam as tarefas mais comuns) dinâmicas ou estáticas.
Por exemplo, quando se chama uma função que não faz parte do programa, o compilador guarda
o seu nome. Após, o linkeditor combina o código escrito com o código objeto já encontrado na
biblioteca.
CASE-SENSITIVE
O C é sensível a palavras maiúsculas e minusculas. Dessa forma ele encara 'voce', 'Voce' e
'VOCE' como palavras diferentes. Isso vale para todos os identificadores em C (variáveis,
funções, etc. Que serão explicados mais adiante). Não são aceitas palavras acentuadas. Muita
atenção: o seu compilador geralmente informará erros dessa natureza, mas evitar cometê-los é o
melhor caminho.
PALAVRAS RESERVADAS
São palavras usadas pelo programador para acessar funcionalidades da linguagem. Veja uma
lista de palavras reservadas usadas em C:
TIPOS BÁSICOS
Os tipos básicos em C são: Inteiro (int), Caractere (char), Real (Ponto Flutuante, float), Real
Longo (Ponto Flutuante de precisão dupla, double) e void (Genérico/sem definição).
* Long: É empregado aos tipos de dados 'int' e 'double' para indicar um tipo de dado maior.
Também pode ser declarado em conjunto com o 'float', mas isto seria a mesma coisa de usar o
tipo double.
* Short: Muito utilizado para indicar valores inteiros curtos (short int). Normalmente possui o
mesmo tamanho do tipo int, mas, geralmente são armazenados em um numero menor de bytes.
* Signed: A declaração padrão dos tipos já permite o uso de sinais (- unário: -1,-2,-3, não
confundir com o operador) em números int e caracteres, então seu uso seria redundante.
* Unsigned: Não permite o uso de sinais. Este modificador não é indicado para o tipo int, pois
podem ocasionar algumas complicações caso seja atribuído em algum lugar do código um valor
negativo.
* para os tipos de dados em ponto flutuante (float, double) é usada, geralmente a notação em
"dígitos de precisão". Analogamente, poderíamos dizer que são a quantidade de zeros após a
vírgula: 0,000000, por exemplo.
O TIPO 'void'
Este tipo genérico é usado quando se desconhece o tamanho daquilo armazenado ou lido na
memória. Muito cuidado com seu uso pois pode trazer problemas à suas aplicações. No entanto,
seu uso correto permitirá generalizar muitos dados em seu código, mas dependerá bastante de
casting (métodos de conversão de tipo, coerção), o que será tratado a seguir.
O TIPO 'char'
Este tipo possui uma característica um tanto explorada no ínicio da vida de programação: é
necessária uma tabela para organizar os caracteres, por conseqüência, associando-os a valores
inteiros, de modo que sejam acessíveis em código binário assim como qualquer outro dado. O C
ANSI usa a tabela ASCII (American Standard Code for Information Interchange), que usa até um
byte (8 bits) para fazer a representação dos caracteres, um a um. Lembre-se que um texto inteiro
é interpretado e impresso usando essa tabela como intermédio. Visite:
http://www.tabelaascii.com/ para visualizá-la.
OPERADORES
Existem, basicamente, três classes de operadores em C: Aritméticos, Lógicos e Binários. Além
disso
LEMBRETE: A atribuição, em C é feita com um único sinal de igual ( = ). Portanto não confunda
com a igualdade lógica, que usa um sinal duplo ( == ). Veja:
if ( a == b ) { /*se a é igual a b*/
...
}
ARITMÉTICOS
Os operadores aritméticos são:
+ Adição
- Subtração
* Multiplicação
/ Divisão
% Módulo (resto da divisão de inteiros)*
O operador módulo não funciona com número em ponto flutuante, pois não considera a parte
fracionária do número (neste caso o resto é conservado inteiro).
DICA: Todos os operadores aritméticos podem ser combinados com a atribuição. Pode causar
confusão no início, mas evita a repetição do nome da variável (por exemplo) de destino.
Exemplos:
x+=y; equivale a x = x + y;
LEMBRETE: Não existem true e false (palavras reservadas), nem um tipo boolean no C ANSI,
use essas características do retorno e dos valores reconhecidos como verdadeiro e falso para
verificar a veracidade de uma expressão relacional/lógica.
Relacionais:
Lógicos:
LEMBRETE: O que você compara são os valores das entidades. Algumas vezes você pode
comparar o retorno de funções, endereços de memória e muitas outras coisas. Lembre-se de
usar parêntesis para alternar a ordem de verificação. Exemplo:
(a && b) || c == !((a || b) && c);
É usado quando se deseja fazer uma ação ou atribuir um valor à expressão verificada se verdade
ou falso. Seu uso ainda traz muitas dificuldades para iniciantes, pois sua leitura não é clara.
Porém, com prática, alguns comandos de seleção (if-then-else) serão facilmente substituídos por
ele. Observe:
Assim ocorre a validação da primeira expressão (Exp1). Sendo verdade, valida-se a segunda
expressão e ela se torna o valor da primeira. Se não, a terceira expressão é validada e se torna o
valor da primeira. Um exemplo retirado do mesmo livro exemplifica bem isso:
x = 10;
y = x > 9 ? 100 : 200;
Ou seja, se x for maior que nove, 100 é retornado à expressão e é atribuído à y. Se não, ocorre a
atribuição de 200 em y. Outro exemplo:
char r = „R‟;
char s = „A‟;
r > s? ++r : s = --r; /*Geralmente lê-se: r é maior que s? Se sim, r mais, mais. Se
não, s recebe menos, menos r.*/
OPERADORES * e &
Operadores de ponteiro são importantes em C. Permitem a passagem de vetores, strings e
structs (estruturas) para funções, além de permitir que as mesmas alterem o conteúdo dos
argumentos passados. Os dois operadores de ponteiros são & e * (Diferente do operador
aritmético, este operador é unário a um ponteiro ou expressão)
O operador * leva o conteúdo da variável à que precede e usa este valor como endereço da
informação na memória.
PRECEDÊNCIA DE OPERADORES
Para se construir e ler corretamente expressões em C, é necessário um conhecer a precedência
entre eles.
A tabela seguinte lista as precedências por ordem decrescente bem como o sentido de avaliação
(associatividade).
Operadores Associatividade
() [] -> . da esquerda para a direita
! ^ ++ -- + - * & (tipo) sizeof da direita para a esquerda
* / % da esquerda para a direita
+ - da esquerda para a direita
<< >> da esquerda para a direita
< <= > >= da esquerda para a direita
== != da esquerda para a direita
& da esquerda para a direita
^ da esquerda para a direita
COERÇÃO DE TIPOS
Com um pouco mais de experiência, você perceberá que algumas funções mais antigas que
lidam com caracteres, recebem/retornam um int no lugar de um char. Como isso acontece? há,
de certa forma, uma similaridade entre os dois tipos: mesmo que o tamanho de um char seja
menor que o de um int (8 bits e 16, respectivamente), é possível acessar um caractere
informando seu correspondente inteiro. Como uma sequência binária pode ser qualquer coisa, o
que muda de caso a caso é o contexto. Perceba que, 'A' tem como correspondente binário "0100
0001" e ao fazer a conversão dessa seqüência a um número inteiro obtemos 65. Se ele for usado
para referenciar o char 'A', está correto (Pela tabela ASCII, informada anteriormente). A
sequência equivalente a este char ficaria representada numa posição de memória do tipo int
desse modo: "0000 0000 0100 0001", portanto, podemos afirmar que todo char pode ser
representado num int, mas o contrário não acontece. Para tentar resolver esses problemas são
usadas técnicas de coerção.
---------------------
#include <stdio.h>
i = si;
d = f;
printf(“numero i como real = %f”, i); /*coerção interna do computador, não se altera o
tipo da variável.*/
/*Para visualizar i como número real, informamos à função printf que ela deve exibir o
conteúdo da variável como float (%f). Trataremos dessa função a seguir*/
...
Como se sabe, a atribuição copia o valor daquilo referenciado na direita para aquilo referenciado
à esquerda do „=‟. Portanto há a mudança no valor, ou atualização. Para converter, nesse caso, a
coerção se apresenta com a inscrição, entre parêntesis, do novo tipo, segundo o protótipo:
variável1 = (novo_tipo) variável2;
Ou
variável0 = variável1 + (novo tipo) variável2;
Onde as variáveis devem ser de tipos diferentes e o novo tipo deve ser igual ao da variável que
recebe a atribuição. Se não, seria ilógica a conversão. Segue o exemplo:
int i;
float f;
…
f = (int) i;
…
Correto Incorreto
count Count
count1 1count
_abc abc!
abc abc.
Assim declara-se x como uma variável do tipo inteiro. (lembra-se do tamanho mínimo em bytes e
a faixa de valores?)
Exercício:
Como seria a declaração de inteiro sem sinal? Informe seu tamanho em bits. E faça assim com
os outros tipos.
Todas as variáveis precisam ser declaradas antes de serem usadas. Existem algumas formas de
fazer essa declaração: Fora de todas as funções (variável global), dentro de uma função (variável
local) ou como parâmetro (valores de entrada de uma função). Declararíamos várias variáveis do
mesmo tipo usando vírgula:
int x, y, z;
ESCOPO
É comum se ouvir referência ao “Escopo” de uma variável. Este seria a porção de código onde a
variável foi declarada. Isso determina seu tempo de vida e possibilidades de acesso e são
classificadas, em C, em variáveis locais, parâmetros formais, e globais.
VARIÁVEIS LOCAIS
Comumente declaradas em funções, são aquelas que somente são acessíveis dentro do bloco
onde ocorreu a declaração. Simplesmente, a variável é criada ao iniciar o bloco e destruída,
assim inacessível, quando o bloco termina. Por exemplo:
float f1 () {
float x;
float y;
x = 36,63;
y = x * 8 /6,5 ;
return ( x * y );
}
float f2 () {
float x;
float y;
x = 15.1;
y = 16.9;
return ( x * y );
}
Aqui temos duas funções onde as variáveis são locais e todas do tipo float. Perceba que o nome
dado à variável é uma marcação e não tem nada a ver com o seu tipo ou com outros homônimos
Uma forma de declaração pouco abordada em leituras iniciais sobre C, por causar confusão, é a
de declarar variáveis dentro de um bloco de código específico. Isso é importante em ocasiões de
grande esforço computacional ou de memória baixa, criando variáveis condicionalmente. A
confusão dessa forma de declaração, geralmente, está no pensamento de que a variável estaria
visível a partir dali quando ela é interna a um bloco. Usando a conceituação citada acima, a
variável tem seu fim junto com o bloco de código. Portanto, veja o exemplo:
float f1 () {
float x;
float y;
x = 36;
y = x * 8 /6;
int a = 36;
/*a declaração está dentro do bloco da função e permite que se utilize a partir daqui,
mas antes, impossível. Vale-se dos mesmos pretextos alicerçados antes*/
PARÂMETROS
Em algum momento, funções precisarão tratar de variáveis que já sofreram alterações no
programa (trataremos as funções logo mais). Usam-se argumentos - parâmetros para o
funcionamento da função - que são, essencialmente, variáveis locais, para se utilizar esses
valores de entrada na função que os recebe.
Exemplo:
int sub (int x, int y /*parâmetros são listados aqui e separados por vírgula*/ ){
if(a > b) return (a-b);
else return (b-a);
}
É necessário informar o tipo do parâmetro que será recebido na abertura da função, como visto
acima. Logicamente, os parâmetros que serão passados devem ser do mesmo tipo daqueles que
serão recebidos, ou então podem acontecer erros inesperados. Mais adiante trataremos dos
mecanismos de passagem de parâmetros.
VARIÁVEIS GLOBAIS
Raramente haverá a necessidade de usá-las, pois a parametrização das funções garante seu
reaproveitamento. Ou seja, o uso de variáveis locais permite uma maior generalização de seus
programas e funções. Uma variável global é declarada fora de todas as funções – recomenda-se
Observe que não mudamos o caráter da variável x, pois são duas variáveis distintas. Acontece
que x, local à main, é mais específica que x, global ao programa sendo usado o último. As
variáveis globais são alocadas em uma região de memória fixa, ocupando espaço adicional do
seu programa, podendo ser alteradas acidentalmente. Entenda que uma variável global é visível
dentro de um bloco de código maior, que é o programa em si. Lembra das variáveis locais? Elas
não são destruídas ao fim do bloco onde foram declaradas? Então uma variável global é
destruída com o término do programa.
DICA: Inicialização de variáveis: As variáveis podem ser inicializadas logo após sua declaração
sendo desnecessária mais uma instrução para colocar o valor inicial à variável. Quando
colocamos “int x = 3;” em um código, isso significa que a variável x foi alocada com valor inicial 3.
Se você não inicializasse x e quisesse obter seu valor para alguma coisa em um programa,
ocorreriam erros imprevisíveis (seria lido um trecho de memória com restos de programas
anteriores). Inicializar as variáveis promove segurança à utilização do seu programa.
Recomendamos deixar de inicializar uma variável somente quando for estritamente necessário e
que, se possível, marque-a ou recorde-se dela quando for fazer alguma alteração.
COMANDOS
São as palavras reservadas responsáveis por fazer seu código executar ações pré-estabelecidas
pela linguagem. Basicamente, existem comandos de seleção, laço e desvio, em C. Existem
outras nomenclaturas e outros comandos, mas nosso intuito aqui é mostrar os principais e de
forma rápida .
SELEÇÃO
IF - ELSE
O se – então – senão (if-else) é usado caso queiramos dar um tratamento a depender do valor
booleano da expressão avaliada. Protótipo:
if (expressão) comando;
else
comando;
Ou
A expressão booleana, não necessariamente precisa ter operadores relacionais para ser validada
dentro do if. Se não houver, assume-se que se questiona se o valor da expressão é verdadeiro. O
else é opcional e somente é executado se for obtido o valor booleano contrário ao esperado na
expressão dentro do if. Podemos usar um comando único ou um bloco – não se esquecer das
chaves –. Exemplos:
if (a>b) b-=a;
else b*=a;
DICA: Muitas vezes você quererá executar um comando num if em caso de algo retornar zero.
Naturalmente, como o valor da expressão seria zero, não se “entraria” no if. Para isso, use o
operador de negação ( ! ), que inverterá o valor obtido na expressão. Então toda vez que uma
expressão for verdadeira, o if ,com a inversão, a tratará como falsa e vice-versa. Exemplo:
If (!(a-b)) printf (“ os números são iguais!\n”); /* se a-b == 0, quer dizer que os
números são iguais: a=8 e b=8*/
Perceba que somente verificar-se-á j se i apresentar um valor falso (entenda zero, por falso), e k
se i e j forem falsos e assim sucessivamente. O mais importante: ao ser cumprida uma validação
do cascateamento, o programa não permanece mais preso a ele e prossegue a partir do “bloco if-
else-if” .
SWITCH
Esta é uma solução mais organizada que os ifs aninhados. É usado quando se tem muitas
possibilidades no valor de uma expressão. Trata-se no switch também o caso de não ser
cumprida nenhuma das possibilidades esperadas. São usados, o que são chamados de
operadores de rótulo (pois atuam sobre uma marca. Neste caso um valor), dois outros comandos:
o break e o default. Veja o protótipo.
switch (expressão) {
case valor_constante1 :
comando;
comando;
...
break;
case valor_constante2 :
comando;
comando;
...
break;
...
default : comando;
comando;
...
}
A expressão é avaliada e é verificado se seu valor retornado está enquadrado em algum dos
casos (case). Dessa forma, são executados os comandos referentes aquele caso linha por linha.
E, se o retorno da expressão não se enquadra em nenhum caso, recomendamos a utilização do
default para tratar isso. Para evitar que o compilador execute comandos referentes a outro caso
(fall-through), utiliza-se o comando break, que desvia a execução do programa à linha seguinte ao
fim do bloco (prioritariamente, laços).
É possível perceber que em cada caso pode haver um comando ou vários, porém como usamos
o break não há a necessidade de chaves para o bloco de comandos e o uso delas não influi no
comportamento do compilador. Veja um exemplo de switch:
case 3:
system("cls");
printf("\n\nOpcao escolhida: 3");
break;
case 4:
system("cls");
printf("\n\nOpcao escolhida: 4");
break;
// opção padrão
default: system("cls");
} /*fim do bloco do switch*/
LAÇO
Comandos usados quando é necessário repetir uma operação várias vezes em tempo de
execução.
FOR
Quando se quer fazer um laço com controle claro de final, geralmente, se usa um for para isso,
pois sua leitura exige pouco já que agrega informações cruciais para a sua execução. Veja o
protótipo:
for (comando1; comando2; comando4) comando3;
/*para entender, siga o número dos comandos*/
A posição do comando no for é importante para a execução correta do mesmo. Cada um tem
uma função específica e é opcional o seu preenchimento. Porém não usar corretamente os
comandos de laço pode gerar o que chamamos de “loop infinito”, que é a execução ininterrupta
de uma mesma porção de código.
O primeiro comando no for é a inicialização. Aqui provavelmente se indicará qual o início de uma
faixa de valores ou condições. No segundo comando existe a expressão condicional, que
determina até quando será executado o comando ou o bloco de comandos interno ao for
(comando3). Já no terceiro (comando4) ocorre o incremento/decremento, que possibilitará atingir
a condição informada no comando dois. Ou seja o for executa a operação interna de uma
condição inicial até uma condição terminal. Veja exemplos de for:
int i;
for (i = 1; i <=100; i++) /*como não há um bloco se dispensam as chaves*/
if (i % 3 == 0) printf(“%d, “, i);
WHILE E DO-WHILE
Os “enquantos”, geralmente são usados quando não se necessitam muitos condicionantes numa
operação. O while, em particular é a mais usada estrutura de repetição. Protótipos:
while (expressão) comando;
Ou
while (expressão) {
bloco_de_comandos;
}
LEMBRETE: Qual dos dois usar é opção do programador. É importante salientar que qualquer
estrutura de repetição precisa de condições claras de parada. Havendo o engano com uma
condição o programa executará infinitamente o mesmo bloco (loop infinito). Cuidado!
DESVIO
BREAK
Este é usado, como já comentado antes, na parada brusca de um laço ou switch:
int i = 1;
while ( i <=100) {
if (i > 15) break;
if (i % 3 == 0) printf("%d\n", i);
i++;
}
Neste caso, não ocorreria a impressão dos múltiplos de 3 após o número 15.
CONTINUE
Pouco explorado, o continue força a execução de mais uma repetição no laço (quando usado no
fim do laço, próximo às chaves):
for (i= 100; i >1; i--) {
if (i % 3 == 0) printf(“%d, “, i);
else continue;
}
Geralmente é usado para poupar ao programa outras verificações antes da repetição.
VETORES
São um conjunto contíguo de memória de dimensão única que agrega elementos de um mesmo
tipo. Declaração:
tipo nome_do_vetor[TAMANHO];
Exemplo:
float mensalidades[50];
As três primeiras posições deste vetor foram inicializadas. Ainda, pode-se criar um TED sem
tamanho definido. Porém é exigida uma inicialização na declaração.
float mensalidades[] = {1,2,3};
LEMBRETE: Os limites de cada TED devem ser controlados pelo programador. Se o programa
ultrapassar um limite durante sua execução, pode haver erros graves. A linguagem C não lida
com validações de limites de estruturas. Então, tenha cuidado. Somente crie TEDs sem tamanho
conhecido se realmente necessário e fique de olho nas validações que você deverá fazer para
que não ocorram erros.
ANTES, A INDEXAÇÃO
Como acessar elementos dentro de um TED? Uma forma eficiente e clara é a indexação.
Consiste em usar o número das posições (iniciando em zero) para acessar o elemento. Para isso
usamos os colchetes com valores constantes ou variáveis (da mesma forma que denominamos o
tamanho). Exemplo
Temos que:
float[1] == 2;
float[2] ==3;
LEMBRETE: Perceba que o último índice é 2. Então todo e qualquer tamanho definido a um TED
é acessível de 0 ao tamanho-1. Isso é muito importante.
Aqui, preenchemos o vetor com o valor dos índices somado a 1, de modo que:
vetor[0] == 1;
vetor[1] == 2;
vetor[2] == 3;
...
vetor[99] == 100;
LEMBRETE: Mesmo que tenha declarado um tamanho, um algoritmo que ultrapasse esse
tamanho, em C, não será barrado. O que pode fazer o erro perceptível é a parada abrupta do
programa por tentar acessar uma área de outro.
onde: mapa [0][0], mapa[1][2], mapa [9][9], são posições na matriz. Ela deve ser acessada com os
índices relacionados.
Mas, podemos ser mais precisos nessa representação. Podemos incluir os segundos como
dimensão. Temos, então:
char mapa [181][361][60];
Para inicializar uma matriz de duas dimensões (mais utilizada), uma forma é percorrê-la é a
seguinte:
int i,j matriz [5][5];
for (i=0; i<5; i++)
for(j=0; j<5; j++)
matriz[i][j] = i * 5 + (i + 1);
/*não precisamos de chaves pois cada comando executa um comando. Mas não faz mal usá-
las.*/
STRINGS
São vetores do tipo char com dimensão única, finalizados com um caractere nulo („\0‟). Não há
uma implementação natural das strings em C, pois em outras linguagens existe um tipo string.
Como já manipulamos um vetor, como acima. Basta perceber que DEVE haver um caractere nulo
no fim se o programador quiser usar o vetor de char com funções destinadas à manipulação de
strings.
Essas funções estão informadas no cabeçalho string.h, que deve ser incluído ao seu código fonte
(#include <string.h>). Em http://www.cplusplus.com/reference/string/ há uma referência sobre
essas funções. Acostume-se com o inglês. Visite.
PONTEIROS
Sabemos que as variáveis locais, por exemplo, são destruídas após o termino da função aonde
ela foi declarada. E que não são acessíveis em outras funções. Ou seja, como sabemos, são
A declaração é feita com relação ao tipo da variável a ser apontada. O ponteiro deve referenciar
sempre um objeto do mesmo tipo (com exceção do void).
Ao se declarar um ponteiro para char se utiliza o operador * após o tipo. Alguns compiladores
permitem que este operador seja colocado logo após o nome, como char*.
se declara um ponteiro
Segundo o exemplo acima podemos acessar o valor 'a' através do ponteiro se usarmos: „*c‟.
assim podemos alterar o valor da variável ch sem usá-la, isso chama-se desreferenciamento do
ponteiro:
char *c;
char ch = 'a';
c = &ch; /*a atribuição do endereço de ch, a c*/
*c = 'b'; /* o valor de ch foi alterado a partir dessa linha */
O operador & é usado quando se deseja obter o valor do endereço na memória de uma variável
(por exemplo):
char *c;
char ch = 'a';
c = &ch;
Deve-se lembrar que esse operador é geral e seu propósito não se limita aos ponteiros. Você
pode obter o endereço de memória de qualquer variável.
O foco principal dado aos ponteiros é o de poder acessar locais de memória em tempo de
execução, dinamizando o seu programa. Para alguns dos dados que podem ser acessados, são
usadas as funções de alocação dinâmica.
MÚLTIPLA INDIREÇÃO
É criar ponteiros para ponteiros (e assim sucessivamente) de um determinado tipo.
Por Exemplo:
*ptrVetor[valor] // vetor de ponteiros
É considerado múltipla indireção. Uma vez que o nome do vetor puro (rótulo, ptrVetor) é um
ponteiro para a primeira posição do vetor (que também é um ponteiro).
Código Exemplo:
ARITMÉTICA DE PONTEIROS
Expliquemos rapidamente: O C reconhece comandos que comparam e operam ponteiros. Usado
geralmente na manipulação de vetores de maneira prática e concisa.
Quando se usam os operadores aritméticos, ocorre a relação com o tipo. Move-se a quantidade
de bytes de cada tipo quantas vezes for informado pelo programador através da operação de
soma ou subtração (*(p+7) = acesso em “7 vezes bytes do tipo” ao longo de um tipo estruturado).
Uso recomendado em vetores.
Por questões de organização mantenha sempre um protótipo de sua função declarando-a antes
do main ou num arquivo de cabeçalho. Segue o protótipo geral:
tipo nome_da_função (tipo_parâmetro1, tipo_parâmetro2, ... tipo_parâmetro_n);
Onde:
Funções sem parâmetros podem usar parêntesis vazios ou a palavra void entre eles.
As funções void, como não retornam valor (pelo nome void, vazio) não é necessário usar a
palavra return.
RELEMBRANDO PARÂMETROS
Lembra-se deles? Variáveis com comportamento local? Pois bem. Essa será a entrada dos dados
que a sua função precisa tratar. Por exemplo, uma função de somar dois inteiros:
#include <stdio.h>
#include <stdlib.h>
int soma (int, int);
int main (void) {
int a, b;
int soma (int x, int y) {/*não haveria problema se os nomes dos parâmetros fossem
iguais aos do main*/
return (x + y); /*se retorna o valor inteiro resultado da expressão*/
}
A função soma recebe dois parâmetros inteiros (x e y) e retorna a sua soma à posição requerida
no main. Cabe ao programador realizar todas as validações possíveis em seu programa. O valor
da soma poderia ser armazenado em outra variável, mas isso gasta tempo e memória com a
alocação de uma nova variável e sua atribuição.
PASSAGEM DE PARÂMETROS
É o ato de entrar valores para tratamento numa função. São feitas passagens de duas formas:
cópia (valor), onde não ocorre alteração do valor original do dado na função chamadora e por
referência (ponteiros) onde isso ocorre. Veja o programa de soma:
#include <stdio.h>
#include <stdlib.h>
int soma (int, int);
int main (void) {
int a, b;
int soma (int x, int y) {/*não haveria problema se os nomes dos parâmetros fossem
iguais às do main*/
return (x + y); /*se retorna o valor inteiro resultado da expressão*/
}
Neste caso acima, o valor de a e b foi “copiado” para x e y respectivamente na função soma. Mas
se quisermos alterar o conteúdo de uma variável fora do âmbito da função? Coisa impossível?
Ponteiros são a solução do problema.
LEMBRETE: A passagem de parâmetros pode ser considerada uma atribuição entre as variáveis
passadas e os parâmetros de entrada. No caso acima, x = a; e y = b; caracterizariam esse
processo. Perceba que assim como uma atribuição podem ser passados resultados de
expressões, retornos de funções ou até uma coerção para um tipo esperado do outro lado.
int soma (int x, int y) {/*não haveria problema se os nomes dos parâmetros fossem
iguais aos do main*/
x += y +1;
y *= x;
printf(“valor de x = %d | valor de y = %d\n”, x, y);
return (x + y); /*se retorna o valor inteiro resultado da expressão*/
}
Pronto. Se perceberá que o valor de a e b não sofreu alteração alguma.
int soma (int *x, int *y) {/*x e y são ponteiros agora*/
DICA: numa função que recebe ponteiros, você pode fazê-lo por cópia. Simples: o valor do
ponteiro é copiado. Qual o valor esperado de um ponteiro? Um endereço, uma vez copiado,
desreferenciações simples funcionam muito bem.
Pronto. Alteramos ou não o valor das variáveis inteiras? As duas formas usadas foram: transferir
o valor do ponteiro por cópia ou passar diretamente a referência da entidade.
PONTEIROS E TED
Podemos usar ponteiros para acessar e manipular (sem indexação) vetores e strings. Assim
como podemos declarar TED de ponteiros como faríamos a qualquer outro tipo. Para isso
usamos a aritmética de ponteiros.
LEMBRETE: É interessante saber que todo o rótulo de vetor (e string também) é um ponteiro
constante (sem possibilidade de ser alterado) para o início da área do mesmo. Ou seja:
Ao usar aritmética de ponteiros para percorrer o vetor si usando uneb há também duas formas:
/*preservando a referência ao primeiro elemento*/
*(uneb + 1);
Como uneb aponta para o primeiro elemento de si, dessa forma eu acesso o segundo elemento.
Veja: se uneb aponta a si[0], uneb +1 aponta a si[0+1] ou si[1]. Para o quarto elemento usaríamos
*(uneb + 3) e assim sucessivamente.
/*Atualizando o início da referência*/
uneb++;
LEMBRETE: Não esquecer do desconhecimento de limites do C com relação a esses tipos. Não
é feita pela linguagem validação quanto ao espaço percorrido através da estrutura. isso é papel
do programador e é crucial para construção de um bom programa.
ALOCAÇÃO DINÂMICA
A alocação dinâmica permite a criação de dados na área destinada a isso (heap) na memória do
computador. Usa-se a função malloc, que retorna um ponteiro do tipo void que pode ser
assignado a qualquer tipo de ponteiro se a alocação foi bem sucedida e NULL (nulo), se não. E
free que libera a área alocada previamente. Eis os exemplos de uso:
char* p = malloc(1000);
/* o parâmetro de entrada de malloc é a quantidade de bytes que será alocada. Essa
função devolve endereço do primeiro desses bytes.*/
int *in = malloc(8);
A mesma coisa acontece aqui, mas como em alguns computadores um inteiro ocupa 4 bytes
estão alocados dois. O que fazer para não corrigir seu código em cada PC que usar? faça uso de
uma função chamada sizeof que recebe um tipo ou número e retorna o tamanho em bytes usado
no PC. Assim o seu programa fica portabilizado, usável em qualquer PC. Seguem exemplos:
char* p = malloc(1000 * sizeof(char)); /*alocando espaço para 1000 caracteres*/
Para liberar o espaço que foi alocado anteriormente usa-se free que recebe um ponteiro void para
a área alocada. Dessa forma:
free (p); ou free (in); /*marca-se, na memória principal como sem uso e, portanto
poderá ser sobreescrito*/
Exercícios
Construa um trecho de código que transforme uma string minúscula para maiúscula. Sem o uso
de funções. Dica: lembre-se da tabela ASCII e o do poder de se referir a um caractere como um
int, e dos mecanismos de coerção. (se não conseguir, dê uma olhada na seção exercícios
resolvidos).
ESTRUTURAS
São a agregação de tipos permitindo criar o modelo de um novo tipo de elementos. É usado
quando se intenciona ter vários tipos de informação numa mesma entidade. Entenda que seu uso
Note que não há declaração ou inicialização de nenhuma variável. Mas a criação de uma
estrutura é um comando como qualquer outro. Portanto o ponto-e-vírgula no final.
É possível criar uma variável do tipo struct pessoa logo após a declaração, antes do ponto e
vírgula final:
struct pessoa {
char nome[80];
char cpf[11];
}Joao, Elias, Jose;
/* Separamos por „virgula‟ elementos da estrutura. Para que não haja confusão com
funções ou variáveis que você criar no seu programa, use pelo ou menos a Primeira Letra
em Maiúsculo.*/
Lembrando que, como toda estrutura é declarada fora das funções ela é acessível em todo o
programa, e qualquer elemento dessa estrutura declarado dessa forma será global (assim como
as variáveis). Podemos criar elementos de uma estrutura em qualquer parte do programa.
Assuma como a declaração de qualquer variável. Observe:
int main () {
...
struct pessoa Novo;
return 0;
}
O acesso aos “campos” de uma estrutura local é feito a partir do operador „.‟. Então podemos
inicializar a estrutura da seguinte maneira:
strcpy (Novo.nome, “ConsultJR”); /*ambas funções para manipulação de strings*/
strcpy (Novo.cpf,”12345678909”);
strcpy(p->nome, “ConsultJR”);
strcpy(p->cpf,”12345678909”);
...
return 0;
}
DICA: Podem ser usadas estruturas como qualquer outro tipo. Podemos declarar vetores,
matrizes e estruturas de estruturas. Pratique!
O TYPEDEF
É usado quando, seja para a clareza ou estética do código, se necessita renomear um tipo de
dado. Lembremos que as structs podem ser consideradas tipos e, por conseqüência, sofrem ação
do typedef.
struct aluno {
char nome[80];
int cod_turma;
...
int cod_curso;
char nome_curso[80];
};/*não esquecer do ponto-e-vírgula*/
/*Agora usamos o typedef para deixarmos de usar o „struct aluno‟ toda vez que fizer
referência à estrutura*/
Então podemos usar os apelidos dados para economizar em declarações, mas ressalva-se a
importância de um código claro, que não seja necessário verificar a declaração toda a vez que se
queira entender o real teor daquilo.
ARQUIVOS
Antes de trabalharmos com arquivos, é importante saber diferenciar as streams dos arquivos.
STREAM TEXTO
Uma stream de texto é uma sequência de caracteres que pode ou não conter um caractere de
quebra de linha. O padrão C ANSI não exige que as linhas sejam organizadas com quebra de
linha. Outro fato importante a observar é que não é necessário na última linha um caractere de
final de linha.
STREAM BINÁRIA
Uma stream binária é composta por uma seqüência de bytes lidos, sem tradução, diretamente do
dispositivo externo. Não ocorre nenhuma tradução e existe uma correspondência um para um
entre os dados do dispositivo e os que estão no arquivo.
MANIPULANDO ARQUIVOS
Para utilizar um arquivo você deve associá-lo a uma stream e, então, manipulá-la. Os arquivos
são associados a uma stream através de uma operação de abertura (fopen) e desassociados por
uma operação de fechamento (fclose) que serão vistos posteriormente.
Função Descrição
fopen( ) Abrir um arquivo
fclose( ) Fechar um arquivo
putc( ) Escrever um caracter em um arquivo
fputc( ) O mesmo que putc( )
getc( ) Ler um caracter de um arquivo
fgetc( ) O mesmo que getc( )
fseek( ) Posicionar o ponteiro de arquivo num byte específico
fprintf( ) É para o arquivo o que printf é para o console
fscanf( ) É para o arquivo o que scanf é para o console
feof ( ) Devolve verdadeiro se o fim do arquivo foi atingido
ferror( ) Devolve verdadeiro se ocorreu um erro
rewind( ) Posicionar o ponteiro de arquivo no início deste
remove( ) Apagar um arquivo
fflush( ) Descarregar um arquivo
ABRINDO UM ARQUIVO
Para abrir um arquivo usa-se a função fopen, essa função faz a associação do arquivo a uma
stream retornando um ponteiro de arquivos associado que será aberto. Um arquivo pode ser
aberto de diversas maneiras: leitura, escrita, leitura/escrita, adição de texto, etc.
Obs:Se não for informado o caminho absoluto do arquivo (c:\diretório) será criado no diretório
onde o programa esta sendo executado.
Exemplo: Para abrir um arquivo com o nome de tutorial.txt para que permita escrita pode digitar:
FILE *arq = fopen(“tutorial.txt”,w);
Obs: Caso o arquivo tutorial.txt ainda não exista ele será criado pronto para escrita, caso ele já
exista ele será sobrescrito. Se você deseja escrever a partir do final do arquivo existente você
deve abrir no modo de adicionar texto (a) no final do arquivo.
onde arq é um ponteiro de arquivo para o arquivo que deve ser fechado. Um valor zero de retorno
significa que a operação foi executada com êxito, qualquer outro valor implica em erro.
ESCREVENDO UM CARACTERE:
Para escrever um caractere em um arquivo previamente aberto utiliza-se a função putc() ou
fputc().
Protótipo:
int putc (char c,FILE *arq);
Onde c é o caractere a ser escrito no arquivo apontado por arq. O mesmo protótipo serve para
fputc()
Protótipo:
int getc(FILE *arq);
A função lê o caracter como um unsigned char mas retorna o valor como um inteiro, onde o byte
mais significativo vale zero. A função devolve o código EOF ao chegar ao final do arquivo. O valor
EOF também é um inteiro válido e, portanto ao usar arquivos binários é necessário que a função
feof() seja utilizada para verificar o final do arquivo.
feof()
Às vezes é necessário verificar se um arquivo chegou ao fim, para isto podemos usar a função
feof().
Esta função retorna diferente zero se o arquivo chegou ao EOF, caso contrário retorna zero.
Para escrever a cadeia de caracteres apontada por str no arquivo apontado por arq.
Essa função lê uma cadeia de caracteres do arquivo apontado por “arq” até que um caracter de
nova linha seja encontrado ou comp-1(comprimento) caracteres sejam lidos. Se bem sucedida a
função retorna um ponteiro para “str” caso contrário retorna NULL.
fprintf() e fscanf()
As funções fprintf() e fscanf() são equivalentes às funções printf() e scanf(), sendo a única
diferença o fato de que elas trabalham com fluxos de dados (arquivos).O protótipo das duas
funções são:
int fprintf(FILE *arq, const char *formatacao, ...);
Onde “FILE *arq” – o arquivo a ser escrito e “const char *formatacao” - o que será escrito.
int fscanf(FILE *arq, const char *formatacao, ...);
Onde “FILE *arq” – o arquivo a ser lido e “const char *formatacao” – qual a variável que receberá
os dados do arquivo.
Exemplo:
Char x[50], c;
size_t fread (void *buffer, int numero_de_bytes, int count, FILE *arq);
- “int count” – indica quantas unidades devem ser lidas cada uma com comprimento
numero_de_bytes.
- “int count” – indica quantas unidades devem ser escritas cada uma com comprimento
numero_de_bytes.
A função fread devolve o número de itens lidos, esse valor poderá ser menor que count se o final
do arquivo for atingido ou ocorrer algum erro.A função fwrite devolve o número de itens escritos,
esse valor será igual a count a menos que ocorra algum erro.
fseek()
Operações de escrita e leitura aleatória(randômica)pode ser realizadas com a ajuda do
fseek().Esta função move a posição corrente de leitura ou escrita no arquivo de um valor
especificado, a partir de um ponto especificado. Protótipo:
int fseek (FILE *arq, long num_bytes, int origem);
- “long numbytes” – indica quantos bytes o cursor de posição do arquivo será movimentado a
partir da sua posição atual.
Para mover num_byte do inicio do arquivo então origem deve ser SEEK_SET
Para mover num_byte a partir da posição atual do arquivo então origem deve ser SEEK_CUR
Para mover num_byte a partir do final do arquivo então origem deve ser SEEK_END
rewind
Retorna o indicador de posição do arquivo para o início dele. Protótipo:
void rewind (FILE *arq);
remove()
Esta função apaga o arquivo especificado, ela devolve zero se a operação foi bem sucedida ou
um valor diferente de zero caso contrário. Protótipo:
int remove(char*nome_do_arquivo);
fflush()
A função fflush escreve o que existe no buffer para o arquivo. O fluxo permanece aberto após a
execução da função. Retorna zero no caso de sucesso e EOF se ocorreu um erro. Protótipo:
int fflush (FILE *arq)
EXERCÍCIOS
Questão 1.
Uma empresa tem para um determinado funcionário uma ficha contendo o nome, número de
horas trabalhadas e o n0 de dependentes de um funcionário.
Considerando que:
Sobre o salário são feito descontos de 8,5% para o INSS e 5% para IR.
Faça um algoritmo para ler o Nome, número de horas trabalhadas e número de dependentes de
um funcionário. Após a leitura, escreva qual o Nome, salário bruto, os valores descontados para
cada tipo de imposto e finalmente qual o salário líquido do funcionário.
Em Algoritmo:
Algoritmo salario
variaveis
nome : cadeia
dependente : inteiro
horas, salarioLiq, salarioBruto, DescontoINSS, DescontoIR : real;
Inicio
Leia(nome,horas, dependente);
salarioBruto <- (12 * horas) + (40 * dependente);
DescontoINSS <- (salarioBruto*0,085);
DescontoIR <-(salarioBruto*0,05) ;
Em C:
int main () {
char nome[50];
int dependente
float horas, salarioLiq, salarioBase, DescontoINSS, DescontoIR;
printf(“Escreva o nome”);
gets(nome);
printf(“Escreva a quantidade de horas”);
scanf("%f",&horas);
printf(“Escreva a quantidade de dependentes”);
scanf("%i",&dependente);
salarioBruto = (12 * horas) + (40 * dependente);
descontoINSS = (salarioBruto * 0,085);
descontoIR = (salarioBruto * 0,05);
salarioLiq = (salarioBase – (DescontoINSS + DescontoIR));
printf(“%s ,%f , %f, %f , %f”,nome,salarioBruto,DescontoINSS,DescontoIR,
salarioLiq,);
return 0;
}
Questão 2.
Faça um algoritmo para ler a base e a altura de um triângulo. Em seguida, escreva a área do
mesmo.
Área = (Base * Altura ) / 2
Em Algoritmo:
Variaveis:
base, altura, area : real;
Inicio
Leia(Base)
Leia(Altura)
Area<- (Base * Altura)/2
Escreva (Area)
Fim
Em C
int main(){
float base, altura, area;
printf(“informe a base ”);
scanf(“%f”, &base);
printf(“informe a altura ”);
scanf(“%f”, &altura);
área = (base * altura)/2;
QUESTÕES EM C
5) Ler um numero e imprimir: maior que 20, igual a 20 ou menor que 20.
8) Crie um programa que receba uma palavra letras em minúsculas e escreva essa palavra em
letras maiúculas.
9) Apresentar todos os números divisíveis por 4 que sejam menores que 200.
Pesquisar se esse número existe no vetor. Se existir,imprimir em qual posição do vetor. Se não
12)Preencher um vetor de 8 elementos inteiros. Mostrar o vetor e informar quantos números são
13)Preencher um vetor com 3 nomes com 20 letras no máximo cada. Imprimir os Nomes.
ultimo numeros
15)Criar uma função que receba um caractere como parâmetro e retorne 1 (um) caso seja uma
17)Criar um algoritmo que leia os elementos de uma matriz inteira de 3 x 3 e imprimir todos os
1)
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<math.h>
#include<string.h>
main()
{
int x, n1, n2;
printf("\n\n Digite um numero: ");
scanf("%d",&x);
n1=x+1;
n2=x-1;
printf("\n\nSeu sucessor e : %d",n1);
printf("\n\nSeu antecessor e : %d",n2);
printf("\n\n");
system("pause");
return (0);
}
2)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
int main()
{
int a,b,c;
printf("Informe um numero inteiro: ");
scanf("%d",&a);
printf("Informe um numero inteiro: ");
scanf("%d",&b);
printf("Informe um numero inteiro: ");
scanf("%d",&c);
printf("A media dos tres numeros informados e: %4.2f\n\n",float((a+b+c))/3);
system("PAUSE");
return 0;
}
3)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
int main()
{
float a;
printf("Informe um numero inteiro: ");
scanf("%f",&a);
4)
#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
float numero;
printf("Informe um numero: ");
scanf("%f",&numero);
if (numero > 20)
printf("A metade desse numero e %3.2f", numero/2);
system("PAUSE");
return 0;
}
5)
#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
float numero;
printf("Informe um numero: ");
scanf("%f",&numero);
if (numero > 20)
printf("\nNumero informado e maior a 20.\n");
else
if (numero = 20)
printf("\nNumero informado e igual a 20.\n");
else
printf("\nNumero informado e menor que 20.\n\n");
system("PAUSE");
return 0;
}
6)
#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
char nome[30], sexo;
int idade;
printf("Informe seu nome: ");
gets(nome);
printf("Informe seu sexo: ");
scanf("%c",&sexo);
printf("Informe sua idade: ");
scanf("%d",&idade);
if (sexo == 'f' || sexo == 'F' && idade < 25)
7)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
main()
{
int x,soma=0;
for(x=15; x<=200;x++)
printf("O quadrado do numero %d eh: %d\n",x, x*x);
system("pause");
return 0;
}
8)int main(){
char cadeia[10] ;
int i;
printf("escreva a palavra ");
gets(cadeia);
printf("\n");
system("pause");
9)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
main()
10)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main()
{
char nome[30]; int x,t;
printf("\n\n DIGITE UM NOME: ");
gets(nome);
t=strlen(nome);
for(x=t+1;x>=0;x++)
printf("%c",nome[x]);
printf("\n\n");
system("pause");
return(0);
11)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
main()
{
int x, vet[8], num, achei=0;
for(int x=0;x<8;x++)
{
printf("\n[%d] Digite um numero: ",x);
scanf("%d",&vet[x]);
}
printf("\n\n");
printf("Digite um valor a ser pesquisado: ");
scanf("%d",&num);
for(int x=0;x<8;x++)
if(vet[x]==num)
{
printf("\n O numero %d esta na posicao %d: ",num,x);
achei=1;
}
if(achei!=1)
printf("\n\n");
system("pause");
return(0);
12)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
main()
{
int vet1[8], x, cont=0, soma=0, soma2=0;
for(x=0;x<=7;x++)
{
printf("\nDigite um valor: ");
scanf("%d",&vet1[x]);
if(vet1[x]>30)
{
cont++;
soma=soma+vet1[x];
}
}
for(x=0;x<=7;x++)
printf("\t%d",vet1[x]);
printf("\n\n %d Numeros sao maiores que 30",cont);
printf("\n\n A Soma dos numeros maiores que 30 e = %d",soma);
for(x=0;x<=7;x++)
soma2=soma2+vet1[x];
printf("\n\n A Soma dos numeros digitados e = %d",soma2);
printf("\n\n");
system("pause");
return(0);
13)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include <string.h>
main()
{
char nome[3][20],;
int x;
for(x=0;x<=2;x++)
{
printf("\n[%d] Digite o nome : %d ",x,(x+1));
gets(nome[x]);
}
for(x=0;x<=2;x++)
{
printf("\n %s",nome[x],x);
printf("\tO NOME %s tem %d letras",nome[x],strlen(nome[x]));
}
printf("\n\n");
14)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
void preenche(int vetp[])
{
int x;
for (x=0; x<6; x++)
{
// [%d] e o x vao mostrar a posição do número digitado
printf ("\t[%d] Digite um numero: ",x);
scanf("%d",&vetp[x]);
printf ("\n");
}
}
void imprimevet(int vetp[])
{
int x;
for (x=0; x<6; x++)
printf (" [%d] %d\t",x,vetp[x]);
}
void quadrado(int vetp[])
{
int x;
for(x=0; x<6; x++)
printf("%d\t",vetp[x]*vetp[x]);
}
void primultimo(int vetp[])
{
printf ("%d\t %d\t",vetp[0], vetp[5]);
}
int vetp[5];
main()
{
int x, resp;
resp=1;
while(resp!=0)
{
printf("\n 1 - Preenche o vetor: ");
printf("\n");
printf("\n 2 - Imprime o vetor: ");
printf("\n");
printf("\n 3 - Imprime o quadrado do vetor original: ");
printf("\n");
printf("\n 4 - Imprime o primeiro e ultimo numero: ");
printf("\n");
printf("\n 0 - Sair do programa: ");
scanf("%d",&resp);
printf("\n");
if(resp==0)break;
if(resp==1)
15)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
int verificavogal (char M)
{
if(M=='a' || M=='A' || M=='e' || M=='E' || M=='i' || M=='I' || M=='o' || M=='O' ||
M=='u' || M=='U')
return(1);
else
return(0);
}
main()
{
char x;
printf("Digite uma letra: ");
scanf("%c",&x);
if(verificavogal(x)==1)
printf("\nA letra [ %c ] eh uma vogal: ",x);
else
printf("\nA letra [ %c ] eh uma constante: ",x);
printf("\n\n");
system("pause");
return(0);
}
16)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <string.h>
main()
{
int lin,col, tab;
int mat[4][4];
for (lin=0; lin<=3; lin++)
{
for (col=0; col<=3;col++)
{
printf("Digite ELEMENTO da linha %d, coluna %d da matriz: ",lin+1,col+1);
// aqui no scanf preenchemos a matriz
scanf("%d", &mat[lin][col]);
17)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <string.h>
main()
{
int lin,col, tab;
int mat[3][3];
for (lin=0; lin<3; lin++)
{
for (col=0; col<3;col++)
{
printf("Digite ELEMENTO da linha %d, coluna %d da matriz: ",lin+1,col+1);
// aqui no scanf preenchemos a matriz
scanf("%d", &mat[lin][col]);
}
}
//Imprimindo a matriz
printf("Matriz\n");
for (lin=0;lin<=2;lin++)
{
for (col=0;col<3;col++)
printf("%d\t",mat[lin][col]);
printf("\n\n");
}
// Imprimindo a matriz menos diagonal principal
printf("\n\nMatriz menos a diagonal principal\n\n");
for (lin=0; lin<3;lin++)
{
for (col=0;col<3;col++)
{
if (lin != col)
printf("%d",mat[lin][col]);
printf("\t");
printf("\n\n");
system("pause");
return 0;
}
18)
int main(){
if(sexo == „m‟){
printf(“A altura da pessoa é: %f” ,altura);
}
else{
printf(“A cor dos olhos é: %s” ,cor);
}
cont++;
}
system("pause");
return 0;
}
ftp://ftp.unicamp.br/pub/apoio/treinamentos/logica/logica.pdf
http://minerva.ufpel.edu.br/~guntzel/prog1/prog1_aula4.pdf
http://www.juliobattisti.com.br/tutoriais/katiaduarte/cbasico002.asp
http://www.carlosfelgueiras.hpg.com.br/Cursos/LinguagemC/Cap_7.html
http://www.portaldaprogramacao.com/artigos2.asp?n=897
http://www.dca.ufrn.br/~lmarcos/courses/DCA800/pdf/Algoritmos01.pdf
SCHILDT, Herbert. C Completo e Total. 3 Ed. São Paulo: Makron Books, 1996.
JAMSA, Kris; KANDLER, Lars. Programando em C/C++ - A Bíblia. 1 ed. São Paulo: Makron
Books, 1999.