Teste

Conjunto de problemas 1

Estude o programa a seguir e responda às perguntas abaixo. Gostaríamos que você respondesse às perguntas analisando apenas o código-fonte, ou seja, não o copie em um arquivo, compile-o e responda às perguntas com base na execução. Isso vai tirar toda a diversão!

int main() {
  int counter, first, last, next;
  first = 1; last = 2;

  for (counter = first; counter <= last; counter++) {
    cout << "\n " << counter;
    next = counter * counter;
    cout << " " << next;
  }

  counter = first;
  while (counter <= last) {
    cout << "\n " << counter;
    next = counter * counter;
    cout << " " << next;
    counter++;
  }

  counter = first;
  do {
    cout << "\n " << counter;
    next = counter * counter;
    cout << " " << next;
    counter++;
  } while (counter < last);
}

Pergunta 1: qual é o resultado do programa?

R) 1 2
2 4
1 2
2 4
1 2
2:4
B) 1 1
2 4
1 1
2 4
1 1
2 4
C) 1 1
2 4
1 1
2 4
1 1
D) 1 1
2 4
1 1
1 1
2 4
E) Não gera resultados. Há erros de sintaxe.

Pergunta 2: o que aconteceria se removêssemos a inicialização do "counter" antes da repetição do-while?

R) Um loop infinito: o loop do-while gera uma série de
B) O resultado do programa não vai mudar
C) A repetição do-while gera 2 e 4.
D) A repetição do-while não gera resultados
E) As saídas do loop do-while são 3 e 9.

Pergunta 3: Dado o programa original no topo desta página, suponha que temos removeu a linha que inicializa a variável de contador antes da repetição while. O quê? aconteceria se também removêssemos a linha do contador ++ dentro da repetição, como em o seguinte?

R) A repetição "while" não gera nada.
B) A repetição "while" resulta em 1 e 1. a repetição do-while não gera resultados.
C) A saída do loop "while" é a mesma de quando ambas as linhas são incluída.
D) O sistema vai gerar números aleatórios até ligarmos o computador
E) A repetição "while" é infinita

Pergunta 4: Dado o programa original no topo desta página, o que aconteceria se a repetição "while" fosse assim?

counter = first;
while (counter <= last) {
  cout << "\n" << counter;
  if (first % 2 == 0)
    next = counter * counter;
  cout << "  " << next;
  counter++;
}
R) A saída da repetição "while" é a mesma do programa original.
B) A repetição "while" não gera nada
C) A saída da repetição "while" é 1 1 e 1 4.
D) A saída da repetição "while" é 1 2 e 2 4.
E) A saída da repetição "while" é 1 4 e 2 4.
F) A saída da repetição "while" é 2 4 e 2 4.

Pergunta 5: o que aconteceria se a primeira variável fosse maior que a última?

R) A repetição "while" vai gerar algo, mas nada mais vai gerar.
B) A repetição do código ao vivo gera uma saída, mas nada mais gera.
C) Não haverá saída.
D) O programa vai encontrar falhas ou falhas
E) A repetição "for" gera uma saída, mas nada mais gera.

Pergunta 6: qual será a saída do programa se inicializarmos a primeira variável igual à última variável?

R) A repetição do código ao vivo gera uma saída, mas nada mais gera.
B) A repetição "while" vai gerar algo, mas nada mais vai gerar.
C) Cada loop vai gerar uma linha.
D) A repetição do código do processo gera 2 linhas, e o da repetição do processo gera uma linha.
E) Não vai gerar uma saída
F) A repetição "for" gera uma saída, mas nada mais gera.


Conjunto de problemas 2

Como no conjunto de problemas anterior, aqui está um programa para você considerar. Responda às perguntas a seguir observando apenas o código-fonte.

#include <iostream>
using namespace std;

int main() {
  int Boys = 3, Girls = 5;
  void F1(int males, int females);
  void F2(int &m, int &f);

  F1(Boys, Girls);
  cout << "\nAfter calling F1, within main()";
  cout << "\n\tBoys = " << Boys; // #2
  cout << "\n\tGirls = " << Girls;

  F2(Boys, Girls);
  cout << "\nAfter calling F2, within main()";
  cout << "\n\tBoys = " << Boys; // #4
  cout << "\n\tGirls = " << Girls;
}

