Vous êtes sur la page 1sur 18

Introdução Primeiro Programa A Forma Geral de um Programa

main(){ /* função obrigatória */ declarações das variáveis globais


● Criada em 1972 por Dennis Ritchie no centro de declarações dos protótipos das funções
printf("oi");
Pesquisas da Bell Laboratories. } tipo-devolvido main (lista-de-parâmetros){
● Existem várias versões de compiladores C sequência-de-comandos;
oferecidas por várias empresas. ● Um programa em C consiste de um ou várias funções. }
● A única função que necessariamente precisa estar presente
● O C é mais utilizada para escrever compiladores, é a main(). É a primeira função a ser chamada quando a
tipo-devolvido f1 (lista-de-parâmetros){
sequência-de-comandos;
bancos de dados, editores de texto, etc. execução de um programa começa. }
● Segue quase todos os conceitos da PE ● As chaves indicam o início e término de um bloco de
comandos. tipo-devolvido f2 (lista-de-parâmetros){
(programação estruturada). ● Toda isntrução deve ser finalizada com um ponto-e-vírgula.
sequência-de-comandos;
}
● Linguagem de Médio Nível. ● printf() é uma das funções da linguagem C, que ...
● Possui recursos de baixo nível. detalharemos adiante. tipo-devolvido fn (lista-de-parâmetros){
sequência-de-comandos;
● Gera código eficiente }

Obs.: f1() até fn() representam as funções definidas


pelo usuário.

Tipos Básicos de Dados Declaração de Variáveis Escopo de Variáveis – Variáveis Locais


● Caractere (char) main(){ ● São declaradas dentro de uma função e seu escopo é o bloco de

Inteiro (int) int idade; código onde foram declaradas.
● Ponto flutuante (float) idade = 30; ● Ocupam espaço na memória somente durante a execução do

Ponto flutuante de precisão dupla (double) printf(“A idade é %d\n”, idade); bloco de código a que pertence.
● Sem valor (void) }
void f (){
● As duas primeiras instruções poderiam ser substituídas por: int t
int idade = 30; scanf(“%d”,&t);
if (t ==1){
● C é case sensitive, ou seja, as letras maiúsculas diferem das char s[80];
minúsculas. printf(“entre com o nome: “);
gets(s);
● Em C pode-se declarar variáveis em qualquer parte do programa. /* faz alguma coisa... */
}
}
● A variável t pode ser referenciada em qualquer ponto do bloco de
código da função f().
● A variável s só pode ser referenciada dentro do bloco de código
em que fora declarada, ou seja, dentro do comando if.
Escopo de Variáveis – Parâmetros Formais Escopo de Variáveis – Variáveis Globais Operadores Aritméticos
● Se uma função usa argumentos, ela deve declarar variáveis que ● São reconhecidas pelo programa inteiro e podem ser referenciadas em ● Atribuição =
receberão os valores dos argumentos. Essas variáveis são qualquer ponto do código. ● Multiplicação *
denominadas parâmetros formais da função.
● Ocupam espaço na memória durante toda a execução do programa. ● Divisão /
● Possuem o comportamento como qualquer outra variável local
● Devem ser declaradas fora de qualquer função. ● Adição +
dentro da função a que pertence.
● Um dos objetivos do programador é a modularização, ou seja, fazer ● Subtração -
com que o programa seja dividido em módulos com funções ● Módulo (Resto) %
● Deve ser declarada após o nome da função dentro dos específicas. Conseguimos este objetivo através do uso de variáveis ● Incremento de 1 ++
parênteses. locais e funções. Portanto devemos evitar o uso de variáveis globais ● Decremento de 1 --
devido a dependência criada entre os módulos.
Soma( int x, int y){ ● Operador pré-fixado: A variável é incrementada antes de seu valor ser
... ● Qual função abaixo é mais adequada? Porque? usado. Exemplo: ++n
} ● Operadro pós-fixado: A variável é incrementada depois de seu valor ser
soma(int x, int y){ usado. Exemplo: n++
return(x+y);
} ● i += 2 equivale a i=i+2
● i *= y +1 equivale a i = i * (y + 1)
int x,y; ● i /= 2 equivale a i=i /2
soma(){ ● i %= 2 equivale a i=i%2
return(x+y); ● i -= 2 equivale a i=i–2
}

Operadores Lógicos Operador Vírgula A Função printf()


● && e ● É usado para encadear diversas expressões. ● Sintaxe: printf(“string de controle”, lista de argumentos);
● || ou ● Exemplo: printf(“A idade é %d\n”, idade);
● ! negação ● Exemplo: x = (y=3,y+1)
● O primeiro argumento contém caracteres e códigos de formatação: %
● Exp1 && Exp2: O resultado será verdadeiro se as duas ● Primeiro atribui o valor 3 a y e, em seguida, atribui o valor 4 a x. + letra, conforme abaixo:
expressões forem verdadeiras.
Qual a saída produzida pela instrução destacada abaixo? – %c caractere simples

Exp1 || Exp2: O resultado sera verdadeiro se pelo menos uma – %d decimal
expressão for verdadeira. /* virgula.cpp */ – %f ponto flutuante
#include <stdio.h> – %s cadeia de caracteres

!Exp1: O resultado sera verdadeiro se a Exp1 for falsa e vice- #include <conio.h> – %u decimal sem sinal
versa. main(){ – %e notação científica
int x,y;
x = (y=3,y+1,y*10); ● O segundo argumento apresenta o valor a ser exibido
printf("%d",x); ● Deve haver tantos argumentos após a string de controle quantos
getch(); forem os códigos de formatação.
} ● \n é um código de formatação especial que força a mudança de linha.
● \t permite realizar tabulação.
Exercício A Função scanf() A Função getche() e getch()

