Aula 2 - Linguagem C -...
Transcript of Aula 2 - Linguagem C -...
Estrutura de Dados:Aula 2 - Linguagem C
Tipos Básicos
Operadores de Incremento e Decremento
● ++ e –– Incrementa ou decrementa o valor de uma variável de uma
unidade
– O incremento/decremento pode ser antes ou depois da variável ser usada
● N++, incrementa n depois de ser usado● ++N, incrementa n antes de ser usado
Operador Sizeof
● Retorna o número de bytes ocupado por um determinado tipo– int a = sizeof (float);
– Armazena 4 na variável a pois um float ocupa 4 bytes de memória
● Também pode ser usado em uma variável, retornando o número de bytes ocupado por esta variável
Conversão de tipo
● Ou “Type Casting”
– Conversão é feita automaticamente pelo C na avaliação de expressões
– Pode ser requisitado explicitamente pelo programador
Entrada e saída● São feitas com uso de funções
● Função printf
– printf (formato, lista de constantes/variáveis/expr...);
Entrada e saída
● printf ("Inteiro = %d Real = %g", 33, 5.3);
● com saída:– Inteiro = 33 Real = 5.3
● Caracteres de escape
Entrada e saída
● Especificação do tamanho do campo
Entrada e saída
● scanf (formato, lista de endereços das variáveis...)
– int n;
– scanf ("%d", &n);
Funções
● Comando de definição de uma função
Tipo_retorno nome_funcao (lista de parametros)
{
Corpo da função
}
Funções
● Definição
#include<stdio.h>
Int fat (int n);
Int main(void){
printf(“Digite um número não negativo”);
Scanf(“%d”,&n);
r=fat(n);
printf(“Fatorial =%d/n”,r);
Return 0;
}
int fat (int n) {
int i;
int f=1;
for(i=; i<=n;n++)
f*=i;
return f;
}
Pilha de Execução
● Variáveis locais têm escopo local● Funções são independentes entre si● Transferência de dados entre funções através de
– Passagem de parâmetros– Valor de retorno
● Parâmetros em C são passados por valor● Pilha de Execução: Coordena comunicação entre a
função que chama e a função chamada● Permite passagem de parâmetros e valores de retorno
Esquema Representativo da Memória
Exemplo fat (5)/*imprime o fatorial de 5*/
#include<stdio.h>
int fat (int n);
int main(void){
int n=5;
int r;r = fat(n);
printf(“Fatorial de %d = %d\n”,n,r);
Return 0;
}
int fat (int n) {
int f=1;
while(n !=0){
f *=n;n--;
}
return f;
}
Pilha de execução
Ponteiro de variáveis
● Pode ser necessário comunicar mais de um valor de retorno para função que chama
● Por exemplo, uma função que deve calcular a soma e o produto de dois números
#include <stdio.h>void somaprod (int a, int b, int c, int d){ c = a + b;d = a * b;}int main (void){int s, p;somaprod (3, 5, s, p);printf (“soma = %d produto =%d\n”, s, p);return 0;}
Ponteiros
Ponteiros
● Permitem manipulação direta de endereços de memória no C
● Variáveis do tipo ponteiro
– Armazenam endereços de memória
– É possível definir um ponteiro para cada tipo do C que seja capaz de armazenar endereços de memória em que existem valores do tipo correpondente
– int a;
– int* p; // p armazena endereço de memória em que há valor inteiro
Operadores de ponteiros
● Operador & (“endereço de”)– Aplicado a variáveis, retorna o endereço da
posição de memória reservada para variável● Operador * (“conteúdo de”)
– Aplicado a ponteiros, acessa o conteúdo de memória do endereço armazenado pela variável ponteiro
Exemplo● int a; int* p; int c;
Exemplos
int main (void){
int a;
int *p;
p = &a;
*p = 2;
printf (“ %d “, a);
return;
}
Ponteiros
Documento
Memória
Ponteiro (Atalho)
Ponteiros
#include <stdio.h> int main() { int i = 10 ; int *p ; p = &i ; *p = 5 ; printf ("%d\t%d\t%p\n", i, *p, p); return 0; }
Linha i &i p *p
1 10 0022FF74
2 10 0022FF74
null null
3 10 0022FF74
0022FF74
10
4 5 0022FF74
0022FF74
5
Ponteiros
0A1 0A2 0A3 0A4 0A5 0A6
Memória
Ponteiros
0A1 0A2 0A3 0A4 0A5 0A6
X=25
*X → 25/ &X → 0A1
*Y
Y → / &Y →
*Y
Ponteiros
0A1 0A2 0A3 0A4 0A5 0A6
X=25
*X → 25/ &X → 0A1
Y=&X
*Y → 25/ &Y → 0A1
Y=&X
Ponteiros
0A1 0A2 0A3 0A4 0A5 0A6
X=5
*X → 5/ &X → 0A1
*Y=5
*Y → 5/ &Y → 0A1
*Y=5
Ponteiros
#include <stdio.h> int main() { int i = 10 ; int j=2; int a=0; int *p ; int *q; q=&j; p = &i ; *q=*p; p=&a; return 0; }
Ponteiros
#include <stdio.h> int main() { int i = 10 ; int j=2; int k=1; int *p ; p = &i ; (*p)++; p++; *p++; *p++; return 0; }
10 2 1 1000 -5 0
0A1 0A2 0A3 0A4 0A5 0A6
Memória
Ponteiros
#include <stdio.h> int main() { int i = 10 ; int j=2; int k=1; int *p ; p = &i ; q=*(p + 4); return 0; }
10 2 1 1000 -5 0
0A1 0A2 0A3 0A4 0A5 0A6
Memória
Ponteiros
int *a, *b, c = 4, d = 2;a = &c; // a apontará para cb = &d; // b apontará para d*b = 8; // altero o valor existente na variavel d*a = *b; // copio o valor de d (apontado por b)para c (apontado por a)*a = 1; // altero o valor da variável cb = a; // b aponta para o mesmo lugar que a, ou seja, para c*b = 0; // altero o valor de c
Ponteiro de estrutura
● Struct
#include <stdio.h>#include <string.h> int main() { struct aluno{ char nome[10]; int matricula; } ; struct aluno a; strcpy(a.nome,"João"); a.matricula=120251; return 0; }
Ponteiro de estrutura
● Struct#include <stdio.h> #include <string.h> struct tipo_endereco { char rua [50]; int numero; char bairro [20]; char cidade [30]; char sigla_estado [3]; long int CEP; }; struct ficha_pessoal { char nome [50]; long int telefone; struct tipo_endereco endereco; };
main (void) { struct ficha_pessoal ficha; strcpy (ficha.nome,"Luiz Osvaldo Silva"); ficha.telefone=4921234; strcpy (ficha.endereco.rua,"Rua das Flores"); ficha.endereco.numero=10; strcpy (ficha.endereco.bairro,"Cidade Velha"); strcpy (ficha.endereco.cidade,"Belo Horizonte"); strcpy (ficha.endereco.sigla_estado,"MG"); ficha.endereco.CEP=31340230; return 0; }
Ponteiro de estrutura
● int main() { struct minha_estrutura{ int i; double f; } ; struct minha_estrutura teste; teste.i=20; teste.f=15.89; return 0; }
struct minha_estrutura *p_minha_estrutura;
p_minha_estrutura-> i = 1; p_minha_estrutura-> f = 1.2;
(*p_minha_estrutura).i = 1; (*p_minha_estrutura).f = 1.2;
Ponteiro de estrutura
● #include <stdio.h>#include <string.h> int main() { struct aluno{ char nome[10]; int matricula; } ; struct aluno a; strcpy(a.nome,"João"); a.matricula=10; struct aluno b; strcpy(b.nome,"João2"); b.matricula=9; struct aluno c; strcpy(c.nome,"João3"); c.matricula=8;
struct aluno *p; p=&a; printf ("%s",(*p).nome ); printf ("-----------\n"); p++; printf ("%s",(*p).nome ); printf ("-----------\n"); return 0; }
Passando ponteiros para função
● Ponteiros permitem modificar o valor das variáveis indiretamente
● Possível solução para passagem por ref!void somaprod (int a, int b, int *p, int *q){
*p = a + b;*q = a * b;
}int main (void){
int s, p;somaprod (3, 5, &s, &p);printf (“soma = %d produto =%d\n”, s, p);return 0;
}
Exemplo
/*função troca*/#include <stdio.h>void troca(int *px, int *py){
Int temp;temp = *px;*px = *py*py = temp;
}Int main ( void ){
int a = 5, b = 7;troca (&a, &b);/*passando os endereçõs das var.*/printf(“%d %d \n”,a,b);return 0;
}
Ponteiros e vetores
●
#include <stdio.h> int main () { int i; int vetorTeste[3] = {4, 7, 1}; int *ptr = vetorTeste; printf("%d\n",*ptr);
ptr++;printf("%d\n",*ptr);ptr++;printf("%d\n",*ptr);
return 0; }
Ponteiros e vetores
● Referências
– https://pt.wikibooks.org/wiki/Programar_em_C/Ponteiros
– http://www2.dcc.ufmg.br/disciplinas/pc/source/introducao_c_renatocm_deeufmg.pdf
Vetores
● int vetor[5];
● int vetor[5] = {17, 42, 9, 33, 12};
● Abreviando as declarações
– int valores[5] = {1, 2, 3, 4, 5}; ● int valores[] = {1, 2, 3, 4, 5};
Vetores multidimensionais (matrizes)
● tipo_da_variável nome_da_variável [altura][largura];
– char str_vect [3][9] = { "Joao", "Maria", "Jose" };
–
J O A
O
M a r
i a
J o s
e
Vetores multidimensionais (matrizes)
● tipo_da_variável nome_da_variável [altura][largura];
– tipo_da_variável nome_da_variável [tam1][tam2] ... [tamN] = {lista_de_valores};
– float vect [6] = { 1.3, 4.5, 2.7, 4.1, 0.0, 100.1 };
– int matrx [3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
– char str [10] = { 'J', 'o', 'a', 'o', '\0' };
– char str [10] = "Joao";
– char str_vect [3][10] = { "Joao", "Maria", "Jose" };
– int matrx[2][4]= { { 1,2,3,4 }, { 5,6,7,8 } };
Vetores multidimensionais (matrizes)
● Exemplo da inicialização de um vetor multidimensional usando loops.
int i,j;
for (i=0; i<=2; i++){ for (j=0; j<=3; j++){ Tabela[i][j] = 0;
}}
Variáveis Globais
● Declaradas fora do escopo das funções● São visíveis a todas as funções
● Existem enquanto o programa existir (não estão na pilha de execução)
● Utilização:
– Devem ser usadas com critério
– Pode criar muita dependência entre as funções
– Dificulta o entendimento e o reuso de código
Exemplo de Variáveis Globais
Variáveis Estáticas
● Declaradas no escopo de funções● Existem enquanto o programa existir (não estão na
pilha de execução)
● Somente são visíveis dentro das funções nas quais são declaradas
● Utilização
– Quando for necessário recuperar o valor de uma variável na execução passada da função
Exemplo de variável estática● Função que imprime números reais
– Imprime um número por vez (máximo de 5 números por
linha)
Sobre variáveis estáticas e globais...
● Variáveis estáticas e globais são inicializadas com zero, quando não forem explicitamente inicializadas
● Variáveis globais estáticas
– São visíveis para todas funções subsequentes
– Não podem ser acessadas por funções de outros arquivos
● Funções estáticas
– Não podem ser acessadas por funções de outros arquivos
Pré-processador e Macros
● Código C antes de ser compilado é passado pelo pré-processador
● O Pré-processador
– Reconhece diretivas
– Altera o código e envia para o compilador● Diretiva #include
– O pré-processador substitui pelo corpo do arquivo especificado
Pré-processador e Macros
● # include “nome_do_arquivo”
– Procura o arquivo do diretório local
– Caso não encontre, procura nos diretórios de include especificados para compilação
● # include <nome_do_arquivo>– Não procura no diretório local
Pré-processador e Macros● Constantes
– #define PI 3.1415● Macros
– Definição com parâmetros
– #define MAX (a,b) ((a)>(b)?(a):(b))
– O pré-processador substituirá o trecho de código:● V = 4.5;● c = MAX (v, 3.0);
– Por:● V = 4.5;● c = ((v) > (3.0) ? (v): (3.0));
typedef
● TIPO DE DADO ABSTRATO
● typedef é comumente usado com structs
● sintaxe do typedef
– typedef tipo_existente nome_escolhido;● Exemplos de uso do typedef:
– typedef int meuInteiro;
– typedef char* String;
– typedef unsigned short int idade;
typedef
● Como usar typedef para structs
– typedef struct Alunos{ //código da struct } Aluno;
–
typedef
● Como usar typedef para structs
– typedef struct Alunos{ //código da struct } Aluno;
–
Enumerations
● Enum
– As enumerations definem um nova tipo de variável e limita desde logo os valores.
● enum colors {black, blue, green, cyan, red, purple, yellow, white};
● enum forma {quadrado=5, rectangulo,triangulo=27, circulo, elipse};
●
Enumerations
● Enum#include <stdio.h> /*Definindo o cabeçalho*/ enum cores {AZUL = 1, VERDE, BRANCO, }; /*Aqui um ponto virgula*/ /*typedef transformamos 2 palavras em uma -> tipo_cores*/ typedef enum cores tipo_cores ;
int main(void) {
tipo_cores cor = BRANCO ; if(cor == 1){printf("Cor azul \n");}
if(cor == 2){printf("Cor verde \n");}
if(cor == 3 ){printf("Cor branco \n");}return 0 ;
}
Alocação dinâmica● Vetor
– Int x[50]– Predeterminação da memória– Leva a um desperdício de memória
● A memória não usada só é devolvida no final da execução
● Alocar memória dinamicamente
– O tamanho é determinado em tempo de execução.
– O espaço reservado permanece até que seja liberado pelo programa
Alocação dinâmica
● Alocar memória dinamicamente
–
Alocação dinâmica
● Biblioteca
– stdlib ● Função
– malloc
● O parâmetro é recebido em bytes● Retorna o endereço inicial da memória alocada● Exemplo:
– int *v;– v = malloc(10*4);– Cabem 10 inteiros, cada um com 4 bytes–
Alocação dinâmica
● Função
– malloc
● int *v;● v = malloc(10*sizeof(int));
– Quando não há espaço para o alocação dinâmica a função retorna nulo.
v = (int*) malloc(10*sizeof(int));if (v==NULL){printf("Memoria insuficiente.\n");exit(1); /* aborta o programa e retorna 1 para o sist. operacional */}
Alocação dinâmica● Função malloc é usada para alocar qualquer tipo.
● v = (int *) malloc(10*sizeof(int)); ●
Alocação dinâmica
● Função free– Libera espaço de memória alocado dinamicamente
● free (v)
–
Alocação dinâmica
● Função free– Libera espaço de memória alocado dinamicamente
● free (v)
–
/* Cálculo da média e da variância de n reais */#include <stdio.h>#include <stdlib.h> int main ( void ){
int i, n;float *v;float med, var;scanf("%d", &n);/* leitura do número de valores */v = (float*) malloc(n*sizeof(float));/* alocação dinâmica */if (v==NULL) {
printf("Memoria insuficiente.\n”);return 1;
}for (i = 0; i < n; i++)/* leitura dos valores */scanf("%f", &v[i]);med = media(n,v);var = variancia(n,v,med);printf("Media = %f Variancia = %f \n", med, var);free(v);/* libera memória */return 0;
}
String
● Cadeia de caracteres
int main ( void ){
char cidade[4];cidade[0] = 'R';cidade[1] = 'i';cidade[2] = 'o';cidade[3] = '\0';printf("%s \n", cidade);return 0;
}
int main ( void ){char cidade[ ] = "Rio";printf("%s \n", cidade);return 0;}
String● Cadeia de caracteres
– Leitura
● char a;● scanf("%c", &a);
– Caracteres brancos
● char a;● scanf(" %c", %a);
– Ler String
● char cidade[81];● scanf("%s", cidade);
– Ler nomes compostos
● char cidade[81];● scanf(" %[^\n]", cidade);
– Ler nomes compostos para o tamanho do vetor
● char cidade[81];● scanf(" %80[^\n]", cidade);
String
● Funções – Biblioteca
● string.h– Tamanhho
● strlen() – Copiar
● strcpy() – Concatenar
● strcat()
String
● Funções
#include <stdlib.h>#include <string.h>char* duplica (char* s){
int n = strlen(s);char* d = (char*) malloc ((n+1)*sizeof(char));strcpy(d,s);return d;
}
Recursão● Cada instância do problema contém uma instância menor do mesmo problema.
– Problema da Torres de Hanoi
Recursão
● Problema da Torres de Hanoi
Recursão
● Série de Fibonacci
Recursão●
– Determinar o valor de um elemento máximo de um vetor v[0..n-1] . É claro que o problema só faz sentido se o vetor não é vazio, ou seja, se n ≥ 1.
int maximo (int n, int v[]) { int j, x; x = v[0]; for (j = 1; j < n; j += 1) if (x < v[j]) x = v[j]; return x;}
Recursão● Determinar o valor de um elemento máximo de um vetor v[0..n-1] . É
claro que o problema só faz sentido se o vetor não é vazio, ou seja, se n ≥ 1.
int maximoR (int n, int v[]){ if (n == 1) return v[0]; else { int x; x = maximoR (n-1, v); // x é o máximo de v[0..n-2] if (x > v[n-1]) return x; else return v[n-1]; }}
Recursão● A partir de um número inteiro, somar todos os números
existentes de 0 até ele.
– Sem recursão:#include <stdio.h> int main(){ int n,soma=0; printf("Digite um inteiro positivo: "); scanf("%d", &n); for(int i=n; i>0;i--){
soma+=i;}
printf("Soma: %d\n", soma);}
Recursão● A partir de um número inteiro, somar todos os números
existentes de 0 até ele.
– Com recursão:#include <stdio.h> int soma(int n){ if(n == 1) return 1; else return ( n + soma(n-1) );} int main(){
int n; printf("Digite um inteiro positivo: "); scanf("%d", &n); printf("Soma: %d\n", soma(n));}
Recursão● Calcular o fatorial de um número
– Sem recursão:
#include <stdio.h> int main(){ int n,soma=1; printf("Digite um inteiro positivo: "); scanf("%d", &n); for(int i=1; i<=n;i++){
soma*=i;}
printf("Soma: %d\n", soma);}
Recursão● Calcular o fatorial de um número
– Com recursão:
#include <stdio.h>int fatorial(int n){ if(n == 1) return 1; else return ( n * fatorial(n-1) );}int main(){ int n; printf("Digite um inteiro positivo: "); scanf("%d", &n); printf("%d! = %d\n", n, fatorial(n));}
Recursão● Cada instância do problema contém uma instância menor do mesmo problema.
– char v[5]=”Facol”;
void imprime_rec (char* s){
if (s[0] != '\0'){
printf("%c",s[0]);imprime_rec(&s[1]);
}}