CPP - alandrade21/docsCompartilhados GitHub Wiki

Nesse documento:

GCC

Testa se o GCC está instalado com o comando gcc.

Se estiver instalado vai dar erro de arquivo de entrada não especificado. Se não estiver instalado, vai dar erro de comando não encontrado.

Se não estiver instalado, instala com:

sudo apt install gcc
sudo apt install g++
sudo apt install gdb
sudo apt install clang

Para verificar as versões instaladas, rode cada comando com a opção -v ou --version.

Compilando e linkando em um passo

g++ -Wall -g -o hello hello.cpp

As opções significam:

  • -Wall: Mostra todos os warnings.
  • -g: Gera build para debug.
  • -o: Especifica o nome do arquivo de saída

Compilando e linkando em dois passos

g++ -c -Wall -g hello.cpp

Só compila. Isso é indicado pela opção -c, e gera hello.o.

g++ -g -o Hello.exe hello.o

Só linka.

VSCode

Instala a extensão c/c++.

Abre uma pasta e cria o primeiro arquivo .cpp. A IDE vai reconhecer como C++ e carregar o intelisense.

Build

Para buildar, vai no menu Terminal | Configure Default Build Task....

Seleciona from template e escolhe other.

Vai criar um arquivo tasks.json na pasta .vscode.

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build",
      "type": "shell",
      "command": "g++ -Wall -g -o hello hello.cpp", --> Linha de comando que vai ser rodada
      "group": {
        "kind": "build",
        "isDefault": true -->  Indica que é esse que vai ser rodado em Terminal>Run Build Task...
      },
      "problemMatcher":"$gcc" --> Permite alimentar a aba Problems.
    }
  ]
}

Para rodar, vai no terminal e roda o programa.

Para buildar projetos mais complicados, no lugar de rodar o g++, pode rodar um shell script que dispara o build.

Geralmente esse .sh fica dentro da pasta .vscode (se esse for o caso, o primeiro comando é dar um CD para a pasta do código.

Debug

Para debugar, vai na aba lateral de debug e ao rodar o debug cria uma nova configuração.

Cria o arquivo launch.json em .vscode.

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "(gdb) Launch",
      "type": "cppdbg",
      "request": "launch",
      "preLaunchTask": "build",    --> Isso faz recompilar. É a task criada acima
      "program": "${workspaceFolder}/hello",    --> Configura isso.
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": true,
      "MIMode": "gdb",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ]
    }
  ]
}

O debug roda num terminal em separado.

Easy C++ Project Extension

Instala a extensão easy c++ projects. Essa extensão cria um novo projeto com uma estrutura de pastas padrão e um arquivo make.

Para criar um novo projeto, crie a pasta no disco e abra-a na IDE. Aperte F1 para abrir o prompt de comando da IDE e digite easy. Localize a opção Create new C++ project. Ele vai perguntar qual compilador utilizar e qual pasta utilizar.

Para rodar o projeto, utilize a opção Build & Run na barra de status.

Linguagem

Main Function

O método int main() é o ponto de entrada do programa. Se ele não retornar nada, o valor 0 é automaticamente retornado.

Para passar parâmetros via linha de comando, o método main foca assim: int main(int argc, char *argv[]).

argc é a quantidade de parâmetros passados, uma vez que será necessário acessar memória via o array de ponteiros para strings argv.

Includes

Um include com <>, por exemplo #include <iostrem>, indica que o arquivo inserido deve ser buscado no diretório padrão do sistema em os arquivos de cabeçalho são armazenados. Tb é possível fornecer um caminho relativo para o cabeçalho importado, nesse caso, ao incés de <> usa-se "".

Cabeçalhos do C++ geralmente não tem a extensão .h, como os do C.

I/O

I/O está na lib iostream da STD.

Imprime coisas no console com cout.

#include <iostream>
...
std::cout << "teste" << std::endl;

Pra não ter que ficar repetindo std:: usa:

#include <iostream>
...
using namespace std;
std::cout << "teste" << std::endl;

Entra dados do console com cin.

using namespace std;
int age = 0;
cout << "Please, enter an age:" << endl;
cin >> age;
cout << "You entered:" << age << endl;

cerr imprime na standard error output.

Tipos

  • int para números inteiros. Ocupa 4 bytes.
  • float para números decimais com até 7 casas decimais. Ocupa 4 bytes.
  • double tb para números demais, mas com até 15 casas decimais. Ocupa 8 bytes.
  • bool para booleano. os valores são true e false. false é traduzido para 0 (zero). Ocupa 1 byte.
  • char guarda um caractere ASCII. Ocupa 1 byte.

