Quiz

Ensemble de problèmes 1

Étudiez le programme suivant, puis répondez aux questions ci-dessous. Nous aimerions que vous répondiez aux questions en examinant uniquement le code source. Autrement dit, veuillez ne pas le copier dans un fichier, le compiler et répondre aux questions en fonction de son exécution. Ça va t'arranger.

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);
}

Question 1: Quels sont les résultats de ce programme ?

A) 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. Elle ne renvoie aucune information, car elle contient des erreurs de syntaxe.

Question 2: Que se passerait-il si nous supprimions l'initialisation de "counter" avant la boucle "do-while" ?

A) Boucle infinie : elle génère une série de 1
B) La sortie du programme ne changera pas
C) La boucle do-while génère les valeurs 2 et 4.
D) La boucle "do-while" ne génère aucun résultat
E. La boucle do-while génère les valeurs 3 et 9.

Question 3: Compte tenu du programme d'origine affiché en haut de cette page, supposons que nous avons supprimé la ligne qui initialise la variable de compteur avant la boucle while. Que se passe-t-il si nous supprimons également la ligne counter++ dans la boucle "while", comme illustré ci-dessous ?

A) La boucle "while" ne produit rien.
B) La boucle "while" génère les valeurs 1 et 1. La boucle "do-while" ne produit rien.
C) Le résultat de la boucle "while" est le même que lorsque les deux lignes sont incluses.
D) Le système affichera des nombres aléatoires jusqu'à ce que nous éteignions l'ordinateur.
E. La boucle "while" est une boucle infinie.

Question 4: Compte tenu du programme d'origine en haut de cette page, que se passerait-il si la boucle "while" ressemblait à ceci ?

counter = first;
while (counter <= last) {
  cout << "\n" << counter;
  if (first % 2 == 0)
    next = counter * counter;
  cout << "  " << next;
  counter++;
}
A) La sortie de la boucle "while" est identique à celle du programme d'origine.
B) La boucle "while" ne génère rien
C) La sortie de la boucle "while" est 1 1 et 1 4.
D) La sortie de la boucle "while" est 1 2 et 2 4.
E. La sortie de la boucle "while" est 1 4 et 2 4.
F) La sortie de la boucle "while" est 2 4 et 2 4.

Question 5: Que se passerait-il si la première variable est supérieure à la dernière ?

A) La boucle "while" produit un résultat, mais rien d'autre.
B) La boucle faire pendant affiche une sortie, mais rien d'autre.
C) Il n'y aura aucun résultat.
D) Le programme plantera ou plantera
E. La boucle For produit un résultat, mais rien d'autre.

Question 6: Quel sera le résultat du programme si nous initialisons la première variable pour qu'elle soit identique à la dernière ?

A) La boucle faire pendant affiche une sortie, mais rien d'autre.
B) La boucle "while" produit un résultat, mais rien d'autre.
C) Chaque boucle affiche une ligne.
D) La boucle "dowhile" produit deux lignes et l'autre une boucle.
E. Elle ne générera rien
F) La boucle For produit un résultat, mais rien d'autre.


Ensemble de problèmes 2

Comme pour l'ensemble de problèmes précédent, voici un programme que vous pouvez prendre en compte. Veuillez répondre aux questions qui suivent en examinant uniquement le code source.

#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;
}

Question 1: Quelle est la sortie de la variable "Boys" sur les lignes marquées ?

A) N° 1: 6
#2: 3
#3: 11
#4: 11
B) N° 1: 6
#2: 3
#3: 11
#4: 3
C) N° 1: 6
#2: 6
#3: 11
#4: 11
D) Il ne génère rien, car il n'est pas compilé ou exécuté.

Question 2: Sélectionnez toutes les réponses qui s'appliquent aux lignes suivantes du programme:

void F1(int males, int females);
void F2(int &m, int &f);
A) Les règles C++ indiquent que nous pouvons supprimer ces deux lignes tant que les méthodes sont définies avant utilisation.
B) Les règles C++ stipulent que les noms des arguments doivent être identiques entre la déclaration et la définition.
C) Ce programme plante si nous supprimons ces deux lignes.
D) Il est plus courant que les déclarations soient indiquées dans le champ d'application global.
E. C'est ce qu'on appelle des déclarations de transfert.

Question 3: Que se passe-t-il si nous déplaçons la ligne suivante de main() et que nous la plaçons dans le champ d'application global ?

int Boys = 3, Girls = 5;
A) Le résultat serait le même.
B) Garçons = 3 et filles = 5
C) Les garçons = 3 et les filles = 5 uniquement dans la sortie de main()

Question 4: Que se passerait-il si nous modifiions le début du programme comme suit:

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

void main() {
  //int Boys = 3, Girls = 5;
A) Le programme se compile, mais plante lorsque nous essayons de l'exécuter.
B) Le résultat ne sera pas modifié
C) Le résultat est "Garçons = 3 filles = 5" tout au long du programme.
D) Le résultat serait "Boys = 3 Girls = 5" uniquement dans la sortie de main().
E. Le programme ne sera probablement pas compilé (en fonction du compilateur).

