Diferenças

Aqui você vê as diferenças entre duas revisões dessa página.

Link para esta página de comparações

Ambos lados da revisão anterior Revisão anterior
c:a_funcao_main [2023/08/01 17:12] – edição externa 127.0.0.1c:a_funcao_main [2023/08/15 11:55] (atual) maziero
Linha 1: Linha 1:
 +====== A função main ======
 +
 +{{ progc_funcao_main.mkv |Video desta aula}}
 +
 +{{ main.png?100|https://www.redbubble.com/i/framed-print/T-Shirt-programmer-main-function-by-mohammedisoft/32698776.AJ1A3}}A função ''main'' é o local de início (//[[https://en.wikipedia.org/wiki/Entry_point#C_and_C++|entry point]]//) da execução de um código em C. Apesar de termos usado até o momento essa função sem parâmetros, ela possui alguns parâmetros que permitem a comunicação entre o programa em C e o //shell// do sistema operacional.
 +
 +===== Protótipos =====
 +
 +O protótipo da função ''main'' depende do sistema operacional subjacente:
 +
 +<code c>
 +// padrão C ANSI
 +int main (void) ;
 +int main (int argc, char **argv) ;
 +int main (int argc, char *argv[]) ;
 +
 +// sistemas UNIX-like (Linux, FreeBSD, Solaris, ...) e Windows
 +int main (int argc, char **argv, char **envp) ;
 +
 +// sistemas Apple (MacOS, iOS)
 +int main (int argc, char **argv, char **envp, char **apple) ;
 +</code>
 +
 +===== Argumentos da linha de comando =====
 +
 +Significado dos parâmetros usuais:
 +
 +  * ''argc'': número de argumentos na linha de comando que lançou a execução;
 +  * ''argv'': vetor de strings (''char *'') contendo os argumentos da linha de comando, finalizado por um ponteiro nulo;
 +  * ''envp'': vetor de strings (''char *'') na forma "nome=valor" contendo as [[https://www.gnu.org/software/libc/manual/html_node/Environment-Variables.html|variáveis de ambiente]] exportadas pelo //shell// que lançou a execução do programa (também finalizado por um ponteiro nulo);
 +
 +O código a seguir imprime na tela os argumentos usados no lançamento do programa:
 +
 +<code c argv.c>
 +#include <stdio.h>
 +
 +int main (int argc, char **argv, char **envp)
 +{
 +  int i ;
 +
 +  printf ("Numero de argumentos: %d\n", argc) ;
 +
 +  for (i = 0; i < argc; i++)
 +    printf ("argv[%d]: %s\n", i, argv[i]) ;
 +
 +  return (0) ;
 +}
 +</code>
 +
 +Um exemplo de compilação e execução do código acima:
 +
 +  $ gcc argv.c -o argv -Wall
 +  
 +  $ ./argv teste 1 2 3 --help
 +  Numero de argumentos: 6
 +  argv[0]: ./argv
 +  argv[1]: teste
 +  argv[2]: 1
 +  argv[3]: 2
 +  argv[4]: 3
 +  argv[5]: --help
 +
 +===== Funções específicas =====
 +
 +Para ler e tratar mais facilmente as opções da linha de comando informadas por //argc/argv//, sugere-se usar funções já prontas para isso, como ''getopt'' ou ''arg_parse'' ([[https://www.gnu.org/software/libc/manual/html_node/Parsing-Program-Arguments.html#Parsing-Program-Arguments|link]])
 +
 +Eis um exemplo de uso da função ''getopt'' para a leitura de opções da linha de comando, adaptado do [[https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt|manual da GNU-LibC]]:
 +
 +<code c options.c>
 +#include <ctype.h>
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <unistd.h>
 +
 +int main (int argc, char **argv)
 +{
 +  int flag_a = 0;
 +  int flag_b = 0;
 +  char *value_c = NULL;
 +  int option;
 +
 +  opterr = 0;
 +
 +  // options:  -a, -b, -c value (defined by "abc:")
 +  while ((option = getopt (argc, argv, "abc:")) != -1)
 +    switch (option)
 +      {
 +      case 'a':      // option -a was set
 +        flag_a = 1;
 +        break;
 +      case 'b':      // option -b was set
 +        flag_b = 1;
 +        break;
 +      case 'c':      // option -c was set with value
 +        value_c = optarg;
 +        break;
 +     default:
 +        fprintf (stderr, "Usage: %s -a -b -c value\n", argv[0]);
 + exit (1) ;
 +      }
 +
 +  printf ("flag_a = %d, flag_b = %d, value_c = %s\n",
 +          flag_a, flag_b, value_c);
 +
 +  return 0;
 +}
 +</code>
 +
 +===== Status de saída =====
 +
 +Outro canal de interação importante entre o programa C e o sistema operacional é o valor de retorno da função ''main'', que é devolvido ao SO após a execução na forma de um //status// de saída (//exit status//).
 +
 +<code c retval.c>
 +#include <stdio.h>
 +
 +int main (int argc, char **argv, char **envp)
 +{
 +  return (14) ;
 +}
 +</code>
 +
 +O //status// de saída de um processo pode ser consultado no terminal UNIX (shell Bash) através da variavel ''$?'' disponível no shell:
 +
 +<code>
 +$ gcc retval.c -o retval -Wall
 +$ ./retval
 +$ echo $?
 +14
 +</code>
 +
 +O status de saída também pode ser usado em scripts do shell:
 +
 +<code sh testa-retorno.sh>
 +#!/bin/sh
 +
 +if retval
 +then
 +  # exit status is zero
 +  echo "true"
 +else
 +  # exit status is NOT zero
 +  echo "false"
 +fi
 +</code>
 +
 +===== Exercícios =====
 +
 +  - Escrever um programa que recebe uma lista de parâmetros na linha de comando. Ele não escreve nada na saída, mas devolve como //status// de saída o número de parâmetros que iniciam com o caractere "''-''".
 +  - Escrever um programa ''exists'', que recebe um nome (ou caminho) de arquivo na linha de comando e devolve, no //status// de saída,  0 se o arquivo existe ou 1 se ele não existe.
 +  - Escrever um programa para listar as variáveis de ambiente recebidas pelo programa (parâmetro ''envp'' da função ''main''); essas variáveis podem ser consultadas no terminal (//shell//) através do comando ''env''.