Teste

Conjunto de problemas 1

Estude o programa a seguir e responda às perguntas abaixo. Queremos que você responda à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 dele. Isso vai acabar com 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 desse programa?

A) 1 2
2 4
1 2
2 4
1 2
2 4
B) 1
2 4
1
2 4
1
2 4
C) 1
2 4
1
2 4
1
D) 1 1
2 4
1 1
1 1
2 4
E) Ele não gera nenhuma resposta, como há erros de sintaxe.

Pergunta 2: o que aconteceria se a inicialização do "contador" fosse removida antes da repetição "do-while"?

A) Uma repetição infinita: a repetição do-while vai produzir uma série de 1s
B) A saída do programa não vai mudar
C) A repetição do-while gera 2 e 4.
D) A repetição do-while não resultará em nada
E) A repetição do-while gera 3 e 9.

Pergunta 3: considerando o programa original no topo desta página, suponha que removemos a linha que inicializa a variável de contador antes do loop "while". O que aconteceria se também removêssemos a linha contador++ dentro do "while-loop", como no exemplo a seguir?

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

Pergunta 4: considerando o programa original na parte superior 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++;
}
A) A saída da repetição "while" é a mesma do programa original.
B) A repetição "while" não gera resultados
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?

A) A repetição "while" produzirá algo, mas nada mais.
B) A repetição "fazer" vai gerar algo, mas nada mais vai.
C) Não haverá saída.
D) O programa vai separar por falha ou falha
E) A repetição for gera uma saída, mas nada mais.

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

A) A repetição "fazer" vai gerar algo, mas nada mais vai.
B) A repetição "while" produzirá algo, mas nada mais.
C) Cada loop gera uma linha.
D) A repetição "AND" vai produzir duas linhas e a outra vai gerar uma repetição.
E) Não vai gerar nada
F) A repetição for gera uma saída, mas nada mais.


Conjunto de problemas 2

Como no conjunto de problemas anterior, este é um programa para sua consideração. 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 é a saída da variável Boys nas linhas marcadas?

A) 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) Ela não gera resultados porque não é compilado nem executado.

Pergunta 2: escolha todas as opções que se aplicam relacionadas às seguintes linhas do programa:

void F1(int males, int females);
void F2(int &m, int &f);
A) As regras do C++ declaram que é possível remover essas duas linhas, desde que os métodos sejam definidos antes do uso.
B) As regras C++ declaram que os nomes dos argumentos precisam ser os mesmos na declaração e na definição.
C) Este programa falhará se removermos essas duas linhas.
D) É mais comum que as declarações sejam declaradas no escopo global.
E) Elas são chamadas de declarações de encaminhamento.

Pergunta 3: se movermos a linha a seguir de main() e a colocarmos no escopo global, o que acontecerá?

int Boys = 3, Girls = 5;
A) A saída seria 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 que fique assim:

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

void main() {
  //int Boys = 3, Girls = 5;
A) O programa vai ser compilado, mas vai falhar quando for executado.
B) Não haveria mudanças na saída
C) A saída seria Meninos = 3 Meninas = 5 durante todo o programa
D) A saída seria Boys = 3 Girls = 5 apenas na saída de main()
E) O programa provavelmente não vai ser compilado (dependendo do compilador).

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

A) Verdadeiro
B) Falso


Conjunto de problemas 3

Como no conjunto de problemas anterior, este é um programa para sua consideração. Responda às perguntas a seguir observando apenas o código-fonte.Este é mais interessante do que os dois anteriores. Acompanhe o código com cuidado.

#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: o que esse programa gera com entradas 3 para linhas e 4 para colunas?

A) 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 10 12
E) 1 2 3 4
10 11 12 5
9 8 7 6
G) 9 8 7 6
10 11 12 5
1 2 3 4
A) Ele não gera nenhuma resposta. A lógica está com defeito.
I) Ele não gera nenhuma resposta, há erros de sintaxe.
J) Ela não gera nenhuma resposta, como deveria.
K) A saída são os 12 primeiros números que vêm à mente enquanto você espera a execução do programa.

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

MAX_SIZE = 10;
A) Isso não é permitido em C++.
B) Isso é permitido; o programa seria executado com MAX_SIZE definido para 20
C) Isso é permitido. O programa será executado com MAX_SIZE definido como 10.

Pergunta 3: considere as quatro linhas a seguir 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 uma constante em um typedef?
2) É possível usar um typedef em uma declaração antes de uma variável ser declarada desse tipo?