Question 5: Les données sont transmises par valeur dans F2.

A) Vrai
B) Faux


Ensemble de problèmes 3

Comme pour l'ensemble de problèmes précédent, voici un programme que vous pouvez prendre en compte. Veuillez répondre aux questions qui suivent en examinant uniquement le code source.Cette méthode est plus intéressante que les deux précédentes : tracez soigneusement le code.

#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;
  }
}

Question 1: Que produit ce programme avec une entrée de 3 pour les lignes et de 4 pour les colonnes ?

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
h) Elle ne renvoie aucune information, car la logique est défaillante.
I) Elle ne renvoie aucune information, car elle contient des erreurs de syntaxe.
J) Il ne génère rien, alors qu'il n'est pas censé le faire.
000) Elle génère les 12 premiers chiffres qui vous viennent à l'esprit lorsque vous attendez que le programme s'exécute.

Question 2: Et si nous ajoutions la ligne suivante à notre fonction main() ?

MAX_SIZE = 10;
A) Cela n'est pas autorisé en C++.
B) Ceci est autorisé, le programme s'exécuterait avec MAX_SIZE défini sur 20
C) Cela est autorisé, car le programme s'exécuterait avec MAX_SIZE défini sur 10.

Question 3: Prenons les quatre lignes suivantes du programme ci-dessus:

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) Est-il possible d'utiliser une constante dans une définition de type ?
2) Est-il possible d'utiliser un typedef dans une déclaration avant qu'une variable de ce type ne soit déclarée ?

A) 1) Oui 2) Oui
B) 1) Non 2) Non
C) 1) Non 2) Oui
D) 1) Oui 2) Non

Question 4 : Pouvons-nous utiliser les éléments suivants ?

#define MAX_SIZE 20
au lieu de :
const int MAX_SIZE = 20;
A) Oui, cela fonctionne. Vous pouvez utiliser #define pour les constantes en C++.
B) Oui, mais cela fonctionne, mais nous n'utilisons généralement pas #define pour les constantes en C++
C) #define n'est pas disponible en C++
D) Vous ne pouvez effectuer aucune de ces opérations en langage C.

Question 5: typedef est utilisé pour créer un alias pour un nom de type.

A) Vrai
B) Faux

Question 6: Que se passerait-il si le tableau n'était pas initialisé sur 0 dans la fonction Fill() ?

A) Il s'exécutera, mais le résultat sera l'intégralité des 12
B) Il fonctionnera correctement et générera la même sortie que si le tableau était initialisé sur 0
C) Le programme ne s'exécutera pas ou plantera
D) Il sera exécuté, mais le résultat sera tous les zéros
E. Elle s'exécutera, mais ne générera peut-être aucune sortie

Question 7: Cochez toutes les réponses applicables. Pourquoi utiliser "const" pour MAX_SIZE dans ce programme ? N'est-il pas plus facile de saisir "20" au lieu de MAX_SIZE chaque fois que cela est nécessaire ?

A) MAX_SIZE est une valeur C++ intégrée accessible à tous. Il vous suffit de la configurer et de l'utiliser.
B) Les constantes globales doivent être évitées, tout comme les variables globales
C) L'utilisation d'une constante facilite la compréhension de notre programme
D) Les chiffres magiques dans un programme sont généralement considérés comme une bonne pratique.
E. Pour modifier MAX_SIZE, il suffit de le faire à un seul endroit

Question 8: L'instruction switch de la fonction Fill() devrait comporter un cas par défaut, car il est considéré comme approprié d'en inclure un.

A) Vrai
B) Faux

Question 9: Notez que dans la fonction Fill(), nous déclarons les variables entre les instructions. Par exemple, les colonnes cNum et cRow sont déclarées et initialisées après l'exécution d'une boucle "for". Cela fonctionnera-t-il en C++ ou faut-il que toutes les variables soient déclarées en haut de la fonction ?

A) Ce n'est pas un problème.
B) Toutes les variables doivent être déclarées en haut de la fonction.
C) Les deux méthodes sont incorrectes. C++ n'autorise les variables nulle part dans un programme.
D) Toutes les variables doivent être déclarées dans le champ d'application global.

Ensemble de problèmes 4

Voici un ensemble de fichiers définissant et testant une classe simple. Comme d'habitude, répondez aux questions qui suivent en vous reportant uniquement au code source.

Voici le fichier d'en-tête (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

Voici le fichier .cc associé (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;
}

Voici un programme client pour ce cours (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();
}

Question 1: Que produit ce programme ?

A) Betsy dit MOO.
bétisse pèse 400 $, est 0 et dit MOO.
B) Betsy dit MOO.
Betsy pèse 400 $, est noire et dit MOO.
C) Betsy dit MOO.
betsy pèse 400, est

Question 2: Nous ne devons jamais placer le code des méthodes d'accesseur et de mutateur dans un fichier d'en-tête. Notez qu'un accesseur est une méthode qui renvoie une valeur, et qu'un mutateur est une méthode qui modifie une valeur.

