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
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.