void F1(int b, int g) {
  b += 3, g += 4;
  cout << "\nF1";
  cout << "\n\tBoys = " << b; // #1
  cout << "\n\tGirls = " << g;
}

void F2(int &b, int &g) {
  b = b + 8, g = g + 5;
  cout << "\nF2";
  cout << "\n\tBoys = " << b; // #3
  cout << "\n\tGirls = " << g;
}

Pergunta 1: qual é o resultado da variável Boys nas linhas marcadas?

R) 1: 6
2: 3
3: 11
4: 11
B) 1: 6
2: 3
3: 11
4: 3
C) 1: 6
2: 6
3: 11
4: 11
D) Ele não gera resultados porque não é compilado nem executado.

Pergunta 2: escolha todas as opções que se aplicam com relação às seguintes linhas do programa:

void F1(int males, int females);
void F2(int &m, int &f);
R) As regras do C++ afirmam que é possível remover essas duas linhas, desde que os métodos são definidos antes do uso.
B) As regras do C++ declaram que os nomes dos argumentos precisam ser os mesmos entre declaração e definição.
C) Este programa falhará se removermos essas duas linhas.
D) É mais comum que as declarações sejam feitas no formato do projeto.
E) Essas são as declarações encaminhadas.

Pergunta 3: se movermos a linha a seguir de main() e colocá-la na escopo, o que vai acontecer?

int Boys = 3, Girls = 5;
R) A saída será a mesma.
B) Meninos = 3 e Meninas = 5 em toda a saída
C) Meninos = 3 e Meninas = 5 apenas na saída de main()

Pergunta 4: e se mudássemos o início do programa para ficar assim:

// We have moved moved these to global scope
const int Boys = 3;
const int Girls = 5;

void main() {
  //int Boys = 3, Girls = 5;
R) O programa seria compilado, mas falhava quando tentávamos executá-lo.
B) Não haveria mudanças na saída
C) O resultado seria Boys = 3 Girls = 5 ao longo do programa
D) O resultado seria Boys = 3 Girls = 5 apenas na saída de main()
E) O programa provavelmente não será compilado (dependendo do compilador).

Pergunta 5: os dados são transmitidos por valor em F2.

R) Verdadeiro
B) Falso


Conjunto de problemas 3

Como no conjunto de problemas anterior, aqui está um programa para você considerar. Não se esqueça responder às perguntas a seguir observando apenas o código-fonte.Este é mais interessantes que os dois anteriores, rastreie o código cuidadosamente.

#include <iostream>
using namespace std;

const int MAX_SIZE = 20;
typedef int ARR2D[MAX_SIZE][MAX_SIZE];

void Print(ARR2D in_array, int rows, int cols);
void Fill(ARR2D in_array, int rows, int cols);

int main() {
  ARR2D matrix;
  int row, col;
  do {
    cout << "Please enter the size of the matrix to generate (rows and cols) :" << endl;
    cin >> row >> col;
  } while (row <= 0 || row > MAX_SIZE || col <= 0 || col > MAX_SIZE);
  Fill(matrix, row, col);
  Print(matrix, row, col);
  return(0);
}

void Print(ARR2D in_array, int rows, int cols) {
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++)
      cout << '\t' << in_array[i][j];
    cout << endl;
  }
}

void Fill(ARR2D in_array, int rows, int cols) {
  for(int i = 0; i < rows; i++)
    for (int j = 0; j < cols; j++)
      in_array[i][j] = 0;

  const int limit = rows * cols;
  int cNum = 1;
  int cRow = 0;
  int cCol = 0;
  int cDir = 0;  // 0-north, 1-east, 2-south, 3-west

  while(true) {
    // Place the number.
    in_array[cRow][cCol] = cNum;
    cNum++;
    if (cNum > limit) break;

    int fRow = cRow;
    int fCol = cCol;
    while (true) {
      fRow = cRow;
      fCol = cCol;
      switch(cDir) {
        case 0: fRow--; break;
        case 1: fCol++; break;
        case 2: fRow++; break;
        case 3: fCol--; break;
      }

      if ( fRow >= 0 && fRow < rows && fCol >= 0 && fCol < cols && in_array[fRow][fCol] == 0)
        break;
      cDir = (cDir + 1) % 4;
    }
    cRow = fRow;
    cCol = fCol;
  }
}

