Programação Computacional para Engenharia – 2016.1


MENU: [ Avisos | Informações Gerais | Regras | Bibliografia | Plano de Atividades | Dados das Aulas ]


Avisos


Informações Gerais

Nesta disciplina aprende-se a programar – mais precisamente, a resolver problemas por meios de algoritmos estruturados, escritos na linguagem de programação C.

Informações importantes como justificativa, objetivos, ementa e bibliografia podem ser encontrados na regulamentação oficial da disciplina. (Arquivo Faltando!)

Nesta disciplina nós não seguimos nenhum livro em particular, mas na seção de bibliografia há indicações de livros que você pode utilizar para estudar tanto a chamada lógica de programação quanto a linguagem de programação C.

Todas as atividades da disciplina já têm data estimada no plano de atividades. Caso haja choque de datas importantes com outras disciplinas suas e você deseje sugerir alterações de datas, por favor me comunique o quanto antes!

  • Esteja atento(a), desde o início do semestre, às regras para solicitação de segunda chamada e para o cálculo da nota da disciplina.

    A minha sugestão para a obtenção de um bom desempenho na disciplina é, aula-a-aula, participar da aula, estudar o conteúdo ministrado, fazer os exercícios e tirar as dúvidas. Como alunos de graduação fazem muitas disciplinas por semestre, a minha sugestão pragmática é:

    1. Acompanhe as Aulas com Atenção, esclarecendo cada dúvida tão cedo quanto possível.

    2. Faça 2 exercícios depois de cada aula: para quem acompanhou a aula normalmente, essa é uma maneira eficaz de solidificar o conteúdo e descobrir dúvidas. Observe que você pode ir direto aos exercícios, sem revisar o conteúdo da aula (a menos que tenha ficado com uma dúvida significativa); isso não é um problema, pelo contrário: o seu aprendizado terá significado na medida em que lhe servir de ferramenta, seja em questões práticas ou teóricas. A propósito:

      Como fazer exercícios: quase todos os exercícios solicitam que você escreva um programa em C (que realize uma certa tarefa). No início, talvez você prefira escrever os programas num computador, para poder testá-los logo em seguida. À medida, porém, em que você for ganhando familiaridade com a sintaxe de C, lhe será possível escrever os programas em papel, o que tem vantagens significativas. Em particular, escrever programas em papel facilita descobrir dúvidas ("será que essa sintaxe é válida em C?", etc), as quais você deve ter o cuidado de anotar para tirar depois. Naturalmente, você pode e deve reservar um tempo para passar os seus programas do papel para o computador, pois essa experiência também é fundamental. Por fim, é importante lembrar que a linguagem C é apenas um meio para expressarmos os nossos algoritmos, e que nesta disciplina o principal aprendizado é a habilidade de criar algoritmos, independentemente da sintaxe. Isso significa que você pode, ao escrever um programa em papel, concentrar-se primeiramente na lógica da solução, e apenas depois se ocupar em resolver pequenas dúvidas envolvendo a sintaxe da linguagem.
    3. Tenha Disciplina: quem estuda aula-a-aula tem sessões de estudo muito mais fáceis, e amadurece o conteúdo com mais calma. Além disso, o conteúdo total de uma disciplina nunca é pequeno: não é prudente, então, realizar o aprendizado pouco-a-pouco, diminuindo a dificuldade de cada passo?

    Caso você possua uma dúvida no horário da aula, o ideal é tirá-la na própria ocasião, para que os demais alunos também se beneficiem das explicações. Esteja, porém, à vontade para me contactar fora do horário de aula.


    Regras

    • Segunda chamada: consulte as regras para a solicitação de prova de segunda chamada.

    • Nota da disciplina: Consistirá na média aritmética das notas obtidas pelo aluno nas três avaliações parciais da disciplina:
      Média das Avaliações ≥ 7 7 > média ≥ 4 < 4
      Situação Aprovado AF Reprovado

    Bibliografia

    Atenção: consulte a biblioteca para saber sobre a disponibilidade dos livros abaixo.

    Livros sobre Lógica de Programação:

    1. Fundamentos da Programação de Computadores, 3ª edição. Ana Fernanda Gomes Ascencio, Edilene Aparecida Veneruchi de Campos. Editora Pearson. 2012. ISBN: 9788564574168.

    2. Lógica de Programação, 3ª edição. André Luiz Villar Forbellone, Henri Frederico Eberspacher. Editora Pearson. 2005. ISBN: 9788576050247.

    3. Algoritmos e Estruturas de Dados. Guimarães/Lages. Editora LTC. 1994. ISBN: 9788521603788.

    Livros sobre a Linguagem de Programação C:
    1. The C Programming Language, Second Edition. Brian W. Kernighan, Dennis M. Ritchie. Editora Prentice Hall. 1988. ISBN: 0-13-110362-8, 0-13-110370-9.

      Esse é o meu livro favorito sobre a linguagem de programação C, e é o livro do autor da linguagem (devido à idade, porém, ele descreve C89, e não C90 ou C11). Havia uma tradução pela editora Campus ("C - A linguagem de Programação - PADRÃO ANSI"), mas aparentemente ela não está mais sendo impressa. :-( Há exemplares na biblioteca!

    2. Programando em C - Volume I - Fundamentos. Ulysses de Oliveira. Editora Ciência Moderna. 2008. ISBN: 9788573936599.

    3. C: A Reference Manual, Fifth Edition. Samuel P. Harbison, Guy L. Steele. Editora Prentice Hall. 2002. ISBN-13: 978-0-13-089592-9.

    Fontes de qualidade na internet (legalmente de graça):
    1. The C Book, second edition. Mike Banahan, Declan Brady, Mark Doran. Editora Addison Wesley. 1991.

      Um livro didático, preciso, muito bom sobre C89, livremente disponível em html e pdf.

    2. cppreference.com - C reference.

      Não ensina programação para iniciantes, mas é uma excelente referência sobre os detalhes técnicos da linguagem C (C89, C99, C11), e particularmente sobre a biblioteca padrão – útil para perguntas como "qual é mesmo o formato esperado pela função printf?"

    3. O rascunho do padrão ISO C11, diretamente do grupo que o produziu.

      O padrão é a referência definitiva em caso de dúvida sobre a linguagem. Leitura bastante técnica, entretanto: acho que muitos programadores profissionais de C não consultam esse documento (uma pena, porém).


    Plano de Atividades

    Abaixo estão todas as atividades e datas previstas para a disciplina (clique no número da aula para acessar os detalhes dela):

    Observação: as aulas 1–9 foram ministradas pelo professor Bruno, que iniciou a disciplina.

    Aula Data Descrição
    01 15/03 Apresentação
    02 18/03 10h Conceitos Básicos (Lógica, Algoritmo, Linguagem, Programa)
    18/03 16h Aulas Práticas Não Iniciadas
    03 22/03 Tipos de Algoritmos (Narração, Descritiva, Fluxograma e Pseudocódigo)
    04 25/03 10h Tipos primitivos de dados, Variáveis, Constantes, Identificadores
    25/03 16h Aulas Práticas Não Iniciadas
    05 29/03 Operadores (atribuição, aritméticos, lógicos e relacionais), tabela verdade
    06 01/04 10h Exercícios e tira-dúvidas de algoritmos sequenciais
    01/04 16h Aulas Práticas Não Iniciadas
    07 05/04 Estrutura de Seleção SE-SENÃO em Portugol
    08 08/04 10h Tradução dos Comandos de Portugol para C
    09 08/04 16h Prática em Laboratório
    10 12/04 Estrutura de um Programa em C; Argumentos e Retorno de Funções.
    11 15/04 10h Seleção com Múltiplas Escolhas (switch); Repetição (while, do-while).
    12 15/04 16h Prática em Laboratório
    13 19/04 Contagem e Soma por meio de Laço; Repetição com Variável de Controle (via while e for).
    14 22/04 10h Manipulação de Números Racionais (double) e Caracteres (char)
    15 22/04 16h Prática em Laboratório
    16 26/04 Vetores como Variáveis Automáticas; Acesso Indexado; Uso em Funções; Inicialização.
    17 29/04 10h Desvio do Fluxo de Execução (break, continue, goto); Expressão Condicional (?:).
    18 29/04 16h Prática em Laboratório
    19 03/05 Leitura e Escrita de Linhas Caractere-a-Caractere (getchar e putchar)
    20 05/05 16h (Aula extra, Bloco 707, Sala 21)
    Leitura de Números Dígito-a-Dígito via getchar; Operador Vírgula.
    06/05 10h Sem aula: Workshop de Qualidade do Curso de Computação
    21 06/05 16h Prática em Laboratório
    * 10/05 AP1 (Tudo em C)
    22 13/05 10h Notas e Soluções da AP1
    23 13/05 16h Prática em Laboratório
    24 17/05 Ponteiros: Declaração; Operadores e Aritmética; Uso em Parâmetros e Vetores.
    25 20/05 10h Ponteiros para void; Alocação Dinâmica de Memória.
    26 20/05 16h Prática em Laboratório
    27 24/05 Sequências de Caracteres (strings): Definição, Uso em Inicializações, Manipulação.
    28 27/05 10h Arquivos de Texto: Abertura, Leitura, Escrita, Fechamento.
    29 27/05 16h Prática em Laboratório
    30 31/05 Processamento de Arquivos de Texto
    31 03/06 10h Registros (struct's): Definição, Declaração, Inicialização, Acesso, Cópia.
    32 03/06 16h Prática em Laboratório
    33 07/06 Manipulação de Registros
    34 10/06 10h Exercícios sobre Registros, Ponteiros, Arquivos, etc.
    35 10/06 16h Prática em Laboratório — FIM DO CONTEÚDO DA AP2
    36 14/06 Representação de Matrizes via Vetores de Números
    37 17/06 10h Matrizes em C: Declaração, Inicialização, Manipulação em Funções, etc.
    38 17/06 16h Prática em Laboratório
    * 21/06 AP2 (Não Inclui Matrizes)
    39 24/06 10h Correção da AP2; Notas.
    40 24/06 16h Prática em Laboratório
    41 28/06 Bases Numéricas; Representação de Inteiros sem Sinal; Operadores de Bit.
    42 01/07 10h Representação de Inteiros em C (Sinal-e-Magnitude, Complemento de 1 e de 2).
    43 01/07 16h Prática em Laboratório
    44 05/07 Representação de Números em Ponto Flutuante (IEEE 754)
    45 08/07 10h Conversão do Padrão IEEE 754 para Decimal e Vice-Versa
    46 08/07 16h Prática em Laboratório
    * 12/07 AP3
    47 15/07 10h Correção da AP3; Notas.
    * 15/07 16h Prática em Laboratório
    * 19/07 AF
    * 21/07 Resultados Finais

    Aulas: Conteúdo, Materiais e Exercícios

    • Aulas 1–9 (2016-03-15 – 2016-04-08): foram ministradas pelo professor Bruno, que iniciou a disciplina.

      ASSUNTOS: veja o plano de atividades.

      EXERCÍCIOS: veja as duas listas de exercícios disponibilizadas no SIGAA.

    • Aula 10 (2016-04-12, terça-feira):

      • Estrutura de um Programa em C
      • Retorno e Parâmetros de Funções (incluindo void)
      • Simulação da Compilação e Execução de Programas
      • Inicialização dos Parâmetros na Chamada de uma Função
      • Diferenciação de Variáveis de Mesmo Nome mas de Funções Distintas

      CORREÇÃO: foi dito em sala que, quando uma função é declarada como retornando valor mas uma execução dela chega ao fim por atingir o fim do bloco da função ("}"), e não pela execução de um return, então o valor retornado é algum "lixo de memória", isto é, algum valor a priori desconhecido e dependente do estado do programa (KR, pág. 70). Com relação a isso:

      1. Foi dito em sala que isso valia inclusive para a função main, mas esse não é o caso: desde pelo menos C99, "atingir a } que termina a função main retorna um valor de 0" (C11, 5.1.2.2.3). Em particular, isso significa que, em programas simples, onde não há retorno significativo para o ambiente onde o programa é executado, nós podemos omitir o comando return da função main, simplificando o código sem consequências indesejáveis.

      2. Pelo padrão da linguagem, "se a } que termina uma função é atingida, e o valor da chamada da função é usado pelo chamador, o comportamento é indefinido" (C11, 6.9.1, item 12).

        Seja como for, exceto pela função main (caso especial discutido acima), se uma função é declarada como retornando valor mas uma execução dela pode terminar sem ser por meio de um return, isso é provavelmente um sinal de erro de programação (veja também KR, p. 70).

      OBSERVAÇÃO: em C, parâmetros são as variáveis utilizadas pelas funções para receber valores com os quais trabalhar, ao passo que argumentos são as expressões utilizadas, nas chamadas às funções, para fornecer esses valores (C11, 3.3 e 3.16). Parâmetros são variáveis de uma função, e como tais são inerentes à função; argumentos são expressões inerentes às chamadas das funções. Assim sendo, em princípio, devemos nos referir aos "parâmetros de uma função" e aos "argumentos de uma chamada".

      SOLUÇÕES DAS DÚVIDAS:

      1. Função sem parâmetros pode ter como argumento uma chamada a uma função sem retorno?

        Conforme adiantado em sala, não. Em C, função cuja lista de parâmetros consiste apenas em void não possui parâmetros (C11, 6.7.6.3, item 10), e, numa chamada de função, o número de argumentos deve ser igual ao número de parâmetros (C11, 6.5.2.2, item 2). Logo, por exemplo, o seguinte código está errado:

        void f (void)
          {
          ...
          }
        
        ...
        
        f( f() ); // ERRO: "f" tem 0 parâmetros, mas recebeu 1 argumento na chamada externa.
        
      2. É possível declarar funções com [ argumentos ou tipo de retorno ] diferentes mas com o mesmo nome em C?

        Não se a ideia é poder usá-las livremente, por exemplo usar ambas no mesmo trecho do código. Esse "uso livre" de funções é conhecido como sobrecarga (overload) e é permitido, por exemplo, na linguagem C++: a ideia é que, se duas funções possuem um mesmo nome "F" mas possuem, digamos, argumentos distintos, então, para se decidir se uma chamada a "F" se refere a uma função ou à outra, basta analisar a quantidade de argumentos utilizados na chamada, os tipos deles, etc. Em C, porém, esse recurso não existe, pois "entidades diferentes designadas pelo mesmo identificador ou têm escopos diferentes ou estão em diferentes espaços de nome" (C11, 6.2.1, item 2), e esse não seria o caso de funções diferentes sendo usadas num mesmo trecho de código.

        Observação: como não há sobrecarga de funções em C, algumas alternativas são:

        • Escrever uma única função, que receba a descrição dos tipos como argumento, a exemplo da função printf.

        • Colocar os nomes dos tipos nos nomes das funções, levando a funções de nomes semelhantes: somar_int, somar_double, etc.

        • Usar C++ ao invés de C. (Mas não nas provas desta disciplina! :-)) Isso não implica ter que usar o paradigma da orientação-a-objeto (C++ também permite o uso da programação estruturada), nem ter que aprender uma nova linguagem inteira (a maior parte da termilogia C também funciona em C++).

        • Usar o recurso _Generic introduzido em C11, e com o qual é possível simular sobrecarga manualmente.

      EXERCÍCIOS ESSENCIAIS:

      1. (Calculadora) Escreva um programa em C que primeiramente lê do usuário dois números inteiros; esses serão os "operandos". Em seguida, o programa deve ler um terceiro inteiro – a operação. Se esse último inteiro for 1, então o programa deve imprimir a soma dos operandos. Se o último inteiro for 2, então a subtração deve ser impressa. Idem para 3, 4, 5: multiplicação, quociente da divisão, resto da divisão. Caso o terceiro inteiro não seja um número de 1 a 5, o programa deve imprimir algo como "operação inválida". O programa também deve imprimir uma mensagem de erro em caso de divisão por zero.

      2. (Calculadora via Função) Faça uma variação do programa anterior, na qual haja uma função calc que receba os dois operandos e a operação (todos do tipo inteiro, como antes), e que imprima na tela o resultado da operação. A função calc não deve retornar valor algum, e deve ser chamada pela função main, na qual os números devem ser lidos do usuário.

    • Aula 11 (2016-04-15, sexta-feira, 10h):

      • Tratamento de Múltiplas Opções usando if-else
      • Tratamento de Múltiplas Opções usando switch
      • Repetição com Teste no Final: do-while
      • Repetição com Teste no Início: while

      EXERCÍCIOS ESSENCIAIS: veja os exercícios abaixo para a aula de laboratório.

    • Aula 12 (2016-04-15, sexta-feira, 16h): prática em laboratório.

      EXERCÍCIOS PARA O LABORATÓRIO: (SUGESTÃO: crie um arquivo .c para cada questão)

      1. Escreva um programa que lê um inteiro "n" do usuário e então imprime na tela o nome de um polígono de "n" lados (exemplo: 3 → triângulo). O seu programa deve aceitar pelo menos os números de 3 a 6; caso n < 3, o seu programa deve informar que não há polígono com menos de 3 lados, e, caso n > 6, deve informar que o número está fora do escopo do programa.

      2. Faça uma variação do programa anterior que leia o número "n" novamente até que ele esteja no intervalo aceito pelo programa.

      3. Faça uma variação do programa anterior que conte quantas vezes o usuário digitou um número fora do intervalo aceito pelo programa, e que imprima essa quantidade ao final ("você digitou … números fora do intervalo"). Para tanto:

        1. Mantenha um registro da quantidade de números "inválidos" já digitados pelo usuário. Naturalmente, no início essa quantidade é zero.

        2. A cada número inválido digitado pelo usuário, incremente a quantidade de números inválidos usando o operador unário prefixo ++ (o comando ++v; incrementa o valor de uma variável v).

      4. Faça uma variação do programa anterior ao final da qual, ao invés de ser impressa a quantidade de números inválidos digitados pelo usuário, é impressa uma avaliação do usuário:

        1. "Você foi um bom usuário!": se no máximo 3 números inválidos.

        2. "Você é um usuário teimoso!": se mais de 3 números inválidos. :-)

      5. Usando o aprendizado das 2 questões anteriores, escreva um pequeno programa que lê números inteiros do usuário até que ele digite um número negativo. Ao final, o programa deve imprimir a quantidade de números não-negativos digitados.

      6. Escreva uma variação do programa anterior ao final da qual é impressa não apenas a quantidade, mas também a soma dos números não-negativos digitados. Para tanto, use o comando v += exp; , que adiciona ao valor de uma variável v o valor de uma expressão exp.

      7. Escreva uma variação do programa anterior na qual, ao invés de ler números até que um número negativo seja digitado, o programa leia do usuário, em primeiro lugar, a quantidade "n" de números que serão digitados. Em seguida, o programa deve ler os "n" números (que agora podem inclusive ser negativos), e ao final a soma dos "n" números deve ser impressa na tela. Dica: mantenha um registro da quantidade de números que ainda precisam ser lidos do usuário.

      8. Escreva uma variação do programa anterior ao final da qual, além da soma dos "n" números, seja impressa também a quantidade de números negativos, positivos e nulos que foram digitados.

    • Aula 13 (2016-04-19, terça-feira):

      • Contagem usando um Laço
      • Soma usando um Laço
      • Atribuição usando o Valor da Variável Atribuída
      • Laço while com Variável de Controle
      • Laço for com Variável de Controle

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva um programa que lê um inteiro "n" do usuário e então imprime na tela o valor de n! = n*(n-1)*(n-2)*...*2*1.

        Observações:

        1. Se o usuário digitar um valor negativo para "n", a leitura de "n" deve acontecer novamente, até que um valor não-negativo seja digitado. Lembre que 0! = 1.

        2. O seu programa deve usar um laço para a realização do cálculo. Avalie que estrutura de repetição é a mais adequada (while, do-while ou for).

      2. Escreva um programa que lê um inteiro "n" do usuário e então imprime na tela o n-ésimo número de Fibonacci:

        fib(n) = | n,                   se n ≤ 1
                 | fib(n-2) + fib(n-1), se n > 1.
        
        As observações do exercício anterior também se aplicam aqui.
    • Aula 14 (2016-04-22, sexta-feira, 10h):

      • Conversões implícitas entre números racionais (double) e inteiros (int)
      • Conversões aritméticas comuns/padrão
      • Conversão explícita de tipo ("cast")
      • Caracteres em C: pequenos números
      • getchar e a entrada padrão como sucessão de linhas

      OBSERVAÇÃO: para compilar código que use funções de math.h por meio do compilador GCC, use -lm ao final ([1] [2] [3] [4]).

      EXERCÍCIOS: veja abaixo aqueles para a aula de laboratório.

    • Aula 15 (2016-04-22, sexta-feira, 16h): prática em laboratório.

      EXERCÍCIOS PARA O LABORATÓRIO: (SUGESTÃO: crie um arquivo .c para cada questão)

      1. Agora que você sabe o que acontece quando um double é convertido para um int, escreva uma função que receba um double "x" (possivelmente negativo) e que retorne o teto de "x", isto é, o menor inteiro que seja maior ou igual a "x". Esse cálculo deve ser feito por você mesmo (isto é, pela sua função), e não por uma chamada à funções da biblioteca padrão. Escreva também uma função para calcular o piso de "x" (que é o maior inteiro menor ou igual a "x"), e por fim escreva um programa que lê números do usuário e imprime o piso e o teto desses números. A quantidade de números que será lida pelo seu programa deve ficar sob a decisão do usuário, quer ele(a) informe a quantidade de números inicialmente, quer ele responda sempre se deseja digitar mais um número.

      2. Escreva uma função que calcule a distância euclidiana entre dois pontos em R². Depois, escreva um programa que imprima na tela o resultado dado por esta função para dois pontos digitados pelo usuário.

      3. Escreva um programa que leia caracteres do usuário e que imprima na tela os códigos desses caracteres. A condição de parada pode ser a leitura de algum caractere previamente escolhido (em sala, por exemplo, nós paramos após ler 'x').

      4. Escreva um programa que lê um inteiro do usuário e que então imprime na tela o caractere cujo código é o inteiro digitado.

      5. Escreva um programa lê caracteres do usuário (como o penúltimo programa acima) e que ao final imprime quantos dos caracteres lidos eram dígitos. Para tanto, use a função isdigit (<ctype.h>), que recebe um caractere e retorna verdadeiro se e somente se esse caractere é um dígito.

      6. Usando as funções de <ctype.h>, escreva uma extensão do programa anterior, que conta os dígitos, as letras maiúsculas (isupper), as minúsculas (islower) e os caracteres de pontuação (ispunct).

      7. Usando a função toupper, também de ctype.h, escreva um programa que lê letras minúsculas e que imprime as letras maiúsculas correspondentes. Você consegue ler o caractere de novo se ele não for uma letra minúscula? (Você pode supor que o usuário sempre digitará um caractere seguido de "enter"; outra opção é ignorar tudo o que tiver sido digitado depois do caractere em questão e antes do '\n correspondente.)

      8. Escreva um programa que lê do usuário um dígito, como um caractere, e então imprime o inteiro correspondente àquele dígito. A ideia é usar o fato de que a especificação de C garante que, se o código do caractere '0' é um número "x", então o código de '1' é "x+1", o de '2' é "x+2", etc. Lembre que constantes como 'a' e '3' são pequenos números em C, e que portanto podem ser manipulados numericamente.

      9. Usando o aprendizado do exercício anterior, escreva um programa que lê um vários dígitos (como caracteres), um por linha, e que ao final imprime a soma dos dígitos digitados pelo usuário. A digitação dos dígitos será dada como encerrada quando o programa ler o primeiro caractere que não seja nem um dígito nem um '\n'.

      10. Utilizando o aprendizado do exercício anterior, escreva uma função que lê do usuário dígitos consecutivos e que ao final retorne o int correspondente àqueles dígitos. A leitura dos dígitos deve parar após a detecção do primeiro caractere que não seja um dígito. Dica: 421 = (4*10 + 2)*10 + 1.

    • Aula 16 (2016-04-26, terça-feira):

      • Declaração de Vetores como Variáveis Automáticas (isto é, "internas" a uma função).
      • "Variable length arrays" ("VLAs": vetores cujo tamanho é uma expressão envolvendo variáveis, etc)
      • Acesso aos Elementos de um Vetor pelo Operador []
      • Percurso em um Vetor por meio de um Laço
      • Vetor como Argumento de Função
      • Inicialização de Vetores (inicialização parcial; inicialização por designadores; impossibilidade para VLAs)

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva um programa que leia "n" inteiros do usuário e que depois os imprima na tela na ordem contrária à que eles foram digitados.

      2. Escreva um programa que leia "n" inteiros do usuário e que depois repetidamente faça o seguinte:

        1. Leia um número "i".

        2. Se "i" não estiver no intervalo de 1 a n, o programa termina.

        3. Se "i" estiver no intervalo, então o programa deve imprimir na tela o i-ésimo número inicialmente digitado pelo usuário. Em seguida, deve-se retornar ao primeiro passo, para nova leitura de "i".

    • Aula 17 (2016-04-29, sexta-feira, 10h):

      • Verdadeiro e Falso em C
      • O Operador Condicional (?:)
      • O Comando break para Terminação de Laços
      • Uso do break em Percursos de Vetores

      EXERCÍCIOS: veja abaixo aqueles para a aula de laboratório.

    • Aula 18 (2016-04-29, sexta-feira, 16h): prática em laboratório.

      DICA (em 02/05/2016): execute e experimente com este programa, que usa a função getchar.

      EXERCÍCIOS PARA O LABORATÓRIO: (SUGESTÃO: crie um arquivo .c para cada questão)

      1. Escreva um programa que, usando repetidamente a função getchar, lê uma linha digitada pelo usuário e grava os caracteres num vetor (o tamanho do vetor pode ser informado pelo usuário no início). Em seguida, o programa deve ler do usuário mais um caractere, e, por meio de uma inspeção do vetor, imprimir na tela quantas vezes esse caractere ocorre na linha digitada inicialmente.

      2. Escreva uma variação do programa anterior na qual, ao invés de se imprimir a contagem, imprime-se apenas se o caractere ocorre na linha ou não.

        Observação: isso certamente poderia ser feito fazendo-se a contagem e verificando se o número de ocorrências é zero, mas eu lhe solicito que o faça usando o comando break, para interromper o percurso do vetor assim que for detectada uma ocorrência do caractere.

      3. Escreva uma variação do programa de leitura de linha na qual, depois da leitura da linha, são impressos os caracteres da linha, um sim e outro não, sucessivamente na mesma linha. Exemplo: se a linha inicial for "Computador", então a saída impressa ao final deve ser "Cmuao".

      4. Escreva uma variação do programa de leitura de linha na qual, ao final, o programa informa se a linha digitada é um palíndromo, isto é, uma palavra que é igual lida do início para o fim ou do fim para o início.

      5. Em sala, nós escrevemos uma função que descobre se dois vetores "v" e "w" de "n" inteiros são iguais ou não. Escreva agora uma função que descobre e eles possuem algum elemento em comum.

        Dica: percorra o vetor "v", e, para cada elemento de "v", verifique se esse elemento está em alguma posição de "w", parando o processo assim que possível.

      6. Escreva uma função que receba um vetor de inteiros e que informe se ele está ordenado, isto é, se todo elemento é menor ou igual ao seu sucessor no vetor. Usando essa função, escreva também um programa que lê do usuário um vetor de inteiros e então informa se o vetor digitado está ordenado ou não.

      7. Escreva uma função que descubra o maior número de um vetor de inteiros. Use essa função num programa que lê um vetor do usuário e depois imprime o maior valor digitado.

      8. Escreva uma função que ordene um vetor de "n" inteiros, seguindo a seguinte estratégia:

        1. Percorra o vetor, descubra o maior elemento e troque-o de posição com o último elemento do vetor.

        2. Agora que o maior elemento já está no final do vetor, repita o processo para os demais elementos. Em particular, percorra os n-1 primeiros elementos do vetor, descubra o maior deles e então troque-o com o elemento da posição n-1, assim sucessivamente.

        Use a sua função de ordenação para ordenar um vetor de inteiros digitado pelo usuário, imprimindo o vetor ordenado ao final. Use também a função de um exercício anterior para verificar se o vetor final está mesmo ordenado.

    • Aula 19 (2016-05-03, terça-feira):

      • Leitura e Escrita de Linhas Caractere-a-Caractere via getchar e putchar (stdio.h)
      • Manipulação de Caracteres via toupper e Funções Semelhantes em ctype.h
      • Atribuição como Expressão ("a = b = c = d = 0;", "if (a = b)", etc)

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva um programa que lê do usuário um texto, isto é, uma sequência de linhas. O fim do texto será a primeira linha vazia (sem caracteres, apenas um "enter") – esta é a parte mais interessante do programa. Ao final da leitura, o programa deve apenas informar ao usuário o número de linhas do texto. DICA: você não precisa armazenar as linhas do texto!

      2. Escreva uma extensão do programa anterior que, além de contar as linhas do texto, conte também as sentenças. Você pode supor que toda sentença termina com '.', '!' ou '?', e pode ignorar a ocorrência de reticências e complicadores semelhantes.

      3. Escreva uma extensão do programa anterior que conte também as palavras e os caracteres do texto.

        Observação: se você fizer esse exercício, terá escrito um programa semelhante ao wc, que é simples mas bastante útil.

    • Aula 20 (2016-05-05, quinta-feira, 16h) (Dia Alterado Devido ao Workshop da Computação):

      • Leitura de Números Naturais Dígito-a-Dígito via getchar
      • Definição e Exemplos de Uso do Operador Vírgula
        • Exemplo 1: Embutindo printf e scanf na Condição de um while (leitura de número positivo, contando as "falhas")
        • Exemplo 2: Uso de 2 Variáveis de Controle num Laço for (testar se uma palavra é um palíndromo)

      EXERCÍCIOS: veja abaixo aqueles para a aula de laboratório.

    • Aula 21 (2016-05-06, sexta-feira, 16h): prática em laboratório.

      EXERCÍCIOS PARA O LABORATÓRIO: (SUGESTÃO: crie um arquivo .c para cada questão)

      OBSERVAÇÃO: faça primeiramente os exercícios de terça-feira, e não se esqueça de que, além destes exercícios, há também os das aulas anteriores.

      1. Escreva um programa que lê várias linhas do usuário, e que ao final imprima para o usuário a maior delas, assim como o número de caracteres que ela tem (excluindo da contagem o '\n').

        Observação: Neste exercício e nos seguintes, você pode fixar um tamanho máximo para as linhas, digamos, 100 caracteres, de forma a poder armazená-las em vetores de tamanho previamente conhecido.

        Observação e dica: você não sabe quantas linhas o usuário vai digitar, mas isso não é um problema: dois vetores resolvem o problema para qualquer número de linhas!

      2. Escreva um programa que leia duas linhas do usuário e que ao final imprima quantas letras da primeira linha ocorrem também na segunda, excluindo o '\n' da contagem e sem se preocupar com a possibilidade de letras repetidas na primeira linha. Assim como no exercício anterior e nos demais, você pode estipular um tamanho máximo para as linhas.

      3. Escreva uma variação do exercício anterior na qual uma letra que ocorra mais de uma vez na primeira linha e que também ocorra na segunda linha seja contada apenas uma vez.

      4. Escreva um programa que leia duas linhas, e que conte quantas vezes a segunda ocorre como subsequência da primeira (excluindo o '\n' de consideração). Exemplo: se a primeira linha for "Olha, tem folhas no telhado!" e a segunda for "lha", então o programa deve imprimir 3.

        Sugestão:

        1. Escreva uma função que testa se na posição "p" de um vetor "v" há uma ocorrência de um vetor "w".

        2. Para cada posição da primeira linha, verifique se lá há uma ocorrência da segunda linha.

      5. Estenda o programa anterior para um texto inteiro, lendo primeiramente a sequência de caracteres a ser procurada e depois as linhas do texto. Você só precisa contar as ocorrências da sequência procurada que ocorram inteiramente numa linha (ou seja, não precisa se preocupar em contar ocorrências que comecem numa linha e terminem em outra).

        Observação: se você fizer esse exercício, então terá programado o utilíssimo recurso de busca de texto, encontrado em editores de texto, navegadores, etc.

    • 2016-05-10, terça-feira: Avaliação Parcial 1.

    • Aula 22 (2016-05-13, sexta-feira, 10h):

      • Devolução das Provas Corrigidas.
      • Tira-dúvidas e Solução das Questões 1–3 da Prova.
    • Aula 23 (2016-05-13, sexta-feira, 16h):

      • Solução da Questão 4 da AP1.
      • Tira-dúvidas sobre getchar e etc.
      • Prática em Laboratório.
    • Aula 24 (2016-05-17, terça-feira):

      • Motivação para Ponteiros: uma Função de Troca de Valores que Não Funciona.
      • Ponteiros e os Operadores & e * .
      • Declaração, Atribuição e Inicialização de Ponteiros.
      • Atribuição Indireta a Variáveis, via Ponteiros.
      • Funções de Troca e de Leitura via Ponteiros.
      • Ponteiros para Elementos de Vetores; Aritmética de Ponteiros.
      • Ponteiros para Vetores como Argumentos de Função.

      Observações e Material de Estudo:

      1. Como exemplificado em aula e explicado sucintamente aqui, a "aritmética de ponteiros" da linguagem C permite que um ponteiro aponte para o elemento seguinte ao último elemento de um vetor, embora não seja permitido ler o valor desse elemento. Já apontar para o elemento anterior ao primeiro elemento de um vetor infelizmente não possui a mesma garantia. :-(

      2. Este capítulo ensina ponteiros.

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva uma função que calcule a soma dos elementos de um vetor de inteiros; utilize ponteiros para percorrer o vetor (isto é, controlar o laço) e acessar os elementos dele.

        Em seguida, escreva um programa que utilize essa função, idealmente para um vetor informado pelo usuário.

      2. Escreva uma função que inverta os elementos de um vetor de caracteres, usando para isso dois ponteiros – um que percorra o vetor do início para o fim e outro do fim para o início –, e fazendo trocas até que eles se cruzem.

        Em seguida, utilize essa função num programa que:

        1. Leia uma linha do usuário.
        2. Inverta os caracteres da linha.
        3. Imprima a linha invertida para o usuário.
      3. Você consegue escrever o programa anterior usando [ ] apenas na declaração do vetor da linha, e usando ponteiros em todo o restante do código?

    • Aula 25 (2016-05-20, sexta-feira, 10h):

      • Conversão de Vetor para Ponteiro em C
      • Definição do Operador [ ] em C
      • Atribuição entre Ponteiros Incompatíveis em C
      • Ponteiros para void
      • Duração de Armazenamento de Variáveis em C: "Automática", "Estática" e "Alocada".
      • Exemplo de Programa Exibindo Vetores com os 3 Tipos de Duração.
      • Funções de Alocação Dinâmica de Memória: malloc, calloc, realloc e free.

      OBSERVAÇÃO: estude e experimente com este programa, que ilustra o uso das funções de alocação dinâmica de memória.

      EXERCÍCIOS: veja abaixo aqueles para a aula de laboratório.

    • Aula 26 (2016-05-20, sexta-feira, 16h): prática em laboratório.

      EXERCÍCIOS PARA O LABORATÓRIO: (SUGESTÃO: crie um arquivo .c para cada questão)

      1. Escreva um programa que lê "n" double's do usuário e que ao final os imprime na ordem contrária à que foram digitados. Utilize, obrigatoriamente, um vetor alocado dinamicamente.

      2. Escreva uma função que:

        1. Receba dois vetores de "n" números.
        2. Aloque um novo vetor, do mesmo tamanho.
        3. Grave no novo vetor a soma, elemento-a-elemento, dos dois vetores de entrada.
        4. Retorne o vetor alocado.

        Em seguida, escreva um programa que use a função acima, lendo do usuário os dois primeiros vetores, e ao final imprimindo o vetor soma; não se esqueça de desalocar tudo ao final!

      3. Escreva um programa que leia uma linha do usuário. O tamanho da linha é desconhecido, mas o seu programa deve armazená-la completamente, usando realloc para conseguir um vetor maior sempre que necessário. Ao final, imprima a linha lida do usuário.

      4. Escreva um programa que leia do usuário dois vetores de 5 números. Esses vetores devem ser alocados dinamicamente, e além disso os ponteiros para eles devem ser gravados num vetor de 3 ponteiros ( int *vp[3]; ou int *( v[3] ); ). Por fim, use a função de soma de um exercício anterior para alocar um terceiro vetor com a soma dos dois primeiros vetores. Esse novo vetor também deve ser apontado pelo vetor de ponteiros acima. Ao final, imprima para o usuário o vetor de soma.

      5. Combinando as ideias dos dois exercícios anteriores, escreva um programa que leia "n" linhas do usuário ("n" especificado pelo usuário). Cada linha deve estar num vetor alocado separadamente, sem limite de tamanho pré-estabelecido. Utilize um vetor de "n" ponteiros para apontar para as linhas. Ao final, imprima as linhas para o usuário.

      6. Generalize o exercício anterior para o caso em que o número de linhas que o usuário vai digitar é desconhecido. O final do texto será indicado pela primeira linha vazia (apenas o \n). Utilize realloc para realocar o vetor de ponteiros sempre que ele ficar cheio.

    • Aula 27 (2016-05-24, terça-feira):

      • Sequências de Escape
      • Literais de "string"
      • Função para Testar Igualdade entre Strings, Usando Ponteiros.
      • Operadores de Incremento e Decremento Pós-fixos.
      • Função Sucinta para Cópia de Strings, Usando Incremento Pós-fixo.

      EXERCÍCIOS ESSENCIAIS:

      1. Usando getchar para ler os caracteres, escreva uma função void ler_string (char *v, int n) que leia uma linha do usuário e grave-a num vetor "v" de tamanho "n". O \n do final da linha deve ser convertido num \0 para indicar o fim da "string". Caso o vetor não seja grande o suficiente para a linha, apenas os n−1 primeiros caracteres da linha devem ser armazenados, seguidos por um \0.

        Em seguida, usando putchar, escreva uma função void imp_string (char *s) que imprima na tela uma string. O \0 não deve ser impresso, mas também não deve ser convertido num \n.

        Por fim, escreva um programa que, usando as funções acima, leia uma linha do usuário e depois a imprima de volta na tela.

        Extra: experimente acrescentar ao programa acima uma leitura e uma escrita usando scanf, printf e %s: você verá que printf imprime toda a string (exceto o \0, claro), mas que scanf pára a leitura ao encontrar o primeiro caractere em branco (espaço, quebra de linha, tabulação, etc).

      2. Escreva uma função void ler_texto (char *v, int n) que grave, num vetor "v" de tamanho "n", um texto como uma string, isto é, como uma sequência de caracteres terminada por \0. Isso significa que várias linhas serão armazenadas como uma única string; o \n de cada linha também deve ser armazenado, assim como o \0 ao final. A leitura do texto deve ser feita caractere-a-caractere via getchar, e o tamanho do vetor deve ser respeitado, nos moldes da questão anterior. O fim do texto será indicado por uma linha vazia, que não deve ser armazenada no vetor.

    • Aula 28 (2016-05-27, sexta-feira, 10h):

      • Processo de Manipulação de Arquivos em C: Abertura, Uso, Fechamento.
      • Programa para Ler um Arquivo de Texto e Imprimi-lo na Tela (fopen em modo "r", fgetc, fclose).
      • Programa para Criar Cópias de Arquivos (fopen em modo "w", fputc).

      EXERCÍCIOS: veja abaixo aqueles para a aula de laboratório.

    • Aula 29 (2016-05-27, sexta-feira, 16h): prática em laboratório.

      EXERCÍCIOS PARA O LABORATÓRIO: (SUGESTÃO: crie um arquivo .c para cada questão)

      1. Escreva uma função int substr (char *r, char *s) que retorne 1 se a string "r" for substring de "s", e 0 em caso contrário.

        Exemplo: "sol" é substring de "solo" e "solar", mas não de "soma" nem de "Sol".

        Em seguida, escreva um programa que leia duas strings do usuário e que responda se uma é substring da outra.

      2. Escreva uma variação da função do exercício anterior, char * substr_ptr (char *r, char *s), que, ao invés de retornar 0 ou 1, retorne um ponteiro para o início da primeira ocorrência de "r" em "s", se houver tal ocorrência, e que retorne "r" se "r" não ocorrer em "s".

        Em seguida, adapte o programa da questão anterior para usar "substr_ptr" ao invés de "substr".

      3. Escreva um programa que leia do usuário o nome de um arquivo de texto e que em seguida imprima na tela as linhas do arquivo que comecem com letra maiúscula (use isupper).

      4. Escreva um programa que leia do usuário o nome de um arquivo de texto e que imprima na tela a linha mais longa do arquivo. Você não pode estabelecer previamente um limite máximo para o tamanho das linhas; ao invés disso, comece com um vetor dinamicamente alocado e use realloc sempre que necessário.

      5. Escreva um programa que leia do usuário o nome de um arquivo de texto e uma string, e que então imprima na tela as linhas do arquivo nas quais a string digitada aparece.

      6. Escreva uma variação deste exercício que conte as linhas, palavras, caracteres e sentenças de um arquivo informado pelo usuário.

    • Aula 30 (2016-05-31, terça-feira):

      • Exercícios em Sala, sobre Arquivos de Texto:
        1. Programa para Imprimir as Iniciais de um Nome Fixo em "iniciais.txt".

        2. Idem acima, mas lendo do usuário o nome, e identificando iniciais via isupper.

        3. Programa para Informar se a Primeira Linha de um Arquivo é ou não Vazia.

        4. Programa para Contar as Linhas de um Arquivo.

          • Observe que o programa da aula faz mais do que contar o número de \n's do arquivo, já que a última linha do arquivo pode não terminar com um '\n'.

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva um programa que, toda vez que é executado, adiciona ao final do arquivo "linhas.txt" uma linha lida do usuário, usando o modo "a" (append) para abrir o arquivo (o qual, assim como no modo "w", será criado se não existir ainda). Atenção: o seu programa tem que funcionar independentemente de quão grande seja a linha digitada pelo usuário.

      2. Escreva um programa que leia a primeira linha de um arquivo "texto.txt" e imprima na tela quantas vezes o último caractere da linha ocorre nela. Para tanto:

        1. Use um vetor alocado para ler a linha. O tamanho inicial dele não importa muito, mas, para fins da experimentação do seu programa, use um valor pequeno, como 5.

        2. Leia a linha caractere a caractere, gravando-os no vetor.

        3. Se houver um novo caractere a ser gravado mas o vetor estiver cheio, primeiro use realloc para obter um vetor duas vezes maior, e apenas depois grave o novo caractere no vetor.

        4. Ao final da leitura da linha, faça a contagem, e depois não se esqueça de desalocar o vetor.

    • Aula 31 (2016-06-03, sexta-feira, 10h):

      • Registros/estruturas (struct's):

        1. Definição de tipos
        2. Declaração de variáveis
        3. Inicialização por ordem e designada
        4. Cópia
        5. Acesso a membros/campos pelos operadores . e ->
        6. Exemplos de manipulação
      • Exercício em Sala: função retornando estrutura com quociente e resto dos 2 parâmetros inteiros.

      EXERCÍCIOS: veja abaixo aqueles para a aula de laboratório.

    • Aula 32 (2016-06-03, sexta-feira, 16h): prática em laboratório.

      EXERCÍCIOS PARA O LABORATÓRIO: (SUGESTÃO: crie um arquivo .c para cada questão)

      1. Utilizando um struct para armazenar pontos em R², escreva uma função que receba dois pontos em R² e retorne a distância entre eles (a função sqrt pode ser útil).

        Em seguida, escreva um programa que leia dois números do usuário e, utilizando a função acima, imprima na tela a distância entre eles.

      2. Escreva uma função que receba um vetor de "n" pontos em R² e que retorne, por meio de um registro, o menor retângulo que contém todos os "n" pontos (observe que 4 números são suficientes para determinar um retângulo).

        Em seguida, escreva um programa que leia do usuário um vetor de "n" pontos e que, utilizando a função acima, imprima na tela os dados do menor retângulo que contém todos os pontos digitados.

      3. Defina um tipo para armazenar uma data (dia, mês e ano). Em seguida, defina um tipo para armazenar o nome e a data de nascimento de uma pessoa. Daí, escreva um programa que leia do usuário um nome e uma data de nascimento, gravando-os num registro e em seguida armazenando-os num arquivo de texto (use fprintf para gravar cada campo). Certifique-se de que o arquivo final contém o conteúdo desejado.

      4. Escreva agora um programa que leia o arquivo gerado pelo programa acima, grave os dados num registro e em seguida os imprima na tela (use fscanf para ler os campos; a função fgets também pode ser útil para ler uma string até o fim da linha ou do arquivo (ao invés de parar no primeiro espaço em branco, como fscanf)).

      5. Estendendo os programas anteriores, escreva um programa que leia do usuário os nomes e nascimentos de "n" pessoas, gravando-os num arquivo de texto.

      6. Escreva um programa que leia do usuário uma data de nascimento e então, com base num arquivo produzido pelo programa anterior, imprima na tela os nomes das pessoas que nascem naquela data.

      7. Estenda o programa anterior para fazer consultas também pelo nome das pessoas; nesse caso, deve ser impressa na tela a data de nascimento da pessoa cujo nome o usuário digitar (você pode usar a função strcmp para comparar strings).

    • Aula 33 (2016-06-07, terça-feira):

      • Exercícios em Sala sobre Registros, Arquivos, etc:
        1. Programa para ler datas do usuário e gravar parte delas num arquivo (apenas aquelas do mesmo ano da última digitada).

        2. Programa para ler datas de um arquivo e então responder consultas do usuário (imprimir datas do mês fornecido pelo usuário).

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva um programa que leia do usuário "n" pares "(x,y)" de números reais, e que grave num arquivo "pares.txt" os pares que ficam no mesmo quadrante do último par digitado.

      2. Escreva um programa que leia de um arquivo "pares.txt" os pares ordenados escritos pelo programa anterior. Em seguida, responda consultas ao usuário: ele deve digitar um número "z" e o seu programa deve imprimir na tela os pares que possuem pelo menos uma coordenada igual a "z".

    • Aula 34 (2016-06-10, sexta-feira, 10h):

      • Revisão sobre Ponteiros, Alocação de memória e Vetores com o professor Yuri Lenon.
    • Aula 35 (2016-06-10, sexta-feira, 16h): prática em laboratório com o professor Yuri Lenon.

      • Questão sobre leitura e escrita de strings.
      • Tira-dúvidas individuais sobre outras questões.
    • Aula 36 (2016-06-14, terça-feira):

      • Simulação de Matrizes por Vetores de Números:
        1. Relação entre os elementos de um vetor de 4 números e os elementos de uma matriz 2x2.

        2. Programa para ler uma matriz 2x2 e informar se ela é ou não a matriz identidade.

        3. Relação entre os elementos de uma matriz 3x4 e aqueles de um vetor de 12 elementos, e daí para o caso geral de uma matriz "m x n".

        4. Programa para ler duas matrizes 2x3, somá-las e imprimir a soma para o usuário.

      • Matrizes em C: Vetores de Vetores.
        int i;        // um inteiro
        int v[3];     // um vetor de 3 inteiros
        int M[2][3];  // um vetor de 2 vetores de 3 inteiros, ou seja,
                      // uma matriz de 2 linhas e 3 colunas.
        int N[3][2] = { {-1,4},
                        { 2,7},
                        { 0,9} };      // Essa inicialização poderia estar numa única linha.
        int j,k;                       // dois inteiros
        int *pj = &j;                  // um ponteiro para inteiro
        int *(vp[3]) = { &i, &j, &k }; // um vetor de 3 ponteiros para inteiro
        

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva um programa que leia do usuário uma matriz "m x n" ("m" e "n" sendo informados pelo usuário no início do programa) e que então informe se ela é ou não triangular superior.

      2. Escreva um programa que:

        1. Leia (do usuário) inteiros positivos "m" e "n".

        2. Leia uma matriz "m x n".

        3. Leia inteiros "i" e "j" (de 1 a "m").

        4. Adicione os números da linha "i" aos números da linha "j".

        5. Imprima a matriz resultante em forma retangular (experimente usar %4d em printf).

    • Aula 37 (2016-06-17, sexta-feira, 10h):

      • Regras de Declaração de Vetores e Ponteiros, com exemplos.

      • Observação sobre o armazenamento contíguo de linhas, mas não de colunas, de matrizes em C.

      • Função para Trocar Colunas de Matriz; Programa que a Utiliza.

      EXERCÍCIOS: veja abaixo aqueles para a aula de laboratório.

    • Aula 38 (2016-06-17, sexta-feira, 16h): prática em laboratório.

      EXERCÍCIOS PARA O LABORATÓRIO: (SUGESTÃO: crie um arquivo .c para cada questão)

      1. Escreva uma função void transpor (int n, int A[n][n]) que receba uma matriz "n x n" e que a transforme na matriz transposta.

        Em seguida, escreva um programa que leia do usuário uma matriz "n x n", utilize a função acima para computar a matriz transposta, e finalmente imprima o resultado em forma retangular na tela (lembre que usar algo como %4d em printf pode lhe ajudar a alinhar as colunas).

      2. Escreva um programa que leia duas matrizes A e B de dimensões "p x q" e "q x r" e que imprima na tela o produto de "A" e "B".

      3. Escreva um programa que leia uma matriz de um arquivo de texto, imprima-a na tela e informe se ela é ou não simétrica.

      4. Escreva um programa que leia do usuário uma matriz de 5 linhas de tamanhos possivelmente diferentes (informados pelo usuário). Aloque cada linha dinamicamente, e utilize um vetor de 5 ponteiros para apontar para as linhas. Em seguida, trocando os ponteiros, inverta as linhas da matriz, e então imprima o resultado para o usuário.

      5. Escreva um programa que:

        1. Leia do usuário uma matriz "m x n" de racionais.

        2. Leia inteiros "i" e "j" de 1 a "m".

        3. Leia um racional "k".

        4. Adicione os números da linha "i", multiplicados por "k", aos números da linha "j".

        5. Imprima a matriz resultante em forma retangular.

      6. Desenvolvendo o exercício anterior, escreva um programa que:

        1. Leia do usuário uma matriz "m x n".

        2. Adicione múltiplos da 1ª linha às demais linhas, de forma que todos os números da 1ª coluna se tornem zero, exceto o da 1ª linha.

      7. Desenvolvendo o programa anterior, escreva um programa que leia uma matriz e, por meio de operações de adição de um múltiplo de uma linha a outra, transforme a matriz original numa matriz triangular superior (ou seja, numa matriz com apenas zeros abaixo da diagonal principal).

    • 2016-06-21, terça-feira: AP2.

    • Aula 39 (2016-06-24, sexta-feira, 10h): correção da AP2.

    • Aula 40 (2016-06-24, sexta-feira, 16h): prática em laboratório (AP2 e exercícios anteriores).

    • Aula 41 (2016-06-28, terça-feira):

      • Introdução à Representação de Números Naturais: Base Unária, Sistemas "Símbolo-Valor" (ex.: números romanos) e Sistema Posicional.

      • Conversão entre Bases no Sistema Posicional

      • Inteiros sem Sinal (Números Naturais) em C:

        1. unsigned int: representação e tamanho.

        2. Constantes (limits.h): CHAR_BIT, UINT_MAX, ULONG_MAX, ULLONG_MAX.

        3. Aritmética Modular de Inteiros sem Sinal.

        4. Operadores Bit-a-Bit: ~ << >> & ^ | .

        5. Exemplo: Função Recursiva para Imprimir Número em Binário usando Operadores de Bit.

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva:

        1. (100)10 na base 3.

        2. (615)7 na base 9.

        3. (FACA)16 na base 2.

      2. Escreva um programa que leia um inteiro sem sinal do usuário (use %u em scanf) e em seguida grave num vetor os dígitos desse número na base "b", sendo "b" um número também lido do usuário. Ao final, usando o vetor, o programa deve imprimir esses dígitos na tela. (Dica: como você descobriria os dígitos com papel-e-caneta?)

    • Aula 42 (2016-07-01, sexta-feira, 10h):

      • Introdução à Representação de Números Inteiros em C.
      • Representação por Sinal-e-Magnitude.
      • Representação por Complemento de 1.
      • Representação por Complemento de 2.

      EXERCÍCIOS ESSENCIAIS:

      1. Escreva uma tabela de 8 linhas e 5 colunas. A primeira coluna deve conter os números binários 000, 001, 010, …, 111. As outras 4 colunas devem ser preenchidas com a interpretação de cada um dos 8 números binários de acordo com as representações de inteiro sem sinal, sinal-e-magnitude, complemento de 1 e complemento de 2. Exemplo: "100" significa "4" na notação de inteiro sem sinal, "-0" em sinal-e-magnitude, "-3" em complemento de 1 e "-4" em complemento de 2.

      2. Com relação às 4 notações estudadas (inteiros sem sinal, sinal-e-magnitude, complemento de 1 e complemento de 2):

        1. Escreva os números -37, -126 e -65 utilizando 8 bits.

        2. As sequências 10100010, 11100101 e 10010100 representam que números em cada notação?

    • Aula 43 (2016-07-01, sexta-feira, 16h): prática em laboratório (exercícios anteriores).

    • Aula 44 (2016-07-05, terça-feira):

      • Notação Científica: Geral e Normalizada.

      • Leitura e Impressão de Racionais em C, incluindo Notação Científica:

        • %e, %f, %g, largura mínima (%3d, %7f), precisão (%.2f, %10.3e).

      • Representação de Inteiros por "Excesso de K"

      • Números Fracionários em Binário; Conversão para Decimal.

      • Representação de Racionais segundo o Padrão IEEE 754:

        1. Sinal: 1 bit.

        2. Expoente: w bits, representado por Excesso de K = 2w − 1 − 1.

        3. Significando: os demais bits (ficando implícito o dígito 1 antes da vírgula).

      EXERCÍCIOS ESSENCIAIS:

      1. Quais são as representações em 8 bits dos números 101, −77 e −38 nas notações de Sinal-e-Magnitude, Complemento de 1, Complemento de 2 e Excesso de K = 127? E na notação científica normalizada em base 10?

      2. Interpretando as sequências de bits abaixo segundo o padrão IEEE 754 com 8 bits para o expoente, que números elas representam?

        (Veja as respostas no código fonte html dos itens abaixo, mas resolva todos os itens primeiro, para não ver a resposta de um item posterior antes de resolvê-lo.)

        1. 0100 0011 1100 1000 0000 0000 0000 0000

        2. 0100 0011 1010 0000 0000 1000 0000 0000

        3. 1100 0001 1110 0010 0000 0000 0000 0000

        4. 1011 1111 1000 0000 0000 0000 0000 0000

    • Aula 45 (2016-07-08, sexta-feira, 10h):

      • Padrão IEEE 754:

        1. Tipos de Valores: Infinitos, NaNs, Zeros, Números Denormalizados e Normalizados.

        2. Exemplos de Operações que Produzem Infinito e NaN.

        3. Interpretação de Números Normalizados e Denormalizados; Exemplos.

      • Conversão de Números Fracionários da Base 10 para a 2 e para o Formato IEEE 754.

      EXERCÍCIOS ESSENCIAIS:

      1. Descubra quais são os números abaixo segundo o padrão IEEE 754 utilizando 8 bits para o expoente (respostas no código fonte html dos itens, mas resolva todos os itens antes de olhá-las!).

        1. 0100 0011 1111 1110 0100 0011 0011 0011

        2. 1100 0100 1011 1010 0110 0000 0000 0000

        3. 1111 1111 1000 0000 0000 0000 0000 0000

        4. 0111 1111 1000 0000 0000 0000 0000 0001

      2. Escreva os números 30, −191, 1000,25 e −1,78125 na representação do exercício anterior (IEEE 754, 32 bits ao todo, 8 bits para o expoente) (ao final, confira as respostas no código fonte).

    • Aula 46 (2016-07-08, sexta-feira, 16h): entrega das AP2 e prática em laboratório (exercícios anteriores).