Funções#

Introdução#

As funções são uma componente fundamental da programação em C++, agrupando excertos de código em secções reutilizáveis ​​eficientes, concebidas para executar uma tarefa específica. Podem ser chamadas várias vezes dentro de um programa, facilitando a organização do código e ajudando a evitar repetições. Além disso, as funções tornam o código mais fácil de depurar.

Esta página aborda os conceitos básicos da utilização de funções em C++, incluindo:

Estrutura e sintaxe da função#

Em C++, as funções devem ser declaradas com o seu tipo de retorno, nome e parâmetros. A sintaxe básica é:

return_type function_name(parameters) {
  // Code to execute when the function is called
  return result;  // Optional, used to return a value
}

Componentes funcionais

Descrição

return_type

O tipo de dados que a função retorna, algumas opções comuns são:

  • void — Não retorna nada
  • int — Retorna um valor inteiro
  • double — Retorna um número de ponto flutuante
  • bool — Retorna true ou false
  • char — Retorna um único caractere
  • const char* — Retorna uma string de texto
  • tipos definidos pelo utilizador — Retorna uma struct ou um objeto de classe

function_name

O nome da função.

parameters

Opcional. Uma lista de parâmetros tipados, separados por vírgulas, escrita como type name, em que type especifica o tipo de dados do parâmetro e name é o identificador utilizado para aceder a esse valor dentro da função. Os parâmetros recebem valores de entrada quando a função é chamada.

result

Opcional. O valor devolvido pela função. Se o return_type da função não for return_typeeste valor deverá ser fornecido e o seu tipo deverá corresponder exatamente ao void.

Nota: Uma função deve ser sempre declarada antes de ser chamada, ou deve fornecer um protótipo de função.

Protótipos de função#

Em C++, o código é lido de cima para baixo. Isto significa que uma função precisa de ser conhecida pelo compilador antes de poder ser chamada.

Um protótipo de função permite-lhe utilizar uma função antes de escrever o seu código completo. Isto permite-lhe manter main() perto do início do seu programa, enquanto coloca as definições de funções posteriormente, onde são mais fáceis de organizar e ler.

Sem um protótipo, teria de definir todas as funções acima de main() main(), o que pode tornar os projetos mais difíceis de acompanhar à medida que crescem.

// The function's prototype
void greeting();

int main() {
  greeting();
}

// Write the function's body after
void greeting() {
  Brain.Screen.print("Hello!");
}

Definir e Chamar Funções#

Functions with No Parameters#

Se uma função não necessitar de entrada, pode defini-la sem parâmetros. Utilize void como tipo de retorno se a função não devolver um valor.

// Define a function to display a message
void greeting() {
    Brain.Screen.print("Hello!");
}

int main() {
    // Initializing Robot Configuration. DO NOT REMOVE!
    vexcodeInit();
    // Call the function to display the message
    greeting();
}

Functions with Parameters#

Pode também adicionar parâmetros às funções, o que permite passar informação para a função utilizar.

Nota: O texto pode ser passado utilizando strings do estilo C (const char*) ou strings C++ (std::string).

// Define a function with a parameter
void namedGreeting(const char* name) {
    Brain.Screen.print("Hello, %s!", name);
}

int main() {
    // Initializing Robot Configuration. DO NOT REMOVE!
    vexcodeInit();
    namedGreeting("Stranger");
}

Valores de retorno#

As funções podem enviar dados de volta para quem as chamou usando a palavra-chave return . Isto permite capturar e utilizar a saída no seu projeto.

// Define a function that multiplies numbers by 2
int timesTwo(int number) {
    return number * 2;
}

int main() {
    // Initializing Robot Configuration. DO NOT REMOVE!
    vexcodeInit();
    // Display the return value
    Brain.Screen.print("%d", timesTwo(2));
}

Passando por referência#

Por defeito, o C++ passa os parâmetros da função por valor, o que significa que a função recebe uma cópia da variável original. As alterações efetuadas dentro da função não afetam o valor original.

// Add 1 to the number
void addOne(int number) {
  number++;
}

int main() {
  int value = 5;
  addOne(value);
  // "value" will still be 5
}

Para permitir que uma função modifique a variável original, os parâmetros podem ser passados ​​por referência utilizando o símbolo &.

// Add 1 to the number
void addOne(int& number) {
  number++;
}

int main() {
  int value = 5;
  addOne(value);
  // "value" will now be 6
}

A passagem por referência permite que as funções atualizem variáveis definidas fora da função sem devolver um valor.

Funções de retorno de chamada#

Uma função de retorno de chamada (callback) é uma função que é passada para outra função e chamada automaticamente quando ocorre um evento específico.

As funções de callback (callbacks) são normalmente utilizadas para eventos como pressões de botões ou atualizações de sensores.

Em vez de chamar a função por si próprio, o projeto chama-a automaticamente quando o evento ocorre.

void onPressed() {
  Brain.Screen.print("Screen pressed!");
}

// Call onPressed whenever the screen is pressed
int main() {
  vexcodeInit();
  Brain.Screen.pressed(onPressed);
}

Callback Signatures#

Cada função de chamada de retorno deve seguir uma assinatura específica, que define:

  • O tipo de retorno

  • O número de parâmetros

  • Os tipos de parâmetros

A assinatura necessária é determinada pela API. A função de retorno de chamada deve corresponder exatamente a esta assinatura.

// This callback function cannot include any parameters
void callback(void);

// This callback function includes four parameters
void callback(axisType axis, double x, double y, double z);

Os nomes dos parâmetros são descritivos e podem variar, mas o tipo de retorno, a ordem dos parâmetros e os tipos de parâmetros devem corresponder exatamente.

Funções com argumentos padrão#

As funções podem definir valores padrão para um ou mais parâmetros. Um argumento padrão é utilizado quando não é fornecido nenhum valor para esse parâmetro no momento da chamada da função.

Regras para os argumentos padrão:

  • Os argumentos por defeito devem ser os últimos parâmetros na definição da função.

  • Uma vez que um parâmetro tem um valor padrão, todos os parâmetros subsequentes também devem ter valores padrão.

  • Se uma função especificar argumentos padrão no seu protótipo, estes valores padrão não deverão ser novamente especificados na definição da função.

// Required parameter first, default parameter last
void greeting(const char* name, int repeatCount = 1) {

    for (int i = 0; i < repeatCount; i++) {
        Brain.Screen.print("Hello, %s!", name);
        Brain.Screen.newLine();
    }
}

int main() {
    vexcodeInit();

    // Say what name to greet (V5) and
    // use default value for repeatCount (1)
    greeting("V5");

    Brain.Screen.newLine();

    // Overrides the default value to 3
    greeting("V5", 3);
}