Pergunta 1: qual é a saída do programa com a entrada 3 para linhas e 4 para colunas?

R) 1 2 3
4 5 6
7 8 9
10 11 12
B) 1 2 3 4
5 6 7 8
9 10 11 12
C) 12 11 10 9
8 7 6 5
4 3 2 1
D) 1 3 2 4
8 6 7 5
9:11 1012
E) 1 2 3 4
10 11 12 5
9 8 7 6
P) 9 8 7 6
10 11 12 5
1 2 3 4
A) Ele não emite nada. A lógica está defeituosa.
I) Não emite nada, há erros de sintaxe.
J) Isso não acontece porque não deveria.
K) Ela gera os 12 primeiros números que vêm à sua mente enquanto você espera a execução do programa.

Pergunta 2: e se adicionarmos a linha a seguir à função main()?

MAX_SIZE = 10;
R) Isso não é permitido em C++.
B) Isto é permitido; o programa seria executado com MAX_SIZE definido como 20
C) Isto é permitido; o programa seria executado com MAX_SIZE definido como 10.

Pergunta 3: considere as quatro linhas do programa acima:

const int MAX_SIZE = 20;
typedef int ARR2D [MAX_SIZE][MAX_SIZE];

void Print  (ARR2D A, int rows, int cols);
void Fill   (ARR2D A, int rows, int cols);

1) É possível usar um const em um typedef?
2) É possível usar um typedef em uma declaração antes que uma variável seja declarada desse tipo?

R) 1) Sim 2) Sim
B) 1) Não 2) Não
C) 1) Não 2) Sim
D) 1) Sim 2) Não

Pergunta 4: podemos usar o seguinte:

#define MAX_SIZE 20
em vez de:
const int MAX_SIZE = 20;
R) Sim, funcionará e não há problema em usar #define para constantes no C++
B) Sim, funciona, mas normalmente não usamos #define para constantes em C++
C) #define não está disponível em C++
D) Não é possível fazer nenhuma dessas coisas em C

Pergunta 5: typedef é usado para criar um alias para um nome de tipo.

R) Verdadeiro
B) Falso

Pergunta 6: o que aconteceria se não inicializássemos a matriz como 0 no Função Fill()?

R) Ele será executado, mas a saída será todas as 12
B) Ele vai funcionar bem e gerar a mesma saída como se a matriz fosse inicializado como 0
C) O programa não será executado ou falhará
D) Ele será executado, mas a saída será todos 0s
E) Ele será executado, mas talvez não gere nenhuma saída

Pergunta 7: Selecione todas as opções aplicáveis. Por que usamos const para MAX_SIZE neste programa? Não é mais fácil digitar apenas "20" em vez de MAX_SIZE onde quer que esteja necessário?

R) MAX_SIZE é um valor C++ integrado que qualquer pessoa pode usar. Pronto e usá-los.
B) Evite as constantes globais, assim como as variáveis globais
C) O uso de um constante torna nosso programa mais fácil de entender
D) Números mágicos em um programa geralmente são considerados uma boa prática.
E) Se quisermos alterar MAX_SIZE, precisamos alterá-lo de uma só vez lugar

Pergunta 8: a instrução switch na função Fill() deve ter um valor nesse caso, porque é considerado bom estilo incluir um.

R) Verdadeiro
B) Falso

Pergunta 9: Observe que, na função Fill(), declaramos variáveis entre instruções. Por exemplo, cNum e cRow são declarados e inicializados após a execução de um loop for. Isso funcionará em C++ ou todas as variáveis precisam ser declaradas no topo do a função?

R) Não há problema em fazer isso.
B) Todas as variáveis precisam ser declaradas no topo da função.
C) As duas maneiras estão erradas: o C++ não permite variáveis em nenhum lugar da neste programa.
D) Todas as variáveis precisam ser declaradas no escopo global.

Conjunto de problemas 4