Qual a saída produzida pelo programa abaixo? ● Permite a leitura de dados formatados do teclado, após ● A Funcao getche(): Lê e retorna um caracter do teclado sem
pressionar Enter. esperar Enter e permite que o mesmo seja impresso na tela.
/*tabulacao.cpp*/
#include <stdio.h> ● Sintaxe: scanf (“string de controle”, lista-argumentos); ● A Funcao getch(): Lê e retorna um caracter do teclado sem
#include <conio.h> esperar Enter e não permite que o mesmo seja impresso na
● Exemplo: tela.
main(){ printf("Digite a distancia:");
printf("\ncodigo\tquantidade\tpreco"); scanf("%d",&centimetro); ● Protótipos:
printf("\n1\t250\t\t3,55");
printf("\n2\t10\t\t8,00"); ● Os argumentos de scanf devem ser endereços de varíaveis, ou int getch(void)
getch(); seja, o nome da variável precedido pelo símbolo &. int getche(void)
}
● Um endereço é inteiro sem sinal, portanto para mostrar o
endereço de uma variável, seria assim:
printf("centimetro esta no endereco %u\n",&centimetro);

Comandos de Repetição - for Comandos de Repetição - for Comandos de Repetição - for


● Sintaxe: ● O programa a seguir permite que o usuário escreva na tela até que tecle x. ● Variações do Comando For:
for (inicialização; condição; incremento){
instruções; #include <stdio.h>
} #include <conio.h> for (x=0, y=0; x+y<10; ++x)
main(){ ...
● Exemplo: char c; }
for (int i=1; i <10; i++){ printf("\nDigite uma frase. Ao terminar tecle x\n");
printf("%d\n",i); for (c = getche(); c != 'x';c = getche()){ ● Podemos utilizar a vírgula para permitir que duas ou mais
} }
} variáveis controlem a repetição.
● A inicialização é uma instrução de atribuição e é sempre executada uma
única vez antes do comando ser iniciado. ● A instrução for do programa anterior poderia ser assim:
● A condição é avaliada a cada repetição. Se for falsa a repetição é finalizada. for (; (c = getche()) != 'x';)
● O incremento define a maneira como a variável de controle será alterada a
cada repetição. ● Execute o programa anterior e substitua a função getche() por getch() e
● Nenhuma das três definições são obrigatórias. Exemplo: veja a diferença.

for(;;) { ● Se desejar interromper uma repetição use o comando break.


printf("loop infinito\n");
}
Exercícios Comandos de Repetição – while e do...while Exercícios
● Codificar um programa que mostre para o usuário a mensagem: ● Sintaxe: ● Codificar um programa que calcule a quantidade de
“Você está preso, para sair tecle x”, para qualquer tecla caracteres digitados pelo usuário. O programa deverá
pressionada. A mensagem só não será mostrada quando o while (condicao){
instrucoes; solicitar a digitação de uma frase e ser finalizado
usuário teclar x e consequentemente o programa deverá ser
finalizado. (break.cpp) } quando o usuário teclar Enter. (qtcaracteres.cpp)

● Codificar um programa que solicite ao usuário dois caracteres do{ ● Escreva um programa que cause uma pausa até que o
em ordem alfabética crescente e imprima o número de instrucoes;
}
usuário digite a letra 'A'. (pausaatea.cpp)
caracteres que estão entre eles. (qtletras.cpp)
while (condicao);
● Faça um programa que solicite caracteres ao usuário e
● As instruções serão executadas enquanto a condição for imprima seus códigos decimais. O programa deve
verdadeira. terminar quando o usuário pressionar a tecla ESC.
(codigodecimais.cpp)

Exercícios Comando Condicional - if Exercícios


● Construa o seguinte jogo: O computador sorteia uma letra e o usuário ● Sintaxe: ● Codificar um programa capaz de verificar se uma
deverá adivinhá-la. Quando o usuário acertar, o jogo deverá mostrar o divisão de a por b poderá ser realizada. Lembre-se
número de tentativas realizadas e permitir ao usuário jogar mais uma if (condicao){
vez ou finalizar o jogo. (qualletra.cpp) instrucoes; que o denominador (b) não pode ser zero. Não utilize a
}else{ expressão if b > 0. (divzero.cpp)
● Dica: A função rand() retorna um inteiro aleatório entre 0 e 32.767. instrucoes;
Para sortear um número entre 0 e 25 faça: rand() % 26 }
● Codificar um programa para calcular a quantidade de
● Para sortear uma letra entre a e z faça: char x = rand() % 26 +
● A cláusula else é opcional. algarismos e caracteres digitados pelo usuário.
'a' (qtalgacaracteres.cpp)
● Em uma instrução if você não fica restrito a expressões envolvendo
● Se rand() % 26 resultar em 0, x receberá o caractere a.
os operadores lógicos e relacionais. O programa simplesmente
● Se rand() % 26 resultar em 1, x receberá o caractere b.
precisa chegar a um valor zero (falso) e não zero(verdadeiro).
● Se rand() % 26 resultar em 25, x receberá o caractere z.
Exercícios Exercícios Comando Condicional - switch
● Codificar um programa que conte o número de palavras de uma frase ● Codificar um programa que mostre os caracteres digitados pelo
● Sintaxe:
informada pelo usuário. (contapalavras.cpp). Dicas: usuário na tela. A tecla Enter deve ser usada para configurar se os
switch (expressao inteira ou caracter) {
caracteres devem ser mostrados em maiúsculas ou minúsculas. A
case constante1: instrucoes;
1. Para ler uma string do teclado use a função gets(): tecla Esc servirá para finalizar o programa.
case constante2: instrucoes;
(maiusculasminusculas.cpp) ...
printf("\nDigite uma frase: "); default: instrucoes;
gets(frase); ● Dicas: }
– islower(c): Retorna um número diferente de zero se c é uma letra
Ao utilizar gets() você deve incluir a instrução: minúscula, e 0 caso contrário. ● Cada case pode ter várias instruções. Estas instruções não devem
#include <string.h> – isupper(c): Retorna um número diferente de zero se c é uma letra
estar entre chaves.
maiúscula, e 0 caso contrário. ● Se um caso for igual ao valor da expressão a execução comeca nele.
2. A variavel que receberá a string deverá ser um vetor e declarada da – toupper(c): Retorna o equivalente maiúsculo de c se c é uma letra, ● O comando break causa a saida do comando switch. Se nao existir
seguinte forma: char frase[30]; caso contrário, c é devolvido sem alteração. um comando break seguindo as instruções de um caso, o programa
– tolower(c): Retorna o equivalente minúsculo de c se c é uma letra,
segue executando as instruções dos casos seguintes.
caso contrário, c é devolvido sem alteração. ● Se nenhum caso for satisfeito a execução comeca no default.
– Inclua: #include <ctype.h> ● O cláusula default é opcional.

