Introdução C++

De MediaWiki do Campus São José
Revisão de 15h18min de 4 de agosto de 2015 por Msobral (discussão | contribs) (Criou página com '* [http://glu.fcfrp.usp.br/tulio/materiais/c++.pdf Introdução a C++ (USP)] * [http://www.inf.ufrgs.br/~johann/cpp2004/ Introdução a C++ (UFRGS)] * [http://orion.lcg.ufrj.br/C...')
(dif) ← Edição anterior | Revisão atual (dif) | Versão posterior → (dif)
Ir para navegação Ir para pesquisar

A linguagem de programa a ser usada se chama C++. Como indica o nome, essa linguagem é uma extensão à linguagem C, de forma a aderir ao paradigma de orientação a objetos. Como esse assunto será visto em profundidade na 4a fase, na disciplina de POO (Programação Orientada a Objetos), faremos um uso mais superficial dessa linguagem. Quer dizer, usaremos algumas de suas construções, mas não nos deteremos em seus aspectos teóricos. O objetivo de usar C++ é introduzir essa linguagem, que será usada em próximas disciplinas.

Para iniciar o uso da linguagem, vamos começar com um exemplo clássico do tipo hello world:

#include <iostream>

using namespace std;

int main() {
  cout << "Hello world !" << endl;

  return 0;
}

Para compilar este exemplo, grave-o em um arquivo com extensão .cc.Supondo que o nome do arquivo seja hello.cc, pode-se compilá-lo assim:

g++ -o hello hello.cc

O comando acima deve gerar um arquivo executável chamado hello. Para executá-lo, faça o seguinte:

./hello

O exemplo acima pode ser estendido para mostrar como ler dados do teclado:

#include <iostream>
#include <stdio.h>
 
using namespace std;
 
int main() {
  int x;

  cout << "Hello world !" << endl;
  cout << "x: ";
  cin >> x;
  cout << "Voce digitou " << x << endl; 
  return 0;
}

Mas o que tem de especial a linguagem C++ ? Muita coisa, se comparada à linguagem C. Veja este exemplo sobre horários em ambas linguagens:

#include <stdio.h>

struct Horario {
  unsigned int hora, minuto, segundo;
};

struct Horario criaHorario(unsigned int h, unsigned int m, unsigned int s) {
    struct Horario horario;

    if (h < 24) horario.hora = h;
    else horario.hora = 0;

    if (m < 60) horario.minuto = m;
    else horario.minuto = 0;

    if (s < 60) horario.segundo = s;
    else horario.segundo = 0;

    return horario;
}

char * mostraHorario(struct Horario horario) {
  static char buffer[32];

  snprintf(buffer, 32, "%u:%u:%u", horario.hora, horario.minuto, horario.segundo);
  return buffer;
}

void acrescenta(struct Horario * horario, struct Horario * outro) {
    horario->segundo = horario->segundo + outro->segundo;
    if (horario->segundo > 59) {
      horario->minuto++;
      horario->segundo = horario->segundo - 60;
    }
    horario->minuto = horario->minuto + outro->minuto;
    if (horario->minuto > 59) {
      horario->hora++;
      horario->minuto = horario->minuto - 60;
    }
    horario->hora = horario->hora + outro->hora;
    if (horario->hora > 23) horario->hora = horario->hora - 24;
}


int main() {
  struct Horario h1 = criaHorario(9, 45, 0);
  struct Horario h2 = criaHorario(15,20,30);

  printf("horario 1: %s\n", mostraHorario(h1));
  printf("horario 2: %s\n", mostraHorario(h2));

  acrescenta(&h1, &h2);
  printf("horario 1 + horario 2: %s\n", mostraHorario(h1));
}

Um exemplo em linguagem C


#include <iostream>

using namespace std;

class Horario {
 private:
  unsigned int hora, minuto, segundo;
 public:
  Horario() {
    hora = minuto = segundo = 0;
  }