A) Vrai
B) Faux

Question 3: Ai-je besoin de la mention "Cow::" avant chacune des définitions de fonction dans cow.cc ?

A) Non, car cow.h est inclus
B) Oui

Question 4 : Quel est le rôle ?

#ifndef COW_H
#define COW_H
...
#endif

dans le fichier d'en-tête ?

Sélectionnez toutes les réponses qui s'appliquent.

A) Ils ne servent à rien, car le nom du fichier est cow.h et non COW_H.
B) Si nous ne le faisions pas, nous obtiendrions une erreur d'exécution.
C) Si nous ne le faisons pas, nous pouvons inclure le fichier plusieurs fois
D) Il ne fait rien, car un ou plusieurs mots clés sont mal orthographiés.
E. Ils ne font rien, car la classe Cow n'a qu'un seul fichier d'en-tête.

Question 5: Que se passerait-il si nous ajoutions la ligne suivante à cowmain.cc ?

cow1.weight_ = 24;
A) Le programme s'exécuterait et la variable de pondération serait modifiée par cette ligne.
B) Le programme se compile et s'exécute, mais plante sur cette ligne.
C) C++ ne le permet pas.
D) Le programme est compilé et exécuté, mais la variable de pondération n'est pas modifiée par cette ligne.

Question 6: Lorsque la ligne suivante est exécutée, le constructeur de la classe Cow est appelé:

Cow cow1;

Quelles sont les caractéristiques importantes des constructeurs ?

Plusieurs réponses sont possibles.

A) Elles ne renvoient généralement aucune valeur
B) Si nous ne fournissons pas de constructeur dans notre classe, celle-ci ne sera pas compilée.
C) Le constructeur de la classe Cow est atypique, car il n'initialise pas les variables privées.
D) Elles portent toujours le même nom que la classe.
E. Une classe peut contenir plusieurs constructeurs, à condition que les arguments diffèrent.
F) Un constructeur est appelé lorsqu'une classe est instanciée.

Question 7: Quelles sont les caractéristiques importantes d'un destructeur ?

A) Un destructeur est appelé lorsqu'un objet sort du champ d'application.
B) Un destructeur porte le même nom que la classe, mais précédé de "~"
C) Le destructeur de cow.cc ne fonctionne pas correctement.
D) Si nous ne créons pas de destructeur pour notre classe, celle-ci ne sera pas compilée.

Question 8: Compte tenu de la manière dont le programme client utilise la classe, tenez compte des points suivants:

La division des membres en public et en privé dans la classe Cow n'est pas appropriée. Autrement dit, quelque chose de privé devrait être public, ou quelque chose de public devrait être privé.

A) Vrai
B) Faux

Question 9: Que se passe-t-il si nous ajoutions un autre constructeur en plus de celui qui doit être cow.cc ? Voici à quoi ressemble le nouveau constructeur :

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

Et nous ajoutons les lignes suivantes à main():

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

aux clients ?

Plusieurs réponses sont possibles.

A) La ligne dans main() où nous initialisons cow2 plantera.
B) Nous ne pouvons avoir qu'un seul constructeur.
C) Ceci est courant en C++
D) Oui, mais ce n'est pas une utilisation typique de C++
E. Cette opération s'exécutera correctement, mais ne générera rien, car les éléments privés ne sont pas initialisés.
F) Nous ne pouvons pas appeler setName(), setColor() et setWeight() à partir d'une méthode de la même classe.


Questions bonus

Question 1) Quel résultat obtenez-vous ?

#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;
}
 

Question 2) Considérez l'instruction suivante, en supposant qu'une classe Apple existe et ait été initialisée. La classe Apple comporte une variable d'instance color_ :

Apple* granny_smith = new Apple; 

Parmi les affirmations suivantes, sélectionnez celles qui sont vraies:

A) Apple* granny_smith = NULL; if (granny_smith == NULL)... Ce n'est PAS autorisé. NULL n'est pas une valeur qui peut être vérifiée de cette manière.
B) Apple* granny_smith, fuji ; déclare deux pointeurs vers des objets Apple
C) La variable granny_smith contient les valeurs de variable d'instance associées à un objet Apple
D) Apple* granny_smith = NULL. Ce n'est pas grave,
E. La variable granny_smith contient l'adresse d'un objet Apple
F) string gs_color = *(granny_smith.get_color(;) Cette instruction renvoie la couleur de l'objet granny_smith, en supposant qu'il ait été initialisé.
G) Le stockage du nouvel objet Apple est alloué dans le tas de mémoire
h) Le stockage du nouvel objet Apple est alloué sur la pile d'exécution
I) int* a = &b; Cela place l'adresse de b dans a.


Question 3) Quel est le résultat du programme suivant ?

#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;
}


Réponses au quiz

Vous devez essayer de répondre à toutes les questions ci-dessus sans regarder les réponses. Il est préférable de demander de l'aide à quelqu'un plutôt que d'accéder directement à la feuille de réponses pour obtenir de l'aide.

Vous pouvez consulter les réponses aux problèmes ci-dessus ici.