Pré-processador C A Diretiva #define A Diretiva #define


● O pré-processador C é um programa que ● Substitui determinados códigos pré-definidos pelo usuário. ● Se desejarmos usar a palavra VERDADEIRO para o valor 1 e a
● Sintaxe: #define nome expressao. Onde nome é o palavra FALSO para o valor 0, devemos declarar:
examina o programa-fonte em C e executa símbolo a ser trocado e expressao é qualquer expressão.
certas modificações nele, baseado em ● O pré-compilador substitui todas as ocorrências de nome no #define VERDADEIRO 1
#define FALSO 0
instruções chamadas diretivas. codigo fonte pela expressao fornecida.
● Não uitlize ponto-e-virgula no comando #define. Se for
utilizado, o pre-compilador incluira o pornto-e-virgula na
● Isto faz com que o compilador substitua por 1 ou 0 toda vez que
● É executado automaticamente antes da substituição. encontrar VERDADEIRO ou FALSO no seu arquivo fonte. Por
exemplo, a instrução abaixo mostra 0, 1 e 2 na tela:
compilação. ● O comando pode continuar em mais de uma linha utilizando-se
a barra invertida (\) para indicar a continuação na linha de baixo.
printf((“%d %d %d”, FALSE, TRUE, TRUE + 1);
#define tx 1.25
● No exemplo acima definimos tx como 1.25. isto significa que
● Qual a saída produzida pela instrução em destaque abaixo:
em todas as ocorrências do programa, tx sera trocada por 1.25. #define MSG "Mensagem Padrão !!!!!"
...
printf(MSG);
A Diretiva #define com argumentos (macro) Exercícios Matrizes
Uma diretiva #define com argumentos é chamada de macro.
● Quais as saídas do programa abaixo:
● ● Matrizes (vetores = variáveis indexadas = array)
● Macro é semelhante a uma função. ● É uma coleção de variáveis do mesmo tipo que é
/* macro.cpp */
● Sintaxe: #define nome(arg1,arg2,...) expressão #define abs1(a) (a)<0 ? -(a) : (a) referenciada por um nome comum.
● Exemplo:
#define abs2(a) a<0 ? -a : a ● Um elemento específico da matriz é acessado por
#include <stdio.h>
#include <conio.h>
meio de um índice.
/* macropegaproximo.cpp */ ● Uma matriz ocupa posições contíguas da memória. O
#define pega_proximo(x) x+1
#include <stdio.h> main(){
endereço mais baixo corresponde ao primeiro
#include <conio.h> printf("Valor absoluto de -1 = %d", abs1(-1)); elemento e mais alto ao último.
main(){
printf("\nValor absoluto de 1 = %d", abs1(1)); ● Em C, toda matriz tem 0 como o índice do seu primeiro
printf("\nValor absoluto de 10-20 = %d", abs1(10-20)); elemento.
printf("\nProximo no. após 1 = %d", pega_proximo(1));
printf("\nValor absoluto de -1 = %d", abs2(-1));
getch();
printf("\nValor absoluto de 1 = %d", abs2(1));
● Matrizes podem ter uma ou várias dimensões.
}
printf("\nValor absoluto de 10-20 = %d", abs2(10-20));

Exercícios: Codificar um programa para calcular a area de um getch();
circulo. Utilize a diretiva #define para guardar o valor de PI e }
para o cálculo da área. (diretivadefine.cpp)

Declaração de Matriz Unidimensional Exercícios Limites da Matriz


● Sintaxe: tipo nome-variável[tamanho] ● Preencher uma matriz de 10 elementos inteiros de ● A linguagem C não realiza verificação de limites em
● Exemplo: double a[7]; forma que cada elemento receba o dobro da posição matrizes. Se durante uma operação o limite for
● No exemplo acima é declarada um matriz de nome a correspondente. transposto, acarretará resultados imprevisíveis e
com 7 elementos do tipo double. nenhuma mensagem de erro do compilador avisará o
/* preenchematrizdobro.cpp */ que está ocorrendo. O programador tem a
#define MAX 10
#include <stdio.h> responsabilidade de providenciar a verificação dos
#include <conio.h> limites.
main(){
int n[MAX];
for (int i=0; i < MAX; i++){
n[i]=i*i;
}
for (int i=0; i < MAX; i++){
printf("\n%d",n[i]);
}
getch();
}
Strings Funções de Manipulação de Strings Exercícios
● strcpy(s1,s2): copia s2 em s1.
● Em C não existe o tipo string. ● strcat(s1,s2): concatena s2 ao final de s1. ● Se você rodar o programa abaixo e digitar as strings
● Em C uma string é definida como uma matriz de ● strlen(s1): retorna o tamanho de s1. “alo” e “alo”, qual será a saída produzida?
caracteres que é terminada com um nulo (\0). Por esta ● strcmp(s1,s2): retorna 0 se s1=s2, numero negativo se
/* funcoesparastring.cpp */
razão, você precisa declarar matrizes de caracteres se s1<s2 e numero positivo se s1>s2. #include <stdio.h>

como sendo um caractere mais longo que a maior ● strchr(s1,ch): retorna um ponteiro para a 1a. #include <string.h>
#include <conio.h>
string que elas devem guardar. ocorrência de ch em s1. main(){
char s1[80], s2[80];
● Você não precisa adicionar o nulo no final das ● strstr(s1,s2) retorna um ponteiro para a 1a. gets(s1);
gets(s2);
constantes string manualmente. O compilador C faz ocorrência de s2 em s1. printf("comprimentos: %d %d\n", strlen(s1), strlen(s2));
if (!strcmp(s1,s2)){
isso por você automaticamente.Por exemplo: para printf("As strings são iguais\n");
guardar uma string de 10 caracteres, devemos ● Necessitam da instrução: #include <string.h> }
strcat(s1,s2);
escrever: char str[11]; printf("%s\n",s1);
strcpy(s1,"Isso e um teste.\n");
● Com isso reservamos espaço para o nulo no final da printf(s1);
if (strchr("alo",'o')){printf("o esta em alo\n");}
string. if (strstr("alo aqui","alo")){printf("alo encontrado\n");}
● Embora C não tenha o tipo de dado string, ela permite }
getch();

constantes de strings. Exemplo: “ctu”

Exercícios Exercícios Matrizes Bidimensionais


/* funcoesparastring.cpp */
#include <stdio.h>
#include <string.h>
● Codificar um programa capaz de verificar se duas strings ● C suporta matrizes multidimensionais.
#include <conio.h>
main(){
são iguais. (comparastrings.cpp) ● A forma mais simples de matriz multidimensional é a
char s1[80], s2[80];
gets(s1);
matriz bidimensional (uma matriz de matrizes
gets(s2);
● Faça um programa que obtenha um número do unidimensionais)
printf("comprimentos: %d %d\n", strlen(s1), strlen(s2)); teclado e mostre na tela os números ● Declaração: int notas [45] [4];
if (!strcmp(s1,s2)){
printf("As strings são iguais\n"); compreendidos entre ele (inclusive) e zero
} (exclusive), conforme exemplo abaixo ●
Para acessar a 31o Linha (ou linha de número 30) e
strcat(s1,s2);
printf("%s\n",s1); (imprimetrianguloretangulo.cpp): 3o coluna (ou coluna de número 2): notas[30][2];
strcpy(s1,"Isso e um teste.\n");
printf(s1);
if (strchr("alo",'o')){printf("o esta em alo\n");} Número: 8
if (strstr("alo aqui","alo")){printf("alo encontrado\n");} 8, 7, 6, 5, 4, 3, 2, 1
getch(); 7, 6, 5, 4, 3, 2, 1
} 6, 5, 4, 3, 2, 1
respostas:
● Comprimetos: 33
5, 4, 3, 2, 1
● As string são iguais 4, 3, 2, 1
● aloalo 3, 2, 1
● Ísso é um teste 2, 1
● o está em alo
● alo encontrado
1

Matrizes de Strings Inicialização de Matrizes Inicializando uma Matriz Multidimensional

C permite inicializarmos uma matriz no momento da
● Usa-se uma matriz bidimensional de caracteres. declaração. int quadrados[10][2] = {
O tamanho do índice esquerdo indica o número de 1,1,
● ● Exemplo: int i[10]={1,2,3,4,5,6,7,8,9,10} 2,4,
strings. ● Isto siginifica que i[0] terá o valor 1 e i[9] terá o valor 3,9,
● O tamanho do índice direito especifica o comprimento 10. 4,16,
máximo de cada string. ● Matrizes de caracteres que contêm strings permitem uma 5,25,
● Declaração de uma matriz de 30 strings, cada qual inicialização abreviada: 6,36,
com um comprimento máximo de 79 caracteres: char char str[30] = “Colegio Tecnico Universitario”; 7,49,

Isso é o mesmo que: 8,64,
str [30][80]; 9,81,
Char str[30] = {'C','o','l','e',...,'o','\0'};
● Para acessar uma string individual da matriz anterior, 10,100

Lembre-se de adicionar o terminador nulo. Só quando se
específicamos apenas o índice esquerdo: a instrução };
trata de constante string é que o compilador insere o
gets(str[2]) acessa a terceira string. terminador nulo automaticamente. Por isso que
● Para acessar um caractere de uma string individual da dimensionamos a matriz str com tamanho 30 apesar de
matriz anterior, específicamos da seguinte forma: a Colegio Tecnico Universitario só possuir 29 caracteres.
instrução printf(“%c”,str[2][5]) mostra o sexto
caractere da terceira string.

Matriz Não Dimensionada Matriz Não Dimensionada Capacidade e Tamanho de Variáveis


● Se, em um comando de inicialização de matriz, /* matriznaodimensionada */ ● A funcao sizeof() calcula o comprimento em bytes de um tipo de
#include <conio.h> dado. Pode receber como argumento um tipo de dado ou a própria
o tamanho da matriz não é especificado, o #include <stdio.h> variável.
compilador C cria uma matriz grande o bastante main(){ /* funcaosizeof */
para conter todos os inicializadores presentes. char str1[30] = "Colegio Tecnico Universitario"; #include <stdio.h>
char str2[] = "Colegio Tecnico Universitario"; #include <string.h>
Isto é chamado de matriz não-dimensionada. printf("\nTamanho de str1 (%s) e %d",str1,sizeof(str1)); #include <conio.h>
printf("\nTamanho de str2 (%s) e %d",str2,sizeof(str2)); main(){
getch(); char mat1[10];
} char mat2[] = "Colegio Tecnico Universitario";
printf("mat1 tem capacidade = %d\n",sizeof(mat1));
● As saídas do programa acima serão: printf("mat2 tem capacidade = %d\n",sizeof(mat2));
printf("mat2 tem tamanho = %d\n",strlen(mat2));
● Tamanho de str1 e 30 getch();
}
● Tamanho de str2 e 30
● Saídas: mat1 tem capacidade = 10 / mat2 tem capacidade = 30
mat2 tem tamanho = 29
Capacidade dos Tipos Básicos Exercícios Ponteiros
● Um ponteiro é uma variável que contém um endereço de memória.
/* tamanhodostipos.cpp */
● Este endereço é a posição de outra variável na memória.
● Codificar um programa para ler um nome (máximo de 50 caracteres) e ● Se uma variável contém o endereço de uma outra, dizemos que a primeira
#include <stdio.h>
#include <string.h>
abreviar os nomes do meio. Exemplo: Joaquim José da Silva Xavier, ficaria aponta para a segunda.
#include <conio.h> Joaquim J. d. S. Xavier. (abrevianomes.cpp)
main(){ Endereço Conteúdo
char c; ● Codificar um programa que faça a reserva de lugares em um teatro sendo
int i; na Memória
float f;
que: 1000 1003
double d; – O teatro tem 10 fileiras de cadeiras (A, B, C, ... J), cada uma com 50 cadeiras.
– Os lugares são identificados com uma letra (coluna) e um número (fila). Exemplo: 1001
char matc[10][20];
int mati1[10]; A-4, B-23, etc. 1002
int mati2[10][20]; – O programa deverá solicitar do usuário qual lugar ele deseja ocupar. 1003
printf("c tem comprimento de %d\n",sizeof(c)); – Caso o lugar indicado não esteja vago, o programa deverá avisar ao usuário para
printf("i tem comprimento de %d\n",sizeof(i)); que escolha um novo lugar. 1004
printf("f tem comprimento de %d\n",sizeof(f)); – Caso o lugar indicado esteja vago, este deverá ser reservado ao usuário. 1005
printf("d tem comprimento de %d\n",sizeof(d));
– Sempre que uma dada fileira (1a., 2a., 3a., etc) estiver totalmente ocupada, o 1006
printf("matc tem comprimento de %d\n",sizeof(matc));
printf("mati1 tem comprimento de %d\n",sizeof(mati1)); programa deverá informar ao usuário antes que ele efetue a escolha.
– Ao final de cada reserva o programa deverá indicar o total de lugares ocupados e
printf("mati2 tem comprimento de %d\n",sizeof(mati2)); ● Declaração: tipo_base *nome;
printf("Todo int possui comprimento de %d\n",sizeof(int)); o total de lugares vagos.
getch(); – O programa finalizará se:
● Onde tipo_base é qualquer tipo válido em C e nome é o nome da
} ● O usuário teclar Esc variável ponteiro.
● ● Não existir mais lugares vagos ● O tipo_base define que tipo de variáveis o ponteiro pode apontar.
(reservalugar.cpp) ● Exemplo: int *p //p aponta para um inteiro

Operadores de Ponteiros Exercícios Exercícios


● & devolve o endereço na memoria da variável que o segue. ● Qual a saída produzida pelo trecho de código abaixo: ● Qual a saída produzida pelo trecho abaixo?
● * devolve o valor da variável localizada no endereço que o segue

● Para entender melhor: suponha que a variavel contador usa a posicao de int destino, fonte, *m; int x, *p1, *p2;
memoria 2000 para armazenar seu valor. Tambem assuma que contador fonte = 10; x = 10;
tem o valor 100. m = &fonte; p1 = &x;
destino = *m; p2 = p1;
int *m; /* m e um ponteiro para o tipo int */
m = &contador; /* m recebe o endereco de contador */ printf(“%d”, destino); printf("%d", p2);
q = *m /* q recebe o valor que esta no endereco de m */
● Resposta: mostra o endereço de x, não seu valor
● 1a. instrucao: A variavel m não é do tipo int, mas aponta para um valor do
tipo int.
● Após a 2a. Instrução m terá o valor 2000.
● Após a 3a. Instrução q terá o valor 100.
Exercícios Problemas com Ponteiros – Parte 1 Problemas com Ponteiros – Parte 2

Quais as saídas produzidas pelo programa abaixo? ● Analise o código abaixo: ● Analise o código abaixo:

ponteiro2.cpp main(){ main(){


#include <stdio.h> int x, *p; int x, *p;
#include <conio.h> x = 10; x = 10;
*p=x; //o certo seria p = &x p=x;
main(){ } printf(“%d”,*p);
int a=1, b=2; }
int *pa, *pb; ● O problema do código acima é que estamos atribuindo o valor da
printf("a=%d b=%d\n",a,b); variável x para alguma posição da memória desconhecida. ● A instrução printf() não imprime o valor de x, que é 10. Imprime
pa=&a; Desconhecida porque p nunca recebeu um valor. algum valor desconhecido porque a instrução em destaque está
pb=&b; ● Quando o seu programa é pequeno a probalidade deste endereço ser errada. O certo seria: p=&x;
*pa+=5; seguro, ou seja, que não esteja sendo utilizado, é grande. Contudo,
*pb+=5; quando o seu programa cresce, a probalidade de p apontar para algo
printf("a=%d b=%d\n",a,b);
getch(); vital aumenta e seu programa pode parar de funcionar.
}
● Solução: ter certeza de que um ponteiro está apontando para algo
válido antes de usá-lo.

Aritmética de Ponteiros Aritmética de Ponteiros Aritmética de Ponteiros


● Existem apenas duas operações aritméticas que podem ser utilizadas com ● Existem apenas duas operações aritméticas que podem ser utilizadas com ● Vejamos uma comparação entre um ponteiro para int e outro para char.
ponteiros: adição e subtração. ponteiros: adição e subtração.
char *c = 3000;
(I) a = 100; (I) a = 100; int *i = 3000;
int *p; int *p;
p=&a p=&a;
(II) p++; Efeito da Efeito da Efeito da (II) p++;
Instrução Instrução Instrução
(III) p=p+10 I II III
(III) p=p+10
Endereço Valor p p p
● Cada vez que um ponteiro é incrementado, ele aponta para a posição de na
memória do próximo elemento de seu tipo base. O mesmo raciocínio quando Memória
decrementado. 2000 100
2001
● Vamos analisar as instruções I, II e III: 2002
● (I) Vamos imaginar que p passe a apontar para o endereço 2000.
2003
● (II) Partindo do princípio que cada elemento do tipo int ocupa 2 bytes, o
...
próximo elemento do tipo int está na posição 2002, então p passa a
2022
conter 2002 e não 2001.
● (III) Estando p apontando para a posição 2002, ao incremetar 10, p 2023
passa a conter 2022.
Exercicios Comparação de Ponteiros Ponteiros e Matrizes
● Supondo que a variável a ocupará o endereço 2293572 e que o tipo int ● Cuidado! O conteúdo das variáveis abaixo são endereços de ●
Em C, o nome de uma matriz sem índice retorna o
ocupa 4 bytes, quais as saídas produzidas pelo trecho abaixo: memória.
endereço inicial da matriz, que é o primeiro elemento. No
/* ponteiro3.cpp */ /* comparaponteiros*\ trecho de código abaixo, p recebe o endereço do 1o.
#include <stdio.h> #include <stdio.h> elemento da matriz frase.
#include <conio.h>
#include <conio.h>
main(){ char frase[80], *p;
int a=10,*pa;
main(){ p = frase;
pa=&a; int a,b,*p,*q;
printf("pa=%d\n",pa); a=10; P
printf("&a=%d\n",&a); b=10;
printf("*pa=%d\n",*pa); p=&a;
pa++; q=&b;
a++; if (p==q) { frase
printf("\npa=%d\n",pa); printf("Valores iguais.\n"); 0
printf("&a=%d\n",&a); }else{ 1
printf("a=%d\n",a); printf("valores diferentes.\n"); ...
pa=pa+10; } 79
printf("\npa=%d\n",pa);
getch();
getch();
} }

Diferentes Formas de Acessar uma Matriz Diferentes Formas de Acessar uma Matriz Diferentes Formas de Acessar uma Matriz
● C fornece dois métodos para acessar os elementos de matrizes: /* ponteiro1.cpp */ /*
#include <stdio.h> p receberá o endereço do 1o. elemento, então *(p)
indexação de matrizes. #include <conio.h> faz referência ao conteúdo deste endereço.
aritmética de ponteiros. */
main(){ int *p=mat;
● Para acessarmos o 5o. elemento da matriz frase do exemplo int mat[]={10, 20, 30,40,50}; for (int i=0; i < 5; i++){
anterior usamos uma das formas abaixo: printf("%d\n",*(p+i));
/* }
frase[4] Se o nome da matriz sozinho é um ponteiro para o getch();
*(p+4) frase 1o. elemento, então *(mat) faz referência ao
*(frase + 4) 0 conteúdo deste endereço. /*
p[4] 1 */ forma tradicional de se referenciar a um matriz.
2 for (int i=0; i < 5; i++){ */
3 printf("%d\n",*(mat+i)); for (int i=0; i < 5; i++){
4 } printf("%d\n",mat[i]);
... getch(); }
79 getch();
Diferentes Formas de Acessar uma Matriz Exercícios Matrizes de Ponteiros
/* ● Codificar um programa que gere a seguinte matriz: “colegio tecnico ●
Ponteiros podem ser organizados em matrizes como
Em C qualquer ponteiro pode ser indexado como se universitario”. O programa deverá ter duas funções: uma que mostre
fosse uma matriz.
qualquer outro tipo de dado.
todos os elementos da matriz (um de cada vez) utilizando o método
*/ de indexação de matrizes e outra que utiliza aritmética de ponteiros.
● A declaração de uma matriz de 10 ponteiros int: int
for (int i=0; i < 5; i++){ acessavetor.cpp *x[10];
printf("%d\n",p[i]); ● Para atribuir o endereço de uma variável int, chamada
}
getch();
Dica: putchar(): mostra um caractere. num, ao 5o. elemento da matriz de ponteiros: x[4]=&num;
} ● Para acessar a mesma posição seria: *x[4]

Matrizes de Ponteiros Funções Funções


/* matrizponteiro.cpp */
#include <stdio.h>
● Permitem dividir um programa grande em pequenas ● Sintaxe da Função:
#include <conio.h>
#include <string.h> partes.
main(){ ● Pemitem utilizar partes de programas desenvolvidas tipo nome_funcao(argumentos){
static char *lista[] = {
"Monica", por outras pessoas, sem que se tenha acesso ao declaração de variáveis
"Caroline",
"Paulo", código-fonte. Um exemplo: você até agora utilizou a comandos
"Michelle",
"Wanda" função printf() sem conhecer detalhes de sua }
};
char nome[20]; programação.
printf("Digite um nome: "); ● Devemos utilizar diversas pequenas funções, ao invés ● Onde:
gets(nome);
int achou=0; de poucas e grandes funções. – tipo determina o tipo do valor de retorno (se
for (int i=0; i < 5; i++){
if (strcmp(lista[i],nome) == 0){ ● Vantagens: omitido, é assumido int).
achou = 1; – nome representa o nome pelo qual a função será
} – Reaproveitamento de código.
}
printf("%s\n",lista[i]);
– Facilita encontrar erros. chamada (invocada).
if (!achou){ – Trabalho em equipe. – argumentos são informações externas transmitidas
printf("Nome nao cadastrado!!!");
}else{ para a função (opcional)
printf("Nome presente na lista");
}
getch();
}
Invocando (Chamando) uma Função Invocando (Chamando) uma Função Ordem das Funções em um Programa
/* funcao.cpp */
#include <stdio.h>
● Todo programa em C é composto de funções. A #include <conio.h> ● Você reparou que no programa anterior as funções
execução é iniciada pela função main(). int soma; foram declaradas primeiro e que só após a função
void total(int x);
void mostra();
main() é que aparece suas implementações. Se você
● Para executar uma função, ela deve ser chamada no int triplo(int r); colocar as implementações das funções antes da
corpo de uma outra função, exceto a função main(), main(){ função main() não será necessário declará-las.
int cont;
que é executada ao iniciar o programa. for (cont=0; cont < 10; cont++){
total(cont);
mostra();
printf("O triplo de %d e %d\n", cont, triplo(cont));
printf("\n", cont, triplo(cont));
}
getch();
}

void total(int x){


soma+=x;
}
void mostra(){
printf("Soma atual: %d\n",soma);
}
int triplo(int r){
return r*r*r;
}

Argumentos de uma Função Argumentos para main() Argumentos para main()


● São utilizados para transmitir informações para a função. ● Para passar informações para um programa ao executá-lo utilizamos ● O primeiro parâmetro (argc) é um inteiro que contém o número de
● Se uma função usa argumentos, ela deve declarar variáveis que aceitem os argumento de linha de comando. parâmetros da linha de comandos. Ele é sempre pelo menos 1,
valores dos argumentos. Estas variáveis são chamadas de parâmetros ● Argumento de linha de comando é a informação que segue o nome do porque o nome do programa será o primeiro argumento.
formais. programa na linha de comando do sistema operacional. ● O segundo argumento (argv) é um ponteiro para uma matriz de
● Os parâmetros formais se comportam como quaisquer outras variáveis locais ● Para executar o programa abaixo digitamos: argumentosparamain Jose
dentro da função. ponteiros para caractere. Cada elemento nessa matriz aponta para
seguindo de enter.
● Uma função pode receber qualquer número de argumentos, inclusive um argumento da linha de comando. argv[0] aponta para a
nenhum. No caso de uma função sem argumentos pode-se escrevê-la de /* argumentosparamain.cpp */ primeira string, que é sempre o nome do programa, argv[1] aponta
duas formas: deixando a lista de argumentos vazia (mantendo-se entretanto #include <stdio.h> para o primeiro argumento e assim por adiante.
os parênteses) ou colocando o tipo void entre parênteses. #include <stdlib.h> ● Os nomes dos argumentos (argv e argc), são arbitrários mas
#include <conio.h>
tradicionais.
int triplo(int r){
return r*r*r; main(int argc, char *argv[]){
if (argc !=2){ main(int argc, char *argv[]){
} if (argc !=2){
printf("Voce esqueceu de informar o nome.\n");
getch(); printf("Voce esqueceu de informar o nome.\n");
void mostra(){ //ou void mostra(void) getch();
printf("Soma atual: %d\n",soma); exit(1);
} exit(1);
} }
printf("Ola %s",argv[1]);
getch(); printf("Ola %s",argv[1]);
} getch();
}
Valor de Retorno Passando Argumentos por Valor Passando Argumentos por Valor
● É o valor que uma função retorna para a função que a chamou. O tipo de
retorno é fornecido no cabeçalho da função antes de seu nome. ● Copia o valor de um argumento no /* porvalor.cpp */
#include <stdio.h>
int triplo(int r){ parâmetro formal da função. #include <conio.h>
return r*r*r;
} ● Assim alterações no parâmetro formal da int quadrado(int x);
● O comando return faz com seja retornado o valor especificado e faz com função não tem nenhum efeito nos
com a função termine.
argumentos usados na chamada da main(){
● Se uma funcao não retorna nada, seu tipo de retorno deve ser definido como
int t=10;
void. função. printf("%d %d", quadrado(t), t);
void mostra(){ getch();
printf("Soma atual: %d\n",soma);
} }
● O comando return pode ser utilizado numa função com tipo de retorno void.
Neste caso, o comando nao deve retornar nenhum valor: return void. int quadrado(int x){
● O comando return pode ser utilizado também para indicar a saída imediata x = x * x;
da função, basta colacarmos o comando return sozinho.
● Se o tipo de retorno da função não é explicitamente declarado, o compilador return x;
C atribui automaticamente o tipo padrão, que é int. }

Passando Argumentos por Referência Passando Argumentos por Referência Exercícios


● O endereço de um argumento é copiado no /* porreferencia.cpp */ ● Codificar uma função que recebendo um ponteiro para
#include <stdio.h> uma frase retorne o tamanho (quantidade de
parâmetro formal da função. #include <conio.h>
● Dentro da função o endereço é usado para void troca(int *x, int *y);
caracteres) da frase. ponteirotamanhofrase.cpp
acessar o argumento real utilizado na chamada main(){
int a=10;
da função. int b=20;
● Isto significa que alterações feitas nos troca(&a,&b);
parâmetros formais afetam os argumentos printf("%d %d", a,b);
getch();
usados na chamada da função. }
void troca(int *x,int *y){
int temp;
temp=*x;
*x=*y;
*y=temp;
}
Locais de Declaração de Variáveis Matrizes como Argumento para uma Função Matrizes como Argumento para uma Função
● Existem 3 lugares em um programa em C onde as variáveis podem ser ● Em C, quando uma matriz é usada como um argumento para uma função, /* varrematrizcomaritmeticadeponteiros.cpp */
apenas o endereço da matriz é passado, não uma cópia da matriz inteira. #include <stdio.h>
declaradas: #include <conio.h>
● Quando você chama uma função com um nome de matriz como argumento,
Fora de todas as funções, inclusive a função main(). A variável assim um ponteiro para o primeiro elemento da matriz é passado para a função. int numeros[5];
declarada é chamada de variável global e pode ser usada em qualquer int i[10]; void mostra(int *p){
parte do programa. Uma variável global é criada quando o programa func1(i); for (int i=0; i<5; i++){
inicia e é destruída quando o programa é finalizado. printf("\n%d",*(p++)); // ou printf("\n%d",p[i])
● Podemos declarar o parâmetro formal de três formas: }
Dentro de uma função. A variável assim declarada é chamada de }
variável local e só pode ser usada dentro desta função. Uma variável 1. void func1(int *x) como um ponteiro
2. void func1(int x[10]) como uma matriz dimensionada main(void){
local é criada quando a função é invocada e destruída quando a função 3. void func1(int x[]) como uma matriz não dimensionada for(int i=0;i<5;i++){
é finalizada. numeros[i]=i*10;
}
● Podemos verificar que o comprimento da matriz não importa para a função, mostra(numeros);
Na lista de parâmetros formais de uma função, para receber os porque C não realiza verificação de limites. Portanto void func1(int getch();
argumentos que são passados para a função. Variável declarada como x[30]) também funcionaria, porque o compilador C instrui func1 a receber }
parâmetro formal de uma função é criada quando a função é invocada e um ponteiro, ele não cria realmente uma matriz de 10 ou de 30 elementos.
destruída quando a função é finalizada.

Matrizes como Argumento para uma Função Função Retornando Ponteiro Exercícios
● Quando uma matriz bidimensional é usada como argumento para uma ● Indicamos que uma função retornará um ponteiro ● Codificar um programa que implemente o jogo da forca.
função, apenas um ponteiro para o primeiro elemento é realmente passado.
Porém, uma função que recebe uma matriz bidimensional como parâmetro, inserindo um * antes do nome da função. jogoforca.cpp
deve definir pelo menos o comprimento da 2a. Dimensão. Isto ocorre porque
o compilador C precisa saber o comprimento de cada linha para indexar a int *func(); ● Codificar uma função para receber um caractere como
matriz corretamente.
argumento e, se for uma letra minúscula, retorne-a em
● Exemplo: Uma função que recebe uma matriz bidimensional de inteiros 10 x ● Exercício: Codificar uma função que devolve um maiúscula, caso contrário retorne o próprio caractere.
10 é declarada desta forma: void func (int x[ ] [10]);
ponteiro para a primeira ocorrência de um caracter em funcaomaiuscula.cpp
● É importante entender que, quando uma matriz é usada como um argumento uma string. Mostrar este caractere e todos apartir dele.
para uma função, seu endereço é passado para a função. Portanto existe a
● Codificar um programa que solicite a digitação de 10
possibilidade do conteúdo original da matriz ser alterado.
retornandoponteiro.cpp números e os coloque em uma matriz. Chame uma função
que ordene os valores da lista e mostre os valores
● Você pode gerar um ponteiro para o primeiro elemento de uma matriz
simplesmente especificando o nome da matriz, sem nenhum índice. ordenados. ordenavetor.cpp
int *p;
int teste[10];
p = teste /* p recebe o endereço do 1o. elemento de teste. */
Exercícios Funções Recursivas Funções Recursivas
● Codificar um programa para jogar o jogo da velha. Para o jogo da velha é utilizado uma grade de ● Recursão é o processo de definir algo em termos de si mesmo.
três linhas por três colunas. Os jogadores se alternam nas jogadas e marcam sucessivamente int fatr(int n){
uma posição livre a cada jogada. Um jogador usa como marca um O e o outro um X. Vence o ● A função é recursiva se um comando no corpo da função a
jogo quem conseguir preencher em primeiro lugar uma linha, uma coluna ou uma das diagonais chama. int x;
da grade com a sua marca. O jogo acaba empatado se todos as posições tiverem sido
preenchidas e nenhum dos dois jogadores chegou a satisfazer a condição de vitória. /* fatorial.cpp */
if (n==1){
jogodavelha.cpp #include <stdio.h> return(1);
#include <conio.h>
apresente as instruções do jogo int numero; }
sorteie o jogador que inicia o jogo (jogador O ou jogador X)
enquanto não houver vencedor E existir posição desocupada faça
int fat(int n); x=fatr(n-1)*n;
int fatr(int n);
apresente a grade do jogo para mostrar posições ocupadas e desocupadas return(x);
posiçãoNãoVálida <- verdadeiro main(){
repita printf("\nNumero:");
}
leia a localização da posição selecionada pelo jogador de quem for a vez scanf("%d",&numero);
se posição inválida OU posição já ocupada printf("\nFatorial: %d",fat(numero));
então printf("\nFatorial: %d",fatr(numero));
apresente "Posição inaceitável - Selecione outra: " getch();
senão }
posiçãoNãoVálida <- falso
fim-se int fat(int n){
enquanto posiçãoNãoVálida int x=1;
coloque na posição selecionada da grade a marca apropriada for (int i=1; i<=n; i++){
passe a vez para o outro jogador x=x*i;
fim-enquanto }
apresente o vencedor se existir return(x);
}

Alocação Dinâmica de Memória Alocação Dinâmica de Memória Alocação Dinâmica de Memória



É o meio pelo qual um programa pode obter memória
enquanto está em execução. ●
O trecho abaixo aloca 1000 bytes de memória: ● Sempre que alocarmos memória devemos testar
● A função que aloca memória: malloc() se o valor devolvido por malloc()não é nulo:

Cada vez que é feita uma solicitação de memória por char *p;
malloc(), uma porção da memória livre restante é p = malloc(1000) //p apontará p/ o 1o. dos 1000 bytes
alocada. p = malloc(1000)
● A função malloc() devolve um ponteiro do tipo void, if (p == NULL){
o que significa que você pode atribuí-lo a qualquer tipo printf(“Sem memória.”);
de ponteiro (desde que faça o casting corretamente).

O trecho abaixo aloca espaço para 50 inteiros:
...
● Após uma chamada bem sucedida, malloc() devolve
int *p; }
um ponteiro para o primeiro byte da região de memória
alocada. Se não há memória disponível para satisfazer p = malloc(50 * sizeof(int))
a requisição de malloc(), ocorre uma falha de
alocação e malloc() devolve um nulo.
Alocação Dinâmica de Memória Alocação Dinâmica de Memória Estruturas (struct)
● É uma coleção de variáveis referenciadas por
● A função free() libera memória previamente ● Exercício: Codificar um programa para alocar um único nome, permitindo agrupar
alocada ao sistema espaço para uma string (80 caracteres) informações relacionadas.
dinâmicamente, solicitar a entrada do usuário e,
int *p; em seguida, imprimir a string de trás para frente. ● A definição de uma estrutura forma um modelo
p = malloc(500) ; matrizalocadadinamicamente.cpp que pode ser usado para criar variáveis de
free(p); estruturas.
1)Alocar memória
● Ao usar estas funções inclua: stdlib.h 2)Verificar se foi bem sucedida a operação ●
As variáveis que compreendem a estrutura são
3)Solicitar a string chamadas membros da estrutura (ou elementos
4)Mostrar a string de trás para frente ou campos).
5)Liberar memória