  Horario(unsigned int h, unsigned int m, unsigned int s) {
    if (h < 24) hora = h;
    else hora = 0;

    if (m < 60) minuto = m;
    else minuto = 0;

    if (s < 60) segundo = s;
    else segundo = 0;
  }

  ~Horario() {}

  void mostreSe(ostream & out) {
    out << hora << ":" << minuto << ":" << segundo;
  }

  void acrescenta(Horario outro) {
    segundo = segundo + outro.segundo;
    if (segundo > 59) {
      minuto++;
      segundo = segundo - 60;
    }
    minuto = minuto + outro.minuto;
    if (minuto > 59) {
      hora++;
      minuto = minuto - 60;
    }
    hora = hora + outro.hora;
    if (hora > 23) hora = hora - 24;
  }
};

int main() {
  Horario h1(9,45,0);
  Horario h2(15,20,30);

  cout << "horario 1: ";
  h1.mostreSe(cout);
  cout << endl;

  cout << "horario 2: ";
  h2.mostreSe(cout);
  cout << endl;

  cout << "horario 1 + horario 2: ";
  h1.acrescenta(h2);
  h1.mostreSe(cout);
  cout << endl;
}

O mesmo exemplo em linguagem C++


As diferenças não são superficiais, apesar de existirem muitas semelhanças e analogias poderem ser feitas entre os programas. Para entender algumas das novidades de C++, é necessária uma pequena introdução a alguns conceitos essenciais da linguagem.

1 Classes e objetos

A linguagem C foi projetada segundo um paradigma de programação chamado de programação estruturada. Essa forma de expressar programas se baseia em subrotinas (funções no caso da linguagem C), blocos de instruções e laços de repetição, os quais atuam sobre variáveis que contêm os dados a serem acessados e transformados. O que se deve notar é a forma com que se costuma modelar um programa nesse caso, dando-se ênfase aos algoritmos que modificam os dados. Não é à toa que uma ferramenta de modelagem tradicional e ainda muito usada seja o fluxograma. Porém existem outras formas de pensar os problemas a serem resolvidos e expressar programas, dentre elas o paradigma de orientação a objetos seguido por diversas linguagens tais como C++, Java e Python.


Um programa orientado a objetos é composto por objetos que interagem. Um objeto é uma abstração que representa uma coisa que faz parte do problema a ser resolvido. Um objeto contém dados que representam seu estado (chamados de atributos), e procedimentos que representam seu comportamento (chamados de métodos). No caso do exemplo dos horários, um horário pode ser representado por um objeto. O estado desse objeto Horario é definido pelos valores de hora, minuto e segundo, e seu comportamento é dado pelos métodos mostreSe e acrescenta. Isso deve ser entendido da seguinte forma: um objeto 'Horario pode ser mostrado, ao se chamar seu método 'mostreSe, e pode ser somado a outro objeto Horario, ao se chamar seu método acrescenta. Essas são as únicas operações definidas para esse objeto, e assim nada mais se consegue fazer com ele ... a não ser que se definam novas operações.


Muitos objetos similares podem existir. Por exemplo, pode haver muitos diferentes objetos Horario, que se diferenciam por seus estados (valores de hora, minuto e segundo). Todos os objetos cujos estados são definidos pelo mesmo conjunto de atributos, e que possuem o mesmo comportamento (conjunto de métodos), pertencem à mesma classe. O conceito de classe é semelhante ao de tipo de dados, porém tem uma implicação mais profunda. Um tipo de dados define como o conteúdo de uma variável deve ser interpretado (ex: um número inteiro, ponto flutuante, uma string, ...), porém não define os procedimentos que podem manipular essas variáveis. Desta forma, uma classe vincula a seus objetos os algoritmos que atuam sobre eles. Isso tem uma importante implicação no acoplamento e coesão de um programa, que são métricas fundamentais de qualidade de um projeto de software modular.


Mas isso está um tanto abstrato ... o exemplo abaixo pode esclarecer melhor os conceitos de classe e objeto. Ele declara uma classe Vetor, que representa vetores bidimensionais. As operações sobre tais objetos são: módulo, produto escalar, subtração e escrita em um arquivo. Veja como pode ser escrita essa classe.