Este é um conjunto de arquivos que definem e testam uma classe simples. Como sempre, responda às perguntas a seguir mencionando apenas o código-fonte.

Este é o arquivo de cabeçalho (cow.h):

#ifndef COW_H
#define COW_H

using namespace std;

typedef enum Color {black, brown, beige, blackandwhite, nocolor};

class Cow {
 public:
  Cow();
  ~Cow();

  // accessors
  double weight() { return weight_; };
  string name() { return name_; };
  Color color() { return color_; };

  // mutators
  void set_name(string inName) { name_ = inName; };
  void set_color(Color inColor) { color_ = inColor; };
  void set_weight(double inWeight) {weight_ = inWeight; };

  void Moo();
  void Properties();

 private:
  Color color_;
  double weight_;
  string name_;
};

#endif

Este é o arquivo .cc associado (cow.cc):

#include <iostream>
#include "cow.h"

using namespace std;

Cow::Cow() {}

Cow::~Cow() {}

void Cow::Moo() {
  cout << name() << " says MOO." << endl;
}

void Cow::Properties() {
  cout << name() << " weighs " << weight() << ", is "
       << color() << " and says MOO." << endl;
}

E este é um programa cliente para essa classe (cowmain.cc):

#include <iostream>
#include "cow.h"

using namespace std;

int main() {
  Cow cow1;
  cow1.set_name("betsy");
  cow1.set_weight(400.0);
  cow1.set_color(black);

  cow1.Moo();
  cow1.Properties();
}

Pergunta 1: o que esse programa gera?

R) Betsy diz MOO.
betsy pesa 400, é 0 e diz MOO.
B) Betsy diz MOO.
betsy pesa 400, é preta e diz MOO.
C) Betsy diz MOO.
betsy pesa 400, é

Pergunta 2: nunca devemos colocar o código em métodos de acesso e mutador em um arquivo de cabeçalho. (Observe que um acessador é um método que retorna um valor, e um mutador é um método que modifica um valor.)

R) Verdadeiro
B) Falso

Pergunta 3: precisamos que o "Cow::" antes de cada uma das definições de função em cow.cc?

R) Não, já que cow.h está incluído
B) Sim

Pergunta 4: qual é o papel:

#ifndef COW_H
#define COW_H
...
#endif

reproduzir no arquivo principal?

Marque todas as opções válidas:

R) Eles não servem para nenhuma finalidade porque o nome do arquivo é cow.h. e não COW_H.
B) Se não fizéssemos isso, obteríamos um erro de tempo de execução
C) Se não fizermos isso, poderemos incluir o arquivo mais de uma vez
D) Eles não fazem nada porque uma ou mais palavras-chave contêm erros ortográficos.
E) Eles não fazem nada porque a classe Cow tem apenas um arquivo de cabeçalho.

Pergunta 5: o que aconteceria se adicionássemos a linha a seguir a cowmain.cc?

cow1.weight_ = 24;
R) O programa seria executado, e a variável de peso seria modificada por esta linha.
B) O programa era compilado e executado, mas falhava nessa linha.
C) O C++ não permite isso.
D) O programa seria compilado e executado, mas a variável de peso não é alterado por esta linha.

Pergunta 6: quando a linha a seguir é executada, o construtor na classe Cow é chamado:

Cow cow1;

Quais são algumas características importantes dos construtores?

Escolha todas as opções válidas.

R) Elas geralmente não retornam valores
B) Se não fornecermos um construtor em nossa classe, ela não compilar
C) O construtor na classe Cow é atípico, porque não inicializa as variáveis privadas.
D) Eles sempre têm o mesmo nome da classe
E) Podemos ter vários construtores em uma classe, desde que os argumentos diferem
F) Um construtor é invocado quando uma classe é instanciada.

Pergunta 7: Quais são algumas características importantes de um destruidor?

R) Um destrutor é chamado quando um objeto sai do escopo.
B) Um destrutor tem o mesmo nome da classe, mas precedido por "~"
C) Há algo errado com o destructor em cow.cc em que não faz nada.
D) Se não criarmos um destrutor para a classe, ela não compilar

Pergunta 8: considerando a forma como o programa cliente está usando a classe, considere o seguinte:

A divisão de membros em público e privado na classe Vaca não é apropriada. Ou seja, algo privado deve ser público ou algo que é público deve ser privado.

R) Verdadeiro
B) Falso

Pergunta 9: e se adicionarmos outro construtor além daquele que "cow.cc". O novo construtor tem a seguinte aparência:

Cow::Cow(string inName, double inWeight, Color inColor) {
  set_name(inName);
  set_weight(inWeight);
  set_color(inColor);
}

E adicionamos as seguintes linhas a main():

Cow cow2("milly", 350.2, brown);
cow2.Moo();
cow2.Properties();

Podemos fazer isso?

Escolha todas as opções válidas.

R) A linha em main() em que inicializamos cow2 vai falhar.
B) Só podemos ter um construtor.
C) Isso é comum em C++
D) Sim, mas esse não é um uso comum do C++
E) Isso funcionará normalmente, mas não gerará nada porque o privates não são inicializados.
F) Não podemos chamar setName(), setColor() e setWeight() de dentro um método da mesma classe.


Perguntas bônus

Pergunta 1) Qual é o resultado?

#include <iostream>
using namespace std;

void HelpMe(int *p, int *num, int *q);
void WhereAmI(int *p, int *q, int a);

void HelpMe(int *p, int *num, int *q) {
  int a;

  a = 2;
  q = &a;
  *p = *q + *num;
  num = p;
}


void WhereAmI(int *p, int *q, int a) {
  a = 6;
  *p = a + *p;
  *q = a + 3;
  HelpMe(q, &a, p);
}


int main() {
  int *p;
  int q;
  int *num;
  int a;

  a = 3;
  q = 5;
  p = &a;
  num = &q;

  HelpMe(&a, p, num);
  WhereAmI(&q, p, *num);

  cout << "*p = " << *p << " q = " << q << " *num = " << *num << endl;
}
 

Pergunta 2) Considere a seguinte instrução, supondo que uma classe Apple existe e foi inicializada. A classe Apple tem uma variável de instância color_:

Apple* granny_smith = new Apple; 

Escolha todas as afirmações verdadeiras abaixo:

R) Apple* granny_smith = NULL; if (granny_smith == NULL)... Isto não é aceitável - NULL não é um valor que pode ser verificado dessa maneira.
B) Maçã* granny_smith, fuji; Declara dois ponteiros para objetos da Apple.
C) A variável "granny_smith" contém os valores de variável de instância associados a um objeto da Apple.
D) Apple* granny_smith = NULL; Tudo bem,
E) A variável "granny_smith" contém o endereço de um objeto da Apple.
F) string gs_color = *(granny_smith.get_color()); Essa instrução retorna a cor do objeto granny_smith, supondo que ele tenha sido inicializado.
P) O armazenamento do novo objeto da Apple é alocado na heap.
A) O armazenamento do novo objeto da Apple é alocado na pilha do ambiente de execução.
I) int* a = &b; Isso coloca o endereço de b em a.


Pergunta 3) Qual é o resultado do programa a seguir?

#include <iostream>
using namespace std;

const int kNumVeggies = 4;

void Grill(int squash, int *mushroom);
int Saute(int onions[], int celery);


void Grill(int squash, int *mushroom) {
  *mushroom = squash/4;
  cout << *mushroom + squash << endl;
}

int Saute(int onions[], int celery) {
  celery *= 2;
  onions[celery]++;
  Grill(onions[0], &onions[3]);
  cout << celery << " " << onions[3] << endl;
  return celery;
}

int main() {
  int broccoli, peppers[kNumVeggies], *zucchini;

  for (broccoli = 0; broccoli < kNumVeggies; broccoli++)
    peppers[broccoli] = kNumVeggies - broccoli;
  zucchini = &peppers[Saute(peppers,1)];
  Grill(*zucchini, zucchini);
  zucchini--;
  cout << peppers[3] + *zucchini + *(zucchini + 1) << endl;
}


Respostas do teste

Responda a todas as perguntas acima sem ler as respostas. É melhor pedir ajuda a alguém do que ir direto para a folha de respostas.

Veja as respostas para os problemas acima aqui.