A) 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;
A) Sim, isso vai funcionar, e não há problema em usar #define para constantes em C++
B) Sim, vai funcionar, mas geralmente 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.

A) Verdadeiro
B) Falso

Pergunta 6: o que aconteceria se a matriz não fosse inicializada como 0 na função Fill()?

A) Ela será executada, mas a saída será todas as
B) Ele funcionará bem e gerará a mesma saída como se a matriz fosse inicializada como 0.
C) O programa não vai ser executado ou vai falhar
D) Ela será executada, mas a saída será totalmente 0
E) Ela será executada, mas talvez não gere nenhuma saída

Pergunta 7: marque todas as opções que se aplicam. Por que usamos const para MAX_SIZE neste programa? Não é mais fácil digitar "20" em vez de MAX_SIZE onde for necessário?

A) MAX_SIZE é um valor C++ integrado que qualquer pessoa pode usar. Basta configurar e usar.
B) As constantes globais devem ser evitadas, assim como as variáveis globais
C) Usar uma constante torna nosso programa mais fácil de entender
D) Os números mágicos em um programa geralmente são considerados boas práticas.
E) Se quisermos mudar MAX_SIZE, precisaremos alterá-lo em um só lugar.

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

A) 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 precisarão ser declaradas na parte de cima da função?

A) Não há problema em fazer isso.
B) Todas as variáveis precisam ser declaradas no topo da função.
C) Ambas as formas estão erradas. O C++ não permite variáveis em nenhum lugar do programa.
D) Todas as variáveis precisam ser declaradas no escopo global.

Conjunto de problemas 4

Veja um conjunto de arquivos que definem e testam uma classe simples. Como de costume, responda às perguntas seguintes consultando apenas o código-fonte.

Este é o arquivo principal (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 veja um programa cliente para esta 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?

A) 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 dos métodos acessador e mutador em um arquivo principal. Observe que um acessador é um método que retorna um valor e um mutador é um método que modifica um valor.

A) Verdadeiro
B) Falso

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

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

Pergunta 4: Qual função:

#ifndef COW_H
#define COW_H
...
#endif

são reproduzidos no arquivo de cabeçalho?

Marque todas as opções válidas:

A) Eles não têm utilidade porque o nome do arquivo é cow.h, não COW_H.
B) Se isso não fosse feito, receberíamos um erro durante a execução.
C) Se não fizermos isso, podemos incluir o arquivo mais de uma vez
D) Eles não fazem nada porque uma ou mais das palavras-chave estão com a grafia incorreta.
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 ao cowmain.cc?

cow1.weight_ = 24;
A) O programa seria executado, e a variável de peso seria modificada por essa linha.
B) O programa seria compilado e executado, mas falharia nessa linha.
C) O C++ não permite isso.
D) O programa será compilado e executado, mas a variável de peso não será alterada por essa 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.

A) Eles geralmente não retornam nenhum valor
B) Se não fornecermos um construtor na classe, ela não vai compilar
C) O construtor na classe Cow é atípico, já que 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 sejam diferentes
F) Um construtor é invocado quando uma classe é instanciada.

Pergunta 7: quais são algumas características importantes de um destrutor?

A) 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 no destrutor em cow.cc, porque ele não faz nada.
D) Se não criarmos um destrutor para a classe, ela não será compilada

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

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

A) Verdadeiro
B) Falso

Pergunta 9: e se adicionarmos outro construtor além daquele que temos em cow.cc? O novo construtor vai ficar assim

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.

A) A linha em main() em que inicializamos cow2 falhará.
B) Só podemos ter um construtor.
C) Isso é comum em C++
D) Sim, mas esse não é o uso típico de C++
E) Isso funcionará sem problemas, mas não terá saída porque os particulares não são inicializados.
F) Não é possível chamar setName(), setColor() e setWeight() de dentro de um método da mesma classe.


Perguntas bônus

Pergunta 1) Qual é a saída do seguinte?

#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 afirmaçã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:

A) Maçã* granny_smith = NULL; if (granny_smith == NULL)... NÃO é um problema, porque NULL não é um valor que pode ser verificado dessa maneira.
B) Apple* granny_smith, fuji; declara dois ponteiros para objetos Apple
C) A variável granny_smith contém os valores da 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.
G) O armazenamento do novo objeto da Apple é alocado no heap
A) O armazenamento do novo objeto da Apple é alocado na pilha de ambiente de execução.
I) int* a = &b; 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

Você deve responder a todas as perguntas acima sem ver 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.