// a classe Vetor define objetos que representam vetores bidimensionais
class Vetor {
 private: // as declarações abaixo são privativas (podem ser acessadas somente dentro da classe)

  double x, y;

 public: // as declarações abaixo são públicas, podendo ser acessadas de fora da classe

  // construtor da classe: um método especial que cria objetos desta classe
  Vetor(double px, double py) {
    // inicia o estado de um objeto
    x = px;
    y = py;
  }

  // destrutor da classe: um método especial que destrói objetos desta classe
  ~Vetor() {} // nada demais precisa ser feito

  // este método retorna o módulo do vetor
  double modulo() {
    return sqrt(x*x + y*y);
  }

  // este método retorna o produto escalar deste vetor com outro vetor
  double produto_escalar(const Vetor & outro) {
    return x*outro.x + y*outro.y;
  }

  // este método calcula a soma entre este e outro vetor (este + outro),
  // retornando um novo vetor como resultado
  Vetor adicione(const Vetor & outro) {
    Vetor novo(x+outro.x, y+outro.y);

    return novo;
  }

  // este método calcula a diferença entre este e outro vetor (este - outro),
  // retornando um novo vetor como resultado
  Vetor subtraia(const Vetor & outro) {
    Vetor novo(x-outro.x, y-outro.y);

    return novo;
  }

  // este método escreve uma representação do objeto no arquivo "out"
  // (que é um objeto da classe ostream)
  void mostreSe(ostream & out) {
    out << "(";
    out << x;
    out << ", ";
    out << y;
    out << ")";
  }

};

Uma vez existindo a classe Vetor, pode-se escrever um programa que use objetos dessa classe. No exemplo abaixo, calcula-se o vetor resultante de dois outros vetores:

int main() {
  int x, y;

  cout << "Coordenada X do vetor 1: ";
  cin >> x;
  cout << "Coordenada Y do vetor 1: ";
  cin >> y;
  cout << endl;

  // Aqui se cria o primeiro objeto Vetor
  Vetor v1(x, y);

  cout << "Coordenada X do vetor 2: ";
  // Aqui se lê pela entrada padrão a coordenada X
  cin >> x;
  cout << "Coordenada Y do vetor 2: ";
  // Aqui se lê pela entrada padrão a coordenada Y
  cin >> y;
  cout << endl;

  // Aqui se cria o segundo objeto Vetor
  Vetor v2(x, y);

  // Aqui se obtém a resultante dos vetores v1 e v2. Note como a operação "adicione"
  // do objeto "v1" é chamada.
  Vetor v3 = v1.adicione(v2);

  cout << "Vetor resultante: ";
  // Aqui se escreve uma representação de "v3" na tela. "cout" é um objeto da biblioteca C++ padrão
  // que representa a saída padrão de um processo. A saída padrão funciona como um arquivo. O objeto 
  // "cout" é similar ao "stdout" da linguagem C.
  v3.mostreSe(cout);
  cout << endl;
}

O programa em si se apresenta como um pequeno algoritmo que lê pela entrada padrão valores de coordenadas e cria os respectivos vetores (v1 e v2), calculando sua resultante a apresentando na saída padrão o novo vetor (v3).


Além das regras de escrita da linguagem, o que se denomina sintaxe, ressalta-se o uso dos objetos feito no programa. O pequeno programa criado trata de calcular a resultante de dois vetores bidimensionais. As coisas a serem diretamente manipuladas pelo programa são os vetores, sendo estes representado por objetos. Outros objetos usados são os arquivos que representam a entrada e saída padrão do programa (respectivamente cin e cout). O programa usa os objetos da classe Vetor, explorando as operações que eles oferecem. Assim, a declaração da classe Vetor se preocupa em definir o que é um objeto Vetor (seus atributos) e o que ele é capaz de fazer (seu comportamento). Já o programa apenas utiliza esses objetos.