Mudanças entre as edições de "PRG29002 - Programação I - Eng.Telecom 2017-2"
Linha 755: | Linha 755: | ||
==Tipos de dados compostos== | ==Tipos de dados compostos== | ||
− | + | {{collapse top | Estruturas}} | |
;Estruturas | ;Estruturas | ||
Linha 991: | Linha 991: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | {{collapse bottom}} | |
{{collapse top | Exercícios - C (série 5)}} | {{collapse top | Exercícios - C (série 5)}} | ||
Linha 1 052: | Linha 1 052: | ||
*Observe que ao imprimir os valores da instancia "guarda_roupas" o "descricao_generica" apesar de não ter sido formalmente preenchido, foi indiretamente preenchido quando no caso "roupeiro.cor" recebeu um valor. Como este valor foi "Cinza" o C escreveu um "\0" no final da string "roupeiro.cor" que acabou também servindo como final da string "descricao_generica", por isso neste print ambos os campos apresentam o mesmo valor. Porém observe também que os valores de "volume" e "peso" estão perfeitamente preservados. | *Observe que ao imprimir os valores da instancia "guarda_roupas" o "descricao_generica" apesar de não ter sido formalmente preenchido, foi indiretamente preenchido quando no caso "roupeiro.cor" recebeu um valor. Como este valor foi "Cinza" o C escreveu um "\0" no final da string "roupeiro.cor" que acabou também servindo como final da string "descricao_generica", por isso neste print ambos os campos apresentam o mesmo valor. Porém observe também que os valores de "volume" e "peso" estão perfeitamente preservados. | ||
*Agora foi interessante o cado da instancia "vaso_decorativo", ela foi descrita pelo campo "descricao_generica" e apenas para fins didáticos o autor imprimiu o que teria dentro de "roupeiro.cor", "roupeiro.volume" e "roupeiro.peso". Neste caso cairam valores oriundos da constante "em vidro - peça única" que não passam de sujeira neste contexto. | *Agora foi interessante o cado da instancia "vaso_decorativo", ela foi descrita pelo campo "descricao_generica" e apenas para fins didáticos o autor imprimiu o que teria dentro de "roupeiro.cor", "roupeiro.volume" e "roupeiro.peso". Neste caso cairam valores oriundos da constante "em vidro - peça única" que não passam de sujeira neste contexto. | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ==Ponteiros== | ||
+ | |||
+ | {{collapse top | Ponteiros}} | ||
+ | |||
+ | A memória de um computador pode ser vista como um vetor de bytes. Neste espaço vimos a utilização de variáveis diversas que podem armazenar valores que podem ser obtidos do usuários, serem resultados de ariméticas e muitas outras operações. O ponteiro nada mais é que um tipo de dado igualmente armazenado em memória, porém este dado se refere a um endereço da memória, ou seja, a um outro objeto. | ||
+ | |||
+ | Este recurso é muito útil para diversos propósitos, basta pensar na própria aplicação do conceito "endereço", imagine como seria localizar uma casa em uma cidade sem haver uma forma de endereçar e armazenar os endereços das casas. Explorando esta analogia, cada lote possui um endereço e pode ter um conteúdo de diferentes tipos como uma casa, um prédio ou um conjunto de lojas, enfim, trazendo para o C seria como os tipos int, char, vetores diversos, etc. | ||
+ | |||
+ | Assim é a memória, cada byte possui um endereço. O tamanho da memória é definido pelo tamanho do barramento de endereços usado para acessá-la. Uma variável ocupa uma área da memória. Tipicamente uma variável to tipo ''char'' se utiliza de um ''byte''. Já uma variável do tipo ''int'' pode (dependendo do sistema) usar 4 ''bytes'' contíguos. | ||
+ | |||
+ | ;Uma variável possui um endereço e um conteúdo (dados). | ||
+ | |||
+ | Uma variável ponteiro tem como conteúdo um endereço. Portanto a variável ponteiro possui um endereço e contém um endereço como conteúdo. Este recurso é largamente utilizado para passar parâmetros como referência (ao invés de copiar uma variável quando se quiser processá-la em alguma função), bem como para algoritmos diversos que buscam formas mais otimizadas de executar operações. Rode o código a seguir e compare com as respostas que foram obtidas: <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | int main(void) | ||
+ | { | ||
+ | int i = 10; | ||
+ | int *p; | ||
+ | long int li; | ||
+ | p = &i; | ||
+ | printf("Conteúdo de i: i = %d\n",i); | ||
+ | printf("Endereço de i: &i = %p\n",&i); | ||
+ | printf("Conteúdo de p: p = %p\n",p); | ||
+ | printf("Endereço de p: &p = %p\n",&p); | ||
+ | printf("Conteúdo apontado: *p = %d (conteúdo do endereço apontado por p)\n",*p); | ||
+ | printf("Tamanho do ponteiro = %li bytes\n",sizeof(p)); | ||
+ | printf("Tamanho do lont int = %li bytes\n",sizeof(li)); | ||
+ | printf("Tamanho do int = %li bytes\n",sizeof(i)); | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Resposta obtida através do gcc em uma máquina Linux Ubuntu: | ||
+ | Conteúdo de i: i = 10 | ||
+ | Endereço de i: &i = 0x7ffeb25859e4 | ||
+ | Conteúdo de p: p = 0x7ffeb25859e4 | ||
+ | Endereço de p: &p = 0x7ffeb25859e8 | ||
+ | Conteúdo apontado: *p = 10 (conteúdo do endereço apontado por p) | ||
+ | Tamanho do ponteiro = 8 bytes | ||
+ | Tamanho do lont int = 8 bytes | ||
+ | Tamanho do int = 4 bytes | ||
+ | *Observações: | ||
+ | **"&i" e "p" são iguais, isso porque "p" tem como conteúdo um endereço (neste caso o endereço de "i") | ||
+ | **O conteúdo de "i" (10) é igual "*p", que exatamente está extraindo o conteúdo da variável apontada (é o próprio "i") | ||
+ | **O endereço de "p" (&p) é um valor próprio o que prova que p é também uma variável alocada na memória armazenando um valor próprio | ||
+ | **Nesta máquina o ponteiro está representado por uma variável inteira de 8 bytes (uintptr_t). | ||
+ | |||
+ | |||
+ | Resposta obtida através do codechef.com (gcc-4.9.2): | ||
+ | Conteúdo de i: i = 10 | ||
+ | Endereço de i: &i = 0xbfadc2b8 | ||
+ | Conteúdo de p: p = 0xbfadc2b8 | ||
+ | Endereço de p: &p = 0xbfadc2bc | ||
+ | Conteúdo apontado: *p = 10 (conteúdo do endereço apontado por p) | ||
+ | Tamanho do ponteiro = 4 bytes | ||
+ | Tamanho do lont int = 4 bytes | ||
+ | Tamanho do int = 4 bytes | ||
+ | *Observações: | ||
+ | **O endereço de "p" e "i" são completamente diferentes da resposta anterior. Isso ocorre em diferentes máquinas e cada vez que o programa for rodado deverá também gerar novos endereços. O endereço é atribuído pelo sistema operacional que por várias condições naquele instante disponibilizou estes endereços ai listados. | ||
+ | **Nesta máquina o ponteiro está representado por uma variável inteira de 4 bytes (uintptr_t), o tamanho de uma variável ponteiro varia conforme a plataforma. | ||
+ | |||
+ | ;Ponteiro para inteiro | ||
+ | |||
+ | Observe o programa abaixo. A variável ''p'' é um ponteiro para inteiro. Isto significa que ela pode armazenar um endereço | ||
+ | de um inteiro. | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int x; | ||
+ | int *p; | ||
+ | |||
+ | x=5; | ||
+ | printf("Valor de x antes = %d\n", x); | ||
+ | |||
+ | p = &x; | ||
+ | *p=10; | ||
+ | |||
+ | printf("Valor de x depois = %d\n", x); | ||
+ | printf("Valor de p = %p\n", p); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Observe que para se referenciar o conteúdo da posição de memória apontada por ''p'' deve-se usar o asterisco: ''*p'' | ||
+ | |||
+ | |||
+ | ;EXERCÍCIO 1: Considere o programa abaixo: | ||
+ | <syntaxhighlight lang=c> | ||
+ | main() | ||
+ | { | ||
+ | int x=10; | ||
+ | int y, *p; | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Complete o código para copiar o conteúdo de x para y, sem que qualquer variável apareçam no lado esquerdo de um sinal de atribuição. Ou seja, sem envolver diretamente x e y. | ||
+ | |||
+ | ;EXERCÍCIO 2: Tente inferir qual seria o valor da variável y no final do programa abaixo: | ||
+ | <syntaxhighlight lang=c> | ||
+ | main() | ||
+ | { | ||
+ | int x,y,w,*p1,*p2; | ||
+ | x = 20; | ||
+ | w = 30; | ||
+ | p1 = &x; | ||
+ | p2 = &w; | ||
+ | y = *p1 + *p2; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;EXERCÍCIO 3: Tente inferir qual seria o valor da variável y no final do programa abaixo: | ||
+ | <syntaxhighlight lang=c> | ||
+ | main() | ||
+ | { | ||
+ | int x,y,w,*p1,*p2, *p3; | ||
+ | x = 20; | ||
+ | w = 30; | ||
+ | p1 = &x; | ||
+ | p2 = &w; | ||
+ | y = *p1 + w; | ||
+ | p3 = &y; | ||
+ | *p3 = *p3 + 10; | ||
+ | y = *p1 + *p2 + *p3; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;EXERCÍCIO 4: Qual seria o valor das variáveis '''y''' e '''x''' no final do programa abaixo: | ||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | void main() | ||
+ | { | ||
+ | int x,y; | ||
+ | int *p; | ||
+ | y=0; | ||
+ | p=&y; | ||
+ | x=*p; | ||
+ | x=4; | ||
+ | (*p)++; | ||
+ | x--; | ||
+ | (*p) += x; | ||
+ | printf("\ny=%d x=%d\n",y,x); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;Ponteiro para ''char'' | ||
+ | |||
+ | Os ponteiro para ''char'' são muito utilizados pois permitem apontar para ''strings''. A ideia é que ele aponte para o primeiro caracter (char) da ''string''. Veja o exemplo abaixo. | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | main() | ||
+ | { | ||
+ | char x[10]="ifsc"; | ||
+ | char *p; | ||
+ | p = &x[2]; | ||
+ | printf("x[2] = %c\n", *p); | ||
+ | p = x; | ||
+ | printf("string %s\n", p); | ||
+ | while (*p!=0) { | ||
+ | printf("Endereco %p conteúdo %c\n", p,*p); | ||
+ | p++; | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Neste foi usado o incremento de um ponteiro, o que implica em adicionar ao endereço armazenado em ''p'' uma quantidade relativa ao tamanho do tipo apontado. | ||
+ | No caso é 1 (tamanho de um ''char'' é um byte). | ||
+ | |||
+ | ;EXERCÍCIO: Sem executar o programa abaixo, determine o valor de y no final do programa: | ||
+ | <syntaxhighlight lang=c> | ||
+ | main() | ||
+ | { | ||
+ | char x[10]="ifsc"; | ||
+ | char *p, y; | ||
+ | p = x + 2; | ||
+ | y= *p; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | ;Apontando para um vetor de inteiros | ||
+ | |||
+ | |||
+ | Da mesma forma que usamos um ponteiro para ''char'' para apontar uma ''string'', podemos fazer um ponteiro para ''int'' apontar para para um elemento de um vetor de inteiros. | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | main() | ||
+ | { | ||
+ | int x[10]= {0,1,2,3,4,5,6,7,8,9}; | ||
+ | int *p; | ||
+ | int i; | ||
+ | p = x; | ||
+ | i=0; | ||
+ | while (i<10) { | ||
+ | printf(" endereco %p e conteudo %d\n", p, *p); | ||
+ | p++; | ||
+ | i++; | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''OBSERVE''' que p++ incrementa em 4 unidades. | ||
+ | |||
+ | ;Apontando para estruturas | ||
+ | |||
+ | Ponteiros podem apontar para qualquer "objeto" de qualquer tipo. Vamos verificar como é possível apontar para uma estrutura: | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | struct TRegistro { | ||
+ | char nome[20]; | ||
+ | int idade; | ||
+ | } Tabela[4] = { | ||
+ | {"joao",18,}, | ||
+ | {"maria",18,}, | ||
+ | {"jose",19,}, | ||
+ | {"lara",17,}, | ||
+ | }; | ||
+ | struct TRegistro *p; | ||
+ | main() | ||
+ | { | ||
+ | p = &Tabela[3]; /*p aponta para o registro 3 da tabela */ | ||
+ | printf("O nome na posição 3 é %s e idade = %d\n", p->nome,p->idade); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''NOTE''' que o uso de '''p->nome''' é uma alternativa ao uso de (*p).nome | ||
+ | |||
+ | No primeiro caso pode-se ler: o campo nome do objeto que é apontado por p. | ||
+ | |||
+ | ;Escrevendo e lendo de campos de uma estrutura através de ponteiro | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | struct TRegistro { | ||
+ | char nome[20]; | ||
+ | int idade; | ||
+ | } Tabela[4]; | ||
+ | struct TRegistro *p; | ||
+ | main() | ||
+ | { | ||
+ | int i; | ||
+ | p = &Tabela[0]; /*p aponta para o registro 0 da tabela */ | ||
+ | for (i=0;i<4;i++,p++) | ||
+ | { | ||
+ | printf("Digite o nome e idade da pessoa %d\n", i+1); | ||
+ | scanf("%s %d",p->nome,&(p->idade)); | ||
+ | printf("\n\n>>>> O nome e idade da pessoa %d é: %s, %d \n\n\n", i+1, p->nome, p->idade); | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;Retornando uma estrutura em uma função | ||
+ | |||
+ | No exemplo a abaixo a função ''RetornarStruct()'' retorna um ponteiro para uma estrutura. | ||
+ | O cuidadado que se deve ter é que a função não deveria apontar para uma estrutura que foi criada localmente | ||
+ | na função! | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | struct TRegistro { | ||
+ | char nome[20]; | ||
+ | int idade; | ||
+ | } Tabela[4] = { | ||
+ | {"joao",18,}, | ||
+ | {"maria",18,}, | ||
+ | {"jose",19,}, | ||
+ | {"lara",17,}, | ||
+ | }; | ||
+ | struct TRegistro *p; | ||
+ | struct TRegistro * RetornarStruct(int indice) | ||
+ | { | ||
+ | return &Tabela[indice]; | ||
+ | } | ||
+ | main() | ||
+ | { | ||
+ | p = RetornarStruct(2); /*p aponta para o registro 3 da tabela */ | ||
+ | printf("O nome na posição 2 é %s e idade = %d\n", p->nome,p->idade); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;Passando uma estrutura como parâmetro | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | struct TRegistro { | ||
+ | char nome[20]; | ||
+ | int idade; | ||
+ | } Tabela[4] = { | ||
+ | {"joao",18,}, | ||
+ | {"maria",18,}, | ||
+ | {"jose",19,}, | ||
+ | {"lara",17,}, | ||
+ | }; | ||
+ | struct TRegistro *p; | ||
+ | void MudarStruct(struct TRegistro *p1, int indice) | ||
+ | { | ||
+ | Tabela[indice] = *p1; | ||
+ | } | ||
+ | main() | ||
+ | { | ||
+ | struct TRegistro aux = {"luisa",16}; | ||
+ | MudarStruct(&aux,2); | ||
+ | p = &Tabela[2]; | ||
+ | printf("O nome na posição 2 é %s e idade = %d\n", p->nome,p->idade); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | ;Os argumentos argc e argv (o ponteiro de strings argv) | ||
+ | |||
+ | A função main() pode ter parâmetros formais, mas o programador não pode escolhores quais serão eles. | ||
+ | A declaração que se pode ter para a função main() é: | ||
+ | int main (int argc, char *argv[]); | ||
+ | Exemplo: | ||
+ | Escreva um programa que faça uso dos parâmentros argv e argc. O programa deverá receber | ||
+ | da linha de comando o dia, mês e ano correntes (dd/mm/aaaa), e imprimir a data em formato apropriado. | ||
+ | Veja o exemplo, supondo que o executável se chame data: | ||
+ | $ data 04 11 2016 | ||
+ | O programa deverá imprimir: | ||
+ | $ 04 de novembro de 2016<syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | void main(int argc, char *argv[]) | ||
+ | { | ||
+ | int mes; | ||
+ | char *nomemes [] = {"janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"}; | ||
+ | if(argc == 4) /* Testa se o numero de parametros fornecidos esta' (nome do programa, o dia, o mes e os dois ultimos algarismos do ano */ | ||
+ | { | ||
+ | /* argv contem strings. A string referente ao mes deve ser | ||
+ | * transformada em um numero inteiro. A funcao atoi esta sendo | ||
+ | * usada para isto: recebe a string e transforma no inteiro equivalente | ||
+ | */ | ||
+ | mes = atoi(argv[2]); | ||
+ | if (mes<1 || mes>12) /* Testa se o mes e' valido */ | ||
+ | printf("Erro!\nUso mes: mm, deve ser de 1 a 12.\n"); | ||
+ | else | ||
+ | printf("\n%s de %s de %s\n\n", argv[1], nomemes[mes-1],argv[3]); | ||
+ | } | ||
+ | else | ||
+ | printf("Erro!\nUso: dd/mm/aaaa, devem ser inteiros, ou estão faltando.\n"); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | Usando ponteiros como parâmetros de entrada saída de funções}} | ||
+ | Enviar um ponteiro a uma função tem diversas aplicações, uma delas é a de evitar redundância de dados e realizar a leitura de informações "diretas da fonte". Estas informações quando são de grande volume também poderiam requisitar um grande volume de memória para copiar, então mais um motivo para se passar a referência (ponteiro). Observe como podemos usar ponteiros na passagem de parâmetros: <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | void str_cpy(char *pdest, char *pfonte) | ||
+ | { | ||
+ | while (*pfonte!=0) { | ||
+ | *pdest++ = *pfonte++; | ||
+ | } | ||
+ | *pdest = 0; | ||
+ | } | ||
+ | int str_len (char *p) | ||
+ | { | ||
+ | int i=0; | ||
+ | while (*p++!=0) | ||
+ | i++; | ||
+ | return i; | ||
+ | } | ||
+ | main() | ||
+ | { | ||
+ | char fonte[10]="ifsc"; | ||
+ | char destino[10]; | ||
+ | str_cpy(destino, fonte); | ||
+ | printf("string destino = %s\n", destino); | ||
+ | printf("tamanho de dest = %d\n", str_len(destino)); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Este recurso também tem especial utilidade quando se deseja que a função retorne mais de um valor. Como sabemos a função só pode ter um retorno. Utilizando ponteiro, portanto, pode-se passar um endereço de referência para que a função utilize este espaço de memória para copiar um resultado que será posteriormente aproveitado pela função invocadora: <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | void alfa(int *p) | ||
+ | { | ||
+ | *p=10; | ||
+ | } | ||
+ | main() | ||
+ | { | ||
+ | int x; | ||
+ | x =5; | ||
+ | printf("Valor de x antes da chamada de alfa = %d\n", x); | ||
+ | alfa(&x); | ||
+ | printf("Valor de x depois da chamada de alfa = %d\n", x); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | {{collapse top | Exercícios - C (série 5)}} | ||
+ | |||
+ | #Implemente um programa que obtém do usuário uma string, utilizando um laço de repetição imprima esta string caractere por caractere utilizando um ponteiro de char. | ||
+ | #Implementar a função ''str_cat'' que concatena duas ''strings'' usando ponteiros. | ||
+ | #Implemente um programa que receba um vetor de inteiros e invova uma função que retorna o maior elemento e o menor elemento deste vetor. Utilize ponteiro no laço para realizar a busca. Faça também passagem de parâmetro por referência para que haja dois retornos nesta função. Imprima o resultado no final. | ||
+ | #Ordenar valores de um vetor de inteiros passando por referencia o ponteiro para esse vetor. | ||
+ | #Crie um programa que contém uma função "void strcopy(char *, char *, int)" que receba uma string de origem e outra de destino como parâmetro e um inteiro "tamanho" realizando a cópia da string origem na string destino. Imprima em tela ambas as strings para comparação. (id.:5.01) | ||
+ | #Implememtar um programa que recebe 3 parâmetros na linha de comando: dois números reais e um operador (char). Operador pode ser + ou menos. O programa deve mostrar o resultado da operação. Exemplo: calcula 3.5 + 2.6. Dica: usar a função '''atof''' para converter '''string''' em '''float'''. | ||
+ | #Implementar um programa chamado ''cmpcadeia'' que testa se duas strings passadas na linha de comando são iguais. O programa deve imprimir uma mensagem indicando se são iguais ou diferentes. Usar a função strcmp da biblioteca. Caso sejam passados mais ou menos que dois parâmetros o programa deve se encerrar mostrando uma indicão de alerta ao usuario de que os parametros estao incorretos. | ||
+ | |||
+ | ;Referências Complementares | ||
+ | *[http://pw1.netcom.com/~tjensen/ptr/ch1x.htm http://pw1.netcom.com/~tjensen/ptr/ch1x.htm] | ||
+ | *[http://eternallyconfuzzled.com/tuts/languages/jsw_tut_pointers.aspx http://eternallyconfuzzled.com/tuts/languages/jsw_tut_pointers.aspx] | ||
+ | *[http://duramecho.com/ComputerInformation/WhyCPointers.html http://duramecho.com/ComputerInformation/WhyCPointers.html] | ||
+ | *[http://boredzo.org/pointers/ http://boredzo.org/pointers/] | ||
+ | *[http://www.mtm.ufsc.br/~azeredo/cursoC/aulas/c600.html Link Aula Ponteiros UFMG] | ||
{{collapse bottom}} | {{collapse bottom}} | ||
Edição das 06h28min de 14 de novembro de 2017
Dados importantes
- Professor da Disciplina: Cleber Jorge Amaral
- Email: cleber.amaral@ifsc.edu.br
- Atendimento paralelo: terças e quintas das 12:00 as 13:00 na Sala Multimeios de Tele (ao lado da reprografia)
- Agenda do professor: Ver página
Dados da Disciplina
- Ementa da disciplina na wiki: Engenharia de Telecomunicações 2ª Fase
- Página no moodle: moodle
- Monitoria: Programa_de_monitoria_dos_cursos_superiores_de_Telecomunicações
Algoritmos utilizando fluxograma
Introdução aos algoritmos utilizando fluxograma
Introdução aos algoritmos utilizando fluxograma |
---|
|
Desenvolvendo algoritmos na forma de fluxogramas
Desenvolvendo algoritmos na forma de fluxogramas |
---|
Exercícios para resolver em sala de aula:
|
Pseudo-código
Pseudo-código utilizando Portugol - Introdução e condicionais
- Slides sobre pseudocódigo disponibilizados no moodle.
Ver exemplos de códigos Portugol dentro do software portugol (menu Arquivo->Abrir exemplo)
Desenvolvendo algoritmos na forma de pseudo-código - condicionais |
---|
Exercícios para resolver em sala de aula:
|
Desenvolvendo algoritmos na forma de pseudo-código - repetição |
---|
|
Pseudo-código utilizando Portugol - repetições
Exercícios - Pseudocodigo (série 1) |
---|
Exercícios - Pseudocodigo (série 1):
|
Pseudo-código utilizando Portugol - sub-rotinas e registros
Exercícios - Pseudocodigo (série 3) | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Exercícios - Pseudocodigo (série 3):
Parte da implementação do problema das funções trigonométricas
|
Programação em C (ANSI)
Programação em C (ANSI) - Introdução ao C
Introdução ao C e funções de saída e entrada de dados |
---|
|
Programação em C (ANSI) - Controle de fluxo em C
Programação em C (ANSI) - Condicionais
Condicionais em C |
---|
|
Exercícios - C (série 0) |
---|
|
Programação em C (ANSI) - Repetições
Estruturas de repetição em C |
---|
|
Exercícios - C (série 1) |
---|
|
Funções
Funções |
---|
|
Prototipagem de Funções |
---|
O protótipo (ou declaração) de uma função em C é uma interface de acesso a uma função, formada pela declaração da função sem conter seu corpo (implementação ou definição). Desda forma a função que invoca uma outra função conhece os argumentos e retorno da função invocada, isso servirá para um processo seguinte da compilação, o processo de lincagem. Normalmente o protótipo da uma função é realizado no topo do arquivo C ou em uma arquivo de cabeçalho (.h) separado. Em um projeto em que as funções são definidas antes da função que as invoca, neste caso em ordem inversa de invocação, não há problema ou necessidade de prototipagem. Porém, se esta ordem não for respeitada ou se as funções são externas, é necessário prototipar. Na prática, sem o uso de protótipo e com a função sendo definida após a definição de quem a invocou provoca que o compilador irá definir a função invocada de uma forma padrão, que caso não se adeque a forma da função verdadeiramente, irá causar erro. Considere o código a seguir, observe que a função media está sendo definida antes de main que a invoca, este código roda corretamente.
|
A função main |
---|
O programa inicia pela primeira instrução contida na função main() e também se encerra na última instrução. O retorno padrão da função main é um int que representa um código de erros reconhecidos por muitos sistemas operacionais. Se o programa terminou sua execução corretamente o retorno deverá ser 0 (zero). int main(void)
{
//Programa
return 0;
}
|
O método exit() |
---|
Uma alternativa a terminação do programa chegando ao fim da função main é a função exit da biblioteca <stdlib.h>. Para esta função deve-se passar um argumento inteiro que tem o mesmo significado do código de retorno da função main, portanto exit(0) representa uma terminação normal, alternativamente exit(EXIT_SUCCESS). Para representar uma terminação anormal pode-se utilizar exit(EXIT_FAILURE) ou exit(1).
|
Exercícios - C (série 2) |
---|
|
Vetores, strings e matrizes em C
- Matrizes de qualquer dimensão são caracterizadas por terem todos os elementos pertencentes ao mesmo tipo de dado;
- Vetores são matrizes unidimensionais;
- O indexador começa sempre em zero;
- É importante observar que o C não controla se o programador está ou não acessando uma posição de memória válida da estrutura, cabe ao programador criar proteções;
- Declaração:
tipo_da_variável nome_do_vetor [tamanho]; tipo_da_variável nome_da_matriz [linhas][colunas];
- Strings são vetores de chars, a biblioteca string.h traz diversas funções de tratamento de strings;
- Têm o seu último elemento como um '\0'
Declaração:
char nome_da_string [tamanho];
- Inicialização:
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" };
- Inicialização sem especificação de tamanho
char mess [] = "Linguagem C: flexibilidade e poder."; int matrx [][2] = { 1,2,2,4,3,6,4,8,5,10 };
Gerando números pseudo-aleatórios |
---|
|
Tabela ASCII |
---|
|
Vetor de tamanho variável |
---|
O vetor de tamanho variável (variable lenght array) é um recurso do C que permite que o tamanho do vetor seja definido em tempo de execução. Na prática o C irá alocar uma quantidade de memória que não precisa estar definida antes da execução. variable-lenght |
Exercícios - C (série 3) |
---|
|
Exercícios - C (série 4) |
---|
|
Tipos de dados compostos
Estruturas |
---|
Assim como o vetor a estrutura é um conjunto de dados, mas traz uma vantagem: a possibilidade de possuir "campos" de diferentes tipos de variáveis. Por exemplo, a struct TPessoa poderia ter os campos nome (char[40]) e idade (int). A declaração genérica da estrutura é: struct TNome_do_tipo { //variável 1 //variável 2 //variável N } nome_instancia;
#include <stdio.h>
struct TUsuario /* struct TUsuario é o nome do tipo que está sendo criado */
{
char userID[20];
char senha[20];
} Usuario; /* aqui é definida uma variável do tipo struct TUsuario */
struct TUsuario TabelaUsuario[20];
main()
{
scanf("%s", Usuario.userID);
scanf("%s", Usuario.senha);
scanf("%s", TabelaUsuario[10].userID);
scanf("%s", TabelaUsuario[10].senha);
}
Neste exemplo, foi definido um tipo (modelo) para o registro (struct TUsuario) e foi criada uma variável chamada Usuario a partir deste tipo. Na sequência foi criada mais uma variável (um vetor de estruturas) chamada TabelaUsuario. Note que basta usar as palavras chave struct Usuario para criar novas variáveis. O tipo completo é definido uma única vez no início.
#include <stdio.h>
#define NUM_MAX 3
struct TAluno {
char nome[30];
char matricula[11];
float b1,b2,b3,b4;
} Turma[NUM_MAX];
void print_aluno(struct TAluno aux)
{
printf("Nome -> %s\n", aux.nome);
printf("Matrícula -> %s\n", aux.matricula);
printf("Bimestre 1 -> %f\n", aux.b1);
printf("Bimestre 2 -> %f\n", aux.b2);
printf("Bimestre 3 -> %f\n", aux.b3);
printf("Bimestre 4 -> %f\n", aux.b4);
}
main()
{
int i;
for(i=0;i<NUM_MAX;i++) {
printf("Entre com o nome do aluno\n");
scanf("%s", Turma[i].nome);
printf("Entre com a matrícula do aluno\n");
scanf("%s", Turma[i].matricula);
printf("Entre com a nota do bimestre 1\n");
scanf("%f", &Turma[i].b1);
printf("Entre com a nota do bimestre 2\n");
scanf("%f", &Turma[i].b2);
printf("Entre com a nota do bimestre 3\n");
scanf("%f", &Turma[i].b3);
printf("Entre com a nota do bimestre 4\n");
scanf("%f", &Turma[i].b4);
}
for(i=0;i<NUM_MAX;i++) {
printf("=========== Aluno %d ============\n", i);
print_aluno(Turma[i]);
}
}
O exemplo a seguir demonstra como se pode copiar uma variável struct para outra do mesmo tipo. #include <stdio.h>
struct THoras{
int hora;
int minuto;
int segundo;
};
struct THoras Ontem = {2,10,57};
void main()
{
struct THoras Hoje;
Hoje = Ontem;
printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo);
}
Vamos ver um exemplo com estruturas definidas dentro de estruturas: #include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
void main()
{
struct TCidadao Cidadao;
printf("Entre com o nome\n");
scanf ("%s",Cidadao.nome);
printf("Entre com o cpf\n");
scanf ("%s",Cidadao.cpf);
printf("Entre a rua\n");
scanf ("%s",Cidadao.endereco.rua);
printf("Entre a numero\n");
scanf ("%s",Cidadao.endereco.numero);
printf("Entre com o número de filhos\n");
scanf ("%d",&Cidadao.num_filhos);
}
Como toda variável, é possível dar valores para uma variável do tipo struct definida no programa: #include <stdio.h>
struct TEndereco {
char rua[50];
int numero;
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
};
int main(void)
{
//Inicializando com parâmetros em sequencia (ordem tem que ser respeitada)
struct TCidadao CidadaoMaria = {"Maria","42342342234",{"Rua AlfaBeta",145}};
//Inicializando com parâmetros via campo (não é necessário respeitar qualquer ordem)
struct TCidadao CidadaoJose = {.cpf = "1234567890", .endereco.numero = 541,.nome = "Jose",.endereco.rua = "Rua GamaDelta"};
printf("Rua do cidadao %s = %s\n", CidadaoMaria.nome, CidadaoMaria.endereco.rua);
printf("Rua do cidadao %s = %s\n", CidadaoJose.nome, CidadaoJose.endereco.rua);
}
Se não for usado o operador "&" , um parâmetro que é estrutura será passado por cópia. Não apresentaremos agora a passagem por endereço pois necessita do conceita de ponteiro. Observe o exercício abaixo. #include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
void print_struct (struct TCidadao aux)
{
printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
printf("endereço inicial do aux %p\n", &aux);
}
void main()
{
struct TCidadao Cidadao;
printf("Entre com o nome\n");
scanf ("%s",Cidadao.nome);
printf("Entre com o cpf\n");
scanf ("%s",Cidadao.cpf);
printf("Entre a rua\n");
scanf ("%s",Cidadao.endereco.rua);
printf("Entre a numero\n");
scanf ("%s",Cidadao.endereco.numero);
printf("Entre com o número de filhos\n");
scanf ("%d",&Cidadao.num_filhos);
print_struct(Cidadao);
printf("endereço inicial do Cidadao %p\n", &Cidadao);
}
|
Exercícios - C (série 5) |
---|
|
Unions |
---|
Union é um recurso do C que permite declarar um conjunto de dados que irá ocupar um mesmo espaço. É bastante empregado quando se deseja economizar espaço ou não se tem certeza sobre qual tipo de dado deve ser armazenado para determinada instancia. No exemplo a seguir é criada uma struct chamada TProduto e dentro destra estrutura há uma área de detalhamento do produto que é de uso genérico, para alguns produtos há campos específicos para preenchimento e outros não se tem ao certo os detalhes, portanto fica um campo de uso geral.
#include <stdio.h>
struct TRoupeiro{
char cor[20];
int volume;
float peso;
};
struct TProduto{
int id;
char nome[20];
union {
struct TRoupeiro roupeiro;
char descricao_generica[sizeof(int)+sizeof(float)+20];
};
};
int main(void)
{
struct TProduto vaso_decorativo = {
.id = 2,.nome = "Vaso decorativo 1",
.descricao_generica = "em vidro - peça única"
};
struct TProduto guarda_roupas_solteiro = {
.id = 1,.nome = "Roupeiro 3 portas",
.roupeiro.cor = "CZ", .roupeiro.volume = 304,.roupeiro.peso = 50.0
};
printf("nome = %s, \ndescrição = %s, \ncor = %s, \nvolume = %d, \npeso = %f\n\n\n",
guarda_roupas_solteiro.nome,
guarda_roupas_solteiro.descricao_generica,
guarda_roupas_solteiro.roupeiro.cor,
guarda_roupas_solteiro.roupeiro.volume,
guarda_roupas_solteiro.roupeiro.peso
);
printf("nome = %s, \ndescrição = %s, \ncor = %s, \nvolume = %d, \npeso = %f\n\n\n",
vaso_decorativo.nome,
vaso_decorativo.descricao_generica,
vaso_decorativo.roupeiro.cor,
vaso_decorativo.roupeiro.volume,
vaso_decorativo.roupeiro.peso
);
}
|
Ponteiros
Ponteiros |
---|
A memória de um computador pode ser vista como um vetor de bytes. Neste espaço vimos a utilização de variáveis diversas que podem armazenar valores que podem ser obtidos do usuários, serem resultados de ariméticas e muitas outras operações. O ponteiro nada mais é que um tipo de dado igualmente armazenado em memória, porém este dado se refere a um endereço da memória, ou seja, a um outro objeto. Este recurso é muito útil para diversos propósitos, basta pensar na própria aplicação do conceito "endereço", imagine como seria localizar uma casa em uma cidade sem haver uma forma de endereçar e armazenar os endereços das casas. Explorando esta analogia, cada lote possui um endereço e pode ter um conteúdo de diferentes tipos como uma casa, um prédio ou um conjunto de lojas, enfim, trazendo para o C seria como os tipos int, char, vetores diversos, etc. Assim é a memória, cada byte possui um endereço. O tamanho da memória é definido pelo tamanho do barramento de endereços usado para acessá-la. Uma variável ocupa uma área da memória. Tipicamente uma variável to tipo char se utiliza de um byte. Já uma variável do tipo int pode (dependendo do sistema) usar 4 bytes contíguos.
#include <stdio.h>
int main(void)
{
int i = 10;
int *p;
long int li;
p = &i;
printf("Conteúdo de i: i = %d\n",i);
printf("Endereço de i: &i = %p\n",&i);
printf("Conteúdo de p: p = %p\n",p);
printf("Endereço de p: &p = %p\n",&p);
printf("Conteúdo apontado: *p = %d (conteúdo do endereço apontado por p)\n",*p);
printf("Tamanho do ponteiro = %li bytes\n",sizeof(p));
printf("Tamanho do lont int = %li bytes\n",sizeof(li));
printf("Tamanho do int = %li bytes\n",sizeof(i));
return 0;
}
Resposta obtida através do gcc em uma máquina Linux Ubuntu: Conteúdo de i: i = 10 Endereço de i: &i = 0x7ffeb25859e4 Conteúdo de p: p = 0x7ffeb25859e4 Endereço de p: &p = 0x7ffeb25859e8 Conteúdo apontado: *p = 10 (conteúdo do endereço apontado por p) Tamanho do ponteiro = 8 bytes Tamanho do lont int = 8 bytes Tamanho do int = 4 bytes
Conteúdo de i: i = 10 Endereço de i: &i = 0xbfadc2b8 Conteúdo de p: p = 0xbfadc2b8 Endereço de p: &p = 0xbfadc2bc Conteúdo apontado: *p = 10 (conteúdo do endereço apontado por p) Tamanho do ponteiro = 4 bytes Tamanho do lont int = 4 bytes Tamanho do int = 4 bytes
Observe o programa abaixo. A variável p é um ponteiro para inteiro. Isto significa que ela pode armazenar um endereço de um inteiro. #include <stdio.h>
main()
{
int x;
int *p;
x=5;
printf("Valor de x antes = %d\n", x);
p = &x;
*p=10;
printf("Valor de x depois = %d\n", x);
printf("Valor de p = %p\n", p);
}
Observe que para se referenciar o conteúdo da posição de memória apontada por p deve-se usar o asterisco: *p
main()
{
int x=10;
int y, *p;
}
Complete o código para copiar o conteúdo de x para y, sem que qualquer variável apareçam no lado esquerdo de um sinal de atribuição. Ou seja, sem envolver diretamente x e y.
main()
{
int x,y,w,*p1,*p2;
x = 20;
w = 30;
p1 = &x;
p2 = &w;
y = *p1 + *p2;
}
main()
{
int x,y,w,*p1,*p2, *p3;
x = 20;
w = 30;
p1 = &x;
p2 = &w;
y = *p1 + w;
p3 = &y;
*p3 = *p3 + 10;
y = *p1 + *p2 + *p3;
}
#include <stdio.h>
void main()
{
int x,y;
int *p;
y=0;
p=&y;
x=*p;
x=4;
(*p)++;
x--;
(*p) += x;
printf("\ny=%d x=%d\n",y,x);
}
Os ponteiro para char são muito utilizados pois permitem apontar para strings. A ideia é que ele aponte para o primeiro caracter (char) da string. Veja o exemplo abaixo. #include <stdio.h>
main()
{
char x[10]="ifsc";
char *p;
p = &x[2];
printf("x[2] = %c\n", *p);
p = x;
printf("string %s\n", p);
while (*p!=0) {
printf("Endereco %p conteúdo %c\n", p,*p);
p++;
}
}
Neste foi usado o incremento de um ponteiro, o que implica em adicionar ao endereço armazenado em p uma quantidade relativa ao tamanho do tipo apontado. No caso é 1 (tamanho de um char é um byte).
main()
{
char x[10]="ifsc";
char *p, y;
p = x + 2;
y= *p;
}
#include <stdio.h>
main()
{
int x[10]= {0,1,2,3,4,5,6,7,8,9};
int *p;
int i;
p = x;
i=0;
while (i<10) {
printf(" endereco %p e conteudo %d\n", p, *p);
p++;
i++;
}
}
OBSERVE que p++ incrementa em 4 unidades.
Ponteiros podem apontar para qualquer "objeto" de qualquer tipo. Vamos verificar como é possível apontar para uma estrutura: #include <stdio.h>
struct TRegistro {
char nome[20];
int idade;
} Tabela[4] = {
{"joao",18,},
{"maria",18,},
{"jose",19,},
{"lara",17,},
};
struct TRegistro *p;
main()
{
p = &Tabela[3]; /*p aponta para o registro 3 da tabela */
printf("O nome na posição 3 é %s e idade = %d\n", p->nome,p->idade);
}
NOTE que o uso de p->nome é uma alternativa ao uso de (*p).nome No primeiro caso pode-se ler: o campo nome do objeto que é apontado por p.
#include <stdio.h>
struct TRegistro {
char nome[20];
int idade;
} Tabela[4];
struct TRegistro *p;
main()
{
int i;
p = &Tabela[0]; /*p aponta para o registro 0 da tabela */
for (i=0;i<4;i++,p++)
{
printf("Digite o nome e idade da pessoa %d\n", i+1);
scanf("%s %d",p->nome,&(p->idade));
printf("\n\n>>>> O nome e idade da pessoa %d é: %s, %d \n\n\n", i+1, p->nome, p->idade);
}
}
No exemplo a abaixo a função RetornarStruct() retorna um ponteiro para uma estrutura. O cuidadado que se deve ter é que a função não deveria apontar para uma estrutura que foi criada localmente na função! #include <stdio.h>
struct TRegistro {
char nome[20];
int idade;
} Tabela[4] = {
{"joao",18,},
{"maria",18,},
{"jose",19,},
{"lara",17,},
};
struct TRegistro *p;
struct TRegistro * RetornarStruct(int indice)
{
return &Tabela[indice];
}
main()
{
p = RetornarStruct(2); /*p aponta para o registro 3 da tabela */
printf("O nome na posição 2 é %s e idade = %d\n", p->nome,p->idade);
}
#include <stdio.h>
struct TRegistro {
char nome[20];
int idade;
} Tabela[4] = {
{"joao",18,},
{"maria",18,},
{"jose",19,},
{"lara",17,},
};
struct TRegistro *p;
void MudarStruct(struct TRegistro *p1, int indice)
{
Tabela[indice] = *p1;
}
main()
{
struct TRegistro aux = {"luisa",16};
MudarStruct(&aux,2);
p = &Tabela[2];
printf("O nome na posição 2 é %s e idade = %d\n", p->nome,p->idade);
}
A função main() pode ter parâmetros formais, mas o programador não pode escolhores quais serão eles. A declaração que se pode ter para a função main() é: int main (int argc, char *argv[]); Exemplo: Escreva um programa que faça uso dos parâmentros argv e argc. O programa deverá receber da linha de comando o dia, mês e ano correntes (dd/mm/aaaa), e imprimir a data em formato apropriado. Veja o exemplo, supondo que o executável se chame data: $ data 04 11 2016 O programa deverá imprimir: $ 04 de novembro de 2016#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[])
{
int mes;
char *nomemes [] = {"janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"};
if(argc == 4) /* Testa se o numero de parametros fornecidos esta' (nome do programa, o dia, o mes e os dois ultimos algarismos do ano */
{
/* argv contem strings. A string referente ao mes deve ser
* transformada em um numero inteiro. A funcao atoi esta sendo
* usada para isto: recebe a string e transforma no inteiro equivalente
*/
mes = atoi(argv[2]);
if (mes<1 || mes>12) /* Testa se o mes e' valido */
printf("Erro!\nUso mes: mm, deve ser de 1 a 12.\n");
else
printf("\n%s de %s de %s\n\n", argv[1], nomemes[mes-1],argv[3]);
}
else
printf("Erro!\nUso: dd/mm/aaaa, devem ser inteiros, ou estão faltando.\n");
}
|
Usando ponteiros como parâmetros de entrada saída de funções |
---|
Enviar um ponteiro a uma função tem diversas aplicações, uma delas é a de evitar redundância de dados e realizar a leitura de informações "diretas da fonte". Estas informações quando são de grande volume também poderiam requisitar um grande volume de memória para copiar, então mais um motivo para se passar a referência (ponteiro). Observe como podemos usar ponteiros na passagem de parâmetros: #include <stdio.h>
void str_cpy(char *pdest, char *pfonte)
{
while (*pfonte!=0) {
*pdest++ = *pfonte++;
}
*pdest = 0;
}
int str_len (char *p)
{
int i=0;
while (*p++!=0)
i++;
return i;
}
main()
{
char fonte[10]="ifsc";
char destino[10];
str_cpy(destino, fonte);
printf("string destino = %s\n", destino);
printf("tamanho de dest = %d\n", str_len(destino));
}
#include <stdio.h>
void alfa(int *p)
{
*p=10;
}
main()
{
int x;
x =5;
printf("Valor de x antes da chamada de alfa = %d\n", x);
alfa(&x);
printf("Valor de x depois da chamada de alfa = %d\n", x);
}
|
Exercícios - C (série 5) |
---|
|
Referências
Referências bibliográficas |
---|
|
Ferramentas úteis |
---|
|
Plano de aula
Aula | Data | Horas | Conteúdo | Recursos | |
---|---|---|---|---|---|
1 | 28/7 | 2 | Sem atividades de PRG – reposição de férias – horário disponível para outras atividades letivas | Lab Redes 1 | |
2 | 1/8 | 2 | Sem atividades de PRG – reposição de férias – horário disponível para outras atividades letivas | Lab Redes 1 | |
3 | 4/8 | 2 | Aula inaugural, apresentação do professor e turma, apresentação da disciplina e introdução aos algoritmos | Lab Redes 1 ou Redes 2 | |
4 | 8/8 | 2 | Prática de fluxogramas | Lab Redes 1 | |
5 | 11/8 | 2 | Introdução ao pseudocódigo até condicionais com resolução de exercícios | Lab Redes 1 ou Redes 2 | |
6 | 15/8 | 2 | Prática: Resolução de problemas em pseudocódigo e fluxogramas (declaração de variáveis, leia e escreva, uso de condicionais e biblioteca portugol) | Lab Redes 1 | |
7 | 18/8 | 2 | Pseudocódigo: Uso de vetores e sub-rotinas | Lab Redes 1 ou Redes 2 | |
8 | 22/8 | 2 | Prática: Resolução de problemas com vetores e sub-rotinas | Lab Redes 1 | |
9 | 25/8 | 2 | Pseudocódigo e fluxogramas: Registros e revisão geral | Lab Redes 1 ou Redes 2 | |
10 | 29/8 | 2 | Pseudocódigo e fluxogramas: Exercícios de preparação para prova | Lab Redes 1 | |
11 | 1/9 | 2 | Avaliação1: Introdução a algoritmos (fluxograma e pseudocódigo) | Lab Redes 1 ou Redes 2 | |
12 | 5/9 | 2 | Prática: Correção da Avaliação | Lab Redes 1 | |
13 | 12/9 | 2 | Recuperação1? / Introdução ao C, primeiros conceitos de compilação, variáveis, controle de fluxo, entrada e saída de dados | Lab Redes 1 | |
14 | 15/9 | 2 | Continuação C, condicionais, operadores relacionais, operadores lógicos. Prática: Controle de fluxo em C, entrada e saída de dados | Lab Redes 1 ou Redes 2 | |
15 | 19/9 | 2 | Prática C | Lab Redes 1 | |
16 | 22/9 | 2 | Continuação C: estruturas de repetição | Lab Redes 1 ou Redes 2 | |
17 | 26/9 | 2 | Prática: estruturas de repetição | Lab Redes 1 | |
18 | 29/9 | 2 | Continuação C: funções | Lab Redes 1 ou Redes 2 | |
19 | 3/10 | 2 | Prática: Funções em C | Lab Redes 1 | |
20 | 6/10 | 2 | Avaliação2: C até funções | Lab Redes 1 ou Redes 2 | |
21 | 10/10 | 2 | Correção da prova | Lab Redes 1 | |
22 | 17/10 | 2 | Recuperação2? / Prática para resolução de exercícios | Lab Redes 1 | |
23 | 20/10 | 2 | Introdução a vetores e matrizes em C. | Lab Redes 1 ou Redes 2 | |
24 | 24/10 | 2 | Resolução de exercícios de vetores Prática: Resolução de exercícios de fixação de vetores. | Lab Redes 1 | |
25 | 27/10 | 2 | Structs e Unions | Lab Redes 1 ou Redes 2 | |
26 | 31/10 | 2 | Prática: Structs e unions | Lab Redes 1 | |
27 | 7/11 | 2 | Prática: Structs e unions / Compreendendo melhor a função main e exit, gerando números pseudo-aleatórios, defines e operadores e precedências | Lab Redes 1 | |
28 | 10/11 | 2 | Ponteiros | Lab Redes 1 ou Redes 2 | |
29 | 14/11 | 2 | Prática: Exercicios ponteiros | Lab Redes 1 | |
30 | 17/11 | 2 | Vetor de Ponteiros e Ponteiro Para Estruturas, typedef, recursividade, apresentação do projeto | Lab Redes 1 ou Redes 2 | |
31 | 21/11 | 2 | Prática de Ponteiros e structs | Lab Redes 1 | |
32 | 24/11 | 2 | Avaliação: C até structs e ponteiros | Lab Redes 1 ou Redes 2 | |
33 | 28/11 | 2 | Prática: Correção da Avaliação / Desenvolvimento do projeto | Lab Redes 1 | |
34 | 1/12 | 2 | Apresentação do projeto. Prática: Desenvolvimento do Projeto | Lab Redes 1 ou Redes 2 | |
35 | 5/12 | 2 | Recuperação3? / Prática: Desenvolvimento do Projeto | Lab Redes 1 | |
36 | 8/12 | 2 | Prática: Desenvolvimento do Projeto | Lab Redes 1 ou Redes 2 | |
37 | 12/12 | 2 | Avaliação4: Apresentação do projeto | Lab Redes 1 | |
38 | 15/12 | 2 | Avaliação4 (continuação): Apresentação do projeto | Lab Redes 1 ou Redes 2 | |
39 | 19/12 | 2 | Encerramento da disciplina / Recuperação4? | Lab Redes 1 | |
TOTAL | 80 |
Conceitos
Ver moodle da disciplina.