Modificadores

  • signed
  • unsigned: Não permite valores negativos.
  • short: Meia o tamanho do tipo
  • long: Dobra o tamanho do tipo

coloca unsigned na frente do tipo para não permitir valores negativos:

unsigned int idade;

sizeof

O operador sizeof diz o tamanho em bytes de um tipo:

cout << "Size of int: " << sizeof(int) << endl;

A linha acima retorna 4, que é o tamanho em bytes do tipo int. É possível fazer o teste numa variável:

int value = 10;
cout << "Size of value: " << sizeof(value) << endl;

Dá o mesmo resultado 4 bytes.

sizeof(string) retorna 32 bytes, independente da quantidade de caracteres presentes na string. Isso pq sizeof mede o tamanho do objeto string, e não da cadeia de caracteres em si.

Constantes

const double pi = 3.1415

enums

enum Color {
  red,green,blue
};

Color myColor = Color::blue;

Enums são zero base indexed.

Pode redefinir os indices.

enum Color 
{
  red = 100,green = 50,blue = 256
};

Structures

Criam data types.

struct product
{
  int weight;
  double value;
  Color color; //enum
};

product laptop;

laptop.value = 540.87;

Arrays

Arrays basta serem declarados. Não é necessário criar como em java.

int values[3]; // Cria um array de 3 posições.
values[0] = 88;

As posições dos arrays não são inicializadas. Após a criação elas contém lixo. A linha abaixo cria e inicializa um array:

int values[3] = {88, 123, 7};

Para inicializar com o valor default do tipo:

int values[3] = {};

C++ não tem um array index out of bounds. Se vc acessar uma posição além do final do array, ele vai permitir o acesso a uma posição de memória que contém lixo.

Para saber o tamanho do array em tempo de execução, usa o operador sizeof:

int values[] = {7, 9, 11};

cout << "Size of values: " << sizeof(values) << "bytes" << endl;
// resulta 12 bytes. 3 posições x 4 bytes do int.

cout << "Size of values: " << sizeof(values)/sizeof(int) << "posições" << endl;
// Resulta 3 elementos.

Em arrays multidimensionais:

string multidimensional[2][3] = {
  {"01.01", "01.02", "01.03"},
  {"02.01", "02.02", "02.03"}
};

cout << "Número de linhas: " << sizeof(multidimensional)/sizeof(multidimensional[0]) << endl;
cout << "Número de colunas: " << sizeof(multidimensional[0])/sizeof(string) << endl;

IF

int age = 0;
cout << "Enter your age:" << endl;
cin >> age;

if(age == 0) cout << "erro" << endl;

Se o cin acima ler uma string, o if resolve como true.

Ponteiros

char* p; declara um ponteiro para um char.

char v[6];
char* p = &v[3];
char x = *p;

No exemplo acima, o prefixo unário * significa "conteúdo de", enquanto o prefixo unário & significa "endereço de".

int& v; é uma referência. Uma referência é similar a um ponteiro, sendo que não é necessário utilizar o prefixo * para acessar o elemento apontado. Além disso, uma referência não pode mudar seu apontamento depois da inicialização.

int* var = nullptr; é um ponteiro com valor nulo.

Se o elemento apontado for um objeto, para acessar os atributos desse objeto:

void f(Vector v, Vector& rv, Vector* pv) {
  int i1 = v.sz;    // Acessando via nome.
  int i2 = rv.sz;   // Acessando via referência.
  int i3 = pv->sz;  // Acessando via ponteiro.
}

Ponteiros são gerenciados pelo programador. É preciso alocar e desalocar memória para eles:

Object *o = new Object(); // Alocação da memória
...
delete o; // Liberação da memória.

Libs Interessantes

limits

Tem constantes referentes aos valores máximos e mínimos de cada tipo.

Qt

Core

Lib QCoreApplication.

Qt I/O

Imprime coisas no console com qInfo().

qInfo() << "Coisa a ser impressa" << "Manis coisa a ser impressa";

qDebug() imprime uma mensagem de debug no console.

qCritical() imprime uma mensagem de erro crítico no console.

qFatal()imprime uma mensagem de erro fatal e crasha o sistema.

qWarning() imprime um warning no console.

Dá pra interceptar essas mensagens e fazer um tratamento mais interessante, como mandar pra um arquivo de log.

⚠️ **GitHub.com Fallback** ⚠️