Estruturas (struct) Estruturas (struct) Estruturas (struct)


● Definição de uma estrutura: ● Referenciando Elementos de Estruturas atribuicaoestruturas.cpp
#include <stdio.h>
struct dados{ #include <conio.h>
char nome[30]; nome_da_estrutura .nome_do_elemento main(){ Toda informação contida
char curso[20];
char turma; struct { em uma estrutura pode
int a; ser atribuída a outra
double nota; ●
Exemplos: int b;
}; estrutura do mesmo
}x,y; tipo.
printf(“%s”, aluno.nome);
● O trecho de código anterior, não declarou nenhuma gets(aluno.nome); x.a=10;
variável, apenas definiu a forma dos dados. Para aluno.nota = 100; y=x;
declarar uma variável de nome aluno do tipo dados, printf("%d",y.a);
escreva: getch();
}
struct dados aluno;
Estruturas (struct) Exercícios: exemplo de uso de matriz de estruturas Estruturas (struct)

Matrizes de Estruturas: Para declarar uma matriz de matrizestrutura.cpp ● Exercício: Codificar um programa que mostre as horas,
estruturas, você deve primeiro definir uma estrutura e, #define MAX 3 minutos e segundos na tela como se fosse um relógio
então, declarar uma variável matriz desse tipo. #include <stdio.h> Atenção digital. O programa deverá mostrar a hora no seguinte
#include <conio.h> p[i].nome formato: hh:mm:ss. relogio.cpp
struct dados{ struct dados{
p->nome
char nome[30];
char nome[30]; float nota;
char curso[20]; }; O operador -> é usado
char turma; struct dados alunos[MAX]; no lugar do operador
double nota; void inclui(struct dados *p); ponto quando se está
}; void mostra(struct dados *p); acessando um
main(){ elemento de estrutura
struct dados alunos[100] inclui(alunos); por meio de um
mostra(alunos); ponteiro para a
getch(); estrutura.
}

Vous aimerez peut-être aussi